@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,8 +1,166 @@
1
- import type { S3Client } from '@aws-sdk/client-s3';
2
1
  /**
3
- * Idempotently ensure a `${ttlDays}`-day expiration lifecycle rule exists for
4
- * `prefix`. Reads existing rules, preserves user-defined ones, and only
5
- * adds/updates the library's prefix-scoped rule.
2
+ * Hides the bucket lifecycle configuration this package maintains.
3
+ *
4
+ * Two rules per prefix — one expiring objects a day after the ttl plus the
5
+ * sweep margin and keeping a released payload's noncurrent version for a grace
6
+ * window, one reclaiming expired delete markers — are written without
7
+ * disturbing any other rule on the bucket, rewritten only when they differ,
8
+ * and followed by a report of whether the bucket keeps versions at all.
6
9
  */
7
- export declare function ensureLifecycleRule(client: S3Client, bucket: string, prefix: string, ttlDays: number): Promise<void>;
8
- //# sourceMappingURL=lifecycle.d.ts.map
10
+ import type { LifecycleRule, S3Client } from '@aws-sdk/client-s3';
11
+ import type { Logger } from '../../logging/logger';
12
+ /**
13
+ * Days a released payload's noncurrent version survives behind its delete
14
+ * marker before S3 reclaims it. One day is the smallest the lifecycle API
15
+ * accepts and it rounds up to the next UTC midnight, so the window is 24-48 h:
16
+ * long enough to restore a payload released in error, short enough that a
17
+ * versioned bucket does not pay for every release it has ever made. It is a
18
+ * floor and never a cap — a longer retention the bucket already carries is
19
+ * kept, because this package has no business shortening someone else's
20
+ * recovery window. Inert on an unversioned bucket, which has no noncurrent
21
+ * versions to expire.
22
+ */
23
+ export declare const S3_RELEASE_GRACE_DAYS = 1;
24
+ /** The rules to ensure: on which bucket, for which prefix, expiring after how many days. */
25
+ export interface LifecycleTarget {
26
+ readonly bucket: string;
27
+ readonly prefix: string;
28
+ readonly days: number;
29
+ }
30
+ /**
31
+ * Ensure the two rules scoped to `target.prefix` exist on `target.bucket`: a
32
+ * `target.days`-day expiration for current versions, and the reclaim that
33
+ * removes the delete marker a released payload leaves behind.
34
+ *
35
+ * Accepts: `target.prefix` — re-checked for scoping here, because these rules
36
+ * are the one place an unscoped prefix would destroy data outside this
37
+ * library's. `target.days` — the current-version expiry only. Released
38
+ * versions are governed by the release grace instead (see {@link ttlRule}),
39
+ * which is a floor measured against every rule already governing these keys.
40
+ * Both are inert on an unversioned bucket, which keeps no noncurrent version
41
+ * and leaves no marker.
42
+ *
43
+ * Returns: nothing. Idempotent: when both rules already say this, no write is
44
+ * issued. The bucket's versioning state is reported either way, because the
45
+ * containment a released payload depends on is missing or present regardless
46
+ * of whether this particular call had a rule to write.
47
+ *
48
+ * Throws: `VALIDATION` naming `s3.keyPrefix` for an unscoped prefix, or when
49
+ * either rule id this prefix produces is already held by a different prefix
50
+ * (see {@link assertNoIdCollision}); otherwise whatever the SDK rejects with. A
51
+ * bucket with no lifecycle configuration at all is not an error — S3 reports
52
+ * `NoSuchLifecycleConfiguration` and this starts from an empty rule set.
53
+ *
54
+ * Guarantees: rules this package did not write are preserved, and so is the
55
+ * bucket-level `TransitionDefaultMinimumObjectSize` — a Put replaces the whole
56
+ * configuration, so dropping it would silently reset the bucket to the default.
57
+ */
58
+ export declare function ensureLifecycleRule(client: S3Client, target: LifecycleTarget, logger: Logger): Promise<void>;
59
+ /** The rule to build: its id, its prefix, and the days after which current versions expire. */
60
+ interface RuleTarget {
61
+ readonly id: string;
62
+ readonly prefix: string;
63
+ readonly days: number;
64
+ }
65
+ /**
66
+ * The rule that expires current versions on the TTL's schedule and released
67
+ * ones on the grace.
68
+ *
69
+ * Accepts: `rules` — everything the bucket holds, which is what the grace is
70
+ * measured against. `existing` — the rule this one replaces, if any.
71
+ *
72
+ * Returns: the rule to write. Every field of `existing` this package does not
73
+ * manage is carried through, because the rewrite a changed TTL triggers is
74
+ * otherwise unrecoverable: the next call reads the rewritten rule as already
75
+ * correct and never restores what it dropped.
76
+ *
77
+ * Throws: nothing.
78
+ *
79
+ * Guarantees: the `Expiration` is replaced rather than merged. Merging this
80
+ * package's `Days` into a `Date` an operator set would change the expiry they
81
+ * configured, whatever the service made of the pair.
82
+ */
83
+ export declare function ttlRule(rule: RuleTarget, rules: readonly LifecycleRule[], existing?: LifecycleRule): LifecycleRule;
84
+ /**
85
+ * The rule that reclaims the delete marker a release leaves, once its last
86
+ * noncurrent version has expired.
87
+ *
88
+ * Accepts: `existing` — the rule this one replaces, if any.
89
+ *
90
+ * Returns: the rule to write, a second one rather than a field on the TTL
91
+ * rule: S3 refuses `ExpiredObjectDeleteMarker` inside an `Expiration` that
92
+ * also carries `Days`, so each rule's `Expiration` holds its own half and
93
+ * nothing of the other's. Fields this package does not manage are carried
94
+ * through as they are on the TTL rule — this id is one this package invented,
95
+ * but that is no reason to drop what an operator has since put on it.
96
+ *
97
+ * Throws: nothing.
98
+ */
99
+ export declare function markerRule(id: string, prefix: string, existing?: LifecycleRule): LifecycleRule;
100
+ /**
101
+ * Refuse to touch a rule that carries one of this prefix's ids but scopes a
102
+ * different prefix. Three shapes reach here: slugging maps every
103
+ * non-alphanumeric character to `-`, so `app/langgraph/` and `app-langgraph/`
104
+ * produce one id; the marker rule appends `-markers`, so `app/`'s marker id is
105
+ * the expiration id of `app-markers/`; and a rule written in the older schema
106
+ * holds an id this package would take while naming its scope in the top-level
107
+ * `Prefix`.
108
+ *
109
+ * Accepts: `rule` — the rule holding `id`, or nothing. `prefix` — the one this
110
+ * call scopes rules to.
111
+ *
112
+ * Returns: nothing: `rule` is kept under its declared type, and this checks
113
+ * it. A rule naming no scope anywhere is taken over, and so is one already
114
+ * scoping this prefix — including in the older schema, which is then upgraded
115
+ * to a filter.
116
+ *
117
+ * Throws: `VALIDATION` naming `s3.keyPrefix`. The id and the scope are
118
+ * both bounded by {@link truncateForLog}: the scope is whatever the bucket's
119
+ * lifecycle configuration holds, and the id is composed from an
120
+ * `s3.keyPrefix` checked for shape and never for length.
121
+ *
122
+ * Guarantees: the scope is read wherever the rule names it, through the same
123
+ * {@link scopeOf} the floor uses. Reading only `Filter.Prefix` would let a
124
+ * rule in the older schema through, and the rewrite would then replace its
125
+ * scope with this one's — so the objects that rule governs would silently
126
+ * lose their expiration, and a bucket-wide rule would narrow to this prefix.
127
+ */
128
+ export declare function assertNoIdCollision(rule: LifecycleRule | undefined, prefix: string, id: string): void;
129
+ /**
130
+ * Whether the rule the bucket carries already says what would be written.
131
+ *
132
+ * Accepts: `existing` — the held rule, or nothing. `desired` — what a write
133
+ * would put there.
134
+ *
135
+ * Returns: whether a write can be skipped. A rule in the older schema never
136
+ * matches, because it names its prefix somewhere this does not read, so it is
137
+ * rewritten once into a filter and matches from then on.
138
+ *
139
+ * Throws: nothing.
140
+ */
141
+ export declare function alreadyCorrect(existing: LifecycleRule | undefined, desired: LifecycleRule): boolean;
142
+ /**
143
+ * Report whether `bucket` keeps versions, which is the whole of the recovery
144
+ * window behind a released payload.
145
+ *
146
+ * Accepts: `bucket` — the offload bucket. `logger` — the adapter's; silent by
147
+ * default, like every other event this package emits.
148
+ *
149
+ * Returns: nothing. A versioned bucket is silent; the other two states warn
150
+ * and name their own remedy, because those remedies differ — a bucket that
151
+ * never had versioning needs it enabled, while a suspended one needs it
152
+ * re-enabled *and* an accounting of what suspension has already destroyed.
153
+ *
154
+ * Throws: nothing, deliberately. A failure of the call itself is a `warn` too,
155
+ * including the `AccessDenied` of a role that provisioned lifecycle rules
156
+ * yesterday without this action: a permission the call did not need then must
157
+ * not break it now. This runs after the rules are written for the same reason
158
+ * — a bucket that cannot answer still gets them.
159
+ *
160
+ * Guarantees: a bucket that has never been versioned answers with an empty
161
+ * body, so the absent state is `Status === undefined`. It is never the string
162
+ * `'Disabled'`, which this API does not return, and testing for one would read
163
+ * an unversioned bucket as a versioned one.
164
+ */
165
+ export declare function reportBucketVersioning(client: S3Client, bucket: string, logger: Logger): Promise<void>;
166
+ export {};
@@ -1,47 +1,355 @@
1
1
  "use strict";
2
+ /**
3
+ * Hides the bucket lifecycle configuration this package maintains.
4
+ *
5
+ * Two rules per prefix — one expiring objects a day after the ttl plus the
6
+ * sweep margin and keeping a released payload's noncurrent version for a grace
7
+ * window, one reclaiming expired delete markers — are written without
8
+ * disturbing any other rule on the bucket, rewritten only when they differ,
9
+ * and followed by a report of whether the bucket keeps versions at all.
10
+ */
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.S3_RELEASE_GRACE_DAYS = void 0;
3
13
  exports.ensureLifecycleRule = ensureLifecycleRule;
14
+ exports.ttlRule = ttlRule;
15
+ exports.markerRule = markerRule;
16
+ exports.assertNoIdCollision = assertNoIdCollision;
17
+ exports.alreadyCorrect = alreadyCorrect;
18
+ exports.reportBucketVersioning = reportBucketVersioning;
19
+ const classify_1 = require("../../errors/classify");
20
+ const errors_1 = require("../../errors/errors");
21
+ const truncate_1 = require("../../logging/truncate");
4
22
  const client_1 = require("./client");
5
23
  const config_1 = require("./config");
6
- async function readRules(client, bucket) {
24
+ /**
25
+ * Days a released payload's noncurrent version survives behind its delete
26
+ * marker before S3 reclaims it. One day is the smallest the lifecycle API
27
+ * accepts and it rounds up to the next UTC midnight, so the window is 24-48 h:
28
+ * long enough to restore a payload released in error, short enough that a
29
+ * versioned bucket does not pay for every release it has ever made. It is a
30
+ * floor and never a cap — a longer retention the bucket already carries is
31
+ * kept, because this package has no business shortening someone else's
32
+ * recovery window. Inert on an unversioned bucket, which has no noncurrent
33
+ * versions to expire.
34
+ */
35
+ exports.S3_RELEASE_GRACE_DAYS = 1;
36
+ async function readState(client, bucket) {
7
37
  const { GetBucketLifecycleConfigurationCommand } = await (0, client_1.loadS3Sdk)();
8
38
  try {
9
39
  const existing = await client.send(new GetBucketLifecycleConfigurationCommand({ Bucket: bucket }));
10
- return existing.Rules ?? [];
40
+ return {
41
+ rules: existing.Rules ?? [],
42
+ transitionDefaultMinimumObjectSize: existing.TransitionDefaultMinimumObjectSize,
43
+ };
11
44
  }
12
45
  catch (error) {
13
- if (error.name === 'NoSuchLifecycleConfiguration')
14
- return [];
46
+ if ((0, classify_1.isMissingLifecycleConfiguration)(error))
47
+ return { rules: [] };
15
48
  throw error;
16
49
  }
17
50
  }
18
- function alreadyCorrect(rule, ttlDays) {
19
- return rule?.Status === 'Enabled' && rule.Expiration?.Days === ttlDays;
51
+ /** `rules` with `rule` replacing the one holding its id, or appended when none does. */
52
+ function upsert(rules, rule) {
53
+ return rules.some((held) => held.ID === rule.ID)
54
+ ? rules.map((held) => (held.ID === rule.ID ? rule : held))
55
+ : [...rules, rule];
56
+ }
57
+ /** Replace the bucket's whole configuration with `rules`, carrying its own field back. */
58
+ async function putRules(client, bucket, state, rules) {
59
+ const { PutBucketLifecycleConfigurationCommand } = await (0, client_1.loadS3Sdk)();
60
+ await client.send(new PutBucketLifecycleConfigurationCommand({
61
+ Bucket: bucket,
62
+ LifecycleConfiguration: { Rules: rules },
63
+ ...(state.transitionDefaultMinimumObjectSize === undefined
64
+ ? {}
65
+ : { TransitionDefaultMinimumObjectSize: state.transitionDefaultMinimumObjectSize }),
66
+ }));
20
67
  }
21
68
  /**
22
- * Idempotently ensure a `${ttlDays}`-day expiration lifecycle rule exists for
23
- * `prefix`. Reads existing rules, preserves user-defined ones, and only
24
- * adds/updates the library's prefix-scoped rule.
69
+ * Ensure the two rules scoped to `target.prefix` exist on `target.bucket`: a
70
+ * `target.days`-day expiration for current versions, and the reclaim that
71
+ * removes the delete marker a released payload leaves behind.
72
+ *
73
+ * Accepts: `target.prefix` — re-checked for scoping here, because these rules
74
+ * are the one place an unscoped prefix would destroy data outside this
75
+ * library's. `target.days` — the current-version expiry only. Released
76
+ * versions are governed by the release grace instead (see {@link ttlRule}),
77
+ * which is a floor measured against every rule already governing these keys.
78
+ * Both are inert on an unversioned bucket, which keeps no noncurrent version
79
+ * and leaves no marker.
80
+ *
81
+ * Returns: nothing. Idempotent: when both rules already say this, no write is
82
+ * issued. The bucket's versioning state is reported either way, because the
83
+ * containment a released payload depends on is missing or present regardless
84
+ * of whether this particular call had a rule to write.
85
+ *
86
+ * Throws: `VALIDATION` naming `s3.keyPrefix` for an unscoped prefix, or when
87
+ * either rule id this prefix produces is already held by a different prefix
88
+ * (see {@link assertNoIdCollision}); otherwise whatever the SDK rejects with. A
89
+ * bucket with no lifecycle configuration at all is not an error — S3 reports
90
+ * `NoSuchLifecycleConfiguration` and this starts from an empty rule set.
91
+ *
92
+ * Guarantees: rules this package did not write are preserved, and so is the
93
+ * bucket-level `TransitionDefaultMinimumObjectSize` — a Put replaces the whole
94
+ * configuration, so dropping it would silently reset the bucket to the default.
25
95
  */
26
- async function ensureLifecycleRule(client, bucket, prefix, ttlDays) {
27
- const ruleId = (0, config_1.buildLifecycleRuleId)(prefix);
28
- const rules = await readRules(client, bucket);
29
- const existing = rules.find((rule) => rule.ID === ruleId);
30
- if (alreadyCorrect(existing, ttlDays))
31
- return;
32
- const newRule = {
33
- ID: ruleId,
96
+ async function ensureLifecycleRule(client, target, logger) {
97
+ (0, config_1.assertScopedKeyPrefix)(target.prefix);
98
+ const ttlId = (0, config_1.buildLifecycleRuleId)(target.prefix);
99
+ const markerId = (0, config_1.buildMarkerRuleId)(target.prefix);
100
+ const state = await readState(client, target.bucket);
101
+ const heldTtl = state.rules.find((rule) => rule.ID === ttlId);
102
+ const heldMarker = state.rules.find((rule) => rule.ID === markerId);
103
+ assertNoIdCollision(heldTtl, target.prefix, ttlId);
104
+ assertNoIdCollision(heldMarker, target.prefix, markerId);
105
+ const expiry = ttlRule({ id: ttlId, prefix: target.prefix, days: target.days }, state.rules, heldTtl);
106
+ const reclaim = markerRule(markerId, target.prefix, heldMarker);
107
+ if (!alreadyCorrect(heldTtl, expiry) || !alreadyCorrect(heldMarker, reclaim)) {
108
+ await putRules(client, target.bucket, state, upsert(upsert(state.rules, expiry), reclaim));
109
+ }
110
+ await reportBucketVersioning(client, target.bucket, logger);
111
+ }
112
+ /**
113
+ * The prefix a rule governs, wherever it names one: in its filter, nested
114
+ * under the filter's `And` beside tags or size bounds, or in the top-level
115
+ * `Prefix` of a rule written before `Filter` existed. `undefined` means the
116
+ * rule names no prefix at all — it is bucket-wide, or filtered only by tags or
117
+ * object size — and a rule like that governs every key here.
118
+ */
119
+ function scopeOf(rule) {
120
+ return rule.Filter?.Prefix ?? rule.Filter?.And?.Prefix ?? rule.Prefix;
121
+ }
122
+ /**
123
+ * Whether `rule` governs every key under `prefix`.
124
+ *
125
+ * Only an enabled rule does. A disabled one expires nothing, so it cannot
126
+ * shorten anyone's window and must not lengthen this package's either: an
127
+ * operator who disables their own retention rule to hand the job over would
128
+ * otherwise pin this package at that rule's value for good. A rule scoped
129
+ * beside this prefix governs none of its keys and one scoped beneath it only
130
+ * some, so neither of them speaks for all of them.
131
+ */
132
+ function governs(rule, prefix) {
133
+ const scope = scopeOf(rule);
134
+ return rule.Status === 'Enabled' && (scope === undefined || prefix.startsWith(scope));
135
+ }
136
+ /**
137
+ * The noncurrent retention to write: the longest one already governing these
138
+ * keys, and never less than the release grace.
139
+ *
140
+ * S3 honours the **shorter** of two overlapping expirations, so a rule this
141
+ * package does not own decides how long a released payload really survives
142
+ * under its prefix. Writing the grace beside a bucket-wide 90-day retention
143
+ * would cut that window to a day for every key here, which is the opposite of
144
+ * what a floor is for.
145
+ *
146
+ * The rule being replaced counts whatever its status, unlike every other rule
147
+ * here: that value is this package's own committed floor rather than a
148
+ * constraint someone else placed on these keys, and `Status` has nothing to say
149
+ * about it. An operator who disables the rule to pause expiry during an
150
+ * incident would otherwise find the recovery window cut to the grace on the
151
+ * next deploy — a second way down from the ratchet, and a silent one.
152
+ *
153
+ * The rule this package writes is itself in the set, so the floor ratchets: a
154
+ * value written once outlives the rule that justified it, and the way back
155
+ * down is to delete this package's rule and let it be written afresh.
156
+ */
157
+ function noncurrentDays(rules, prefix, existing) {
158
+ const held = rules
159
+ .filter((rule) => governs(rule, prefix))
160
+ .map((rule) => rule.NoncurrentVersionExpiration?.NoncurrentDays ?? 0);
161
+ return Math.max(...held, existing?.NoncurrentVersionExpiration?.NoncurrentDays ?? 0, exports.S3_RELEASE_GRACE_DAYS);
162
+ }
163
+ /**
164
+ * What a rewrite carries over from the rule it replaces: everything this
165
+ * package does not set itself, less the top-level `Prefix`.
166
+ *
167
+ * That `Prefix` is how a rule written before `Filter` existed names its scope,
168
+ * and the two are alternatives rather than a pair — S3 refuses a rule carrying
169
+ * both, which would fail the provisioning call this package documents as a
170
+ * deployment step. Such a rule is upgraded to a filter, never merged with one.
171
+ */
172
+ function carried(existing) {
173
+ const kept = { ...existing };
174
+ delete kept.Prefix;
175
+ return kept;
176
+ }
177
+ /**
178
+ * The rule that expires current versions on the TTL's schedule and released
179
+ * ones on the grace.
180
+ *
181
+ * Accepts: `rules` — everything the bucket holds, which is what the grace is
182
+ * measured against. `existing` — the rule this one replaces, if any.
183
+ *
184
+ * Returns: the rule to write. Every field of `existing` this package does not
185
+ * manage is carried through, because the rewrite a changed TTL triggers is
186
+ * otherwise unrecoverable: the next call reads the rewritten rule as already
187
+ * correct and never restores what it dropped.
188
+ *
189
+ * Throws: nothing.
190
+ *
191
+ * Guarantees: the `Expiration` is replaced rather than merged. Merging this
192
+ * package's `Days` into a `Date` an operator set would change the expiry they
193
+ * configured, whatever the service made of the pair.
194
+ */
195
+ function ttlRule(rule, rules, existing) {
196
+ return {
197
+ ...carried(existing),
198
+ ID: rule.id,
199
+ Filter: { Prefix: rule.prefix },
200
+ Status: 'Enabled',
201
+ Expiration: { Days: rule.days },
202
+ NoncurrentVersionExpiration: {
203
+ ...existing?.NoncurrentVersionExpiration,
204
+ NoncurrentDays: noncurrentDays(rules, rule.prefix, existing),
205
+ },
206
+ };
207
+ }
208
+ /**
209
+ * The rule that reclaims the delete marker a release leaves, once its last
210
+ * noncurrent version has expired.
211
+ *
212
+ * Accepts: `existing` — the rule this one replaces, if any.
213
+ *
214
+ * Returns: the rule to write, a second one rather than a field on the TTL
215
+ * rule: S3 refuses `ExpiredObjectDeleteMarker` inside an `Expiration` that
216
+ * also carries `Days`, so each rule's `Expiration` holds its own half and
217
+ * nothing of the other's. Fields this package does not manage are carried
218
+ * through as they are on the TTL rule — this id is one this package invented,
219
+ * but that is no reason to drop what an operator has since put on it.
220
+ *
221
+ * Throws: nothing.
222
+ */
223
+ function markerRule(id, prefix, existing) {
224
+ return {
225
+ ...carried(existing),
226
+ ID: id,
34
227
  Filter: { Prefix: prefix },
35
228
  Status: 'Enabled',
36
- Expiration: { Days: ttlDays },
229
+ Expiration: { ExpiredObjectDeleteMarker: true },
37
230
  };
38
- const merged = existing
39
- ? rules.map((rule) => (rule.ID === ruleId ? newRule : rule))
40
- : [...rules, newRule];
41
- const { PutBucketLifecycleConfigurationCommand } = await (0, client_1.loadS3Sdk)();
42
- await client.send(new PutBucketLifecycleConfigurationCommand({
43
- Bucket: bucket,
44
- LifecycleConfiguration: { Rules: merged },
45
- }));
46
231
  }
47
- //# sourceMappingURL=lifecycle.js.map
232
+ /**
233
+ * Refuse to touch a rule that carries one of this prefix's ids but scopes a
234
+ * different prefix. Three shapes reach here: slugging maps every
235
+ * non-alphanumeric character to `-`, so `app/langgraph/` and `app-langgraph/`
236
+ * produce one id; the marker rule appends `-markers`, so `app/`'s marker id is
237
+ * the expiration id of `app-markers/`; and a rule written in the older schema
238
+ * holds an id this package would take while naming its scope in the top-level
239
+ * `Prefix`.
240
+ *
241
+ * Accepts: `rule` — the rule holding `id`, or nothing. `prefix` — the one this
242
+ * call scopes rules to.
243
+ *
244
+ * Returns: nothing: `rule` is kept under its declared type, and this checks
245
+ * it. A rule naming no scope anywhere is taken over, and so is one already
246
+ * scoping this prefix — including in the older schema, which is then upgraded
247
+ * to a filter.
248
+ *
249
+ * Throws: `VALIDATION` naming `s3.keyPrefix`. The id and the scope are
250
+ * both bounded by {@link truncateForLog}: the scope is whatever the bucket's
251
+ * lifecycle configuration holds, and the id is composed from an
252
+ * `s3.keyPrefix` checked for shape and never for length.
253
+ *
254
+ * Guarantees: the scope is read wherever the rule names it, through the same
255
+ * {@link scopeOf} the floor uses. Reading only `Filter.Prefix` would let a
256
+ * rule in the older schema through, and the rewrite would then replace its
257
+ * scope with this one's — so the objects that rule governs would silently
258
+ * lose their expiration, and a bucket-wide rule would narrow to this prefix.
259
+ */
260
+ function assertNoIdCollision(rule, prefix, id) {
261
+ if (rule === undefined)
262
+ return;
263
+ const found = scopeOf(rule);
264
+ if (found === undefined || found === prefix)
265
+ return;
266
+ throw (0, errors_1.validationError)(`the S3 lifecycle rule id "${(0, truncate_1.truncateForLog)(id)}" is already used by the prefix ` +
267
+ `"${(0, truncate_1.truncateForLog)(found)}"; an id is the key ` +
268
+ 'prefix with every non-alphanumeric character replaced by "-", and the marker rule appends ' +
269
+ '"-markers" to that, so "a/b/" takes the id of "a-b/" and "app/" takes the marker id of ' +
270
+ '"app-markers/" — choose an s3.keyPrefix that produces neither id of any other prefix on ' +
271
+ 'this bucket', 's3.keyPrefix');
272
+ }
273
+ /**
274
+ * The fields this package manages on a rule, as one value two rules compare
275
+ * by. Comparing whole rules would issue a write on every call over a field S3
276
+ * reports and this package never sets.
277
+ */
278
+ function managedShape(rule) {
279
+ return JSON.stringify([
280
+ rule?.Status,
281
+ rule?.Filter?.Prefix,
282
+ rule?.Expiration?.Days,
283
+ rule?.Expiration?.ExpiredObjectDeleteMarker,
284
+ rule?.NoncurrentVersionExpiration?.NoncurrentDays,
285
+ ]);
286
+ }
287
+ /**
288
+ * Whether the rule the bucket carries already says what would be written.
289
+ *
290
+ * Accepts: `existing` — the held rule, or nothing. `desired` — what a write
291
+ * would put there.
292
+ *
293
+ * Returns: whether a write can be skipped. A rule in the older schema never
294
+ * matches, because it names its prefix somewhere this does not read, so it is
295
+ * rewritten once into a filter and matches from then on.
296
+ *
297
+ * Throws: nothing.
298
+ */
299
+ function alreadyCorrect(existing, desired) {
300
+ return managedShape(existing) === managedShape(desired);
301
+ }
302
+ /**
303
+ * Report whether `bucket` keeps versions, which is the whole of the recovery
304
+ * window behind a released payload.
305
+ *
306
+ * Accepts: `bucket` — the offload bucket. `logger` — the adapter's; silent by
307
+ * default, like every other event this package emits.
308
+ *
309
+ * Returns: nothing. A versioned bucket is silent; the other two states warn
310
+ * and name their own remedy, because those remedies differ — a bucket that
311
+ * never had versioning needs it enabled, while a suspended one needs it
312
+ * re-enabled *and* an accounting of what suspension has already destroyed.
313
+ *
314
+ * Throws: nothing, deliberately. A failure of the call itself is a `warn` too,
315
+ * including the `AccessDenied` of a role that provisioned lifecycle rules
316
+ * yesterday without this action: a permission the call did not need then must
317
+ * not break it now. This runs after the rules are written for the same reason
318
+ * — a bucket that cannot answer still gets them.
319
+ *
320
+ * Guarantees: a bucket that has never been versioned answers with an empty
321
+ * body, so the absent state is `Status === undefined`. It is never the string
322
+ * `'Disabled'`, which this API does not return, and testing for one would read
323
+ * an unversioned bucket as a versioned one.
324
+ */
325
+ async function reportBucketVersioning(client, bucket, logger) {
326
+ const { GetBucketVersioningCommand } = await (0, client_1.loadS3Sdk)();
327
+ // `s3.bucketName` is checked for being a non-empty string and never for
328
+ // length, so it reaches these three lines as whatever the caller's options
329
+ // carried. It is quoted here as the identifier it is, cut at the log cap:
330
+ // the line's job is to say which bucket to go and look at, and the bucket
331
+ // holds the rest.
332
+ const named = (0, truncate_1.truncateForLog)(bucket);
333
+ let status;
334
+ try {
335
+ status = (await client.send(new GetBucketVersioningCommand({ Bucket: bucket }))).Status;
336
+ }
337
+ catch (error) {
338
+ // The error's name, never its message, which can carry credential text —
339
+ // and read off a shape rather than an Error, because a client seam can
340
+ // reject with anything at all and this function promises not to throw. Cut
341
+ // like the bucket beside it: a name is a string the SDK or a client seam
342
+ // produced, `message` is already bounded where `redactedMessage` relays
343
+ // it, and the two are one value.
344
+ const reason = (0, truncate_1.truncateForLog)(error?.name ?? 'unknown');
345
+ logger.warn('ensureS3LifecycleRule: could not read the offload bucket versioning state, so whether a released payload is recoverable is unknown; the lifecycle rules were written, and the role needs s3:GetBucketVersioning', { bucket: named, reason });
346
+ return;
347
+ }
348
+ if (status === 'Enabled')
349
+ return;
350
+ if (status === undefined) {
351
+ logger.warn('ensureS3LifecycleRule: versioning is off on the offload bucket, so releasing a payload deletes it outright with no recovery window; enable bucket versioning to gain one', { bucket: named });
352
+ return;
353
+ }
354
+ logger.warn('ensureS3LifecycleRule: versioning is suspended on the offload bucket, so releasing a payload deletes it outright; re-enable versioning, and note that the payloads released while it was suspended are already gone', { bucket: named });
355
+ }