effect 4.0.0-rc.112 → 4.0.0-rc.113

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 (1229) hide show
  1. package/AGENTS.md +24 -9
  2. package/CLAUDE.md +24 -9
  3. package/ai-docs/package.json +2 -2
  4. package/ai-docs/src/01_effect/01_basics/02_effect-fn.ts +18 -5
  5. package/ai-docs/src/01_effect/01_basics/index.md +5 -3
  6. package/ai-docs/src/01_effect/03_services/20_layer-composition.ts +1 -1
  7. package/ai-docs/src/01_effect/03_services/20_layer-unwrap.ts +2 -2
  8. package/ai-docs/src/01_effect/05_resources/10_acquire-release.ts +2 -2
  9. package/ai-docs/src/03_stream/30_encoding.ts +5 -7
  10. package/ai-docs/src/08_observability/10_logging.ts +1 -1
  11. package/ai-docs/src/70_cli/10_basics.ts +7 -7
  12. package/ai-docs/src/71_ai/10_language-model.ts +2 -2
  13. package/ai-docs/src/71_ai/20_tools.ts +1 -1
  14. package/ai-docs/src/71_ai/30_chat.ts +1 -1
  15. package/dist/Array.d.ts +86 -50
  16. package/dist/Array.d.ts.map +1 -1
  17. package/dist/Array.js +58 -32
  18. package/dist/Array.js.map +1 -1
  19. package/dist/BigDecimal.d.ts +5 -1
  20. package/dist/BigDecimal.d.ts.map +1 -1
  21. package/dist/BigDecimal.js +40 -23
  22. package/dist/BigDecimal.js.map +1 -1
  23. package/dist/ByteSize.d.ts +633 -0
  24. package/dist/ByteSize.d.ts.map +1 -0
  25. package/dist/ByteSize.js +524 -0
  26. package/dist/ByteSize.js.map +1 -0
  27. package/dist/Cache.d.ts.map +1 -1
  28. package/dist/Cache.js +17 -3
  29. package/dist/Cache.js.map +1 -1
  30. package/dist/Cause.d.ts +1 -1
  31. package/dist/Cause.d.ts.map +1 -1
  32. package/dist/Channel.d.ts +97 -24
  33. package/dist/Channel.d.ts.map +1 -1
  34. package/dist/Channel.js +66 -39
  35. package/dist/Channel.js.map +1 -1
  36. package/dist/Chunk.d.ts +49 -28
  37. package/dist/Chunk.d.ts.map +1 -1
  38. package/dist/Chunk.js +27 -18
  39. package/dist/Chunk.js.map +1 -1
  40. package/dist/Config.d.ts +162 -201
  41. package/dist/Config.d.ts.map +1 -1
  42. package/dist/Config.js +103 -212
  43. package/dist/Config.js.map +1 -1
  44. package/dist/ConfigProvider.d.ts +4 -4
  45. package/dist/ConfigProvider.d.ts.map +1 -1
  46. package/dist/ConfigProvider.js +7 -7
  47. package/dist/ConfigProvider.js.map +1 -1
  48. package/dist/Context.d.ts +31 -0
  49. package/dist/Context.d.ts.map +1 -1
  50. package/dist/Context.js.map +1 -1
  51. package/dist/Cron.d.ts +2 -2
  52. package/dist/Cron.d.ts.map +1 -1
  53. package/dist/Cron.js +2 -2
  54. package/dist/Cron.js.map +1 -1
  55. package/dist/Crypto.d.ts +1 -1
  56. package/dist/Crypto.d.ts.map +1 -1
  57. package/dist/Crypto.js +3 -2
  58. package/dist/Crypto.js.map +1 -1
  59. package/dist/DateTime.d.ts +2 -2
  60. package/dist/DateTime.d.ts.map +1 -1
  61. package/dist/Deferred.d.ts.map +1 -1
  62. package/dist/Deferred.js +6 -6
  63. package/dist/Deferred.js.map +1 -1
  64. package/dist/Duration.d.ts +1 -1
  65. package/dist/Duration.d.ts.map +1 -1
  66. package/dist/Duration.js +1 -1
  67. package/dist/Duration.js.map +1 -1
  68. package/dist/Effect.d.ts +220 -113
  69. package/dist/Effect.d.ts.map +1 -1
  70. package/dist/Effect.js +27 -26
  71. package/dist/Effect.js.map +1 -1
  72. package/dist/Effectable.d.ts +58 -2
  73. package/dist/Effectable.d.ts.map +1 -1
  74. package/dist/Effectable.js +58 -6
  75. package/dist/Effectable.js.map +1 -1
  76. package/dist/Encoding.d.ts +3 -1
  77. package/dist/Encoding.d.ts.map +1 -1
  78. package/dist/Encoding.js +40 -10
  79. package/dist/Encoding.js.map +1 -1
  80. package/dist/Equal.d.ts +1 -1
  81. package/dist/Equal.d.ts.map +1 -1
  82. package/dist/Equal.js +1 -1
  83. package/dist/Equal.js.map +1 -1
  84. package/dist/ExecutionPlan.d.ts.map +1 -1
  85. package/dist/ExecutionPlan.js +1 -0
  86. package/dist/ExecutionPlan.js.map +1 -1
  87. package/dist/Fiber.d.ts +32 -8
  88. package/dist/Fiber.d.ts.map +1 -1
  89. package/dist/Fiber.js.map +1 -1
  90. package/dist/FiberHandle.js +3 -3
  91. package/dist/FiberHandle.js.map +1 -1
  92. package/dist/FiberMap.d.ts +12 -6
  93. package/dist/FiberMap.d.ts.map +1 -1
  94. package/dist/FiberMap.js +11 -6
  95. package/dist/FiberMap.js.map +1 -1
  96. package/dist/FileSystem.d.ts +42 -210
  97. package/dist/FileSystem.d.ts.map +1 -1
  98. package/dist/FileSystem.js +16 -148
  99. package/dist/FileSystem.js.map +1 -1
  100. package/dist/Formatter.d.ts +1 -0
  101. package/dist/Formatter.d.ts.map +1 -1
  102. package/dist/Formatter.js +19 -3
  103. package/dist/Formatter.js.map +1 -1
  104. package/dist/Graph.d.ts +48 -20
  105. package/dist/Graph.d.ts.map +1 -1
  106. package/dist/Graph.js +20 -5
  107. package/dist/Graph.js.map +1 -1
  108. package/dist/Hash.d.ts +1 -1
  109. package/dist/Hash.d.ts.map +1 -1
  110. package/dist/Hash.js +5 -14
  111. package/dist/Hash.js.map +1 -1
  112. package/dist/HashMap.d.ts +1 -1
  113. package/dist/HashMap.d.ts.map +1 -1
  114. package/dist/HashRing.d.ts +6 -1
  115. package/dist/HashRing.d.ts.map +1 -1
  116. package/dist/HashRing.js +9 -2
  117. package/dist/HashRing.js.map +1 -1
  118. package/dist/HashSet.d.ts +1 -1
  119. package/dist/HashSet.d.ts.map +1 -1
  120. package/dist/HashSet.js.map +1 -1
  121. package/dist/Iterable.d.ts +33 -15
  122. package/dist/Iterable.d.ts.map +1 -1
  123. package/dist/Iterable.js +58 -45
  124. package/dist/Iterable.js.map +1 -1
  125. package/dist/JsonPatch.js +4 -4
  126. package/dist/JsonPatch.js.map +1 -1
  127. package/dist/JsonPointer.d.ts +68 -4
  128. package/dist/JsonPointer.d.ts.map +1 -1
  129. package/dist/JsonPointer.js +90 -4
  130. package/dist/JsonPointer.js.map +1 -1
  131. package/dist/JsonSchema.js +8 -22
  132. package/dist/JsonSchema.js.map +1 -1
  133. package/dist/Layer.d.ts +47 -4
  134. package/dist/Layer.d.ts.map +1 -1
  135. package/dist/Layer.js +4 -6
  136. package/dist/Layer.js.map +1 -1
  137. package/dist/LayerMap.d.ts +1 -3
  138. package/dist/LayerMap.d.ts.map +1 -1
  139. package/dist/LayerMap.js +7 -5
  140. package/dist/LayerMap.js.map +1 -1
  141. package/dist/LayerRef.d.ts.map +1 -1
  142. package/dist/LayerRef.js +7 -5
  143. package/dist/LayerRef.js.map +1 -1
  144. package/dist/Logger.d.ts +114 -9
  145. package/dist/Logger.d.ts.map +1 -1
  146. package/dist/Logger.js +109 -9
  147. package/dist/Logger.js.map +1 -1
  148. package/dist/ManagedRuntime.js +1 -1
  149. package/dist/ManagedRuntime.js.map +1 -1
  150. package/dist/Match.d.ts +43 -31
  151. package/dist/Match.d.ts.map +1 -1
  152. package/dist/Match.js +5 -2
  153. package/dist/Match.js.map +1 -1
  154. package/dist/Metric.d.ts +11 -4
  155. package/dist/Metric.d.ts.map +1 -1
  156. package/dist/Metric.js +14 -18
  157. package/dist/Metric.js.map +1 -1
  158. package/dist/MutableHashMap.d.ts +1 -1
  159. package/dist/MutableHashMap.d.ts.map +1 -1
  160. package/dist/MutableHashMap.js +1 -1
  161. package/dist/MutableHashMap.js.map +1 -1
  162. package/dist/MutableHashSet.d.ts +1 -1
  163. package/dist/MutableHashSet.d.ts.map +1 -1
  164. package/dist/MutableHashSet.js +1 -1
  165. package/dist/MutableHashSet.js.map +1 -1
  166. package/dist/MutableList.d.ts +13 -2
  167. package/dist/MutableList.d.ts.map +1 -1
  168. package/dist/MutableList.js +18 -2
  169. package/dist/MutableList.js.map +1 -1
  170. package/dist/Number.d.ts +6 -0
  171. package/dist/Number.d.ts.map +1 -1
  172. package/dist/Number.js +3 -1
  173. package/dist/Number.js.map +1 -1
  174. package/dist/Optic.d.ts.map +1 -1
  175. package/dist/Optic.js +5 -4
  176. package/dist/Optic.js.map +1 -1
  177. package/dist/Option.d.ts +1 -1
  178. package/dist/Option.d.ts.map +1 -1
  179. package/dist/Option.js +1 -1
  180. package/dist/Option.js.map +1 -1
  181. package/dist/Order.d.ts +1 -0
  182. package/dist/Order.d.ts.map +1 -1
  183. package/dist/Order.js +3 -1
  184. package/dist/Order.js.map +1 -1
  185. package/dist/PartitionedSemaphore.d.ts.map +1 -1
  186. package/dist/PartitionedSemaphore.js +1 -2
  187. package/dist/PartitionedSemaphore.js.map +1 -1
  188. package/dist/Path.d.ts +1 -1
  189. package/dist/Path.d.ts.map +1 -1
  190. package/dist/Path.js +1 -1
  191. package/dist/Path.js.map +1 -1
  192. package/dist/PlatformError.d.ts +1 -1
  193. package/dist/PlatformError.d.ts.map +1 -1
  194. package/dist/PlatformError.js +1 -1
  195. package/dist/PlatformError.js.map +1 -1
  196. package/dist/Pool.d.ts +38 -1
  197. package/dist/Pool.d.ts.map +1 -1
  198. package/dist/Pool.js +81 -5
  199. package/dist/Pool.js.map +1 -1
  200. package/dist/PrimaryKey.d.ts +1 -1
  201. package/dist/PrimaryKey.d.ts.map +1 -1
  202. package/dist/PrimaryKey.js +1 -1
  203. package/dist/PrimaryKey.js.map +1 -1
  204. package/dist/PubSub.d.ts +21 -9
  205. package/dist/PubSub.d.ts.map +1 -1
  206. package/dist/PubSub.js +18 -14
  207. package/dist/PubSub.js.map +1 -1
  208. package/dist/Queue.d.ts +82 -6
  209. package/dist/Queue.d.ts.map +1 -1
  210. package/dist/Queue.js +116 -27
  211. package/dist/Queue.js.map +1 -1
  212. package/dist/Random.d.ts +17 -4
  213. package/dist/Random.d.ts.map +1 -1
  214. package/dist/Random.js +1 -1
  215. package/dist/Random.js.map +1 -1
  216. package/dist/RcMap.d.ts.map +1 -1
  217. package/dist/RcMap.js +15 -9
  218. package/dist/RcMap.js.map +1 -1
  219. package/dist/Redacted.d.ts +1 -1
  220. package/dist/Redacted.d.ts.map +1 -1
  221. package/dist/Redacted.js +1 -1
  222. package/dist/Redacted.js.map +1 -1
  223. package/dist/RequestResolver.d.ts +15 -9
  224. package/dist/RequestResolver.d.ts.map +1 -1
  225. package/dist/RequestResolver.js +33 -15
  226. package/dist/RequestResolver.js.map +1 -1
  227. package/dist/Result.d.ts +1 -1
  228. package/dist/Result.d.ts.map +1 -1
  229. package/dist/Result.js +1 -1
  230. package/dist/Result.js.map +1 -1
  231. package/dist/Scheduler.d.ts.map +1 -1
  232. package/dist/Scheduler.js +19 -10
  233. package/dist/Scheduler.js.map +1 -1
  234. package/dist/Schema.d.ts +2155 -2415
  235. package/dist/Schema.d.ts.map +1 -1
  236. package/dist/Schema.js +2755 -4174
  237. package/dist/Schema.js.map +1 -1
  238. package/dist/SchemaAST.d.ts +354 -183
  239. package/dist/SchemaAST.d.ts.map +1 -1
  240. package/dist/SchemaAST.js +277 -601
  241. package/dist/SchemaAST.js.map +1 -1
  242. package/dist/SchemaGetter.d.ts +46 -22
  243. package/dist/SchemaGetter.d.ts.map +1 -1
  244. package/dist/SchemaGetter.js +56 -53
  245. package/dist/SchemaGetter.js.map +1 -1
  246. package/dist/SchemaIssue.d.ts +122 -188
  247. package/dist/SchemaIssue.d.ts.map +1 -1
  248. package/dist/SchemaIssue.js +48 -263
  249. package/dist/SchemaIssue.js.map +1 -1
  250. package/dist/SchemaParser.js +2 -9
  251. package/dist/SchemaParser.js.map +1 -1
  252. package/dist/SchemaRepresentation.d.ts +1099 -16
  253. package/dist/SchemaRepresentation.d.ts.map +1 -1
  254. package/dist/SchemaRepresentation.js +1341 -20
  255. package/dist/SchemaRepresentation.js.map +1 -1
  256. package/dist/SchemaTransformation.d.ts +49 -16
  257. package/dist/SchemaTransformation.d.ts.map +1 -1
  258. package/dist/SchemaTransformation.js +75 -98
  259. package/dist/SchemaTransformation.js.map +1 -1
  260. package/dist/ScopedCache.d.ts.map +1 -1
  261. package/dist/ScopedCache.js +10 -3
  262. package/dist/ScopedCache.js.map +1 -1
  263. package/dist/Sink.d.ts +9 -4
  264. package/dist/Sink.d.ts.map +1 -1
  265. package/dist/Sink.js +49 -31
  266. package/dist/Sink.js.map +1 -1
  267. package/dist/Stream.d.ts +221 -35
  268. package/dist/Stream.d.ts.map +1 -1
  269. package/dist/Stream.js +168 -84
  270. package/dist/Stream.js.map +1 -1
  271. package/dist/String.d.ts +16 -6
  272. package/dist/String.d.ts.map +1 -1
  273. package/dist/String.js +12 -5
  274. package/dist/String.js.map +1 -1
  275. package/dist/Struct.d.ts.map +1 -1
  276. package/dist/Struct.js +7 -4
  277. package/dist/Struct.js.map +1 -1
  278. package/dist/SynchronizedRef.d.ts +3 -2
  279. package/dist/SynchronizedRef.d.ts.map +1 -1
  280. package/dist/SynchronizedRef.js.map +1 -1
  281. package/dist/Terminal.d.ts +3 -3
  282. package/dist/Terminal.d.ts.map +1 -1
  283. package/dist/Terminal.js +3 -3
  284. package/dist/Terminal.js.map +1 -1
  285. package/dist/Tracer.d.ts +27 -7
  286. package/dist/Tracer.d.ts.map +1 -1
  287. package/dist/Tracer.js +38 -13
  288. package/dist/Tracer.js.map +1 -1
  289. package/dist/Trie.d.ts +1 -1
  290. package/dist/Trie.d.ts.map +1 -1
  291. package/dist/Tuple.d.ts +2 -1
  292. package/dist/Tuple.d.ts.map +1 -1
  293. package/dist/Tuple.js.map +1 -1
  294. package/dist/TxChunk.d.ts +1 -1
  295. package/dist/TxChunk.d.ts.map +1 -1
  296. package/dist/TxChunk.js +1 -1
  297. package/dist/TxChunk.js.map +1 -1
  298. package/dist/TxDeferred.d.ts +1 -1
  299. package/dist/TxDeferred.d.ts.map +1 -1
  300. package/dist/TxDeferred.js +1 -1
  301. package/dist/TxDeferred.js.map +1 -1
  302. package/dist/TxHashMap.d.ts +1 -1
  303. package/dist/TxHashMap.d.ts.map +1 -1
  304. package/dist/TxHashMap.js +1 -1
  305. package/dist/TxHashMap.js.map +1 -1
  306. package/dist/TxHashSet.d.ts +1 -1
  307. package/dist/TxHashSet.d.ts.map +1 -1
  308. package/dist/TxHashSet.js +1 -1
  309. package/dist/TxHashSet.js.map +1 -1
  310. package/dist/TxPriorityQueue.d.ts +1 -1
  311. package/dist/TxPriorityQueue.d.ts.map +1 -1
  312. package/dist/TxPriorityQueue.js +1 -1
  313. package/dist/TxPriorityQueue.js.map +1 -1
  314. package/dist/TxPubSub.d.ts +1 -1
  315. package/dist/TxPubSub.d.ts.map +1 -1
  316. package/dist/TxPubSub.js +1 -1
  317. package/dist/TxPubSub.js.map +1 -1
  318. package/dist/TxQueue.d.ts +9 -9
  319. package/dist/TxQueue.d.ts.map +1 -1
  320. package/dist/TxQueue.js +93 -86
  321. package/dist/TxQueue.js.map +1 -1
  322. package/dist/TxReentrantLock.d.ts +29 -1
  323. package/dist/TxReentrantLock.d.ts.map +1 -1
  324. package/dist/TxReentrantLock.js +29 -1
  325. package/dist/TxReentrantLock.js.map +1 -1
  326. package/dist/TxRef.d.ts +1 -1
  327. package/dist/TxRef.d.ts.map +1 -1
  328. package/dist/TxRef.js +1 -1
  329. package/dist/TxRef.js.map +1 -1
  330. package/dist/TxSemaphore.d.ts +1 -1
  331. package/dist/TxSemaphore.d.ts.map +1 -1
  332. package/dist/TxSemaphore.js +1 -1
  333. package/dist/TxSemaphore.js.map +1 -1
  334. package/dist/TxSubscriptionRef.d.ts +1 -1
  335. package/dist/TxSubscriptionRef.d.ts.map +1 -1
  336. package/dist/TxSubscriptionRef.js +1 -1
  337. package/dist/TxSubscriptionRef.js.map +1 -1
  338. package/dist/Types.d.ts +33 -19
  339. package/dist/Types.d.ts.map +1 -1
  340. package/dist/Utils.d.ts.map +1 -1
  341. package/dist/Utils.js +2 -1
  342. package/dist/Utils.js.map +1 -1
  343. package/dist/index.d.ts +4 -0
  344. package/dist/index.d.ts.map +1 -1
  345. package/dist/index.js +4 -0
  346. package/dist/index.js.map +1 -1
  347. package/dist/internal/arbitrary/model.d.ts +2 -0
  348. package/dist/internal/arbitrary/model.d.ts.map +1 -0
  349. package/dist/internal/arbitrary/model.js +495 -0
  350. package/dist/internal/arbitrary/model.js.map +1 -0
  351. package/dist/internal/arbitrary/regexp.d.ts +2 -0
  352. package/dist/internal/arbitrary/regexp.d.ts.map +1 -0
  353. package/dist/internal/arbitrary/regexp.js +789 -0
  354. package/dist/internal/arbitrary/regexp.js.map +1 -0
  355. package/dist/internal/arbitrary/runner.d.ts +2 -0
  356. package/dist/internal/arbitrary/runner.d.ts.map +1 -0
  357. package/dist/internal/arbitrary/runner.js +496 -0
  358. package/dist/internal/arbitrary/runner.js.map +1 -0
  359. package/dist/internal/arbitrary/schema.d.ts.map +1 -0
  360. package/dist/internal/arbitrary/schema.js +1340 -0
  361. package/dist/internal/arbitrary/schema.js.map +1 -0
  362. package/dist/internal/core.js +27 -13
  363. package/dist/internal/core.js.map +1 -1
  364. package/dist/internal/count.d.ts +2 -0
  365. package/dist/internal/count.d.ts.map +1 -0
  366. package/dist/internal/count.js +14 -0
  367. package/dist/internal/count.js.map +1 -0
  368. package/dist/internal/dateTime.js +4 -10
  369. package/dist/internal/dateTime.js.map +1 -1
  370. package/dist/internal/effect.js +386 -251
  371. package/dist/internal/effect.js.map +1 -1
  372. package/dist/internal/graph.js +3 -1
  373. package/dist/internal/graph.js.map +1 -1
  374. package/dist/internal/hashMap.js +5 -3
  375. package/dist/internal/hashMap.js.map +1 -1
  376. package/dist/internal/hashSet.js +1 -1
  377. package/dist/internal/hashSet.js.map +1 -1
  378. package/dist/internal/matcher.js +1 -1
  379. package/dist/internal/matcher.js.map +1 -1
  380. package/dist/internal/metric.js +1 -1
  381. package/dist/internal/metric.js.map +1 -1
  382. package/dist/internal/option.js +6 -5
  383. package/dist/internal/option.js.map +1 -1
  384. package/dist/internal/random.js +17 -0
  385. package/dist/internal/random.js.map +1 -1
  386. package/dist/internal/rcRef.js +10 -7
  387. package/dist/internal/rcRef.js.map +1 -1
  388. package/dist/internal/references.js +1 -0
  389. package/dist/internal/references.js.map +1 -1
  390. package/dist/internal/request.js +13 -6
  391. package/dist/internal/request.js.map +1 -1
  392. package/dist/internal/result.js +11 -9
  393. package/dist/internal/result.js.map +1 -1
  394. package/dist/internal/schema/annotations.js +1 -1
  395. package/dist/internal/schema/annotations.js.map +1 -1
  396. package/dist/internal/schema/fromJsonSchemaDocument.js +14 -12
  397. package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
  398. package/dist/internal/schema/fromRepresentation.js +5 -5
  399. package/dist/internal/schema/fromRepresentation.js.map +1 -1
  400. package/dist/internal/schema/make.d.ts +2 -0
  401. package/dist/internal/schema/make.d.ts.map +1 -0
  402. package/dist/internal/schema/{schema.js → make.js} +1 -25
  403. package/dist/internal/schema/make.js.map +1 -0
  404. package/dist/internal/schema/parser.d.ts +0 -12
  405. package/dist/internal/schema/parser.d.ts.map +1 -1
  406. package/dist/internal/schema/parser.js +7 -0
  407. package/dist/internal/schema/parser.js.map +1 -1
  408. package/dist/internal/schema/standardSchema.d.ts +2 -0
  409. package/dist/internal/schema/standardSchema.d.ts.map +1 -0
  410. package/dist/internal/schema/standardSchema.js +112 -0
  411. package/dist/internal/schema/standardSchema.js.map +1 -0
  412. package/dist/internal/schema/toCodeDocument.js +34 -22
  413. package/dist/internal/schema/toCodeDocument.js.map +1 -1
  414. package/dist/internal/schema/toCodec.d.ts +2 -0
  415. package/dist/internal/schema/toCodec.d.ts.map +1 -0
  416. package/dist/internal/schema/toCodec.js +242 -0
  417. package/dist/internal/schema/toCodec.js.map +1 -0
  418. package/dist/internal/schema/toDifferJsonPatch.d.ts +2 -0
  419. package/dist/internal/schema/toDifferJsonPatch.d.ts.map +1 -0
  420. package/dist/internal/schema/toDifferJsonPatch.js +20 -0
  421. package/dist/internal/schema/toDifferJsonPatch.js.map +1 -0
  422. package/dist/internal/schema/toEncoderXml.d.ts +2 -0
  423. package/dist/internal/schema/toEncoderXml.d.ts.map +1 -0
  424. package/dist/internal/schema/toEncoderXml.js +104 -0
  425. package/dist/internal/schema/toEncoderXml.js.map +1 -0
  426. package/dist/internal/schema/toEquivalence.js +66 -0
  427. package/dist/internal/schema/toEquivalence.js.map +1 -1
  428. package/dist/internal/schema/toFormatter.d.ts +2 -0
  429. package/dist/internal/schema/toFormatter.d.ts.map +1 -0
  430. package/dist/internal/schema/toFormatter.js +227 -0
  431. package/dist/internal/schema/toFormatter.js.map +1 -0
  432. package/dist/internal/schema/toIso.d.ts +2 -0
  433. package/dist/internal/schema/toIso.d.ts.map +1 -0
  434. package/dist/internal/schema/toIso.js +17 -0
  435. package/dist/internal/schema/toIso.js.map +1 -0
  436. package/dist/internal/schema/toJsonSchemaDocument.js +122 -71
  437. package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
  438. package/dist/internal/schema/toRepresentation.js +3 -1
  439. package/dist/internal/schema/toRepresentation.js.map +1 -1
  440. package/dist/internal/schemaError.d.ts +4 -0
  441. package/dist/internal/schemaError.d.ts.map +1 -0
  442. package/dist/internal/schemaError.js +6 -0
  443. package/dist/internal/schemaError.js.map +1 -0
  444. package/dist/internal/stream.js +5 -6
  445. package/dist/internal/stream.js.map +1 -1
  446. package/dist/internal/tracer.d.ts +1 -3
  447. package/dist/internal/tracer.d.ts.map +1 -1
  448. package/dist/internal/tracer.js +6 -0
  449. package/dist/internal/tracer.js.map +1 -1
  450. package/dist/internal/trie.js +2 -2
  451. package/dist/internal/trie.js.map +1 -1
  452. package/dist/internal/uuid.d.ts +1 -2
  453. package/dist/internal/uuid.d.ts.map +1 -1
  454. package/dist/internal/uuid.js +2 -0
  455. package/dist/internal/uuid.js.map +1 -1
  456. package/dist/testing/TestSchema.d.ts +9 -11
  457. package/dist/testing/TestSchema.d.ts.map +1 -1
  458. package/dist/testing/TestSchema.js +20 -18
  459. package/dist/testing/TestSchema.js.map +1 -1
  460. package/dist/testing/index.d.ts +0 -4
  461. package/dist/testing/index.d.ts.map +1 -1
  462. package/dist/testing/index.js +0 -4
  463. package/dist/testing/index.js.map +1 -1
  464. package/dist/unstable/ai/AiError.d.ts +74 -23
  465. package/dist/unstable/ai/AiError.d.ts.map +1 -1
  466. package/dist/unstable/ai/AiError.js +59 -5
  467. package/dist/unstable/ai/AiError.js.map +1 -1
  468. package/dist/unstable/ai/AnthropicStructuredOutput.d.ts.map +1 -1
  469. package/dist/unstable/ai/AnthropicStructuredOutput.js +2 -1
  470. package/dist/unstable/ai/AnthropicStructuredOutput.js.map +1 -1
  471. package/dist/unstable/ai/Chat.d.ts +27 -32
  472. package/dist/unstable/ai/Chat.d.ts.map +1 -1
  473. package/dist/unstable/ai/Chat.js +10 -13
  474. package/dist/unstable/ai/Chat.js.map +1 -1
  475. package/dist/unstable/ai/EmbeddingModel.d.ts +23 -16
  476. package/dist/unstable/ai/EmbeddingModel.d.ts.map +1 -1
  477. package/dist/unstable/ai/EmbeddingModel.js +13 -11
  478. package/dist/unstable/ai/EmbeddingModel.js.map +1 -1
  479. package/dist/unstable/ai/LanguageModel.d.ts +48 -37
  480. package/dist/unstable/ai/LanguageModel.d.ts.map +1 -1
  481. package/dist/unstable/ai/LanguageModel.js +150 -47
  482. package/dist/unstable/ai/LanguageModel.js.map +1 -1
  483. package/dist/unstable/ai/McpServer.d.ts +2 -2
  484. package/dist/unstable/ai/McpServer.d.ts.map +1 -1
  485. package/dist/unstable/ai/McpServer.js +21 -12
  486. package/dist/unstable/ai/McpServer.js.map +1 -1
  487. package/dist/unstable/ai/OpenAiStructuredOutput.d.ts.map +1 -1
  488. package/dist/unstable/ai/OpenAiStructuredOutput.js +2 -1
  489. package/dist/unstable/ai/OpenAiStructuredOutput.js.map +1 -1
  490. package/dist/unstable/ai/Prompt.d.ts +1 -1
  491. package/dist/unstable/ai/Prompt.d.ts.map +1 -1
  492. package/dist/unstable/ai/Prompt.js +15 -4
  493. package/dist/unstable/ai/Prompt.js.map +1 -1
  494. package/dist/unstable/ai/Response.d.ts +37 -94
  495. package/dist/unstable/ai/Response.d.ts.map +1 -1
  496. package/dist/unstable/ai/Response.js +46 -96
  497. package/dist/unstable/ai/Response.js.map +1 -1
  498. package/dist/unstable/ai/Tokenizer.js +4 -5
  499. package/dist/unstable/ai/Tokenizer.js.map +1 -1
  500. package/dist/unstable/ai/Tool.d.ts +38 -20
  501. package/dist/unstable/ai/Tool.d.ts.map +1 -1
  502. package/dist/unstable/ai/Tool.js +27 -1
  503. package/dist/unstable/ai/Tool.js.map +1 -1
  504. package/dist/unstable/ai/Toolkit.d.ts +1 -1
  505. package/dist/unstable/ai/Toolkit.d.ts.map +1 -1
  506. package/dist/unstable/ai/Toolkit.js +30 -18
  507. package/dist/unstable/ai/Toolkit.js.map +1 -1
  508. package/dist/unstable/ai/internal/structured-output.js +8 -5
  509. package/dist/unstable/ai/internal/structured-output.js.map +1 -1
  510. package/dist/unstable/arbitrary/Arbitrary.d.ts +626 -0
  511. package/dist/unstable/arbitrary/Arbitrary.d.ts.map +1 -0
  512. package/dist/unstable/arbitrary/Arbitrary.js +238 -0
  513. package/dist/unstable/arbitrary/Arbitrary.js.map +1 -0
  514. package/dist/unstable/arbitrary/index.d.ts +8 -0
  515. package/dist/unstable/arbitrary/index.d.ts.map +1 -0
  516. package/dist/unstable/arbitrary/index.js +9 -0
  517. package/dist/unstable/arbitrary/index.js.map +1 -0
  518. package/dist/unstable/cli/Argument.d.ts +104 -108
  519. package/dist/unstable/cli/Argument.d.ts.map +1 -1
  520. package/dist/unstable/cli/Argument.js +56 -57
  521. package/dist/unstable/cli/Argument.js.map +1 -1
  522. package/dist/unstable/cli/CliError.d.ts +2 -0
  523. package/dist/unstable/cli/CliError.d.ts.map +1 -1
  524. package/dist/unstable/cli/CliError.js +2 -0
  525. package/dist/unstable/cli/CliError.js.map +1 -1
  526. package/dist/unstable/cli/CliOutput.js +26 -3
  527. package/dist/unstable/cli/CliOutput.js.map +1 -1
  528. package/dist/unstable/cli/Command.d.ts +73 -73
  529. package/dist/unstable/cli/Command.js +18 -18
  530. package/dist/unstable/cli/Completions.d.ts +4 -4
  531. package/dist/unstable/cli/Completions.d.ts.map +1 -1
  532. package/dist/unstable/cli/Flag.d.ts +150 -161
  533. package/dist/unstable/cli/Flag.d.ts.map +1 -1
  534. package/dist/unstable/cli/Flag.js +79 -90
  535. package/dist/unstable/cli/Flag.js.map +1 -1
  536. package/dist/unstable/cli/GlobalFlag.d.ts +3 -3
  537. package/dist/unstable/cli/GlobalFlag.js +13 -13
  538. package/dist/unstable/cli/GlobalFlag.js.map +1 -1
  539. package/dist/unstable/cli/Param.d.ts +118 -126
  540. package/dist/unstable/cli/Param.d.ts.map +1 -1
  541. package/dist/unstable/cli/Param.js +104 -113
  542. package/dist/unstable/cli/Param.js.map +1 -1
  543. package/dist/unstable/cli/Primitive.d.ts +69 -58
  544. package/dist/unstable/cli/Primitive.d.ts.map +1 -1
  545. package/dist/unstable/cli/Primitive.js +65 -66
  546. package/dist/unstable/cli/Primitive.js.map +1 -1
  547. package/dist/unstable/cli/Prompt.d.ts +23 -24
  548. package/dist/unstable/cli/Prompt.d.ts.map +1 -1
  549. package/dist/unstable/cli/Prompt.js +68 -63
  550. package/dist/unstable/cli/Prompt.js.map +1 -1
  551. package/dist/unstable/cli/internal/completions/descriptor.js +23 -11
  552. package/dist/unstable/cli/internal/completions/descriptor.js.map +1 -1
  553. package/dist/unstable/cli/internal/completions/zsh.js +2 -2
  554. package/dist/unstable/cli/internal/completions/zsh.js.map +1 -1
  555. package/dist/unstable/cli/internal/config.js +4 -4
  556. package/dist/unstable/cli/internal/parser.js +1 -1
  557. package/dist/unstable/cli/internal/parser.js.map +1 -1
  558. package/dist/unstable/cli/internal/wizard.d.ts.map +1 -1
  559. package/dist/unstable/cli/internal/wizard.js +14 -13
  560. package/dist/unstable/cli/internal/wizard.js.map +1 -1
  561. package/dist/unstable/cluster/ClusterSchema.d.ts +13 -0
  562. package/dist/unstable/cluster/ClusterSchema.d.ts.map +1 -1
  563. package/dist/unstable/cluster/ClusterSchema.js +16 -1
  564. package/dist/unstable/cluster/ClusterSchema.js.map +1 -1
  565. package/dist/unstable/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
  566. package/dist/unstable/cluster/ClusterWorkflowEngine.js +57 -14
  567. package/dist/unstable/cluster/ClusterWorkflowEngine.js.map +1 -1
  568. package/dist/unstable/cluster/Entity.d.ts.map +1 -1
  569. package/dist/unstable/cluster/Entity.js +2 -0
  570. package/dist/unstable/cluster/Entity.js.map +1 -1
  571. package/dist/unstable/cluster/EntityProxyServer.d.ts +2 -2
  572. package/dist/unstable/cluster/EntityProxyServer.d.ts.map +1 -1
  573. package/dist/unstable/cluster/EntityProxyServer.js.map +1 -1
  574. package/dist/unstable/cluster/Envelope.d.ts +4 -4
  575. package/dist/unstable/cluster/Envelope.d.ts.map +1 -1
  576. package/dist/unstable/cluster/Envelope.js +2 -3
  577. package/dist/unstable/cluster/Envelope.js.map +1 -1
  578. package/dist/unstable/cluster/HttpRunner.d.ts.map +1 -1
  579. package/dist/unstable/cluster/HttpRunner.js +5 -2
  580. package/dist/unstable/cluster/HttpRunner.js.map +1 -1
  581. package/dist/unstable/cluster/MessageStorage.d.ts +34 -4
  582. package/dist/unstable/cluster/MessageStorage.d.ts.map +1 -1
  583. package/dist/unstable/cluster/MessageStorage.js +28 -9
  584. package/dist/unstable/cluster/MessageStorage.js.map +1 -1
  585. package/dist/unstable/cluster/Reply.d.ts +1 -1
  586. package/dist/unstable/cluster/Sharding.d.ts +1 -1
  587. package/dist/unstable/cluster/Sharding.d.ts.map +1 -1
  588. package/dist/unstable/cluster/Sharding.js +32 -17
  589. package/dist/unstable/cluster/Sharding.js.map +1 -1
  590. package/dist/unstable/cluster/ShardingConfig.js +23 -23
  591. package/dist/unstable/cluster/ShardingConfig.js.map +1 -1
  592. package/dist/unstable/cluster/SocketRunner.d.ts +2 -2
  593. package/dist/unstable/cluster/SocketRunner.d.ts.map +1 -1
  594. package/dist/unstable/cluster/SocketRunner.js +4 -3
  595. package/dist/unstable/cluster/SocketRunner.js.map +1 -1
  596. package/dist/unstable/cluster/SqlMessageStorage.js +11 -8
  597. package/dist/unstable/cluster/SqlMessageStorage.js.map +1 -1
  598. package/dist/unstable/cluster/SqlRunnerStorage.d.ts.map +1 -1
  599. package/dist/unstable/cluster/SqlRunnerStorage.js +11 -4
  600. package/dist/unstable/cluster/SqlRunnerStorage.js.map +1 -1
  601. package/dist/unstable/cluster/internal/clusterAbandon.d.ts +5 -0
  602. package/dist/unstable/cluster/internal/clusterAbandon.d.ts.map +1 -0
  603. package/dist/unstable/cluster/internal/clusterAbandon.js +9 -0
  604. package/dist/unstable/cluster/internal/clusterAbandon.js.map +1 -0
  605. package/dist/unstable/cluster/internal/entityManager.js +7 -4
  606. package/dist/unstable/cluster/internal/entityManager.js.map +1 -1
  607. package/dist/unstable/cluster/internal/interruptors.js +30 -1
  608. package/dist/unstable/cluster/internal/interruptors.js.map +1 -1
  609. package/dist/unstable/cluster/internal/resourceRef.js +12 -7
  610. package/dist/unstable/cluster/internal/resourceRef.js.map +1 -1
  611. package/dist/unstable/devtools/DevToolsClient.d.ts.map +1 -1
  612. package/dist/unstable/devtools/DevToolsClient.js +12 -7
  613. package/dist/unstable/devtools/DevToolsClient.js.map +1 -1
  614. package/dist/unstable/encoding/Ini.d.ts +2 -0
  615. package/dist/unstable/encoding/Ini.d.ts.map +1 -1
  616. package/dist/unstable/encoding/Ini.js +2 -0
  617. package/dist/unstable/encoding/Ini.js.map +1 -1
  618. package/dist/unstable/encoding/SchemaBinary.d.ts +27 -3
  619. package/dist/unstable/encoding/SchemaBinary.d.ts.map +1 -1
  620. package/dist/unstable/encoding/SchemaBinary.js +108 -39
  621. package/dist/unstable/encoding/SchemaBinary.js.map +1 -1
  622. package/dist/unstable/encoding/Sse.js +1 -1
  623. package/dist/unstable/encoding/Sse.js.map +1 -1
  624. package/dist/unstable/encoding/Toml.d.ts +2 -0
  625. package/dist/unstable/encoding/Toml.d.ts.map +1 -1
  626. package/dist/unstable/encoding/Toml.js +6 -4
  627. package/dist/unstable/encoding/Toml.js.map +1 -1
  628. package/dist/unstable/encoding/Yaml.d.ts +2 -0
  629. package/dist/unstable/encoding/Yaml.d.ts.map +1 -1
  630. package/dist/unstable/encoding/Yaml.js +16 -5
  631. package/dist/unstable/encoding/Yaml.js.map +1 -1
  632. package/dist/unstable/encoding/index.d.ts +0 -4
  633. package/dist/unstable/encoding/index.d.ts.map +1 -1
  634. package/dist/unstable/encoding/index.js +0 -4
  635. package/dist/unstable/encoding/index.js.map +1 -1
  636. package/dist/unstable/eventlog/Event.d.ts +5 -5
  637. package/dist/unstable/eventlog/Event.d.ts.map +1 -1
  638. package/dist/unstable/eventlog/Event.js +3 -3
  639. package/dist/unstable/eventlog/Event.js.map +1 -1
  640. package/dist/unstable/eventlog/EventJournal.d.ts +7 -7
  641. package/dist/unstable/eventlog/EventJournal.d.ts.map +1 -1
  642. package/dist/unstable/eventlog/EventJournal.js +9 -9
  643. package/dist/unstable/eventlog/EventJournal.js.map +1 -1
  644. package/dist/unstable/eventlog/EventLog.d.ts +1 -1
  645. package/dist/unstable/eventlog/EventLog.d.ts.map +1 -1
  646. package/dist/unstable/eventlog/EventLog.js +4 -4
  647. package/dist/unstable/eventlog/EventLog.js.map +1 -1
  648. package/dist/unstable/eventlog/EventLogMessage.d.ts +11 -5
  649. package/dist/unstable/eventlog/EventLogMessage.d.ts.map +1 -1
  650. package/dist/unstable/eventlog/EventLogMessage.js +25 -15
  651. package/dist/unstable/eventlog/EventLogMessage.js.map +1 -1
  652. package/dist/unstable/eventlog/EventLogRemote.d.ts +7 -1
  653. package/dist/unstable/eventlog/EventLogRemote.d.ts.map +1 -1
  654. package/dist/unstable/eventlog/EventLogRemote.js +13 -3
  655. package/dist/unstable/eventlog/EventLogRemote.js.map +1 -1
  656. package/dist/unstable/eventlog/EventLogServerUnencrypted.js +2 -2
  657. package/dist/unstable/eventlog/EventLogServerUnencrypted.js.map +1 -1
  658. package/dist/unstable/eventlog/SqlEventJournal.d.ts.map +1 -1
  659. package/dist/unstable/eventlog/SqlEventJournal.js +26 -13
  660. package/dist/unstable/eventlog/SqlEventJournal.js.map +1 -1
  661. package/dist/unstable/eventlog/SqlEventLogServerUnencrypted.d.ts.map +1 -1
  662. package/dist/unstable/eventlog/SqlEventLogServerUnencrypted.js +5 -1
  663. package/dist/unstable/eventlog/SqlEventLogServerUnencrypted.js.map +1 -1
  664. package/dist/unstable/http/Cookies.d.ts +1 -45
  665. package/dist/unstable/http/Cookies.d.ts.map +1 -1
  666. package/dist/unstable/http/Cookies.js +2 -64
  667. package/dist/unstable/http/Cookies.js.map +1 -1
  668. package/dist/unstable/http/FetchHttpClient.js +1 -1
  669. package/dist/unstable/http/FetchHttpClient.js.map +1 -1
  670. package/dist/unstable/http/FindMyWay/internal/router.js +124 -33
  671. package/dist/unstable/http/FindMyWay/internal/router.js.map +1 -1
  672. package/dist/unstable/http/FindMyWay.d.ts +15 -5
  673. package/dist/unstable/http/FindMyWay.d.ts.map +1 -1
  674. package/dist/unstable/http/FindMyWay.js +3 -1
  675. package/dist/unstable/http/FindMyWay.js.map +1 -1
  676. package/dist/unstable/http/Headers.d.ts +0 -22
  677. package/dist/unstable/http/Headers.d.ts.map +1 -1
  678. package/dist/unstable/http/Headers.js +3 -34
  679. package/dist/unstable/http/Headers.js.map +1 -1
  680. package/dist/unstable/http/HttpBody.d.ts +41 -10
  681. package/dist/unstable/http/HttpBody.d.ts.map +1 -1
  682. package/dist/unstable/http/HttpBody.js +64 -10
  683. package/dist/unstable/http/HttpBody.js.map +1 -1
  684. package/dist/unstable/http/HttpClient.d.ts +1 -1
  685. package/dist/unstable/http/HttpClient.d.ts.map +1 -1
  686. package/dist/unstable/http/HttpClient.js +28 -18
  687. package/dist/unstable/http/HttpClient.js.map +1 -1
  688. package/dist/unstable/http/HttpClientRequest.d.ts +28 -6
  689. package/dist/unstable/http/HttpClientRequest.d.ts.map +1 -1
  690. package/dist/unstable/http/HttpClientRequest.js +8 -19
  691. package/dist/unstable/http/HttpClientRequest.js.map +1 -1
  692. package/dist/unstable/http/HttpClientResponse.d.ts +6 -1
  693. package/dist/unstable/http/HttpClientResponse.d.ts.map +1 -1
  694. package/dist/unstable/http/HttpClientResponse.js +10 -6
  695. package/dist/unstable/http/HttpClientResponse.js.map +1 -1
  696. package/dist/unstable/http/HttpEffect.d.ts +16 -0
  697. package/dist/unstable/http/HttpEffect.d.ts.map +1 -1
  698. package/dist/unstable/http/HttpEffect.js +121 -65
  699. package/dist/unstable/http/HttpEffect.js.map +1 -1
  700. package/dist/unstable/http/HttpIncomingMessage.d.ts +3 -3
  701. package/dist/unstable/http/HttpIncomingMessage.d.ts.map +1 -1
  702. package/dist/unstable/http/HttpIncomingMessage.js +1 -13
  703. package/dist/unstable/http/HttpIncomingMessage.js.map +1 -1
  704. package/dist/unstable/http/HttpMiddleware.d.ts +1 -1
  705. package/dist/unstable/http/HttpMiddleware.d.ts.map +1 -1
  706. package/dist/unstable/http/HttpMiddleware.js +29 -21
  707. package/dist/unstable/http/HttpMiddleware.js.map +1 -1
  708. package/dist/unstable/http/HttpPlatform.d.ts +12 -11
  709. package/dist/unstable/http/HttpPlatform.d.ts.map +1 -1
  710. package/dist/unstable/http/HttpPlatform.js +36 -10
  711. package/dist/unstable/http/HttpPlatform.js.map +1 -1
  712. package/dist/unstable/http/HttpRouter.d.ts +5 -1
  713. package/dist/unstable/http/HttpRouter.d.ts.map +1 -1
  714. package/dist/unstable/http/HttpRouter.js +22 -8
  715. package/dist/unstable/http/HttpRouter.js.map +1 -1
  716. package/dist/unstable/http/HttpServer.d.ts +11 -42
  717. package/dist/unstable/http/HttpServer.d.ts.map +1 -1
  718. package/dist/unstable/http/HttpServer.js +16 -20
  719. package/dist/unstable/http/HttpServer.js.map +1 -1
  720. package/dist/unstable/http/HttpServerRequest.d.ts.map +1 -1
  721. package/dist/unstable/http/HttpServerRequest.js +11 -11
  722. package/dist/unstable/http/HttpServerRequest.js.map +1 -1
  723. package/dist/unstable/http/HttpServerRespondable.js +1 -1
  724. package/dist/unstable/http/HttpServerRespondable.js.map +1 -1
  725. package/dist/unstable/http/HttpServerResponse.d.ts +9 -13
  726. package/dist/unstable/http/HttpServerResponse.d.ts.map +1 -1
  727. package/dist/unstable/http/HttpServerResponse.js +34 -44
  728. package/dist/unstable/http/HttpServerResponse.js.map +1 -1
  729. package/dist/unstable/http/HttpStaticServer.d.ts +2 -2
  730. package/dist/unstable/http/HttpStaticServer.d.ts.map +1 -1
  731. package/dist/unstable/http/HttpStaticServer.js +19 -19
  732. package/dist/unstable/http/HttpStaticServer.js.map +1 -1
  733. package/dist/unstable/http/Mime.d.ts +28 -0
  734. package/dist/unstable/http/Mime.d.ts.map +1 -0
  735. package/dist/unstable/http/Mime.js +72 -0
  736. package/dist/unstable/http/Mime.js.map +1 -0
  737. package/dist/unstable/http/Multipart.d.ts +22 -9
  738. package/dist/unstable/http/Multipart.d.ts.map +1 -1
  739. package/dist/unstable/http/Multipart.js +26 -10
  740. package/dist/unstable/http/Multipart.js.map +1 -1
  741. package/dist/unstable/http/MultipartParser/internal/multipart.d.ts +1 -1
  742. package/dist/unstable/http/MultipartParser/internal/multipart.d.ts.map +1 -1
  743. package/dist/unstable/http/MultipartParser/internal/multipart.js +8 -3
  744. package/dist/unstable/http/MultipartParser/internal/multipart.js.map +1 -1
  745. package/dist/unstable/http/MultipartParser.d.ts +4 -3
  746. package/dist/unstable/http/MultipartParser.d.ts.map +1 -1
  747. package/dist/unstable/http/MultipartParser.js.map +1 -1
  748. package/dist/unstable/http/UrlParams.d.ts +0 -97
  749. package/dist/unstable/http/UrlParams.d.ts.map +1 -1
  750. package/dist/unstable/http/UrlParams.js +3 -104
  751. package/dist/unstable/http/UrlParams.js.map +1 -1
  752. package/dist/unstable/http/index.d.ts +4 -0
  753. package/dist/unstable/http/index.d.ts.map +1 -1
  754. package/dist/unstable/http/index.js +4 -0
  755. package/dist/unstable/http/index.js.map +1 -1
  756. package/dist/unstable/http/internal/compression.js +8 -11
  757. package/dist/unstable/http/internal/compression.js.map +1 -1
  758. package/dist/unstable/http/internal/headers.d.ts +2 -0
  759. package/dist/unstable/http/internal/headers.d.ts.map +1 -0
  760. package/dist/unstable/http/internal/headers.js +5 -0
  761. package/dist/unstable/http/internal/headers.js.map +1 -0
  762. package/dist/unstable/http/internal/httpBody.js +8 -0
  763. package/dist/unstable/http/internal/httpBody.js.map +1 -1
  764. package/dist/unstable/http/internal/mimeTypes.d.ts +361 -0
  765. package/dist/unstable/http/internal/mimeTypes.d.ts.map +1 -0
  766. package/dist/unstable/http/internal/mimeTypes.js +363 -0
  767. package/dist/unstable/http/internal/mimeTypes.js.map +1 -0
  768. package/dist/unstable/httpapi/HttpApiBuilder.d.ts +13 -0
  769. package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
  770. package/dist/unstable/httpapi/HttpApiBuilder.js +23 -6
  771. package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
  772. package/dist/unstable/httpapi/HttpApiClient.d.ts +4 -3
  773. package/dist/unstable/httpapi/HttpApiClient.d.ts.map +1 -1
  774. package/dist/unstable/httpapi/HttpApiClient.js +25 -13
  775. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  776. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts +8 -3
  777. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts.map +1 -1
  778. package/dist/unstable/httpapi/HttpApiEndpoint.js +9 -6
  779. package/dist/unstable/httpapi/HttpApiEndpoint.js.map +1 -1
  780. package/dist/unstable/httpapi/HttpApiError.d.ts.map +1 -1
  781. package/dist/unstable/httpapi/HttpApiError.js +3 -1
  782. package/dist/unstable/httpapi/HttpApiError.js.map +1 -1
  783. package/dist/unstable/httpapi/HttpApiMiddleware.d.ts.map +1 -1
  784. package/dist/unstable/httpapi/HttpApiMiddleware.js +7 -5
  785. package/dist/unstable/httpapi/HttpApiMiddleware.js.map +1 -1
  786. package/dist/unstable/httpapi/HttpApiSchema.d.ts +12 -0
  787. package/dist/unstable/httpapi/HttpApiSchema.d.ts.map +1 -1
  788. package/dist/unstable/httpapi/HttpApiSchema.js +8 -10
  789. package/dist/unstable/httpapi/HttpApiSchema.js.map +1 -1
  790. package/dist/unstable/httpapi/HttpApiTest.d.ts.map +1 -1
  791. package/dist/unstable/httpapi/HttpApiTest.js +8 -2
  792. package/dist/unstable/httpapi/HttpApiTest.js.map +1 -1
  793. package/dist/unstable/httpapi/OpenApi.d.ts.map +1 -1
  794. package/dist/unstable/httpapi/OpenApi.js +31 -20
  795. package/dist/unstable/httpapi/OpenApi.js.map +1 -1
  796. package/dist/unstable/net/IpInterface.d.ts +140 -0
  797. package/dist/unstable/net/IpInterface.d.ts.map +1 -0
  798. package/dist/unstable/net/IpInterface.js +149 -0
  799. package/dist/unstable/net/IpInterface.js.map +1 -0
  800. package/dist/unstable/net/IpNetwork.d.ts +227 -0
  801. package/dist/unstable/net/IpNetwork.d.ts.map +1 -0
  802. package/dist/unstable/net/IpNetwork.js +239 -0
  803. package/dist/unstable/net/IpNetwork.js.map +1 -0
  804. package/dist/unstable/net/NetAddress.d.ts +705 -0
  805. package/dist/unstable/net/NetAddress.d.ts.map +1 -0
  806. package/dist/unstable/net/NetAddress.js +956 -0
  807. package/dist/unstable/net/NetAddress.js.map +1 -0
  808. package/dist/unstable/net/index.d.ts +16 -0
  809. package/dist/unstable/net/index.d.ts.map +1 -0
  810. package/dist/unstable/net/index.js +17 -0
  811. package/dist/unstable/net/index.js.map +1 -0
  812. package/dist/unstable/observability/OtlpExporter.d.ts +1 -0
  813. package/dist/unstable/observability/OtlpExporter.d.ts.map +1 -1
  814. package/dist/unstable/observability/OtlpExporter.js +4 -6
  815. package/dist/unstable/observability/OtlpExporter.js.map +1 -1
  816. package/dist/unstable/observability/OtlpLogger.js +9 -9
  817. package/dist/unstable/observability/OtlpLogger.js.map +1 -1
  818. package/dist/unstable/observability/OtlpMetrics.d.ts.map +1 -1
  819. package/dist/unstable/observability/OtlpMetrics.js +9 -8
  820. package/dist/unstable/observability/OtlpMetrics.js.map +1 -1
  821. package/dist/unstable/observability/OtlpResource.d.ts.map +1 -1
  822. package/dist/unstable/observability/OtlpResource.js +2 -2
  823. package/dist/unstable/observability/OtlpResource.js.map +1 -1
  824. package/dist/unstable/observability/OtlpTracer.d.ts.map +1 -1
  825. package/dist/unstable/observability/OtlpTracer.js +82 -55
  826. package/dist/unstable/observability/OtlpTracer.js.map +1 -1
  827. package/dist/unstable/observability/internal/otlpEnv.d.ts +1 -1
  828. package/dist/unstable/observability/internal/otlpEnv.d.ts.map +1 -1
  829. package/dist/unstable/observability/internal/otlpEnv.js +5 -9
  830. package/dist/unstable/observability/internal/otlpEnv.js.map +1 -1
  831. package/dist/unstable/persistence/PersistedCache.js +1 -1
  832. package/dist/unstable/persistence/PersistedCache.js.map +1 -1
  833. package/dist/unstable/persistence/PersistedQueue.d.ts +114 -14
  834. package/dist/unstable/persistence/PersistedQueue.d.ts.map +1 -1
  835. package/dist/unstable/persistence/PersistedQueue.js +799 -234
  836. package/dist/unstable/persistence/PersistedQueue.js.map +1 -1
  837. package/dist/unstable/persistence/RateLimiter.d.ts +28 -15
  838. package/dist/unstable/persistence/RateLimiter.d.ts.map +1 -1
  839. package/dist/unstable/persistence/RateLimiter.js +33 -41
  840. package/dist/unstable/persistence/RateLimiter.js.map +1 -1
  841. package/dist/unstable/process/ChildProcess.d.ts +8 -2
  842. package/dist/unstable/process/ChildProcess.d.ts.map +1 -1
  843. package/dist/unstable/process/ChildProcess.js +7 -2
  844. package/dist/unstable/process/ChildProcess.js.map +1 -1
  845. package/dist/unstable/process/ChildProcessSpawner.d.ts +1 -1
  846. package/dist/unstable/process/ChildProcessSpawner.d.ts.map +1 -1
  847. package/dist/unstable/process/ChildProcessSpawner.js +1 -1
  848. package/dist/unstable/process/ChildProcessSpawner.js.map +1 -1
  849. package/dist/unstable/reactivity/Atom.d.ts.map +1 -1
  850. package/dist/unstable/reactivity/Atom.js +6 -3
  851. package/dist/unstable/reactivity/Atom.js.map +1 -1
  852. package/dist/unstable/reactivity/AtomHttpApi.d.ts +3 -6
  853. package/dist/unstable/reactivity/AtomHttpApi.d.ts.map +1 -1
  854. package/dist/unstable/reactivity/AtomHttpApi.js +6 -3
  855. package/dist/unstable/reactivity/AtomHttpApi.js.map +1 -1
  856. package/dist/unstable/reactivity/AtomRegistry.js +2 -3
  857. package/dist/unstable/reactivity/AtomRegistry.js.map +1 -1
  858. package/dist/unstable/reactivity/AtomRpc.d.ts +2 -2
  859. package/dist/unstable/reactivity/AtomRpc.d.ts.map +1 -1
  860. package/dist/unstable/reactivity/AtomRpc.js +1 -1
  861. package/dist/unstable/reactivity/AtomRpc.js.map +1 -1
  862. package/dist/unstable/reactivity/Hydration.d.ts +6 -4
  863. package/dist/unstable/reactivity/Hydration.d.ts.map +1 -1
  864. package/dist/unstable/reactivity/Hydration.js +20 -6
  865. package/dist/unstable/reactivity/Hydration.js.map +1 -1
  866. package/dist/unstable/reactivity/Reactivity.d.ts +26 -26
  867. package/dist/unstable/reactivity/Reactivity.d.ts.map +1 -1
  868. package/dist/unstable/reactivity/Reactivity.js +10 -12
  869. package/dist/unstable/reactivity/Reactivity.js.map +1 -1
  870. package/dist/unstable/rpc/RpcClient.d.ts.map +1 -1
  871. package/dist/unstable/rpc/RpcClient.js +64 -64
  872. package/dist/unstable/rpc/RpcClient.js.map +1 -1
  873. package/dist/unstable/rpc/RpcClientError.d.ts +1 -1
  874. package/dist/unstable/rpc/RpcMessage.d.ts +3 -1
  875. package/dist/unstable/rpc/RpcMessage.d.ts.map +1 -1
  876. package/dist/unstable/rpc/RpcMessage.js +1 -1
  877. package/dist/unstable/rpc/RpcMessage.js.map +1 -1
  878. package/dist/unstable/rpc/RpcMiddleware.d.ts.map +1 -1
  879. package/dist/unstable/rpc/RpcMiddleware.js +7 -5
  880. package/dist/unstable/rpc/RpcMiddleware.js.map +1 -1
  881. package/dist/unstable/rpc/RpcSerialization.d.ts +5 -39
  882. package/dist/unstable/rpc/RpcSerialization.d.ts.map +1 -1
  883. package/dist/unstable/rpc/RpcSerialization.js +22 -115
  884. package/dist/unstable/rpc/RpcSerialization.js.map +1 -1
  885. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  886. package/dist/unstable/rpc/RpcServer.js +104 -57
  887. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  888. package/dist/unstable/schema/Model.d.ts.map +1 -1
  889. package/dist/unstable/schema/Model.js +7 -6
  890. package/dist/unstable/schema/Model.js.map +1 -1
  891. package/dist/unstable/schema/VariantSchema.d.ts.map +1 -1
  892. package/dist/unstable/schema/VariantSchema.js +3 -0
  893. package/dist/unstable/schema/VariantSchema.js.map +1 -1
  894. package/dist/unstable/socket/Socket.d.ts +287 -102
  895. package/dist/unstable/socket/Socket.d.ts.map +1 -1
  896. package/dist/unstable/socket/Socket.js +408 -215
  897. package/dist/unstable/socket/Socket.js.map +1 -1
  898. package/dist/unstable/socket/SocketServer.d.ts +5 -32
  899. package/dist/unstable/socket/SocketServer.d.ts.map +1 -1
  900. package/dist/unstable/socket/SocketServer.js +3 -3
  901. package/dist/unstable/socket/SocketServer.js.map +1 -1
  902. package/dist/unstable/sql/SqlClient.d.ts +20 -0
  903. package/dist/unstable/sql/SqlClient.d.ts.map +1 -1
  904. package/dist/unstable/sql/SqlClient.js +14 -7
  905. package/dist/unstable/sql/SqlClient.js.map +1 -1
  906. package/dist/unstable/sql/SqlConnection.d.ts +15 -0
  907. package/dist/unstable/sql/SqlConnection.d.ts.map +1 -1
  908. package/dist/unstable/sql/SqlConnection.js.map +1 -1
  909. package/dist/unstable/sql/SqlModel.d.ts +1 -1
  910. package/dist/unstable/sql/SqlModel.d.ts.map +1 -1
  911. package/dist/unstable/sql/Statement.d.ts +13 -5
  912. package/dist/unstable/sql/Statement.d.ts.map +1 -1
  913. package/dist/unstable/sql/Statement.js +29 -15
  914. package/dist/unstable/sql/Statement.js.map +1 -1
  915. package/dist/unstable/workers/Transferable.js +1 -1
  916. package/dist/unstable/workers/Worker.d.ts.map +1 -1
  917. package/dist/unstable/workers/Worker.js +3 -1
  918. package/dist/unstable/workers/Worker.js.map +1 -1
  919. package/dist/unstable/workflow/Activity.d.ts +7 -0
  920. package/dist/unstable/workflow/Activity.d.ts.map +1 -1
  921. package/dist/unstable/workflow/Activity.js +14 -4
  922. package/dist/unstable/workflow/Activity.js.map +1 -1
  923. package/dist/unstable/workflow/DurableClock.js +1 -1
  924. package/dist/unstable/workflow/DurableClock.js.map +1 -1
  925. package/dist/unstable/workflow/DurableDeferred.d.ts +2 -2
  926. package/dist/unstable/workflow/DurableDeferred.d.ts.map +1 -1
  927. package/dist/unstable/workflow/DurableDeferred.js.map +1 -1
  928. package/dist/unstable/workflow/DurableQueue.d.ts +8 -0
  929. package/dist/unstable/workflow/DurableQueue.d.ts.map +1 -1
  930. package/dist/unstable/workflow/DurableQueue.js +8 -0
  931. package/dist/unstable/workflow/DurableQueue.js.map +1 -1
  932. package/dist/unstable/workflow/Workflow.d.ts +5 -0
  933. package/dist/unstable/workflow/Workflow.d.ts.map +1 -1
  934. package/dist/unstable/workflow/Workflow.js +70 -12
  935. package/dist/unstable/workflow/Workflow.js.map +1 -1
  936. package/dist/unstable/workflow/WorkflowEngine.d.ts +6 -0
  937. package/dist/unstable/workflow/WorkflowEngine.d.ts.map +1 -1
  938. package/dist/unstable/workflow/WorkflowEngine.js +11 -0
  939. package/dist/unstable/workflow/WorkflowEngine.js.map +1 -1
  940. package/package.json +7 -9
  941. package/src/Array.ts +118 -67
  942. package/src/BigDecimal.ts +50 -28
  943. package/src/ByteSize.ts +838 -0
  944. package/src/Cache.ts +17 -3
  945. package/src/Cause.ts +1 -1
  946. package/src/Channel.ts +183 -48
  947. package/src/Chunk.ts +65 -36
  948. package/src/Config.ts +237 -248
  949. package/src/ConfigProvider.ts +7 -8
  950. package/src/Context.ts +31 -0
  951. package/src/Cron.ts +2 -2
  952. package/src/Crypto.ts +3 -2
  953. package/src/Deferred.ts +7 -6
  954. package/src/Duration.ts +1 -1
  955. package/src/Effect.ts +226 -122
  956. package/src/Effectable.ts +78 -9
  957. package/src/Encoding.ts +101 -11
  958. package/src/Equal.ts +1 -1
  959. package/src/ExecutionPlan.ts +3 -0
  960. package/src/Fiber.ts +33 -8
  961. package/src/FiberHandle.ts +3 -3
  962. package/src/FiberMap.ts +19 -10
  963. package/src/FileSystem.ts +55 -230
  964. package/src/Formatter.ts +21 -3
  965. package/src/Graph.ts +55 -25
  966. package/src/Hash.ts +5 -16
  967. package/src/HashRing.ts +9 -2
  968. package/src/HashSet.ts +56 -0
  969. package/src/Iterable.ts +66 -41
  970. package/src/JsonPatch.ts +4 -4
  971. package/src/JsonPointer.ts +97 -4
  972. package/src/JsonSchema.ts +8 -26
  973. package/src/Layer.ts +59 -18
  974. package/src/LayerMap.ts +8 -6
  975. package/src/LayerRef.ts +7 -5
  976. package/src/Logger.ts +125 -18
  977. package/src/ManagedRuntime.ts +1 -1
  978. package/src/Match.ts +33 -14
  979. package/src/Metric.ts +24 -21
  980. package/src/MutableHashMap.ts +1 -1
  981. package/src/MutableHashSet.ts +1 -1
  982. package/src/MutableList.ts +18 -2
  983. package/src/Number.ts +7 -1
  984. package/src/Optic.ts +8 -4
  985. package/src/Option.ts +1 -1
  986. package/src/Order.ts +3 -1
  987. package/src/PartitionedSemaphore.ts +1 -2
  988. package/src/Path.ts +1 -1
  989. package/src/PlatformError.ts +1 -1
  990. package/src/Pool.ts +125 -8
  991. package/src/PrimaryKey.ts +1 -1
  992. package/src/PubSub.ts +32 -20
  993. package/src/Queue.ts +119 -28
  994. package/src/Random.ts +20 -6
  995. package/src/RcMap.ts +20 -13
  996. package/src/Redacted.ts +1 -1
  997. package/src/RequestResolver.ts +49 -26
  998. package/src/Result.ts +1 -1
  999. package/src/Scheduler.ts +21 -11
  1000. package/src/Schema.ts +4809 -6368
  1001. package/src/SchemaAST.ts +1031 -284
  1002. package/src/SchemaGetter.ts +75 -21
  1003. package/src/SchemaIssue.ts +259 -15
  1004. package/src/SchemaParser.ts +2 -12
  1005. package/src/SchemaRepresentation.ts +1593 -29
  1006. package/src/SchemaTransformation.ts +145 -22
  1007. package/src/ScopedCache.ts +10 -3
  1008. package/src/Sink.ts +31 -15
  1009. package/src/Stream.ts +294 -76
  1010. package/src/String.ts +20 -9
  1011. package/src/Struct.ts +8 -4
  1012. package/src/SynchronizedRef.ts +3 -5
  1013. package/src/Terminal.ts +3 -3
  1014. package/src/Tracer.ts +43 -14
  1015. package/src/Tuple.ts +3 -1
  1016. package/src/TxChunk.ts +1 -1
  1017. package/src/TxDeferred.ts +1 -1
  1018. package/src/TxHashMap.ts +1 -1
  1019. package/src/TxHashSet.ts +92 -11
  1020. package/src/TxPriorityQueue.ts +1 -1
  1021. package/src/TxPubSub.ts +1 -1
  1022. package/src/TxQueue.ts +22 -17
  1023. package/src/TxReentrantLock.ts +29 -1
  1024. package/src/TxRef.ts +1 -1
  1025. package/src/TxSemaphore.ts +1 -1
  1026. package/src/TxSubscriptionRef.ts +1 -1
  1027. package/src/Types.ts +40 -17
  1028. package/src/Utils.ts +3 -1
  1029. package/src/index.ts +5 -0
  1030. package/src/internal/arbitrary/model.ts +701 -0
  1031. package/src/internal/arbitrary/regexp.ts +855 -0
  1032. package/src/internal/arbitrary/runner.ts +608 -0
  1033. package/src/internal/arbitrary/schema.ts +1800 -0
  1034. package/src/internal/core.ts +48 -22
  1035. package/src/internal/count.ts +14 -0
  1036. package/src/internal/dateTime.ts +8 -10
  1037. package/src/internal/effect.ts +475 -295
  1038. package/src/internal/graph.ts +6 -1
  1039. package/src/internal/hashMap.ts +5 -3
  1040. package/src/internal/hashSet.ts +1 -1
  1041. package/src/internal/matcher.ts +34 -19
  1042. package/src/internal/metric.ts +1 -1
  1043. package/src/internal/option.ts +8 -6
  1044. package/src/internal/random.ts +20 -7
  1045. package/src/internal/rcRef.ts +10 -7
  1046. package/src/internal/references.ts +1 -0
  1047. package/src/internal/request.ts +12 -7
  1048. package/src/internal/result.ts +15 -11
  1049. package/src/internal/schema/annotations.ts +3 -3
  1050. package/src/internal/schema/fromJsonSchemaDocument.ts +14 -29
  1051. package/src/internal/schema/fromRepresentation.ts +5 -3
  1052. package/src/internal/schema/{schema.ts → make.ts} +0 -40
  1053. package/src/internal/schema/parser.ts +8 -0
  1054. package/src/internal/schema/standardSchema.ts +125 -0
  1055. package/src/internal/schema/toCodeDocument.ts +58 -44
  1056. package/src/internal/schema/toCodec.ts +312 -0
  1057. package/src/internal/schema/toDifferJsonPatch.ts +24 -0
  1058. package/src/internal/schema/toEncoderXml.ts +110 -0
  1059. package/src/internal/schema/toEquivalence.ts +76 -0
  1060. package/src/internal/schema/toFormatter.ts +230 -0
  1061. package/src/internal/schema/toIso.ts +20 -0
  1062. package/src/internal/schema/toJsonSchemaDocument.ts +125 -67
  1063. package/src/internal/schema/toRepresentation.ts +1 -1
  1064. package/src/internal/schemaError.ts +8 -0
  1065. package/src/internal/stream.ts +14 -6
  1066. package/src/internal/tracer.ts +4 -0
  1067. package/src/internal/trie.ts +5 -2
  1068. package/src/internal/uuid.ts +4 -0
  1069. package/src/testing/TestSchema.ts +36 -30
  1070. package/src/testing/index.ts +0 -5
  1071. package/src/unstable/ai/AiError.ts +69 -5
  1072. package/src/unstable/ai/AnthropicStructuredOutput.ts +4 -1
  1073. package/src/unstable/ai/Chat.ts +35 -36
  1074. package/src/unstable/ai/EmbeddingModel.ts +27 -15
  1075. package/src/unstable/ai/LanguageModel.ts +283 -100
  1076. package/src/unstable/ai/McpServer.ts +36 -20
  1077. package/src/unstable/ai/OpenAiStructuredOutput.ts +4 -1
  1078. package/src/unstable/ai/Prompt.ts +19 -4
  1079. package/src/unstable/ai/Response.ts +107 -189
  1080. package/src/unstable/ai/Tokenizer.ts +4 -5
  1081. package/src/unstable/ai/Tool.ts +58 -35
  1082. package/src/unstable/ai/Toolkit.ts +43 -37
  1083. package/src/unstable/ai/internal/structured-output.ts +5 -5
  1084. package/src/unstable/arbitrary/Arbitrary.ts +715 -0
  1085. package/src/unstable/arbitrary/index.ts +10 -0
  1086. package/src/unstable/cli/Argument.ts +111 -115
  1087. package/src/unstable/cli/CliError.ts +2 -0
  1088. package/src/unstable/cli/CliOutput.ts +40 -3
  1089. package/src/unstable/cli/Command.ts +74 -74
  1090. package/src/unstable/cli/Completions.ts +4 -4
  1091. package/src/unstable/cli/Flag.ts +158 -169
  1092. package/src/unstable/cli/GlobalFlag.ts +13 -13
  1093. package/src/unstable/cli/Param.ts +150 -159
  1094. package/src/unstable/cli/Primitive.ts +75 -76
  1095. package/src/unstable/cli/Prompt.ts +88 -87
  1096. package/src/unstable/cli/internal/completions/descriptor.ts +23 -11
  1097. package/src/unstable/cli/internal/completions/zsh.ts +2 -2
  1098. package/src/unstable/cli/internal/config.ts +4 -4
  1099. package/src/unstable/cli/internal/parser.ts +1 -1
  1100. package/src/unstable/cli/internal/wizard.ts +18 -13
  1101. package/src/unstable/cluster/ClusterSchema.ts +19 -1
  1102. package/src/unstable/cluster/ClusterWorkflowEngine.ts +66 -16
  1103. package/src/unstable/cluster/Entity.ts +3 -0
  1104. package/src/unstable/cluster/EntityProxyServer.ts +6 -2
  1105. package/src/unstable/cluster/Envelope.ts +3 -3
  1106. package/src/unstable/cluster/HttpRunner.ts +7 -2
  1107. package/src/unstable/cluster/MessageStorage.ts +62 -21
  1108. package/src/unstable/cluster/Reply.ts +2 -2
  1109. package/src/unstable/cluster/Sharding.ts +44 -19
  1110. package/src/unstable/cluster/ShardingConfig.ts +23 -23
  1111. package/src/unstable/cluster/SocketRunner.ts +5 -4
  1112. package/src/unstable/cluster/SqlMessageStorage.ts +12 -8
  1113. package/src/unstable/cluster/SqlRunnerStorage.ts +18 -10
  1114. package/src/unstable/cluster/internal/clusterAbandon.ts +14 -0
  1115. package/src/unstable/cluster/internal/entityManager.ts +12 -4
  1116. package/src/unstable/cluster/internal/interruptors.ts +58 -1
  1117. package/src/unstable/cluster/internal/resourceRef.ts +15 -7
  1118. package/src/unstable/devtools/DevToolsClient.ts +13 -3
  1119. package/src/unstable/encoding/Ini.ts +2 -0
  1120. package/src/unstable/encoding/SchemaBinary.ts +150 -44
  1121. package/src/unstable/encoding/Sse.ts +1 -1
  1122. package/src/unstable/encoding/Toml.ts +7 -5
  1123. package/src/unstable/encoding/Yaml.ts +18 -5
  1124. package/src/unstable/encoding/index.ts +0 -5
  1125. package/src/unstable/eventlog/Event.ts +7 -7
  1126. package/src/unstable/eventlog/EventJournal.ts +9 -9
  1127. package/src/unstable/eventlog/EventLog.ts +5 -5
  1128. package/src/unstable/eventlog/EventLogMessage.ts +25 -15
  1129. package/src/unstable/eventlog/EventLogRemote.ts +15 -4
  1130. package/src/unstable/eventlog/EventLogServerUnencrypted.ts +2 -2
  1131. package/src/unstable/eventlog/SqlEventJournal.ts +32 -9
  1132. package/src/unstable/eventlog/SqlEventLogServerUnencrypted.ts +11 -1
  1133. package/src/unstable/http/Cookies.ts +2 -102
  1134. package/src/unstable/http/FetchHttpClient.ts +1 -1
  1135. package/src/unstable/http/FindMyWay/internal/router.ts +139 -33
  1136. package/src/unstable/http/FindMyWay.ts +15 -5
  1137. package/src/unstable/http/Headers.ts +3 -48
  1138. package/src/unstable/http/HttpBody.ts +107 -36
  1139. package/src/unstable/http/HttpClient.ts +41 -30
  1140. package/src/unstable/http/HttpClientRequest.ts +32 -18
  1141. package/src/unstable/http/HttpClientResponse.ts +16 -3
  1142. package/src/unstable/http/HttpEffect.ts +145 -73
  1143. package/src/unstable/http/HttpIncomingMessage.ts +4 -4
  1144. package/src/unstable/http/HttpMiddleware.ts +43 -24
  1145. package/src/unstable/http/HttpPlatform.ts +62 -20
  1146. package/src/unstable/http/HttpRouter.ts +27 -16
  1147. package/src/unstable/http/HttpServer.ts +18 -57
  1148. package/src/unstable/http/HttpServerRequest.ts +17 -15
  1149. package/src/unstable/http/HttpServerRespondable.ts +1 -1
  1150. package/src/unstable/http/HttpServerResponse.ts +49 -40
  1151. package/src/unstable/http/HttpStaticServer.ts +30 -28
  1152. package/src/unstable/http/Mime.ts +76 -0
  1153. package/src/unstable/http/Multipart.ts +35 -18
  1154. package/src/unstable/http/MultipartParser/internal/multipart.ts +10 -3
  1155. package/src/unstable/http/MultipartParser.ts +4 -3
  1156. package/src/unstable/http/UrlParams.ts +3 -161
  1157. package/src/unstable/http/index.ts +5 -0
  1158. package/src/unstable/http/internal/compression.ts +11 -12
  1159. package/src/unstable/http/internal/headers.ts +7 -0
  1160. package/src/unstable/http/internal/httpBody.ts +9 -0
  1161. package/src/unstable/http/internal/mimeTypes.ts +395 -0
  1162. package/src/unstable/httpapi/HttpApiBuilder.ts +52 -6
  1163. package/src/unstable/httpapi/HttpApiClient.ts +44 -24
  1164. package/src/unstable/httpapi/HttpApiEndpoint.ts +24 -11
  1165. package/src/unstable/httpapi/HttpApiError.ts +3 -1
  1166. package/src/unstable/httpapi/HttpApiMiddleware.ts +7 -5
  1167. package/src/unstable/httpapi/HttpApiSchema.ts +14 -7
  1168. package/src/unstable/httpapi/HttpApiTest.ts +6 -1
  1169. package/src/unstable/httpapi/OpenApi.ts +32 -22
  1170. package/src/unstable/net/IpInterface.ts +242 -0
  1171. package/src/unstable/net/IpNetwork.ts +357 -0
  1172. package/src/unstable/net/NetAddress.ts +1271 -0
  1173. package/src/unstable/net/index.ts +20 -0
  1174. package/src/unstable/observability/OtlpExporter.ts +5 -6
  1175. package/src/unstable/observability/OtlpLogger.ts +9 -9
  1176. package/src/unstable/observability/OtlpMetrics.ts +9 -8
  1177. package/src/unstable/observability/OtlpResource.ts +5 -4
  1178. package/src/unstable/observability/OtlpTracer.ts +103 -81
  1179. package/src/unstable/observability/internal/otlpEnv.ts +10 -13
  1180. package/src/unstable/persistence/PersistedCache.ts +1 -1
  1181. package/src/unstable/persistence/PersistedQueue.ts +1100 -291
  1182. package/src/unstable/persistence/RateLimiter.ts +64 -58
  1183. package/src/unstable/process/ChildProcess.ts +15 -4
  1184. package/src/unstable/process/ChildProcessSpawner.ts +1 -1
  1185. package/src/unstable/reactivity/Atom.ts +6 -3
  1186. package/src/unstable/reactivity/AtomHttpApi.ts +21 -10
  1187. package/src/unstable/reactivity/AtomRegistry.ts +2 -4
  1188. package/src/unstable/reactivity/AtomRpc.ts +6 -5
  1189. package/src/unstable/reactivity/Hydration.ts +26 -7
  1190. package/src/unstable/reactivity/Reactivity.ts +49 -36
  1191. package/src/unstable/rpc/RpcClient.ts +62 -59
  1192. package/src/unstable/rpc/RpcMessage.ts +3 -1
  1193. package/src/unstable/rpc/RpcMiddleware.ts +7 -5
  1194. package/src/unstable/rpc/RpcSerialization.ts +27 -117
  1195. package/src/unstable/rpc/RpcServer.ts +143 -80
  1196. package/src/unstable/schema/Model.ts +8 -7
  1197. package/src/unstable/schema/VariantSchema.ts +3 -0
  1198. package/src/unstable/socket/Socket.ts +714 -383
  1199. package/src/unstable/socket/SocketServer.ts +5 -35
  1200. package/src/unstable/sql/SqlClient.ts +42 -7
  1201. package/src/unstable/sql/SqlConnection.ts +18 -0
  1202. package/src/unstable/sql/SqlModel.ts +1 -1
  1203. package/src/unstable/sql/Statement.ts +46 -20
  1204. package/src/unstable/workers/Transferable.ts +1 -1
  1205. package/src/unstable/workers/Worker.ts +3 -1
  1206. package/src/unstable/workflow/Activity.ts +20 -9
  1207. package/src/unstable/workflow/DurableClock.ts +1 -1
  1208. package/src/unstable/workflow/DurableDeferred.ts +6 -0
  1209. package/src/unstable/workflow/DurableQueue.ts +8 -0
  1210. package/src/unstable/workflow/Workflow.ts +105 -28
  1211. package/src/unstable/workflow/WorkflowEngine.ts +22 -0
  1212. package/dist/internal/schema/schema.d.ts.map +0 -1
  1213. package/dist/internal/schema/schema.js.map +0 -1
  1214. package/dist/internal/schema/toArbitrary.d.ts +0 -2
  1215. package/dist/internal/schema/toArbitrary.d.ts.map +0 -1
  1216. package/dist/internal/schema/toArbitrary.js +0 -705
  1217. package/dist/internal/schema/toArbitrary.js.map +0 -1
  1218. package/dist/testing/FastCheck.d.ts +0 -90
  1219. package/dist/testing/FastCheck.d.ts.map +0 -1
  1220. package/dist/testing/FastCheck.js +0 -90
  1221. package/dist/testing/FastCheck.js.map +0 -1
  1222. package/dist/unstable/encoding/Msgpack.d.ts +0 -185
  1223. package/dist/unstable/encoding/Msgpack.d.ts.map +0 -1
  1224. package/dist/unstable/encoding/Msgpack.js +0 -227
  1225. package/dist/unstable/encoding/Msgpack.js.map +0 -1
  1226. package/src/internal/schema/toArbitrary.ts +0 -843
  1227. package/src/testing/FastCheck.ts +0 -90
  1228. package/src/unstable/encoding/Msgpack.ts +0 -432
  1229. /package/dist/internal/{schema → arbitrary}/schema.d.ts +0 -0
@@ -1,14 +1,30 @@
1
+ /**
2
+ * Stores schema-encoded queue work in persistent storage.
3
+ *
4
+ * A `PersistedQueue<A>` keeps JSON-encoded values in a named queue and lets
5
+ * workers take one value at a time inside a scoped processing window. It is
6
+ * useful for durable handoffs, background jobs, outbox-style integrations, and
7
+ * work that should retry across fibers, process restarts, or multiple workers.
8
+ * This module includes a queue factory, store service, id-based de-duplication,
9
+ * retry handling, and in-memory, Redis, and SQL-backed store layers.
10
+ *
11
+ * Delivery is at-least-once: a crash between handler success and the
12
+ * acknowledgement redelivers the element, so handlers must be idempotent.
13
+ *
14
+ * @since 4.0.0
15
+ */
1
16
  import * as Cause from "../../Cause.js";
17
+ import * as Clock from "../../Clock.js";
2
18
  import * as Context from "../../Context.js";
3
- import * as Data from "../../Data.js";
4
19
  import * as Duration from "../../Duration.js";
5
20
  import * as Effect from "../../Effect.js";
6
- import * as Exit from "../../Exit.js";
7
21
  import { flow } from "../../Function.js";
8
- import * as Iterable from "../../Iterable.js";
22
+ import { sqlCleanupBatchSize } from "../../internal/persistence.js";
9
23
  import * as Latch from "../../Latch.js";
10
24
  import * as Layer from "../../Layer.js";
11
25
  import * as MutableRef from "../../MutableRef.js";
26
+ import * as Predicate from "../../Predicate.js";
27
+ import * as Pull from "../../Pull.js";
12
28
  import * as Queue from "../../Queue.js";
13
29
  import * as RcMap from "../../RcMap.js";
14
30
  import * as Schedule from "../../Schedule.js";
@@ -35,10 +51,47 @@ export class PersistedQueueFactory extends /*#__PURE__*/Context.Service()("effec
35
51
  * Accesses `PersistedQueueFactory` to create a named persisted queue for a
36
52
  * schema.
37
53
  *
54
+ * **Details**
55
+ *
56
+ * `maxAttempts` defaults to 10. `retrySchedule` controls the delay before a
57
+ * failed element becomes visible again, and defaults to an exponential delay
58
+ * starting at 1 second and capped at 5 minutes.
59
+ *
60
+ * The schedule's state is the element's persisted attempt count. On each
61
+ * failure the schedule is replayed up to the current attempt, so delays keep
62
+ * progressing even when consecutive retries run in different processes. The
63
+ * schedule input is the attempt number.
64
+ *
65
+ * Replay simulates elapsed time from the sum of the computed delays.
66
+ * Attempt-driven schedules are therefore exact, while wall-clock-anchored
67
+ * schedules observe this idealized time. In particular,
68
+ * `Schedule.upTo({ duration })` caps the summed delays rather than real time
69
+ * since the original failure.
70
+ *
38
71
  * @category accessors
39
72
  * @since 4.0.0
40
73
  */
41
74
  export const make = options => PersistedQueueFactory.use(factory => factory.make(options));
75
+ const defaultRetrySchedule = /*#__PURE__*/Schedule.min([/*#__PURE__*/Schedule.exponential("1 second"), /*#__PURE__*/Schedule.spaced("5 minutes")]);
76
+ // The persisted attempt count is the schedule state: consecutive retries of an
77
+ // element can run in different processes, so a fresh schedule step is replayed
78
+ // up to the given attempt on every call. Delays therefore depend only on the
79
+ // attempt count, with elapsed time simulated from the summed delays.
80
+ const retryDelay = /*#__PURE__*/Effect.fnUntraced(function* (schedule, attempts) {
81
+ const step = yield* Schedule.toStep(schedule);
82
+ let now = 0;
83
+ let delay = Duration.zero;
84
+ for (let i = 0; i < attempts; i++) {
85
+ const result = yield* Pull.catchDone(step(now, i + 1), () => Effect.undefined);
86
+ if (result === undefined) {
87
+ // the schedule is done, keep using its final delay
88
+ break;
89
+ }
90
+ delay = result[1];
91
+ now += Duration.toMillis(delay);
92
+ }
93
+ return delay;
94
+ });
42
95
  /**
43
96
  * Creates a `PersistedQueueFactory` from the current `PersistedQueueStore`.
44
97
  *
@@ -58,6 +111,12 @@ export const makeFactory = /*#__PURE__*/Effect.gen(function* () {
58
111
  const jsonSchema = Schema.toCodecJson(options.schema);
59
112
  const encodeUnknown = Schema.encodeUnknownEffect(jsonSchema);
60
113
  const decodeUnknown = Schema.decodeUnknownEffect(jsonSchema);
114
+ const retrySchedule = options.retrySchedule ?? defaultRetrySchedule;
115
+ const takeOptions = {
116
+ name: options.name,
117
+ maxAttempts: options.maxAttempts ?? 10,
118
+ retryDelay: attempts => retryDelay(retrySchedule, attempts)
119
+ };
61
120
  return Effect.succeed({
62
121
  [TypeId]: TypeId,
63
122
  offer: (value, opts) => Effect.flatMap(encodeUnknown(value), element => {
@@ -69,17 +128,13 @@ export const makeFactory = /*#__PURE__*/Effect.gen(function* () {
69
128
  isCustomId: opts?.id !== undefined
70
129
  }), id);
71
130
  }),
72
- take: (f, opts) => Effect.scopedWith(Effect.fnUntraced(function* (scope) {
73
- const item = yield* store.take({
74
- name: options.name,
75
- maxAttempts: opts?.maxAttempts ?? 10
76
- }).pipe(Scope.provide(scope));
77
- const decoded = yield* decodeUnknown(item.element);
78
- return yield* f(decoded, {
131
+ take: f => {
132
+ const loop = Effect.scopedWith(scope => store.take(takeOptions).pipe(Scope.provide(scope), Effect.flatMap(item => decodeUnknown(item.element).pipe(Effect.catchCause(cause => Cause.hasInterruptsOnly(cause) ? Effect.failCause(cause) : Effect.fail(new DeadLetter(cause))), Effect.flatMap(value => f(value, {
79
133
  id: item.id,
80
134
  attempts: item.attempts
81
- });
82
- }))
135
+ })))))).pipe(Effect.catchIf(isDeadLetter, () => loop));
136
+ return loop;
137
+ }
83
138
  });
84
139
  }
85
140
  });
@@ -91,13 +146,41 @@ export const makeFactory = /*#__PURE__*/Effect.gen(function* () {
91
146
  * @since 4.0.0
92
147
  */
93
148
  export const layer = /*#__PURE__*/Layer.effect(PersistedQueueFactory, makeFactory);
149
+ /**
150
+ * Runs `PersistedQueueStore.cleanup` on a schedule.
151
+ *
152
+ * **Details**
153
+ *
154
+ * Completed elements are retained for `timeToLive` (default 30 days) so
155
+ * offer de-duplication keeps working across replays, then removed. Failed
156
+ * elements are the dead-letter record and are kept forever unless
157
+ * `failedTimeToLive` is set.
158
+ *
159
+ * Run this layer in one instance of a deployment rather than on every worker;
160
+ * racing instances are harmless since deletes are idempotent, but the work is
161
+ * redundant.
162
+ *
163
+ * @category layers
164
+ * @since 4.0.0
165
+ */
166
+ export const layerCleanup = options => Layer.effectDiscard(Effect.gen(function* () {
167
+ const store = yield* PersistedQueueStore;
168
+ const cleanupOptions = {
169
+ timeToLive: Duration.fromInputUnsafe(options?.timeToLive ?? Duration.days(30)),
170
+ failedTimeToLive: options?.failedTimeToLive === undefined ? undefined : Duration.fromInputUnsafe(options.failedTimeToLive)
171
+ };
172
+ yield* store.cleanup(cleanupOptions).pipe(Effect.catchCause(cause => Effect.logWarning("Failed to clean up persisted queue", cause)), Effect.repeat(Schedule.spaced(options?.interval ?? Duration.hours(1))), Effect.interruptible, Effect.forkScoped, Effect.annotateLogs({
173
+ module: "effect/persistence/PersistedQueue",
174
+ fiber: "cleanup"
175
+ }));
176
+ }));
94
177
  /**
95
178
  * Runtime type identifier for `PersistedQueueError`.
96
179
  *
97
180
  * @category type IDs
98
181
  * @since 4.0.0
99
182
  */
100
- export const ErrorTypeId = "~@effect/experimental/PersistedQueue/PersistedQueueError";
183
+ export const ErrorTypeId = "~effect/persistence/PersistedQueue/PersistedQueueError";
101
184
  /**
102
185
  * Error raised by persisted queue store operations.
103
186
  *
@@ -116,6 +199,47 @@ export class PersistedQueueError extends /*#__PURE__*/Schema.Error("effect/persi
116
199
  */
117
200
  [ErrorTypeId] = ErrorTypeId;
118
201
  }
202
+ const makeQueueStates = () => {
203
+ const states = new Map();
204
+ return {
205
+ peek: name => states.get(name),
206
+ get: name => {
207
+ let state = states.get(name);
208
+ if (state === undefined) {
209
+ // the placeholder is overwritten by take before any mailbox reads it,
210
+ // and is kept int32-safe for SQL parameters
211
+ state = {
212
+ maxAttempts: 2147483647,
213
+ nudge: Latch.makeUnsafe(false)
214
+ };
215
+ states.set(name, state);
216
+ }
217
+ return state;
218
+ }
219
+ };
220
+ };
221
+ const makeAckRetrySchedule = lockExpiration => Schedule.min([Schedule.exponential(200, 1.5), Schedule.spaced(5000)]).pipe(Schedule.upTo({
222
+ duration: lockExpiration
223
+ }));
224
+ // Internal signal used by the factory to tell a store that a taken element
225
+ // cannot ever be processed (its stored payload fails to decode) and must be
226
+ // dead-lettered instead of retried.
227
+ class DeadLetter {
228
+ _tag = "~effect/persistence/PersistedQueue/DeadLetter";
229
+ cause;
230
+ constructor(cause) {
231
+ this.cause = cause;
232
+ }
233
+ }
234
+ const isDeadLetter = u => Predicate.isTagged(u, "~effect/persistence/PersistedQueue/DeadLetter");
235
+ const deadLetterFromCause = cause => {
236
+ for (const reason of cause.reasons) {
237
+ if (Cause.isFailReason(reason) && isDeadLetter(reason.error)) {
238
+ return reason.error;
239
+ }
240
+ }
241
+ return undefined;
242
+ };
119
243
  /**
120
244
  * Defines the low-level backing store service used by `PersistedQueue`.
121
245
  *
@@ -129,6 +253,12 @@ export class PersistedQueueError extends /*#__PURE__*/Schema.Error("effect/persi
129
253
  * The store persists offered elements and returns taken elements in a scope so
130
254
  * the finalizer can complete or retry them based on the processing exit.
131
255
  *
256
+ * Claiming an element counts an attempt, so the `attempts` returned by `take`
257
+ * is 1-based. When the take scope closes with a success the element is marked
258
+ * completed; a failure retries it according to `retryDelay` or marks it failed
259
+ * once `maxAttempts` is exhausted; an interruption releases it without
260
+ * counting the attempt.
261
+ *
132
262
  * @category services
133
263
  * @since 4.0.0
134
264
  */
@@ -138,21 +268,23 @@ export class PersistedQueueStore extends /*#__PURE__*/Context.Service()("effect/
138
268
  *
139
269
  * **Details**
140
270
  *
141
- * The store is process-local and volatile; failed takes are requeued until the
142
- * configured maximum attempts is reached.
271
+ * The store is process-local and volatile; failed takes are requeued with the
272
+ * queue's retry schedule until the configured maximum attempts is reached,
273
+ * after which the element is marked as failed.
143
274
  *
144
275
  * @category layers
145
276
  * @since 4.0.0
146
277
  */
147
- export const layerStoreMemory = /*#__PURE__*/Layer.sync(PersistedQueueStore, () => {
278
+ export const layerStoreMemory = /*#__PURE__*/Layer.effect(PersistedQueueStore, /*#__PURE__*/Effect.gen(function* () {
279
+ const clock = yield* Clock.Clock;
148
280
  const queues = new Map();
149
281
  const getOrCreateQueue = name => {
150
282
  let queue = queues.get(name);
151
283
  if (!queue) {
152
284
  queue = {
153
285
  latch: Latch.makeUnsafe(false),
154
- ids: new Set(),
155
- items: new Set()
286
+ entries: new Map(),
287
+ pending: new Set()
156
288
  };
157
289
  queues.set(name, queue);
158
290
  }
@@ -160,102 +292,176 @@ export const layerStoreMemory = /*#__PURE__*/Layer.sync(PersistedQueueStore, ()
160
292
  };
161
293
  return PersistedQueueStore.of({
162
294
  offer: options => Effect.sync(() => {
295
+ const now = clock.currentTimeMillisUnsafe();
163
296
  const queue = getOrCreateQueue(options.name);
164
- if (queue.ids.has(options.id)) return;
165
- queue.ids.add(options.id);
166
- queue.items.add({
297
+ if (queue.entries.has(options.id)) return;
298
+ const entry = {
167
299
  id: options.id,
300
+ element: options.element,
168
301
  attempts: 0,
169
- element: options.element
170
- });
302
+ state: "pending",
303
+ visibleAt: now,
304
+ stateChangedAt: now
305
+ };
306
+ queue.entries.set(options.id, entry);
307
+ queue.pending.add(entry);
171
308
  queue.latch.openUnsafe();
172
309
  }),
173
310
  take: Effect.fnUntraced(function* (options) {
174
311
  const queue = getOrCreateQueue(options.name);
175
312
  while (true) {
176
- yield* queue.latch.await;
177
- const item = Iterable.headUnsafe(queue.items);
178
- queue.items.delete(item);
179
- if (queue.items.size === 0) {
180
- queue.latch.closeUnsafe();
313
+ // close before scanning so a mutation after the scan reopens the latch
314
+ queue.latch.closeUnsafe();
315
+ const now = clock.currentTimeMillisUnsafe();
316
+ let item;
317
+ let nextVisibleAt = Infinity;
318
+ for (const entry of queue.pending) {
319
+ if (entry.attempts >= options.maxAttempts) continue;
320
+ if (entry.visibleAt <= now) {
321
+ item = entry;
322
+ break;
323
+ }
324
+ nextVisibleAt = Math.min(nextVisibleAt, entry.visibleAt);
181
325
  }
182
- yield* Effect.addFinalizer(exit => {
326
+ if (item === undefined) {
327
+ yield* nextVisibleAt === Infinity ? queue.latch.await : Effect.race(queue.latch.await, Effect.sleep(Duration.millis(nextVisibleAt - now)));
328
+ continue;
329
+ }
330
+ const entry = item;
331
+ entry.state = "processing";
332
+ entry.attempts += 1;
333
+ queue.pending.delete(entry);
334
+ queue.latch.openUnsafe();
335
+ yield* Effect.addFinalizer(Effect.fnUntraced(function* (exit) {
336
+ const now = clock.currentTimeMillisUnsafe();
183
337
  if (exit._tag === "Success") {
184
- return Effect.void;
185
- } else if (!Exit.hasInterrupts(exit)) {
186
- item.attempts += 1;
338
+ entry.state = "completed";
339
+ entry.stateChangedAt = now;
340
+ return;
341
+ }
342
+ const deadLetter = deadLetterFromCause(exit.cause);
343
+ if (deadLetter !== undefined) {
344
+ entry.state = "failed";
345
+ entry.stateChangedAt = now;
346
+ return;
187
347
  }
188
- if (item.attempts >= options.maxAttempts) {
189
- return Effect.void;
348
+ if (Cause.hasInterruptsOnly(exit.cause)) {
349
+ entry.attempts -= 1;
350
+ } else if (entry.attempts >= options.maxAttempts) {
351
+ entry.state = "failed";
352
+ entry.stateChangedAt = now;
353
+ return;
354
+ } else {
355
+ entry.visibleAt = now + Duration.toMillis(yield* options.retryDelay(entry.attempts));
190
356
  }
191
- queue.items.add(item);
357
+ entry.state = "pending";
358
+ queue.pending.add(entry);
192
359
  queue.latch.openUnsafe();
193
- return Effect.void;
194
- });
195
- return item;
360
+ }));
361
+ return {
362
+ id: entry.id,
363
+ attempts: entry.attempts,
364
+ element: entry.element
365
+ };
366
+ }
367
+ }),
368
+ cleanup: options => Effect.sync(() => {
369
+ const now = clock.currentTimeMillisUnsafe();
370
+ const completedCutoff = now - Duration.toMillis(options.timeToLive);
371
+ const failedCutoff = options.failedTimeToLive === undefined ? undefined : now - Duration.toMillis(options.failedTimeToLive);
372
+ for (const queue of queues.values()) {
373
+ for (const [id, entry] of queue.entries) {
374
+ const cutoff = entry.state === "completed" ? completedCutoff : entry.state === "failed" ? failedCutoff : undefined;
375
+ if (cutoff !== undefined && entry.stateChangedAt <= cutoff) {
376
+ queue.entries.delete(id);
377
+ }
378
+ }
196
379
  }
197
380
  })
198
381
  });
199
- });
382
+ }));
200
383
  /**
201
384
  * Creates a Redis-backed `PersistedQueueStore`.
202
385
  *
203
386
  * **Details**
204
387
  *
205
- * The store uses Redis lists and hashes with worker locks, periodically
206
- * refreshes locks while items are being processed, and moves exhausted items
207
- * to a failed queue.
388
+ * The store uses Redis lists, hashes, and sorted sets with worker locks,
389
+ * periodically refreshes locks while items are being processed, delays retried
390
+ * items with the queue's retry schedule, and moves exhausted items to a failed
391
+ * queue.
208
392
  *
209
393
  * @category constructors
210
394
  * @since 4.0.0
211
395
  */
212
396
  export const makeStoreRedis = /*#__PURE__*/Effect.fnUntraced(function* (options) {
213
397
  const redis = yield* Redis.Redis;
398
+ const clock = yield* Clock.Clock;
214
399
  const pollInterval = Duration.max(options?.pollInterval ? Duration.fromInputUnsafe(options.pollInterval) : Duration.seconds(1), Duration.millis(1));
215
400
  const lockRefreshMillis = Math.max(options?.lockRefreshInterval ? Duration.toMillis(Duration.fromInputUnsafe(options.lockRefreshInterval)) : 30_000, 1);
216
401
  const lockExpirationMillis = Math.max(options?.lockExpiration ? Duration.toMillis(Duration.fromInputUnsafe(options.lockExpiration)) : 90_000, 1);
217
402
  const prefix = options?.prefix ?? "effectq:";
218
- const keyQueue = name => `${prefix}${name}`;
219
403
  const keyLock = id => `${prefix}${id}:lock`;
220
- const keyPending = name => `${prefix}${name}:pending`;
221
- const keyFailed = name => `${prefix}${name}:failed`;
404
+ const keysFor = name => ({
405
+ queue: `${prefix}${name}`,
406
+ pending: `${prefix}${name}:pending`,
407
+ failed: `${prefix}${name}:failed`,
408
+ delayed: `${prefix}${name}:delayed`,
409
+ attempts: `${prefix}${name}:attempts`,
410
+ ids: `${prefix}${name}:ids`
411
+ });
222
412
  const workerId = crypto.randomUUID();
413
+ const ackRetrySchedule = makeAckRetrySchedule(lockExpirationMillis);
223
414
  const requeue = redis.eval(requeueRedis);
224
415
  const complete = redis.eval(completeRedis);
225
416
  const failed = redis.eval(failedRedis);
417
+ const retry = redis.eval(retryRedis);
226
418
  const resetQueue = redis.eval(resetQueueRedis);
227
419
  const offer = redis.eval(offerRedis);
228
420
  const take = redis.eval(takeRedis);
229
421
  const expireAll = redis.eval(expireAllRedis);
422
+ const trimFailed = redis.eval(trimFailedRedis);
423
+ const queueStates = makeQueueStates();
230
424
  const queues = yield* RcMap.make({
231
425
  lookup: Effect.fnUntraced(function* (name) {
232
- const queueKey = keyQueue(name);
233
- const pendingKey = keyPending(name);
426
+ const keys = keysFor(name);
234
427
  const queue = yield* Queue.make();
235
428
  const takers = MutableRef.make(0);
236
429
  const pollLatch = Latch.makeUnsafe();
237
430
  const takenLatch = Latch.makeUnsafe();
238
- yield* Effect.addFinalizer(() => Effect.orDie(Effect.flatMap(Queue.clear(queue), elements => Effect.forEach(elements, element => requeue(queueKey, pendingKey, keyLock(element.id), element.id, JSON.stringify(element)), {
431
+ const state = queueStates.get(name);
432
+ yield* Effect.addFinalizer(() => Effect.orDie(Effect.flatMap(Queue.clear(queue), elements => Effect.forEach(elements, element => requeue(keys.queue, keys.pending, keyLock(element.id), keys.attempts, element.id, element.payload), {
239
433
  concurrency: "unbounded",
240
434
  discard: true
241
435
  }))));
242
- yield* resetQueue(queueKey, pendingKey, prefix).pipe(Effect.andThen(Effect.sleep(lockRefreshMillis)), Effect.forever, Effect.forkScoped);
243
- const poll = size => take(queueKey, pendingKey, prefix, workerId, size, lockExpirationMillis);
436
+ yield* Effect.suspend(() => resetQueue(keys.queue, keys.pending, keys.attempts, keys.failed, keys.ids, prefix, state.maxAttempts, clock.currentTimeMillisUnsafe())).pipe(Effect.andThen(Effect.sleep(lockRefreshMillis)), Effect.forever, Effect.forkScoped);
437
+ const poll = size => Effect.suspend(() => take(keys.queue, keys.pending, keys.delayed, keys.attempts, prefix, workerId, size, lockExpirationMillis, clock.currentTimeMillisUnsafe()));
244
438
  yield* Effect.gen(function* () {
245
439
  while (true) {
246
440
  yield* pollLatch.await;
247
441
  yield* Effect.yieldNow;
442
+ state.nudge.closeUnsafe();
248
443
  const results = takers.current === 0 ? null : yield* poll(takers.current);
249
- if (results === null) {
250
- yield* Effect.sleep(pollInterval);
444
+ if (results === null || results.length === 0) {
445
+ yield* Effect.race(Effect.sleep(pollInterval), state.nudge.await);
251
446
  continue;
252
447
  }
253
448
  takenLatch.closeUnsafe();
254
- yield* Queue.offerAll(queue, results.map(json => JSON.parse(json)));
449
+ const elements = [];
450
+ for (let i = 0; i < results.length; i += 2) {
451
+ const payload = results[i];
452
+ const parsed = JSON.parse(payload);
453
+ elements.push({
454
+ id: parsed.id,
455
+ element: parsed.element,
456
+ attempts: Number(results[i + 1]),
457
+ payload
458
+ });
459
+ }
460
+ yield* Queue.offerAll(queue, elements);
255
461
  yield* takenLatch.await;
256
462
  yield* Effect.yieldNow;
257
463
  }
258
- }).pipe(Effect.sandbox, Effect.retry(Schedule.spaced(500)), Effect.forkScoped, Effect.interruptible);
464
+ }).pipe(Effect.tapCause(Effect.logWarning), Effect.sandbox, Effect.retry(Schedule.spaced(500)), Effect.forkScoped, Effect.interruptible);
259
465
  return {
260
466
  queue,
261
467
  takers,
@@ -275,70 +481,120 @@ export const makeStoreRedis = /*#__PURE__*/Effect.fnUntraced(function* (options)
275
481
  module: "effect/persistence/PersistedQueue",
276
482
  fiber: "refreshLocks"
277
483
  }));
484
+ const scanKeys = pattern => Effect.gen(function* () {
485
+ const keys = [];
486
+ let cursor = "0";
487
+ do {
488
+ const [next, batch] = yield* redis.send("SCAN", cursor, "MATCH", pattern, "COUNT", "100");
489
+ cursor = next;
490
+ for (const key of batch) keys.push(key);
491
+ } while (cursor !== "0");
492
+ return keys;
493
+ });
278
494
  return PersistedQueueStore.of({
279
495
  offer: ({
280
496
  element,
281
497
  id,
282
498
  isCustomId,
283
499
  name
284
- }) => Effect.mapError(isCustomId ? offer(`${prefix}${name}`, `${prefix}${name}:ids`, id, JSON.stringify({
285
- id,
286
- element,
287
- attempts: 0
288
- })) : redis.send("RPUSH", `${prefix}${name}`, JSON.stringify({
289
- id,
290
- element,
291
- attempts: 0
292
- })), ({
293
- cause
294
- }) => new PersistedQueueError({
295
- message: "Failed to offer element to persisted queue",
296
- cause
297
- })),
298
- take: options => Effect.uninterruptibleMask(restore => RcMap.get(queues, options.name).pipe(Effect.flatMap(({
299
- pollLatch,
300
- queue,
301
- takenLatch,
302
- takers
303
500
  }) => {
304
- takers.current++;
305
- if (takers.current === 1) {
306
- pollLatch.openUnsafe();
307
- }
308
- return Effect.tap(restore(Queue.take(queue)), () => Effect.sync(() => {
309
- takers.current--;
310
- if (takers.current === 0) {
311
- pollLatch.closeUnsafe();
312
- takenLatch.openUnsafe();
313
- } else if (Queue.sizeUnsafe(queue) === 0) {
314
- takenLatch.openUnsafe();
501
+ const keys = keysFor(name);
502
+ const payload = JSON.stringify({
503
+ id,
504
+ element
505
+ });
506
+ return (isCustomId ? offer(keys.queue, keys.ids, id, payload) : redis.send("RPUSH", keys.queue, payload)).pipe(Effect.mapError(({
507
+ cause
508
+ }) => new PersistedQueueError({
509
+ message: "Failed to offer element to persisted queue",
510
+ cause
511
+ })), Effect.tap(() => Effect.sync(() => {
512
+ queueStates.peek(name)?.nudge.openUnsafe();
513
+ })));
514
+ },
515
+ take: options => Effect.uninterruptibleMask(restore => {
516
+ queueStates.get(options.name).maxAttempts = options.maxAttempts;
517
+ return RcMap.get(queues, options.name).pipe(Effect.flatMap(({
518
+ pollLatch,
519
+ queue,
520
+ takenLatch,
521
+ takers
522
+ }) => {
523
+ takers.current++;
524
+ if (takers.current === 1) {
525
+ pollLatch.openUnsafe();
315
526
  }
316
- }));
317
- }), Effect.scoped, Effect.tap(element => {
318
- const lock = keyLock(element.id);
319
- activeLockKeys.add(lock);
320
- return Effect.addFinalizer(Exit.match({
321
- onFailure: cause => {
322
- activeLockKeys.delete(lock);
323
- const nextAttempts = element.attempts + 1;
324
- if (nextAttempts >= options.maxAttempts) {
325
- return Effect.orDie(failed(keyPending(options.name), lock, keyFailed(options.name), element.id, JSON.stringify({
326
- ...element,
327
- lastFailure: Cause.pretty(cause),
328
- attempts: nextAttempts
329
- })));
527
+ // onExit so the decrement also runs when a waiting take is
528
+ // interrupted, otherwise the poller keeps fetching for a phantom
529
+ // taker
530
+ return Effect.onExit(restore(Queue.take(queue)), () => Effect.sync(() => {
531
+ takers.current--;
532
+ if (takers.current === 0) {
533
+ pollLatch.closeUnsafe();
534
+ takenLatch.openUnsafe();
535
+ } else if (Queue.sizeUnsafe(queue) === 0) {
536
+ takenLatch.openUnsafe();
330
537
  }
331
- return Effect.orDie(requeue(keyQueue(options.name), keyPending(options.name), lock, element.id, JSON.stringify(Cause.hasInterruptsOnly(cause) ? element : {
332
- ...element,
538
+ }));
539
+ }), Effect.scoped, Effect.tap(element => {
540
+ const keys = keysFor(options.name);
541
+ const lock = keyLock(element.id);
542
+ activeLockKeys.add(lock);
543
+ const ack = effect => effect.pipe(Effect.retry(ackRetrySchedule), Effect.orDie, Effect.ensuring(Effect.sync(() => activeLockKeys.delete(lock))));
544
+ return Effect.addFinalizer(exit => Effect.suspend(() => {
545
+ const now = clock.currentTimeMillisUnsafe();
546
+ if (exit._tag === "Success") {
547
+ return ack(complete(keys.pending, lock, keys.attempts, keys.ids, element.id, now));
548
+ }
549
+ const dead = deadLetterFromCause(exit.cause);
550
+ const failElement = cause => ack(failed(keys.pending, lock, keys.failed, keys.attempts, keys.ids, element.id, JSON.stringify({
551
+ id: element.id,
552
+ element: element.element,
553
+ attempts: element.attempts,
333
554
  lastFailure: Cause.pretty(cause),
334
- attempts: nextAttempts
555
+ failedAt: now
335
556
  })));
336
- },
337
- onSuccess: () => {
338
- activeLockKeys.delete(lock);
339
- return Effect.orDie(complete(keyPending(options.name), lock, element.id));
340
- }
557
+ if (dead !== undefined) {
558
+ return failElement(dead.cause);
559
+ }
560
+ if (Cause.hasInterruptsOnly(exit.cause)) {
561
+ return ack(requeue(keys.queue, keys.pending, lock, keys.attempts, element.id, element.payload));
562
+ }
563
+ if (element.attempts >= options.maxAttempts) {
564
+ return failElement(exit.cause);
565
+ }
566
+ return Effect.flatMap(options.retryDelay(element.attempts), delay => ack(retry(keys.pending, lock, keys.delayed, element.id, element.payload, now + Duration.toMillis(delay))));
567
+ }));
341
568
  }));
569
+ }),
570
+ cleanup: ({
571
+ failedTimeToLive,
572
+ timeToLive
573
+ }) => Effect.gen(function* () {
574
+ const now = clock.currentTimeMillisUnsafe();
575
+ const idsKeys = yield* scanKeys(`${prefix}*:ids`);
576
+ const cutoff = now - Duration.toMillis(timeToLive);
577
+ yield* Effect.forEach(idsKeys, key => redis.send("ZREMRANGEBYSCORE", key, "-inf", `(${cutoff}`), {
578
+ concurrency: 16,
579
+ discard: true
580
+ });
581
+ if (failedTimeToLive !== undefined) {
582
+ const failedCutoff = now - Duration.toMillis(failedTimeToLive);
583
+ const failedKeys = yield* scanKeys(`${prefix}*:failed`);
584
+ yield* Effect.forEach(failedKeys, key => trimFailed(key, `${key.slice(0, -":failed".length)}:ids`, failedCutoff).pipe(
585
+ // each call trims at most one batch, so drain until done
586
+ Effect.repeat({
587
+ while: removed => removed >= trimFailedBatchSize
588
+ })), {
589
+ concurrency: 16,
590
+ discard: true
591
+ });
592
+ }
593
+ }).pipe(Effect.mapError(({
594
+ cause
595
+ }) => new PersistedQueueError({
596
+ message: "Failed to clean up persisted queue",
597
+ cause
342
598
  })))
343
599
  });
344
600
  });
@@ -349,7 +605,9 @@ local key_ids = KEYS[2]
349
605
  local id = ARGV[1]
350
606
  local payload = ARGV[2]
351
607
 
352
- local result = redis.call("SADD", key_ids, id)
608
+ -- park the dedupe entry outside the timeToLive trim range until the element
609
+ -- completes, so unprocessed elements never lose dedupe protection
610
+ local result = redis.call("ZADD", key_ids, "NX", "+inf", id)
353
611
  if result == 1 then
354
612
  redis.call("RPUSH", key_queue, payload)
355
613
  end
@@ -360,7 +618,12 @@ const resetQueueRedis = /*#__PURE__*/Redis.script((...args) => args, {
360
618
  lua: `
361
619
  local key_queue = KEYS[1]
362
620
  local key_pending = KEYS[2]
621
+ local key_attempts = KEYS[3]
622
+ local key_failed = KEYS[4]
623
+ local key_ids = KEYS[5]
363
624
  local prefix = ARGV[1]
625
+ local max_attempts = tonumber(ARGV[2])
626
+ local now = ARGV[3]
364
627
 
365
628
  local entries = redis.call("HGETALL", key_pending)
366
629
  for i = 1, #entries, 2 do
@@ -369,76 +632,135 @@ for i = 1, #entries, 2 do
369
632
  local lock_key = prefix .. id .. ":lock"
370
633
  local exists = redis.call("EXISTS", lock_key)
371
634
  if exists == 0 then
372
- redis.call("RPUSH", key_queue, payload)
635
+ local attempts = tonumber(redis.call("HGET", key_attempts, id) or "0")
636
+ if attempts >= max_attempts then
637
+ -- compose the failed record by hand so the element payload does not go
638
+ -- through a lossy cjson round-trip
639
+ local record = string.sub(payload, 1, -2) .. ',"attempts":' .. attempts ..
640
+ ',"lastFailure":"Lock expired after final attempt","failedAt":' .. now .. '}'
641
+ redis.call("RPUSH", key_failed, record)
642
+ redis.call("HDEL", key_attempts, id)
643
+ -- failed ids keep their dedupe entry until failedTimeToLive removes the
644
+ -- dead-letter record, so park them outside the timeToLive trim range
645
+ redis.call("ZADD", key_ids, "XX", "+inf", id)
646
+ else
647
+ redis.call("RPUSH", key_queue, payload)
648
+ end
373
649
  redis.call("HDEL", key_pending, id)
374
650
  end
375
651
  end
376
652
  `,
377
- numberOfKeys: 2
653
+ numberOfKeys: 5
378
654
  });
379
655
  const requeueRedis = /*#__PURE__*/Redis.script((...args) => args, {
380
656
  lua: `
381
657
  local key_queue = KEYS[1]
382
658
  local key_pending = KEYS[2]
383
659
  local key_lock = KEYS[3]
660
+ local key_attempts = KEYS[4]
384
661
  local id = ARGV[1]
385
662
  local payload = ARGV[2]
386
663
 
387
664
  redis.call("DEL", key_lock)
388
665
  redis.call("HDEL", key_pending, id)
666
+ local attempts = redis.call("HINCRBY", key_attempts, id, -1)
667
+ if attempts <= 0 then
668
+ redis.call("HDEL", key_attempts, id)
669
+ end
389
670
  redis.call("RPUSH", key_queue, payload)
390
671
  `,
391
- numberOfKeys: 3
672
+ numberOfKeys: 4
392
673
  });
393
674
  const completeRedis = /*#__PURE__*/Redis.script((...args) => args, {
394
675
  lua: `
395
676
  local key_pending = KEYS[1]
396
677
  local key_lock = KEYS[2]
678
+ local key_attempts = KEYS[3]
679
+ local key_ids = KEYS[4]
397
680
  local id = ARGV[1]
681
+ local now = ARGV[2]
398
682
 
399
683
  redis.call("DEL", key_lock)
400
684
  redis.call("HDEL", key_pending, id)
685
+ redis.call("HDEL", key_attempts, id)
686
+ redis.call("ZADD", key_ids, "XX", now, id)
401
687
  `,
402
- numberOfKeys: 2
688
+ numberOfKeys: 4
689
+ });
690
+ const retryRedis = /*#__PURE__*/Redis.script((...args) => args, {
691
+ lua: `
692
+ local key_pending = KEYS[1]
693
+ local key_lock = KEYS[2]
694
+ local key_delayed = KEYS[3]
695
+ local id = ARGV[1]
696
+ local payload = ARGV[2]
697
+ local visible_at = ARGV[3]
698
+
699
+ redis.call("DEL", key_lock)
700
+ redis.call("HDEL", key_pending, id)
701
+ redis.call("ZADD", key_delayed, visible_at, payload)
702
+ `,
703
+ numberOfKeys: 3
403
704
  });
404
705
  const failedRedis = /*#__PURE__*/Redis.script((...args) => args, {
405
706
  lua: `
406
707
  local key_pending = KEYS[1]
407
708
  local key_lock = KEYS[2]
408
709
  local key_failed = KEYS[3]
710
+ local key_attempts = KEYS[4]
711
+ local key_ids = KEYS[5]
409
712
  local id = ARGV[1]
410
713
  local payload = ARGV[2]
411
714
 
412
715
  redis.call("DEL", key_lock)
413
716
  redis.call("HDEL", key_pending, id)
717
+ redis.call("HDEL", key_attempts, id)
414
718
  redis.call("RPUSH", key_failed, payload)
719
+ -- failed ids keep their dedupe entry until failedTimeToLive removes the
720
+ -- dead-letter record, so park them outside the timeToLive trim range
721
+ redis.call("ZADD", key_ids, "XX", "+inf", id)
415
722
  `,
416
- numberOfKeys: 3
723
+ numberOfKeys: 5
417
724
  });
418
725
  const takeRedis = /*#__PURE__*/Redis.script((...args) => args, {
419
726
  lua: `
420
727
  local key_queue = KEYS[1]
421
728
  local key_pending = KEYS[2]
729
+ local key_delayed = KEYS[3]
730
+ local key_attempts = KEYS[4]
422
731
  local prefix = ARGV[1]
423
732
  local worker_id = ARGV[2]
424
733
  local batch_size = tonumber(ARGV[3])
425
734
  local pttl = ARGV[4]
735
+ local now = ARGV[5]
736
+
737
+ local due = redis.call("ZRANGEBYSCORE", key_delayed, "-inf", now, "LIMIT", 0, 100)
738
+ if #due > 0 then
739
+ for i, payload in ipairs(due) do
740
+ redis.call("RPUSH", key_queue, payload)
741
+ end
742
+ redis.call("ZREM", key_delayed, unpack(due))
743
+ end
426
744
 
427
745
  local payloads = redis.call("LPOP", key_queue, batch_size)
428
746
  if not payloads then
429
747
  return nil
430
748
  end
431
749
 
750
+ local result = {}
432
751
  for i, payload in ipairs(payloads) do
433
752
  local id = cjson.decode(payload).id
434
753
  local key_lock = prefix .. id .. ":lock"
435
754
  redis.call("SET", key_lock, worker_id, "PX", pttl)
436
755
  redis.call("HSET", key_pending, id, payload)
756
+ local attempts = redis.call("HINCRBY", key_attempts, id, 1)
757
+ result[i * 2 - 1] = payload
758
+ result[i * 2] = attempts
437
759
  end
438
760
 
439
- return payloads
761
+ return result
440
762
  `,
441
- numberOfKeys: 2
763
+ numberOfKeys: 4
442
764
  }).withReturnType();
443
765
  const expireAllRedis = /*#__PURE__*/Redis.script((keys, ttl) => [...keys, ttl], {
444
766
  numberOfKeys: keys => keys.length,
@@ -449,6 +771,36 @@ for i, key in ipairs(KEYS) do
449
771
  end
450
772
  `
451
773
  });
774
+ const trimFailedBatchSize = 1000;
775
+ const trimFailedRedis = /*#__PURE__*/Redis.script((...args) => args, {
776
+ lua: `
777
+ local key_failed = KEYS[1]
778
+ local key_ids = KEYS[2]
779
+ local cutoff = tonumber(ARGV[1])
780
+ local removed = 0
781
+
782
+ while removed < ${trimFailedBatchSize} do
783
+ local head = redis.call("LINDEX", key_failed, 0)
784
+ if not head then break end
785
+ local ok, decoded = pcall(cjson.decode, head)
786
+ if ok then
787
+ local failed_at = tonumber(decoded.failedAt)
788
+ if failed_at ~= nil and failed_at >= cutoff then break end
789
+ redis.call("LPOP", key_failed)
790
+ if decoded.id ~= nil then
791
+ redis.call("ZREM", key_ids, decoded.id)
792
+ end
793
+ else
794
+ -- a corrupt head would otherwise block trimming of the whole list
795
+ redis.call("LPOP", key_failed)
796
+ end
797
+ removed = removed + 1
798
+ end
799
+
800
+ return removed
801
+ `,
802
+ numberOfKeys: 2
803
+ }).withReturnType();
452
804
  /**
453
805
  * Provides a Redis-backed `PersistedQueueStore` using `makeStoreRedis`.
454
806
  *
@@ -475,46 +827,56 @@ export const makeStoreSql = /*#__PURE__*/Effect.fnUntraced(function* (options) {
475
827
  const pollInterval = Duration.max(options?.pollInterval ? Duration.fromInputUnsafe(options.pollInterval) : Duration.millis(1000), Duration.millis(1));
476
828
  const lockRefreshInterval = Duration.max(options?.lockRefreshInterval ? Duration.fromInputUnsafe(options.lockRefreshInterval) : Duration.seconds(30), Duration.millis(1));
477
829
  const lockExpiration = Duration.max(options?.lockExpiration ? Duration.fromInputUnsafe(options.lockExpiration) : Duration.minutes(2), Duration.millis(1));
478
- const lockExpirationSql = sql.literal(Math.ceil(Duration.toSeconds(lockExpiration)).toString());
479
830
  const workerId = crypto.randomUUID();
831
+ const ackRetrySchedule = makeAckRetrySchedule(lockExpiration);
480
832
  yield* Effect.orDie(Migrator.make({})({
481
833
  loader: sqlMigrations(tableName),
482
834
  table: `${tableName}_migrations`
483
835
  }));
484
836
  const sqlNow = sql.onDialectOrElse({
485
- mssql: () => sql.literal("GETDATE()"),
837
+ // GETDATE() rounds to 1/300s and can land in the future, hiding freshly
838
+ // written visible_at values from the poll query
839
+ mssql: () => sql.literal("SYSDATETIME()"),
486
840
  mysql: () => sql.literal("NOW()"),
487
841
  pg: () => sql.literal("NOW()"),
488
842
  // sqlite
489
843
  orElse: () => sql.literal("CURRENT_TIMESTAMP")
490
844
  });
491
- const expiresAt = sql.onDialectOrElse({
492
- pg: () => sql`${sqlNow} - INTERVAL '${lockExpirationSql} seconds'`,
493
- mysql: () => sql`DATE_SUB(${sqlNow}, INTERVAL ${lockExpirationSql} SECOND)`,
494
- mssql: () => sql`DATEADD(SECOND, -${lockExpirationSql}, ${sqlNow})`,
495
- orElse: () => sql`datetime(${sqlNow}, '-${lockExpirationSql} seconds')`
496
- });
845
+ // `seconds` is a whole number, possibly negative
846
+ const secondsOffset = seconds => {
847
+ const s = sql.literal(seconds.toString());
848
+ return sql.onDialectOrElse({
849
+ pg: () => sql`${sqlNow} + INTERVAL '${s} seconds'`,
850
+ mysql: () => sql`DATE_ADD(${sqlNow}, INTERVAL ${s} SECOND)`,
851
+ mssql: () => sql`DATEADD(SECOND, ${s}, ${sqlNow})`,
852
+ orElse: () => sql`datetime(${sqlNow}, '${s} seconds')`
853
+ });
854
+ };
855
+ const secondsAgo = seconds => secondsOffset(-Math.max(Math.ceil(seconds), 0));
856
+ const secondsFromNow = seconds => secondsOffset(Math.max(Math.ceil(seconds), 0));
857
+ const expiresAt = secondsAgo(Duration.toSeconds(lockExpiration));
497
858
  const offer = sql.onDialectOrElse({
498
859
  pg: () => (id, name, element) => sql`
499
- INSERT INTO ${tableNameSql} (id, queue_name, element, completed, attempts, created_at, updated_at)
500
- VALUES (${id}, ${name}, ${element}, FALSE, 0, ${sqlNow}, ${sqlNow})
860
+ INSERT INTO ${tableNameSql} (id, queue_name, element, state, attempts, visible_at, created_at, updated_at)
861
+ VALUES (${id}, ${name}, ${element}, 'pending', 0, ${sqlNow}, ${sqlNow}, ${sqlNow})
501
862
  ON CONFLICT (id, queue_name) DO NOTHING
502
863
  `,
503
864
  mysql: () => (id, name, element) => sql`
504
- INSERT IGNORE INTO ${tableNameSql} (id, queue_name, element, completed, attempts, created_at, updated_at)
505
- VALUES (${id}, ${name}, ${element}, FALSE, 0, ${sqlNow}, ${sqlNow})
865
+ INSERT IGNORE INTO ${tableNameSql} (id, queue_name, element, state, attempts, visible_at, created_at, updated_at)
866
+ VALUES (${id}, ${name}, ${element}, 'pending', 0, ${sqlNow}, ${sqlNow}, ${sqlNow})
506
867
  `,
507
868
  mssql: () => (id, name, element) => sql`
508
- IF NOT EXISTS (SELECT 1 FROM ${tableNameSql} WHERE id = ${id} AND queue_name = ${name})
509
- BEGIN
510
- INSERT INTO ${tableNameSql} (id, queue_name, element, completed, attempts, created_at, updated_at)
511
- VALUES (${id}, ${name}, ${element}, 0, 0, ${sqlNow}, ${sqlNow})
512
- END
869
+ MERGE ${tableNameSql} WITH (HOLDLOCK) AS target
870
+ USING (SELECT ${id} AS id, ${name} AS queue_name) AS source
871
+ ON target.id = source.id AND target.queue_name = source.queue_name
872
+ WHEN NOT MATCHED THEN
873
+ INSERT (id, queue_name, element, state, attempts, visible_at, created_at, updated_at)
874
+ VALUES (source.id, source.queue_name, ${element}, 'pending', 0, ${sqlNow}, ${sqlNow}, ${sqlNow});
513
875
  `,
514
876
  // sqlite
515
877
  orElse: () => (id, name, element) => sql`
516
- INSERT OR IGNORE INTO ${tableNameSql} (id, queue_name, element, completed, attempts, created_at, updated_at)
517
- VALUES (${id}, ${name}, ${element}, FALSE, 0, ${sqlNow}, ${sqlNow})
878
+ INSERT OR IGNORE INTO ${tableNameSql} (id, queue_name, element, state, attempts, visible_at, created_at, updated_at)
879
+ VALUES (${id}, ${name}, ${element}, 'pending', 0, ${sqlNow}, ${sqlNow}, ${sqlNow})
518
880
  `
519
881
  });
520
882
  const wrapString = sql.onDialectOrElse({
@@ -522,10 +884,6 @@ export const makeStoreSql = /*#__PURE__*/Effect.fnUntraced(function* (options) {
522
884
  orElse: () => s => `'${s}'`
523
885
  });
524
886
  const stringLiteral = s => sql.literal(wrapString(s));
525
- const sqlTrue = sql.onDialectOrElse({
526
- sqlite: () => sql.literal("1"),
527
- orElse: () => sql.literal("TRUE")
528
- });
529
887
  const workerIdSql = stringLiteral(workerId);
530
888
  const elementIds = new Set();
531
889
  const refreshLocks = Effect.suspend(() => {
@@ -538,143 +896,156 @@ export const makeStoreSql = /*#__PURE__*/Effect.fnUntraced(function* (options) {
538
896
  AND acquired_by = ${workerIdSql}
539
897
  `;
540
898
  });
541
- const complete = (sequence, attempts) => {
542
- elementIds.delete(sequence);
543
- return sql`
544
- UPDATE ${tableNameSql}
545
- SET acquired_at = NULL, acquired_by = NULL, updated_at = ${sqlNow}, completed = ${sqlTrue}, attempts = ${attempts}
546
- WHERE sequence = ${sequence}
547
- AND acquired_by = ${workerIdSql}
548
- `.pipe(Effect.retry({
549
- times: 5,
550
- schedule: Schedule.exponential(100, 1.5)
551
- }), Effect.orDie);
552
- };
553
- const retry = (sequence, attempts, cause) => {
554
- elementIds.delete(sequence);
555
- return sql`
556
- UPDATE ${tableNameSql}
557
- SET acquired_at = NULL, acquired_by = NULL, updated_at = ${sqlNow}, attempts = ${attempts}, last_failure = ${Cause.pretty(cause)}
558
- WHERE sequence = ${sequence}
559
- AND acquired_by = ${workerIdSql}
560
- `.pipe(Effect.retry({
561
- times: 5,
562
- schedule: Schedule.exponential(100, 1.5)
563
- }), Effect.orDie);
564
- };
565
- const interrupt = ids => {
566
- for (const id of ids) {
567
- elementIds.delete(id);
899
+ const ack = (statement, sequences) => statement.pipe(Effect.retry(ackRetrySchedule), Effect.orDie, Effect.ensuring(Effect.sync(() => {
900
+ for (const sequence of sequences) {
901
+ elementIds.delete(sequence);
568
902
  }
569
- return sql`
570
- UPDATE ${tableNameSql}
571
- SET acquired_at = NULL, acquired_by = NULL
572
- WHERE sequence IN (${sql.literal(ids.join(","))})
573
- AND acquired_by = ${workerIdSql}
574
- `.pipe(Effect.retry({
575
- times: 5,
576
- schedule: Schedule.exponential(100, 1.5)
577
- }), Effect.orDie);
578
- };
903
+ })), Effect.asVoid);
904
+ const complete = sequence => ack(sql`
905
+ UPDATE ${tableNameSql}
906
+ SET acquired_at = NULL, acquired_by = NULL, updated_at = ${sqlNow}, state = 'completed'
907
+ WHERE sequence = ${sequence}
908
+ AND acquired_by = ${workerIdSql}
909
+ `, [sequence]);
910
+ const fail = (sequence, cause) => ack(sql`
911
+ UPDATE ${tableNameSql}
912
+ SET acquired_at = NULL, acquired_by = NULL, updated_at = ${sqlNow}, state = 'failed', last_failure = ${Cause.pretty(cause)}
913
+ WHERE sequence = ${sequence}
914
+ AND acquired_by = ${workerIdSql}
915
+ `, [sequence]);
916
+ const retry = (sequence, delay, cause) => ack(sql`
917
+ UPDATE ${tableNameSql}
918
+ SET acquired_at = NULL, acquired_by = NULL, updated_at = ${sqlNow}, visible_at = ${secondsFromNow(Duration.toSeconds(delay))}, last_failure = ${Cause.pretty(cause)}
919
+ WHERE sequence = ${sequence}
920
+ AND acquired_by = ${workerIdSql}
921
+ `, [sequence]);
922
+ const interrupt = ids => ack(sql`
923
+ UPDATE ${tableNameSql}
924
+ SET acquired_at = NULL, acquired_by = NULL, attempts = attempts - 1
925
+ WHERE sequence IN (${sql.literal(ids.join(","))})
926
+ AND acquired_by = ${workerIdSql}
927
+ `, ids);
579
928
  yield* refreshLocks.pipe(Effect.tapCause(Effect.logWarning), Effect.retry(Schedule.spaced(500)), Effect.schedule(Schedule.fixed(lockRefreshInterval)), Effect.annotateLogs({
580
929
  package: "@effect/sql",
581
930
  module: "SqlPersistedQueue",
582
931
  fiber: "refreshLocks"
583
932
  }), Effect.forkScoped);
933
+ const queueStates = makeQueueStates();
584
934
  const mailboxes = yield* RcMap.make({
585
- lookup: Effect.fnUntraced(function* ({
586
- maxAttempts,
587
- name
588
- }) {
935
+ lookup: Effect.fnUntraced(function* (name) {
936
+ const state = queueStates.get(name);
937
+ const maxAttempts = state.maxAttempts;
589
938
  const queue = yield* Queue.make();
590
939
  const takers = MutableRef.make(0);
591
940
  const pollLatch = Latch.makeUnsafe();
592
941
  const takenLatch = Latch.makeUnsafe();
942
+ const nudge = state.nudge;
593
943
  yield* Effect.addFinalizer(() => Effect.flatMap(Queue.clear(queue), elements => {
594
944
  if (elements.length === 0) return Effect.void;
595
945
  return interrupt(Array.from(elements, e => e.sequence));
596
946
  }));
947
+ // flip exhausted rows whose lock expired (worker crashed on the final
948
+ // attempt) to failed, since no finalizer will ever run for them
949
+ yield* sql`
950
+ UPDATE ${tableNameSql}
951
+ SET state = 'failed', acquired_at = NULL, acquired_by = NULL, updated_at = ${sqlNow},
952
+ last_failure = COALESCE(last_failure, 'Lock expired after final attempt')
953
+ WHERE queue_name = ${name}
954
+ AND state = 'pending'
955
+ AND attempts >= ${maxAttempts}
956
+ AND (acquired_at IS NULL OR acquired_at < ${expiresAt})
957
+ `.pipe(Effect.tapCause(Effect.logWarning), Effect.ignore, Effect.schedule(Schedule.spaced(lockRefreshInterval)), Effect.forkScoped, Effect.interruptible);
597
958
  const poll = sql.onDialectOrElse({
598
959
  pg: () => size => sql`
599
960
  WITH cte AS (
600
961
  UPDATE ${tableNameSql}
601
- SET acquired_at = ${sqlNow}, acquired_by = ${workerIdSql}
962
+ SET acquired_at = ${sqlNow}, acquired_by = ${workerIdSql}, attempts = attempts + 1
602
963
  WHERE sequence IN (
603
964
  SELECT sequence FROM ${tableNameSql}
604
965
  WHERE queue_name = ${name}
605
- AND completed = FALSE
966
+ AND state = 'pending'
606
967
  AND attempts < ${maxAttempts}
968
+ AND visible_at <= ${sqlNow}
607
969
  AND (acquired_at IS NULL OR acquired_at < ${expiresAt})
608
- ORDER BY updated_at ASC, sequence ASC
970
+ ORDER BY visible_at ASC, sequence ASC
609
971
  FOR UPDATE SKIP LOCKED
610
972
  LIMIT ${sql.literal(size.toString())}
611
973
  )
612
- RETURNING sequence, id, queue_name, element, attempts, updated_at
974
+ RETURNING sequence, id, element, attempts, visible_at
613
975
  )
614
- SELECT sequence, id, queue_name, element, attempts FROM cte
615
- ORDER BY updated_at ASC, sequence ASC
976
+ SELECT sequence, id, element, attempts FROM cte
977
+ ORDER BY visible_at ASC, sequence ASC
616
978
  `,
617
979
  mysql: () => size => sql`
618
- SELECT sequence, id, queue_name, element, attempts FROM ${tableNameSql} q
980
+ SELECT sequence, id, element, attempts FROM ${tableNameSql} q
619
981
  WHERE queue_name = ${name}
620
- AND completed = FALSE
982
+ AND state = 'pending'
621
983
  AND attempts < ${maxAttempts}
984
+ AND visible_at <= ${sqlNow}
622
985
  AND (acquired_at IS NULL OR acquired_at < ${expiresAt})
623
- ORDER BY updated_at ASC, sequence ASC
986
+ ORDER BY visible_at ASC, sequence ASC
624
987
  LIMIT ${sql.literal(size.toString())}
625
988
  FOR UPDATE SKIP LOCKED
626
989
  `.pipe(Effect.tap(rows => {
627
990
  if (rows.length === 0) return Effect.void;
628
991
  return sql`
629
992
  UPDATE ${tableNameSql}
630
- SET acquired_at = ${sqlNow}, acquired_by = ${workerIdSql}
993
+ SET acquired_at = ${sqlNow}, acquired_by = ${workerIdSql}, attempts = attempts + 1
631
994
  WHERE sequence IN (${sql.literal(rows.map(r => r.sequence).join(","))})
632
995
  `.unprepared;
996
+ }), Effect.map(rows => {
997
+ for (const row of rows) {
998
+ row.attempts = Number(row.attempts) + 1;
999
+ }
1000
+ return rows;
633
1001
  }), sql.withTransaction),
634
1002
  mssql: () => size => sql`
635
1003
  WITH cte AS (
636
1004
  SELECT TOP ${sql.literal(size.toString())} sequence FROM ${tableNameSql}
637
1005
  WHERE queue_name = ${name}
638
- AND completed = 0
1006
+ AND state = 'pending'
639
1007
  AND attempts < ${maxAttempts}
1008
+ AND visible_at <= ${sqlNow}
640
1009
  AND (acquired_at IS NULL OR acquired_at < ${expiresAt})
641
- ORDER BY updated_at ASC, sequence ASC
1010
+ ORDER BY visible_at ASC, sequence ASC
642
1011
  )
643
1012
  UPDATE q
644
- SET acquired_at = ${sqlNow}, acquired_by = ${workerIdSql}
645
- OUTPUT inserted.sequence, inserted.id, inserted.queue_name, inserted.element, inserted.attempts
1013
+ SET acquired_at = ${sqlNow}, acquired_by = ${workerIdSql}, attempts = q.attempts + 1
1014
+ OUTPUT inserted.sequence, inserted.id, inserted.element, inserted.attempts
646
1015
  FROM ${tableNameSql} AS q
647
1016
  INNER JOIN cte ON q.sequence = cte.sequence
648
1017
  `,
649
1018
  // sqlite
650
1019
  orElse: () => size => sql`
651
1020
  UPDATE ${tableNameSql}
652
- SET acquired_at = ${sqlNow}, acquired_by = ${workerIdSql}
1021
+ SET acquired_at = ${sqlNow}, acquired_by = ${workerIdSql}, attempts = attempts + 1
653
1022
  WHERE sequence IN (
654
1023
  SELECT sequence FROM ${tableNameSql}
655
1024
  WHERE queue_name = ${name}
656
- AND completed = FALSE
1025
+ AND state = 'pending'
657
1026
  AND attempts < ${maxAttempts}
1027
+ AND visible_at <= ${sqlNow}
658
1028
  AND (acquired_at IS NULL OR acquired_at < ${expiresAt})
659
- ORDER BY updated_at ASC, sequence ASC
1029
+ ORDER BY visible_at ASC, sequence ASC
660
1030
  LIMIT ${sql.literal(size.toString())}
661
1031
  )
662
- RETURNING sequence, id, queue_name, element, attempts
1032
+ RETURNING sequence, id, element, attempts
663
1033
  `
664
1034
  });
665
1035
  yield* Effect.gen(function* () {
666
1036
  while (true) {
667
1037
  yield* pollLatch.await;
668
1038
  yield* Effect.yieldNow;
1039
+ nudge.closeUnsafe();
669
1040
  const results = takers.current === 0 ? [] : yield* poll(takers.current);
670
1041
  if (results.length === 0) {
671
- yield* Effect.sleep(pollInterval);
1042
+ yield* Effect.race(Effect.sleep(pollInterval), nudge.await);
672
1043
  continue;
673
1044
  }
674
1045
  takenLatch.closeUnsafe();
675
- for (let i = 0; i < results.length; i++) {
676
- const element = results[i];
677
- elementIds.add(element.sequence);
1046
+ for (const row of results) {
1047
+ row.attempts = Number(row.attempts);
1048
+ elementIds.add(row.sequence);
678
1049
  }
679
1050
  yield* Queue.offerAll(queue, results);
680
1051
  yield* takenLatch.await;
@@ -690,6 +1061,50 @@ export const makeStoreSql = /*#__PURE__*/Effect.fnUntraced(function* (options) {
690
1061
  }),
691
1062
  idleTimeToLive: Duration.seconds(30)
692
1063
  });
1064
+ const cleanupBatch = sql.onDialectOrElse({
1065
+ pg: () => (state, seconds) => sql`
1066
+ WITH deleted_entries AS (
1067
+ DELETE FROM ${tableNameSql}
1068
+ WHERE sequence IN (
1069
+ SELECT sequence FROM ${tableNameSql}
1070
+ WHERE state = ${state} AND updated_at <= ${secondsAgo(seconds)}
1071
+ LIMIT ${sql.literal(String(sqlCleanupBatchSize))}
1072
+ )
1073
+ RETURNING 1
1074
+ )
1075
+ SELECT COUNT(*)::INT AS count FROM deleted_entries
1076
+ `.pipe(Effect.map(rows => rows[0].count)),
1077
+ mysql: () => Effect.fnUntraced(function* (state, seconds) {
1078
+ const connection = yield* sql.reserve;
1079
+ const [statement, parameters] = sql`
1080
+ DELETE FROM ${tableNameSql}
1081
+ WHERE state = ${state} AND updated_at <= ${secondsAgo(seconds)}
1082
+ LIMIT ${sql.literal(String(sqlCleanupBatchSize))}
1083
+ `.compile();
1084
+ yield* connection.execute(statement, parameters, undefined);
1085
+ const rows = yield* connection.executeValues("SELECT ROW_COUNT()", []);
1086
+ return Number(rows[0][0]);
1087
+ }, Effect.scoped),
1088
+ mssql: () => (state, seconds) => sql`
1089
+ DELETE TOP (${sql.literal(String(sqlCleanupBatchSize))}) FROM ${tableNameSql}
1090
+ OUTPUT DELETED.sequence
1091
+ WHERE state = ${state} AND updated_at <= ${secondsAgo(seconds)}
1092
+ `.pipe(Effect.map(rows => rows.length)),
1093
+ // sqlite
1094
+ orElse: () => (state, seconds) => sql`
1095
+ DELETE FROM ${tableNameSql}
1096
+ WHERE sequence IN (
1097
+ SELECT sequence FROM ${tableNameSql}
1098
+ WHERE state = ${state} AND updated_at <= ${secondsAgo(seconds)}
1099
+ LIMIT ${sql.literal(String(sqlCleanupBatchSize))}
1100
+ )
1101
+ RETURNING 1 AS deleted
1102
+ `.pipe(Effect.map(rows => rows.length))
1103
+ });
1104
+ const cleanupState = (state, timeToLive) => cleanupBatch(state, Duration.toSeconds(timeToLive)).pipe(Effect.repeat({
1105
+ while: deletedCount => deletedCount === sqlCleanupBatchSize,
1106
+ schedule: Schedule.spaced(Duration.millis(10))
1107
+ }));
693
1108
  return PersistedQueueStore.of({
694
1109
  offer: ({
695
1110
  element,
@@ -698,38 +1113,76 @@ export const makeStoreSql = /*#__PURE__*/Effect.fnUntraced(function* (options) {
698
1113
  }) => Effect.catchCause(Effect.suspend(() => offer(id, name, JSON.stringify(element))), cause => Effect.fail(new PersistedQueueError({
699
1114
  message: "Failed to offer element to persisted queue",
700
1115
  cause
1116
+ }))).pipe(Effect.tap(() => Effect.sync(() => {
1117
+ queueStates.peek(name)?.nudge.openUnsafe();
701
1118
  }))),
702
- take: ({
703
- maxAttempts,
704
- name
705
- }) => Effect.uninterruptibleMask(restore => RcMap.get(mailboxes, new QueueKey({
706
- name,
707
- maxAttempts
708
- })).pipe(Effect.flatMap(({
709
- pollLatch,
710
- queue,
711
- takenLatch,
712
- takers
713
- }) => {
714
- takers.current++;
715
- if (takers.current === 1) {
716
- pollLatch.openUnsafe();
717
- }
718
- return Effect.tap(restore(Queue.take(queue)), () => Effect.sync(() => {
719
- takers.current--;
720
- if (takers.current === 0) {
721
- pollLatch.closeUnsafe();
722
- takenLatch.openUnsafe();
723
- } else if (Queue.sizeUnsafe(queue) === 0) {
724
- takenLatch.openUnsafe();
1119
+ take: options => {
1120
+ queueStates.get(options.name).maxAttempts = options.maxAttempts;
1121
+ const loop = Effect.uninterruptibleMask(restore => RcMap.get(mailboxes, options.name).pipe(Effect.flatMap(({
1122
+ pollLatch,
1123
+ queue,
1124
+ takenLatch,
1125
+ takers
1126
+ }) => {
1127
+ takers.current++;
1128
+ if (takers.current === 1) {
1129
+ pollLatch.openUnsafe();
725
1130
  }
726
- }));
727
- }), Effect.scoped, restore, Effect.tap(element => Effect.addFinalizer(Exit.match({
728
- onFailure: cause => Cause.hasInterruptsOnly(cause) ? interrupt([element.sequence]) : retry(element.sequence, element.attempts + 1, cause),
729
- onSuccess: () => complete(element.sequence, element.attempts + 1)
730
- }))), Effect.map(element => ({
731
- ...element,
732
- element: JSON.parse(element.element)
1131
+ // onExit so the decrement also runs when a waiting take is
1132
+ // interrupted, otherwise the poller keeps fetching for a phantom
1133
+ // taker
1134
+ return Effect.onExit(restore(Queue.take(queue)), () => Effect.sync(() => {
1135
+ takers.current--;
1136
+ if (takers.current === 0) {
1137
+ pollLatch.closeUnsafe();
1138
+ takenLatch.openUnsafe();
1139
+ } else if (Queue.sizeUnsafe(queue) === 0) {
1140
+ takenLatch.openUnsafe();
1141
+ }
1142
+ }));
1143
+ }), Effect.scoped, restore, Effect.flatMap(element => {
1144
+ let parsed;
1145
+ try {
1146
+ parsed = JSON.parse(element.element);
1147
+ } catch (defect) {
1148
+ // a row that cannot be parsed will never succeed, so dead-letter
1149
+ // it and take the next element
1150
+ return Effect.andThen(fail(element.sequence, Cause.die(defect)), loop);
1151
+ }
1152
+ return Effect.as(Effect.addFinalizer(exit => {
1153
+ if (exit._tag === "Success") {
1154
+ return complete(element.sequence);
1155
+ }
1156
+ const dead = deadLetterFromCause(exit.cause);
1157
+ if (dead !== undefined) {
1158
+ return fail(element.sequence, dead.cause);
1159
+ }
1160
+ if (Cause.hasInterruptsOnly(exit.cause)) {
1161
+ return interrupt([element.sequence]);
1162
+ }
1163
+ if (element.attempts >= options.maxAttempts) {
1164
+ return fail(element.sequence, exit.cause);
1165
+ }
1166
+ return Effect.flatMap(options.retryDelay(element.attempts), delay => retry(element.sequence, delay, exit.cause));
1167
+ }), {
1168
+ id: element.id,
1169
+ attempts: element.attempts,
1170
+ element: parsed
1171
+ });
1172
+ })));
1173
+ return loop;
1174
+ },
1175
+ cleanup: ({
1176
+ failedTimeToLive,
1177
+ timeToLive
1178
+ }) => Effect.gen(function* () {
1179
+ yield* cleanupState("completed", timeToLive);
1180
+ if (failedTimeToLive !== undefined) {
1181
+ yield* cleanupState("failed", failedTimeToLive);
1182
+ }
1183
+ }).pipe(Effect.catchCause(cause => Effect.fail(new PersistedQueueError({
1184
+ message: "Failed to clean up persisted queue",
1185
+ cause
733
1186
  }))))
734
1187
  });
735
1188
  });
@@ -764,7 +1217,7 @@ const sqlMigrations = tableName => Migrator.fromRecord({
764
1217
  created_at TIMESTAMP NOT NULL,
765
1218
  updated_at TIMESTAMP NOT NULL
766
1219
  )`,
767
- mssql: () => sql`IF NOT EXISTS (SELECT * FROM sysobjects WHERE name=${tableNameSql} AND xtype='U')
1220
+ mssql: () => sql`IF NOT EXISTS (SELECT * FROM sysobjects WHERE name=${tableName} AND xtype='U')
768
1221
  CREATE TABLE ${tableNameSql} (
769
1222
  sequence INT IDENTITY(1,1) PRIMARY KEY,
770
1223
  id NVARCHAR(36) NOT NULL,
@@ -795,13 +1248,13 @@ const sqlMigrations = tableName => Migrator.fromRecord({
795
1248
  });
796
1249
  yield* sql.onDialectOrElse({
797
1250
  mssql: () => sql`IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = N'idx_${tableName}_id')
798
- CREATE UNIQUE INDEX idx_${tableNameSql}_id ON ${tableNameSql} (id, queue_name)`,
1251
+ CREATE UNIQUE INDEX ${sql(`idx_${tableName}_id`)} ON ${tableNameSql} (id, queue_name)`,
799
1252
  mysql: () => sql`CREATE UNIQUE INDEX ${sql(`idx_${tableName}_id`)} ON ${tableNameSql} (id, queue_name)`.pipe(Effect.ignore),
800
1253
  orElse: () => sql`CREATE UNIQUE INDEX IF NOT EXISTS ${sql(`idx_${tableName}_id`)} ON ${tableNameSql} (id, queue_name)`
801
1254
  });
802
1255
  yield* sql.onDialectOrElse({
803
1256
  mssql: () => sql`IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = N'idx_${tableName}_take')
804
- CREATE INDEX idx_${tableNameSql}_take ON ${tableNameSql} (queue_name, completed, attempts, acquired_at)`,
1257
+ CREATE INDEX ${sql(`idx_${tableName}_take`)} ON ${tableNameSql} (queue_name, completed, attempts, acquired_at)`,
805
1258
  mysql: () => sql`CREATE INDEX ${sql(`idx_${tableName}_take`)} ON ${tableNameSql} (queue_name, completed, attempts, acquired_at)`.pipe(Effect.ignore),
806
1259
  orElse: () => sql`CREATE INDEX IF NOT EXISTS ${sql(`idx_${tableName}_take`)} ON ${tableNameSql} (queue_name, completed, attempts, acquired_at)`
807
1260
  });
@@ -811,9 +1264,121 @@ const sqlMigrations = tableName => Migrator.fromRecord({
811
1264
  mysql: () => sql`CREATE INDEX ${sql(`idx_${tableName}_update`)} ON ${tableNameSql} (sequence, acquired_by)`.pipe(Effect.ignore),
812
1265
  orElse: () => sql`CREATE INDEX IF NOT EXISTS ${sql(`idx_${tableName}_update`)} ON ${tableNameSql} (sequence, acquired_by)`
813
1266
  });
1267
+ }),
1268
+ "0002_upgrade_schema": Effect.gen(function* () {
1269
+ const sql = (yield* SqlClient.SqlClient).withoutTransforms();
1270
+ const tableNameSql = sql(tableName);
1271
+ const takeIndex = sql(`idx_${tableName}_take`);
1272
+ yield* sql.onDialectOrElse({
1273
+ pg: () => Effect.gen(function* () {
1274
+ yield* sql`DROP INDEX IF EXISTS ${takeIndex}`;
1275
+ yield* sql`ALTER TABLE ${tableNameSql}
1276
+ ADD COLUMN state VARCHAR(10),
1277
+ ADD COLUMN visible_at TIMESTAMP`;
1278
+ yield* sql`UPDATE ${tableNameSql}
1279
+ SET state = CASE WHEN completed THEN 'completed' ELSE 'pending' END,
1280
+ visible_at = updated_at`;
1281
+ yield* sql`ALTER TABLE ${tableNameSql}
1282
+ ALTER COLUMN sequence TYPE BIGINT,
1283
+ ALTER COLUMN id TYPE VARCHAR(255),
1284
+ ALTER COLUMN queue_name TYPE VARCHAR(255),
1285
+ ALTER COLUMN state SET NOT NULL,
1286
+ ALTER COLUMN visible_at SET NOT NULL,
1287
+ DROP COLUMN completed`;
1288
+ }),
1289
+ mysql: () => Effect.gen(function* () {
1290
+ yield* sql`DROP INDEX ${takeIndex} ON ${tableNameSql}`;
1291
+ yield* sql`ALTER TABLE ${tableNameSql}
1292
+ MODIFY COLUMN id VARCHAR(255) NOT NULL,
1293
+ MODIFY COLUMN queue_name VARCHAR(255) NOT NULL,
1294
+ MODIFY COLUMN element MEDIUMTEXT NOT NULL,
1295
+ MODIFY COLUMN last_failure MEDIUMTEXT NULL,
1296
+ ADD COLUMN state VARCHAR(10) NULL,
1297
+ ADD COLUMN visible_at DATETIME NULL`;
1298
+ yield* sql`UPDATE ${tableNameSql}
1299
+ SET state = CASE WHEN completed THEN 'completed' ELSE 'pending' END,
1300
+ visible_at = updated_at`;
1301
+ yield* sql`ALTER TABLE ${tableNameSql}
1302
+ MODIFY COLUMN state VARCHAR(10) NOT NULL,
1303
+ MODIFY COLUMN visible_at DATETIME NOT NULL,
1304
+ DROP COLUMN completed`;
1305
+ }),
1306
+ mssql: () => Effect.gen(function* () {
1307
+ const upgradedTableName = `${tableName}_upgrade`;
1308
+ const upgradedTable = sql(upgradedTableName);
1309
+ yield* sql`CREATE TABLE ${upgradedTable} (
1310
+ sequence BIGINT IDENTITY(1,1) PRIMARY KEY,
1311
+ id NVARCHAR(255) NOT NULL,
1312
+ queue_name NVARCHAR(255) NOT NULL,
1313
+ element NVARCHAR(MAX) NOT NULL,
1314
+ state NVARCHAR(10) NOT NULL,
1315
+ attempts INT NOT NULL DEFAULT 0,
1316
+ last_failure NVARCHAR(MAX) NULL,
1317
+ visible_at DATETIME2 NOT NULL,
1318
+ acquired_at DATETIME2 NULL,
1319
+ acquired_by UNIQUEIDENTIFIER NULL,
1320
+ created_at DATETIME2 NOT NULL,
1321
+ updated_at DATETIME2 NOT NULL
1322
+ )`;
1323
+ yield* sql`SET IDENTITY_INSERT ${upgradedTable} ON;
1324
+ INSERT INTO ${upgradedTable}
1325
+ (sequence, id, queue_name, element, state, attempts, last_failure, visible_at,
1326
+ acquired_at, acquired_by, created_at, updated_at)
1327
+ SELECT sequence, id, queue_name, element,
1328
+ CASE WHEN completed = 1 THEN 'completed' ELSE 'pending' END,
1329
+ attempts, last_failure, updated_at, acquired_at, acquired_by, created_at, updated_at
1330
+ FROM ${tableNameSql};
1331
+ SET IDENTITY_INSERT ${upgradedTable} OFF`;
1332
+ yield* sql`DROP TABLE ${tableNameSql}`;
1333
+ yield* sql`EXEC sp_rename ${upgradedTableName}, ${tableName}`;
1334
+ yield* sql`CREATE UNIQUE INDEX ${sql(`idx_${tableName}_id`)} ON ${tableNameSql} (id, queue_name)`;
1335
+ yield* sql`CREATE INDEX ${sql(`idx_${tableName}_update`)} ON ${tableNameSql} (sequence, acquired_by)`;
1336
+ }),
1337
+ // sqlite rebuilds the table because altering or dropping constrained
1338
+ // columns is not portable across supported SQLite versions.
1339
+ orElse: () => Effect.gen(function* () {
1340
+ const upgradedTableName = `${tableName}_upgrade`;
1341
+ const upgradedTable = sql(upgradedTableName);
1342
+ yield* sql`DROP INDEX IF EXISTS ${takeIndex}`;
1343
+ yield* sql`CREATE TABLE ${upgradedTable} (
1344
+ sequence INTEGER PRIMARY KEY AUTOINCREMENT,
1345
+ id TEXT NOT NULL,
1346
+ queue_name TEXT NOT NULL,
1347
+ element TEXT NOT NULL,
1348
+ state TEXT NOT NULL,
1349
+ attempts INTEGER NOT NULL DEFAULT 0,
1350
+ last_failure TEXT NULL,
1351
+ visible_at DATETIME NOT NULL,
1352
+ acquired_at DATETIME NULL,
1353
+ acquired_by TEXT NULL,
1354
+ created_at DATETIME NOT NULL,
1355
+ updated_at DATETIME NOT NULL
1356
+ )`;
1357
+ yield* sql`INSERT INTO ${upgradedTable}
1358
+ (sequence, id, queue_name, element, state, attempts, last_failure, visible_at,
1359
+ acquired_at, acquired_by, created_at, updated_at)
1360
+ SELECT sequence, id, queue_name, element,
1361
+ CASE WHEN completed THEN 'completed' ELSE 'pending' END,
1362
+ attempts, last_failure, updated_at, acquired_at, acquired_by, created_at, updated_at
1363
+ FROM ${tableNameSql}`;
1364
+ yield* sql`DROP TABLE ${tableNameSql}`;
1365
+ yield* sql`ALTER TABLE ${upgradedTable} RENAME TO ${tableNameSql}`;
1366
+ yield* sql`CREATE UNIQUE INDEX ${sql(`idx_${tableName}_id`)} ON ${tableNameSql} (id, queue_name)`;
1367
+ yield* sql`CREATE INDEX ${sql(`idx_${tableName}_update`)} ON ${tableNameSql} (sequence, acquired_by)`;
1368
+ })
1369
+ });
1370
+ // partial index where supported, so pollers never scan completed rows
1371
+ yield* sql.onDialectOrElse({
1372
+ mssql: () => sql`CREATE INDEX ${takeIndex} ON ${tableNameSql} (queue_name, visible_at)
1373
+ WHERE state = 'pending'`,
1374
+ mysql: () => sql`CREATE INDEX ${takeIndex} ON ${tableNameSql} (queue_name, state, visible_at)`,
1375
+ pg: () => sql`CREATE INDEX ${takeIndex} ON ${tableNameSql} (queue_name, visible_at)
1376
+ WHERE state = 'pending'`,
1377
+ orElse: () => sql`CREATE INDEX ${takeIndex} ON ${tableNameSql} (queue_name, visible_at)
1378
+ WHERE state = 'pending'`
1379
+ });
814
1380
  })
815
1381
  });
816
- class QueueKey extends Data.Class {}
817
1382
  /**
818
1383
  * Provides a SQL-backed `PersistedQueueStore` using `makeStoreSql`.
819
1384
  *