effect 4.0.0-beta.94 → 4.0.0-beta.97

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 (410) hide show
  1. package/dist/Array.d.ts.map +1 -1
  2. package/dist/BigDecimal.d.ts.map +1 -1
  3. package/dist/BigDecimal.js.map +1 -1
  4. package/dist/BigInt.d.ts.map +1 -1
  5. package/dist/Boolean.d.ts.map +1 -1
  6. package/dist/Brand.d.ts.map +1 -1
  7. package/dist/Cache.d.ts.map +1 -1
  8. package/dist/Cause.d.ts.map +1 -1
  9. package/dist/Channel.d.ts.map +1 -1
  10. package/dist/ChannelSchema.d.ts.map +1 -1
  11. package/dist/Chunk.d.ts.map +1 -1
  12. package/dist/Combiner.d.ts.map +1 -1
  13. package/dist/Config.d.ts.map +1 -1
  14. package/dist/Config.js.map +1 -1
  15. package/dist/ConfigProvider.d.ts +44 -6
  16. package/dist/ConfigProvider.d.ts.map +1 -1
  17. package/dist/ConfigProvider.js +63 -24
  18. package/dist/ConfigProvider.js.map +1 -1
  19. package/dist/Console.d.ts.map +1 -1
  20. package/dist/Context.d.ts.map +1 -1
  21. package/dist/Cron.d.ts +4 -1
  22. package/dist/Cron.d.ts.map +1 -1
  23. package/dist/Cron.js +98 -53
  24. package/dist/Cron.js.map +1 -1
  25. package/dist/Crypto.d.ts.map +1 -1
  26. package/dist/Data.d.ts.map +1 -1
  27. package/dist/DateTime.d.ts +12 -12
  28. package/dist/DateTime.d.ts.map +1 -1
  29. package/dist/Deferred.d.ts.map +1 -1
  30. package/dist/Duration.d.ts.map +1 -1
  31. package/dist/Effect.d.ts.map +1 -1
  32. package/dist/Effectable.d.ts.map +1 -1
  33. package/dist/Encoding.d.ts.map +1 -1
  34. package/dist/Equal.d.ts.map +1 -1
  35. package/dist/Equivalence.d.ts.map +1 -1
  36. package/dist/ErrorReporter.d.ts.map +1 -1
  37. package/dist/ExecutionPlan.d.ts +2 -2
  38. package/dist/ExecutionPlan.d.ts.map +1 -1
  39. package/dist/Fiber.d.ts.map +1 -1
  40. package/dist/FiberHandle.d.ts +8 -8
  41. package/dist/FiberHandle.d.ts.map +1 -1
  42. package/dist/FiberMap.d.ts +8 -8
  43. package/dist/FiberMap.d.ts.map +1 -1
  44. package/dist/FiberSet.d.ts +4 -4
  45. package/dist/FiberSet.d.ts.map +1 -1
  46. package/dist/FileSystem.d.ts.map +1 -1
  47. package/dist/Filter.d.ts.map +1 -1
  48. package/dist/Function.d.ts.map +1 -1
  49. package/dist/Graph.d.ts.map +1 -1
  50. package/dist/Graph.js.map +1 -1
  51. package/dist/Hash.d.ts.map +1 -1
  52. package/dist/HashMap.d.ts.map +1 -1
  53. package/dist/HashRing.d.ts.map +1 -1
  54. package/dist/Inspectable.d.ts.map +1 -1
  55. package/dist/Inspectable.js.map +1 -1
  56. package/dist/Iterable.d.ts.map +1 -1
  57. package/dist/Latch.d.ts.map +1 -1
  58. package/dist/Layer.d.ts.map +1 -1
  59. package/dist/LayerMap.d.ts.map +1 -1
  60. package/dist/LayerRef.d.ts +1 -1
  61. package/dist/LayerRef.d.ts.map +1 -1
  62. package/dist/LogLevel.d.ts.map +1 -1
  63. package/dist/Logger.d.ts.map +1 -1
  64. package/dist/ManagedRuntime.d.ts.map +1 -1
  65. package/dist/Metric.d.ts.map +1 -1
  66. package/dist/MutableHashMap.d.ts.map +1 -1
  67. package/dist/MutableHashSet.d.ts.map +1 -1
  68. package/dist/MutableList.d.ts.map +1 -1
  69. package/dist/MutableRef.d.ts.map +1 -1
  70. package/dist/NonEmptyIterable.d.ts.map +1 -1
  71. package/dist/Number.d.ts.map +1 -1
  72. package/dist/Optic.d.ts.map +1 -1
  73. package/dist/Option.d.ts.map +1 -1
  74. package/dist/Order.d.ts.map +1 -1
  75. package/dist/Ordering.d.ts.map +1 -1
  76. package/dist/PartitionedSemaphore.d.ts.map +1 -1
  77. package/dist/Pipeable.d.ts.map +1 -1
  78. package/dist/PlatformError.d.ts.map +1 -1
  79. package/dist/Pool.d.ts.map +1 -1
  80. package/dist/PrimaryKey.d.ts.map +1 -1
  81. package/dist/PubSub.d.ts.map +1 -1
  82. package/dist/Pull.d.ts.map +1 -1
  83. package/dist/Queue.d.ts.map +1 -1
  84. package/dist/Random.d.ts.map +1 -1
  85. package/dist/RcMap.d.ts.map +1 -1
  86. package/dist/Record.d.ts.map +1 -1
  87. package/dist/Redactable.d.ts.map +1 -1
  88. package/dist/Redacted.d.ts.map +1 -1
  89. package/dist/Ref.d.ts.map +1 -1
  90. package/dist/RegExp.d.ts.map +1 -1
  91. package/dist/Request.d.ts +1 -1
  92. package/dist/Request.d.ts.map +1 -1
  93. package/dist/RequestResolver.d.ts.map +1 -1
  94. package/dist/Resource.d.ts.map +1 -1
  95. package/dist/Result.d.ts.map +1 -1
  96. package/dist/Runtime.d.ts.map +1 -1
  97. package/dist/Schedule.d.ts +1206 -4013
  98. package/dist/Schedule.d.ts.map +1 -1
  99. package/dist/Schedule.js +244 -1348
  100. package/dist/Schedule.js.map +1 -1
  101. package/dist/Scheduler.d.ts.map +1 -1
  102. package/dist/Scheduler.js.map +1 -1
  103. package/dist/Schema.d.ts +49 -0
  104. package/dist/Schema.d.ts.map +1 -1
  105. package/dist/Schema.js +40 -0
  106. package/dist/Schema.js.map +1 -1
  107. package/dist/SchemaAST.d.ts.map +1 -1
  108. package/dist/SchemaAST.js.map +1 -1
  109. package/dist/SchemaGetter.d.ts.map +1 -1
  110. package/dist/SchemaIssue.d.ts.map +1 -1
  111. package/dist/SchemaIssue.js.map +1 -1
  112. package/dist/SchemaParser.d.ts.map +1 -1
  113. package/dist/SchemaRepresentation.d.ts +106 -106
  114. package/dist/SchemaTransformation.d.ts +38 -2
  115. package/dist/SchemaTransformation.d.ts.map +1 -1
  116. package/dist/SchemaTransformation.js +38 -2
  117. package/dist/SchemaTransformation.js.map +1 -1
  118. package/dist/ScopedCache.d.ts.map +1 -1
  119. package/dist/ScopedRef.d.ts.map +1 -1
  120. package/dist/Semaphore.d.ts.map +1 -1
  121. package/dist/Sink.d.ts.map +1 -1
  122. package/dist/Stdio.d.ts.map +1 -1
  123. package/dist/Stream.d.ts +2 -2
  124. package/dist/Stream.d.ts.map +1 -1
  125. package/dist/Stream.js +1 -1
  126. package/dist/String.d.ts.map +1 -1
  127. package/dist/String.js.map +1 -1
  128. package/dist/Struct.d.ts.map +1 -1
  129. package/dist/SubscriptionRef.d.ts.map +1 -1
  130. package/dist/SynchronizedRef.d.ts.map +1 -1
  131. package/dist/Take.d.ts.map +1 -1
  132. package/dist/Terminal.d.ts.map +1 -1
  133. package/dist/Tracer.d.ts.map +1 -1
  134. package/dist/Trie.d.ts.map +1 -1
  135. package/dist/Tuple.d.ts.map +1 -1
  136. package/dist/TxChunk.d.ts.map +1 -1
  137. package/dist/TxDeferred.d.ts.map +1 -1
  138. package/dist/TxHashMap.d.ts.map +1 -1
  139. package/dist/TxHashSet.d.ts.map +1 -1
  140. package/dist/TxPriorityQueue.d.ts.map +1 -1
  141. package/dist/TxPubSub.d.ts.map +1 -1
  142. package/dist/TxQueue.d.ts.map +1 -1
  143. package/dist/TxReentrantLock.d.ts.map +1 -1
  144. package/dist/TxRef.d.ts.map +1 -1
  145. package/dist/TxSemaphore.d.ts.map +1 -1
  146. package/dist/TxSubscriptionRef.d.ts.map +1 -1
  147. package/dist/Types.d.ts +1 -1
  148. package/dist/Types.d.ts.map +1 -1
  149. package/dist/UndefinedOr.d.ts.map +1 -1
  150. package/dist/Utils.d.ts.map +1 -1
  151. package/dist/internal/effect.js.map +1 -1
  152. package/dist/internal/schema/schema.d.ts.map +1 -1
  153. package/dist/testing/TestClock.d.ts.map +1 -1
  154. package/dist/testing/TestConsole.d.ts.map +1 -1
  155. package/dist/testing/TestSchema.d.ts.map +1 -1
  156. package/dist/unstable/ai/AiError.d.ts +1 -1
  157. package/dist/unstable/ai/AiError.d.ts.map +1 -1
  158. package/dist/unstable/ai/Chat.d.ts +1 -1
  159. package/dist/unstable/ai/Chat.d.ts.map +1 -1
  160. package/dist/unstable/ai/IdGenerator.d.ts.map +1 -1
  161. package/dist/unstable/ai/LanguageModel.d.ts.map +1 -1
  162. package/dist/unstable/ai/McpSchema.d.ts +221 -221
  163. package/dist/unstable/ai/McpSchema.d.ts.map +1 -1
  164. package/dist/unstable/ai/McpServer.d.ts.map +1 -1
  165. package/dist/unstable/ai/Model.d.ts.map +1 -1
  166. package/dist/unstable/ai/Prompt.d.ts.map +1 -1
  167. package/dist/unstable/ai/Response.d.ts.map +1 -1
  168. package/dist/unstable/ai/Telemetry.d.ts.map +1 -1
  169. package/dist/unstable/ai/Tokenizer.d.ts.map +1 -1
  170. package/dist/unstable/ai/Tool.d.ts.map +1 -1
  171. package/dist/unstable/ai/Toolkit.d.ts.map +1 -1
  172. package/dist/unstable/cli/Argument.d.ts.map +1 -1
  173. package/dist/unstable/cli/CliError.d.ts.map +1 -1
  174. package/dist/unstable/cli/CliOutput.d.ts.map +1 -1
  175. package/dist/unstable/cli/Command.d.ts.map +1 -1
  176. package/dist/unstable/cli/Completions.d.ts.map +1 -1
  177. package/dist/unstable/cli/Flag.d.ts.map +1 -1
  178. package/dist/unstable/cli/GlobalFlag.d.ts.map +1 -1
  179. package/dist/unstable/cli/Param.d.ts.map +1 -1
  180. package/dist/unstable/cli/Primitive.d.ts.map +1 -1
  181. package/dist/unstable/cli/Prompt.d.ts.map +1 -1
  182. package/dist/unstable/cli/Prompt.js.map +1 -1
  183. package/dist/unstable/cli/internal/ansi.d.ts.map +1 -1
  184. package/dist/unstable/cli/internal/ansi.js.map +1 -1
  185. package/dist/unstable/cli/internal/command.d.ts.map +1 -1
  186. package/dist/unstable/cli/internal/help.d.ts.map +1 -1
  187. package/dist/unstable/cli/internal/parser.js.map +1 -1
  188. package/dist/unstable/cluster/ClusterCron.d.ts.map +1 -1
  189. package/dist/unstable/cluster/ClusterCron.js +1 -1
  190. package/dist/unstable/cluster/ClusterCron.js.map +1 -1
  191. package/dist/unstable/cluster/ClusterError.d.ts.map +1 -1
  192. package/dist/unstable/cluster/ClusterSchema.d.ts +1 -1
  193. package/dist/unstable/cluster/ClusterSchema.d.ts.map +1 -1
  194. package/dist/unstable/cluster/ClusterWorkflowEngine.d.ts +1 -1
  195. package/dist/unstable/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
  196. package/dist/unstable/cluster/ClusterWorkflowEngine.js +1 -1
  197. package/dist/unstable/cluster/ClusterWorkflowEngine.js.map +1 -1
  198. package/dist/unstable/cluster/DeliverAt.d.ts.map +1 -1
  199. package/dist/unstable/cluster/Entity.d.ts.map +1 -1
  200. package/dist/unstable/cluster/EntityAddress.d.ts.map +1 -1
  201. package/dist/unstable/cluster/EntityId.d.ts.map +1 -1
  202. package/dist/unstable/cluster/EntityProxy.d.ts.map +1 -1
  203. package/dist/unstable/cluster/EntityProxyServer.d.ts.map +1 -1
  204. package/dist/unstable/cluster/EntityType.d.ts.map +1 -1
  205. package/dist/unstable/cluster/Envelope.d.ts.map +1 -1
  206. package/dist/unstable/cluster/HttpRunner.d.ts.map +1 -1
  207. package/dist/unstable/cluster/MachineId.d.ts.map +1 -1
  208. package/dist/unstable/cluster/Message.d.ts.map +1 -1
  209. package/dist/unstable/cluster/MessageStorage.d.ts +25 -29
  210. package/dist/unstable/cluster/MessageStorage.d.ts.map +1 -1
  211. package/dist/unstable/cluster/Reply.d.ts.map +1 -1
  212. package/dist/unstable/cluster/Runner.d.ts.map +1 -1
  213. package/dist/unstable/cluster/RunnerAddress.d.ts.map +1 -1
  214. package/dist/unstable/cluster/RunnerHealth.d.ts.map +1 -1
  215. package/dist/unstable/cluster/RunnerServer.d.ts +1 -1
  216. package/dist/unstable/cluster/RunnerStorage.d.ts.map +1 -1
  217. package/dist/unstable/cluster/Runners.d.ts +8 -8
  218. package/dist/unstable/cluster/ShardId.d.ts.map +1 -1
  219. package/dist/unstable/cluster/Sharding.js +3 -4
  220. package/dist/unstable/cluster/Sharding.js.map +1 -1
  221. package/dist/unstable/cluster/ShardingConfig.d.ts.map +1 -1
  222. package/dist/unstable/cluster/ShardingRegistrationEvent.d.ts +6 -8
  223. package/dist/unstable/cluster/ShardingRegistrationEvent.d.ts.map +1 -1
  224. package/dist/unstable/cluster/SingleRunner.d.ts.map +1 -1
  225. package/dist/unstable/cluster/Singleton.d.ts.map +1 -1
  226. package/dist/unstable/cluster/SingletonAddress.d.ts.map +1 -1
  227. package/dist/unstable/cluster/Snowflake.d.ts +1 -1
  228. package/dist/unstable/cluster/Snowflake.d.ts.map +1 -1
  229. package/dist/unstable/cluster/Snowflake.js +1 -1
  230. package/dist/unstable/cluster/Snowflake.js.map +1 -1
  231. package/dist/unstable/cluster/SqlMessageStorage.d.ts.map +1 -1
  232. package/dist/unstable/cluster/SqlRunnerStorage.d.ts +1 -1
  233. package/dist/unstable/cluster/SqlRunnerStorage.d.ts.map +1 -1
  234. package/dist/unstable/cluster/internal/entityManager.js +11 -12
  235. package/dist/unstable/cluster/internal/entityManager.js.map +1 -1
  236. package/dist/unstable/devtools/DevTools.d.ts.map +1 -1
  237. package/dist/unstable/encoding/Msgpack.d.ts.map +1 -1
  238. package/dist/unstable/encoding/Ndjson.d.ts.map +1 -1
  239. package/dist/unstable/encoding/Sse.d.ts.map +1 -1
  240. package/dist/unstable/eventlog/Event.d.ts.map +1 -1
  241. package/dist/unstable/eventlog/EventGroup.d.ts.map +1 -1
  242. package/dist/unstable/eventlog/EventJournal.d.ts.map +1 -1
  243. package/dist/unstable/eventlog/EventJournal.js.map +1 -1
  244. package/dist/unstable/eventlog/EventLog.d.ts.map +1 -1
  245. package/dist/unstable/eventlog/EventLog.js +2 -2
  246. package/dist/unstable/eventlog/EventLog.js.map +1 -1
  247. package/dist/unstable/eventlog/EventLogEncryption.d.ts.map +1 -1
  248. package/dist/unstable/eventlog/EventLogMessage.d.ts.map +1 -1
  249. package/dist/unstable/eventlog/EventLogRemote.d.ts +21 -21
  250. package/dist/unstable/eventlog/EventLogServer.d.ts.map +1 -1
  251. package/dist/unstable/eventlog/EventLogServerEncrypted.d.ts +1 -1
  252. package/dist/unstable/eventlog/EventLogServerUnencrypted.d.ts +3 -4
  253. package/dist/unstable/eventlog/EventLogServerUnencrypted.d.ts.map +1 -1
  254. package/dist/unstable/eventlog/EventLogSessionAuth.d.ts.map +1 -1
  255. package/dist/unstable/eventlog/SqlEventJournal.d.ts.map +1 -1
  256. package/dist/unstable/eventlog/SqlEventLogServerEncrypted.d.ts.map +1 -1
  257. package/dist/unstable/eventlog/SqlEventLogServerUnencrypted.d.ts.map +1 -1
  258. package/dist/unstable/http/Cookies.d.ts +1 -1
  259. package/dist/unstable/http/Cookies.d.ts.map +1 -1
  260. package/dist/unstable/http/Etag.d.ts.map +1 -1
  261. package/dist/unstable/http/Headers.d.ts.map +1 -1
  262. package/dist/unstable/http/HttpBody.d.ts.map +1 -1
  263. package/dist/unstable/http/HttpClient.d.ts.map +1 -1
  264. package/dist/unstable/http/HttpClientError.d.ts +1 -1
  265. package/dist/unstable/http/HttpClientError.d.ts.map +1 -1
  266. package/dist/unstable/http/HttpClientRequest.d.ts.map +1 -1
  267. package/dist/unstable/http/HttpClientResponse.d.ts.map +1 -1
  268. package/dist/unstable/http/HttpEffect.d.ts.map +1 -1
  269. package/dist/unstable/http/HttpIncomingMessage.d.ts.map +1 -1
  270. package/dist/unstable/http/HttpMethod.d.ts.map +1 -1
  271. package/dist/unstable/http/HttpMiddleware.d.ts +1 -1
  272. package/dist/unstable/http/HttpMiddleware.d.ts.map +1 -1
  273. package/dist/unstable/http/HttpRouter.d.ts.map +1 -1
  274. package/dist/unstable/http/HttpServer.d.ts.map +1 -1
  275. package/dist/unstable/http/HttpServerError.d.ts +1 -1
  276. package/dist/unstable/http/HttpServerError.d.ts.map +1 -1
  277. package/dist/unstable/http/HttpServerRequest.d.ts +2 -2
  278. package/dist/unstable/http/HttpServerRequest.d.ts.map +1 -1
  279. package/dist/unstable/http/HttpServerRespondable.d.ts.map +1 -1
  280. package/dist/unstable/http/HttpServerResponse.d.ts.map +1 -1
  281. package/dist/unstable/http/HttpStaticServer.d.ts.map +1 -1
  282. package/dist/unstable/http/HttpTraceContext.d.ts.map +1 -1
  283. package/dist/unstable/http/Multipart.d.ts +2 -1
  284. package/dist/unstable/http/Multipart.d.ts.map +1 -1
  285. package/dist/unstable/http/Url.d.ts.map +1 -1
  286. package/dist/unstable/http/UrlParams.d.ts.map +1 -1
  287. package/dist/unstable/httpapi/HttpApi.d.ts.map +1 -1
  288. package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
  289. package/dist/unstable/httpapi/HttpApiClient.d.ts.map +1 -1
  290. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts +22 -22
  291. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts.map +1 -1
  292. package/dist/unstable/httpapi/HttpApiError.d.ts +1 -1
  293. package/dist/unstable/httpapi/HttpApiError.d.ts.map +1 -1
  294. package/dist/unstable/httpapi/HttpApiGroup.d.ts.map +1 -1
  295. package/dist/unstable/httpapi/HttpApiMiddleware.d.ts.map +1 -1
  296. package/dist/unstable/httpapi/HttpApiScalar.d.ts.map +1 -1
  297. package/dist/unstable/httpapi/HttpApiSchema.d.ts.map +1 -1
  298. package/dist/unstable/httpapi/HttpApiSecurity.d.ts.map +1 -1
  299. package/dist/unstable/httpapi/HttpApiSwagger.d.ts.map +1 -1
  300. package/dist/unstable/httpapi/HttpApiTest.d.ts +1 -1
  301. package/dist/unstable/observability/Otlp.d.ts.map +1 -1
  302. package/dist/unstable/observability/OtlpExporter.js +3 -1
  303. package/dist/unstable/observability/OtlpExporter.js.map +1 -1
  304. package/dist/unstable/observability/OtlpLogger.d.ts.map +1 -1
  305. package/dist/unstable/observability/OtlpMetrics.d.ts.map +1 -1
  306. package/dist/unstable/observability/OtlpResource.d.ts.map +1 -1
  307. package/dist/unstable/observability/OtlpTracer.d.ts.map +1 -1
  308. package/dist/unstable/observability/PrometheusMetrics.d.ts.map +1 -1
  309. package/dist/unstable/observability/internal/otlpEnv.d.ts.map +1 -1
  310. package/dist/unstable/persistence/KeyValueStore.d.ts.map +1 -1
  311. package/dist/unstable/persistence/KeyValueStore.js.map +1 -1
  312. package/dist/unstable/persistence/Persistable.d.ts.map +1 -1
  313. package/dist/unstable/persistence/PersistedQueue.d.ts +1 -1
  314. package/dist/unstable/persistence/PersistedQueue.d.ts.map +1 -1
  315. package/dist/unstable/persistence/Persistence.d.ts.map +1 -1
  316. package/dist/unstable/persistence/RateLimiter.d.ts.map +1 -1
  317. package/dist/unstable/persistence/Redis.d.ts.map +1 -1
  318. package/dist/unstable/process/ChildProcess.d.ts.map +1 -1
  319. package/dist/unstable/process/ChildProcess.js.map +1 -1
  320. package/dist/unstable/process/ChildProcessSpawner.d.ts.map +1 -1
  321. package/dist/unstable/reactivity/AsyncResult.d.ts +2 -2
  322. package/dist/unstable/reactivity/AsyncResult.d.ts.map +1 -1
  323. package/dist/unstable/reactivity/Atom.d.ts.map +1 -1
  324. package/dist/unstable/reactivity/AtomHttpApi.d.ts.map +1 -1
  325. package/dist/unstable/reactivity/AtomRef.d.ts.map +1 -1
  326. package/dist/unstable/reactivity/AtomRegistry.d.ts +2 -2
  327. package/dist/unstable/reactivity/AtomRegistry.d.ts.map +1 -1
  328. package/dist/unstable/reactivity/AtomRegistry.js +28 -37
  329. package/dist/unstable/reactivity/AtomRegistry.js.map +1 -1
  330. package/dist/unstable/reactivity/AtomRpc.d.ts.map +1 -1
  331. package/dist/unstable/reactivity/Hydration.d.ts.map +1 -1
  332. package/dist/unstable/reactivity/Reactivity.d.ts.map +1 -1
  333. package/dist/unstable/rpc/Rpc.d.ts.map +1 -1
  334. package/dist/unstable/rpc/RpcClient.d.ts +2 -1
  335. package/dist/unstable/rpc/RpcClient.d.ts.map +1 -1
  336. package/dist/unstable/rpc/RpcClient.js +5 -5
  337. package/dist/unstable/rpc/RpcClient.js.map +1 -1
  338. package/dist/unstable/rpc/RpcGroup.d.ts.map +1 -1
  339. package/dist/unstable/rpc/RpcMessage.d.ts +7 -7
  340. package/dist/unstable/rpc/RpcMessage.d.ts.map +1 -1
  341. package/dist/unstable/rpc/RpcMessage.js +2 -2
  342. package/dist/unstable/rpc/RpcMessage.js.map +1 -1
  343. package/dist/unstable/rpc/RpcMiddleware.d.ts.map +1 -1
  344. package/dist/unstable/rpc/RpcSchema.d.ts +1 -1
  345. package/dist/unstable/rpc/RpcSerialization.d.ts.map +1 -1
  346. package/dist/unstable/rpc/RpcSerialization.js +8 -8
  347. package/dist/unstable/rpc/RpcSerialization.js.map +1 -1
  348. package/dist/unstable/rpc/RpcServer.d.ts +2 -2
  349. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  350. package/dist/unstable/rpc/RpcServer.js +5 -5
  351. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  352. package/dist/unstable/rpc/RpcWorker.d.ts.map +1 -1
  353. package/dist/unstable/rpc/Utils.d.ts.map +1 -1
  354. package/dist/unstable/schema/Model.d.ts +24 -38
  355. package/dist/unstable/schema/Model.d.ts.map +1 -1
  356. package/dist/unstable/schema/VariantSchema.d.ts +1 -1
  357. package/dist/unstable/schema/VariantSchema.d.ts.map +1 -1
  358. package/dist/unstable/socket/Socket.d.ts +1 -1
  359. package/dist/unstable/socket/Socket.d.ts.map +1 -1
  360. package/dist/unstable/socket/SocketServer.d.ts.map +1 -1
  361. package/dist/unstable/sql/Migrator.d.ts.map +1 -1
  362. package/dist/unstable/sql/SqlClient.d.ts.map +1 -1
  363. package/dist/unstable/sql/SqlError.d.ts +2 -2
  364. package/dist/unstable/sql/SqlError.d.ts.map +1 -1
  365. package/dist/unstable/sql/SqlError.js.map +1 -1
  366. package/dist/unstable/sql/SqlModel.d.ts.map +1 -1
  367. package/dist/unstable/sql/SqlResolver.d.ts.map +1 -1
  368. package/dist/unstable/sql/SqlSchema.d.ts.map +1 -1
  369. package/dist/unstable/sql/SqlStream.d.ts.map +1 -1
  370. package/dist/unstable/sql/Statement.d.ts.map +1 -1
  371. package/dist/unstable/workers/Transferable.d.ts.map +1 -1
  372. package/dist/unstable/workers/Worker.d.ts.map +1 -1
  373. package/dist/unstable/workers/WorkerError.d.ts.map +1 -1
  374. package/dist/unstable/workflow/Activity.d.ts +1 -1
  375. package/dist/unstable/workflow/Activity.d.ts.map +1 -1
  376. package/dist/unstable/workflow/Activity.js +1 -1
  377. package/dist/unstable/workflow/Activity.js.map +1 -1
  378. package/dist/unstable/workflow/DurableClock.d.ts.map +1 -1
  379. package/dist/unstable/workflow/DurableDeferred.d.ts.map +1 -1
  380. package/dist/unstable/workflow/DurableQueue.d.ts.map +1 -1
  381. package/dist/unstable/workflow/DurableQueue.js +1 -1
  382. package/dist/unstable/workflow/DurableQueue.js.map +1 -1
  383. package/dist/unstable/workflow/Workflow.d.ts.map +1 -1
  384. package/dist/unstable/workflow/WorkflowEngine.d.ts.map +1 -1
  385. package/dist/unstable/workflow/WorkflowEngine.js +1 -1
  386. package/dist/unstable/workflow/WorkflowEngine.js.map +1 -1
  387. package/dist/unstable/workflow/WorkflowProxy.d.ts.map +1 -1
  388. package/dist/unstable/workflow/WorkflowProxyServer.d.ts.map +1 -1
  389. package/package.json +11 -12
  390. package/src/ConfigProvider.ts +79 -27
  391. package/src/Cron.ts +109 -57
  392. package/src/Schedule.ts +1437 -4445
  393. package/src/Schema.ts +53 -0
  394. package/src/SchemaTransformation.ts +42 -2
  395. package/src/Stream.ts +1 -1
  396. package/src/unstable/cluster/ClusterCron.ts +4 -3
  397. package/src/unstable/cluster/ClusterWorkflowEngine.ts +4 -3
  398. package/src/unstable/cluster/Sharding.ts +4 -4
  399. package/src/unstable/cluster/Snowflake.ts +2 -2
  400. package/src/unstable/cluster/internal/entityManager.ts +16 -16
  401. package/src/unstable/eventlog/EventLog.ts +4 -3
  402. package/src/unstable/observability/OtlpExporter.ts +1 -1
  403. package/src/unstable/reactivity/AtomRegistry.ts +35 -44
  404. package/src/unstable/rpc/RpcClient.ts +10 -9
  405. package/src/unstable/rpc/RpcMessage.ts +8 -9
  406. package/src/unstable/rpc/RpcSerialization.ts +16 -16
  407. package/src/unstable/rpc/RpcServer.ts +5 -5
  408. package/src/unstable/workflow/Activity.ts +6 -5
  409. package/src/unstable/workflow/DurableQueue.ts +4 -3
  410. package/src/unstable/workflow/WorkflowEngine.ts +4 -3
package/dist/Schedule.js CHANGED
@@ -1,13 +1,3 @@
1
- /**
2
- * Describes policies for retrying, repeating, and pacing Effect programs.
3
- *
4
- * A `Schedule<Output, Input, Error, Env>` is stepped with an input value. Each
5
- * step either stops or produces an output together with the delay before the
6
- * next step. Schedules are used by retry, repeat, stream, and channel APIs to
7
- * decide when work should continue, how long to wait, and when to stop.
8
- *
9
- * @since 2.0.0
10
- */
11
1
  import * as Cause from "./Cause.js";
12
2
  import * as Context from "./Context.js";
13
3
  import * as Cron from "./Cron.js";
@@ -161,7 +151,7 @@ export const fromStepWithMetadata = step => fromStep(effect.map(step, f => {
161
151
  * import { Effect, Schedule } from "effect"
162
152
  *
163
153
  * // Extract step function from an existing schedule
164
- * const schedule = Schedule.exponential("100 millis").pipe(Schedule.take(3))
154
+ * const schedule = Schedule.exponential("100 millis").pipe(Schedule.upTo({ times: 3 }))
165
155
  *
166
156
  * const program = Effect.gen(function*() {
167
157
  * const stepFn = yield* Schedule.toStep(schedule)
@@ -221,7 +211,7 @@ export const toStepWithMetadata = schedule => effect.clockWith(clock => effect.m
221
211
  * import { Effect, Schedule } from "effect"
222
212
  *
223
213
  * // Convert schedule to step function with automatic sleeping
224
- * const schedule = Schedule.spaced("1 second").pipe(Schedule.take(3))
214
+ * const schedule = Schedule.spaced("1 second").pipe(Schedule.upTo({ times: 3 }))
225
215
  *
226
216
  * const program = Effect.gen(function*() {
227
217
  * const stepWithSleep = yield* Schedule.toStepWithSleep(schedule)
@@ -254,10 +244,10 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
254
244
  *
255
245
  * class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
256
246
  *
257
- * // Add a deterministic extra delay based on the schedule output
247
+ * // Add a deterministic extra delay based on the schedule metadata
258
248
  * const delayedSchedule = Schedule.addDelay(
259
- * Schedule.exponential("100 millis").pipe(Schedule.take(5)),
260
- * (output) =>
249
+ * Schedule.exponential("100 millis").pipe(Schedule.upTo({ times: 5 })),
250
+ * ({ output }) =>
261
251
  * Effect.succeed(Duration.millis(Duration.toMillis(output) * 0.25))
262
252
  * )
263
253
  *
@@ -265,7 +255,7 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
265
255
  * yield* Effect.repeat(
266
256
  * Effect.succeed("delayed task"),
267
257
  * delayedSchedule.pipe(
268
- * Schedule.tapOutput((delay) =>
258
+ * Schedule.tap(({ output: delay }) =>
269
259
  * Console.log(`Base delay: ${delay}`)
270
260
  * )
271
261
  * )
@@ -275,7 +265,7 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
275
265
  * // Add adaptive delay based on execution count
276
266
  * const adaptiveSchedule = Schedule.addDelay(
277
267
  * Schedule.recurs(6),
278
- * (executionCount) =>
268
+ * ({ output: executionCount }) =>
279
269
  * // Increase delay as execution count grows
280
270
  * Effect.succeed(Duration.millis(executionCount * 200))
281
271
  * )
@@ -287,7 +277,7 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
287
277
  * return "adaptive"
288
278
  * }),
289
279
  * adaptiveSchedule.pipe(
290
- * Schedule.tapOutput((count) =>
280
+ * Schedule.tap(({ output: count }) =>
291
281
  * Console.log(`Execution ${count + 1} with adaptive delay`)
292
282
  * )
293
283
  * )
@@ -298,8 +288,8 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
298
288
  * const loadByExecution = [1, 3, 2, 4] as const
299
289
  *
300
290
  * const dynamicSchedule = Schedule.addDelay(
301
- * Schedule.spaced("1 second").pipe(Schedule.take(4)),
302
- * (executionNumber) => {
291
+ * Schedule.spaced("1 second").pipe(Schedule.upTo({ times: 4 })),
292
+ * ({ output: executionNumber }) => {
303
293
  * const load = loadByExecution[executionNumber] ?? 1
304
294
  * return Effect.succeed(Duration.millis(load * 100))
305
295
  * }
@@ -317,7 +307,7 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
317
307
  *
318
308
  * // Combine with retry for progressive backoff
319
309
  * const progressiveRetrySchedule = Schedule.addDelay(
320
- * Schedule.exponential("50 millis").pipe(Schedule.take(4)),
310
+ * Schedule.exponential("50 millis").pipe(Schedule.upTo({ times: 4 })),
321
311
  * () => Effect.succeed(Duration.millis(100)) // Fixed additional delay
322
312
  * )
323
313
  *
@@ -342,7 +332,7 @@ export const toStepWithSleep = schedule => effect.map(toStepWithMetadata(schedul
342
332
  * @category delays & timeouts
343
333
  * @since 2.0.0
344
334
  */
345
- export const addDelay = /*#__PURE__*/dual(2, (self, f) => modifyDelay(self, (output, delay) => effect.map(f(output), d => Duration.sum(Duration.fromInputUnsafe(d), Duration.fromInputUnsafe(delay)))));
335
+ export const addDelay = /*#__PURE__*/dual(2, (self, f) => modifyDelay(self, metadata => effect.map(f(metadata), d => Duration.sum(Duration.fromInputUnsafe(d), metadata.duration))));
346
336
  /**
347
337
  * Returns a schedule that runs `self` to completion, then runs `other`, and
348
338
  * merges their outputs.
@@ -356,10 +346,10 @@ export const addDelay = /*#__PURE__*/dual(2, (self, f) => modifyDelay(self, (out
356
346
  *
357
347
  * // First retry 3 times quickly, then switch to slower retries
358
348
  * const quickRetries = Schedule.exponential("100 millis").pipe(
359
- * Schedule.take(3)
349
+ * Schedule.upTo({ times: 3 })
360
350
  * )
361
351
  * const slowRetries = Schedule.exponential("1 second").pipe(
362
- * Schedule.take(2)
352
+ * Schedule.upTo({ times: 2 })
363
353
  * )
364
354
  *
365
355
  * const combinedRetries = Schedule.andThen(quickRetries, slowRetries)
@@ -383,7 +373,9 @@ export const addDelay = /*#__PURE__*/dual(2, (self, f) => modifyDelay(self, (out
383
373
  * @category sequencing
384
374
  * @since 2.0.0
385
375
  */
386
- export const andThen = /*#__PURE__*/dual(2, (self, other) => map(andThenResult(self, other), result => effect.succeed(Result.merge(result))));
376
+ export const andThen = /*#__PURE__*/dual(2, (self, other) => map(andThenResult(self, other), ({
377
+ output
378
+ }) => effect.succeed(Result.merge(output))));
387
379
  /**
388
380
  * Returns a schedule that runs `self` to completion, then runs `other`, and
389
381
  * preserves which schedule produced each output.
@@ -401,8 +393,8 @@ export const andThen = /*#__PURE__*/dual(2, (self, other) => map(andThenResult(s
401
393
  *
402
394
  * // Track which phase of the schedule we're in
403
395
  * const phaseTracker = Schedule.andThenResult(
404
- * Schedule.exponential("100 millis").pipe(Schedule.take(2)),
405
- * Schedule.spaced("500 millis").pipe(Schedule.take(2))
396
+ * Schedule.exponential("100 millis").pipe(Schedule.upTo({ times: 2 })),
397
+ * Schedule.spaced("500 millis").pipe(Schedule.upTo({ times: 2 }))
406
398
  * )
407
399
  *
408
400
  * const program = Effect.gen(function*() {
@@ -412,7 +404,7 @@ export const andThen = /*#__PURE__*/dual(2, (self, other) => map(andThenResult(s
412
404
  * return "task-result"
413
405
  * }),
414
406
  * phaseTracker.pipe(
415
- * Schedule.tapOutput((result) =>
407
+ * Schedule.tap(({ output: result }) =>
416
408
  * Result.match(result, {
417
409
  * onFailure: (phase1Output) => Console.log(`Phase 1: ${phase1Output}`),
418
410
  * onSuccess: (phase2Output) => Console.log(`Phase 2: ${phase2Output}`)
@@ -429,8 +421,12 @@ export const andThen = /*#__PURE__*/dual(2, (self, other) => map(andThenResult(s
429
421
  export const andThenResult = /*#__PURE__*/dual(2, (self, other) => fromStep(effect.sync(() => {
430
422
  let currentSide = 0;
431
423
  let currentStep;
432
- const left = map(self, Result.fail);
433
- const right = map(other, Result.succeed);
424
+ const left = map(self, ({
425
+ output
426
+ }) => Result.fail(output));
427
+ const right = map(other, ({
428
+ output
429
+ }) => Result.succeed(output));
434
430
  return function recur(now, input) {
435
431
  if (currentStep) return currentStep(now, input);
436
432
  return toStep(currentSide === 0 ? left : right).pipe(effect.flatMap(step => {
@@ -448,366 +444,70 @@ export const andThenResult = /*#__PURE__*/dual(2, (self, other) => fromStep(effe
448
444
  };
449
445
  })));
450
446
  /**
451
- * Combines two `Schedule`s by recurring if both of the two schedules want
452
- * to recur, using the maximum of the two durations between recurrences and
453
- * outputting a tuple of the outputs of both schedules.
447
+ * Combines schedules by recurring while all schedules want to recur, using the
448
+ * maximum delay between recurrences and outputting that maximum delay.
454
449
  *
455
450
  * **When to use**
456
451
  *
457
- * Use when the combined schedule should continue only while both schedules still recur.
452
+ * Use when a combined policy should continue only while every schedule still
453
+ * recurs, and should wait for the slowest schedule between recurrences.
458
454
  *
459
- * **Example** (Combining time and attempt limits)
455
+ * **Example** (Combining retry schedules by their maximum delay)
460
456
  *
461
457
  * ```ts
462
458
  * import { Console, Data, Effect, Schedule } from "effect"
463
459
  *
464
460
  * class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
465
461
  *
466
- * // Both schedules must want to continue for the combined schedule to continue
467
- * const timeLimit = Schedule.spaced("1 second").pipe(Schedule.take(5)) // max 5 times
468
- * const attemptLimit = Schedule.recurs(3) // max 3 attempts
469
- *
470
- * // Continues only while BOTH schedules want to continue (intersection/AND logic)
471
- * const bothSchedule = Schedule.both(timeLimit, attemptLimit)
472
- * // Outputs: [time_result, attempt_count] tuple
462
+ * const retrySchedule = Schedule.max([
463
+ * Schedule.fixed("5 seconds"),
464
+ * Schedule.exponential("5 seconds"),
465
+ * Schedule.spaced("10 seconds")
466
+ * ])
473
467
  *
474
468
  * const program = Effect.gen(function*() {
475
- * const results = yield* Effect.repeat(
476
- * Effect.gen(function*() {
477
- * yield* Console.log("Task executed")
478
- * return "task completed"
479
- * }),
480
- * bothSchedule.pipe(
481
- * Schedule.tapOutput(([timeResult, attemptResult]) =>
482
- * Console.log(`Time: ${timeResult}, Attempts: ${attemptResult}`)
483
- * )
484
- * )
485
- * )
486
- *
487
- * yield* Console.log("Completed all executions")
488
- * })
489
- *
490
- * // Both with different delay strategies - uses maximum delay
491
- * const fastSchedule = Schedule.fixed("500 millis").pipe(Schedule.take(4))
492
- * const slowSchedule = Schedule.spaced("2 seconds").pipe(Schedule.take(6))
493
- *
494
- * // Will use the slower (maximum) delay and stop when first schedule exhausts
495
- * const conservativeSchedule = Schedule.both(fastSchedule, slowSchedule)
496
- *
497
- * const retryProgram = Effect.gen(function*() {
498
469
  * let attempt = 0
499
470
  *
500
- * const result = yield* Effect.retry(
471
+ * yield* Effect.retry(
501
472
  * Effect.gen(function*() {
502
473
  * attempt++
503
474
  * yield* Console.log(`Retry attempt ${attempt}`)
504
- *
505
475
  * if (attempt < 3) {
506
476
  * return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
507
477
  * }
508
- *
509
- * return `Success on attempt ${attempt}`
510
- * }),
511
- * conservativeSchedule
512
- * )
513
- *
514
- * yield* Console.log(`Final result: ${result}`)
515
- * })
516
- *
517
- * // Both provides intersection semantics (AND logic)
518
- * // Compare with either which provides union semantics (OR logic)
519
- * ```
520
- *
521
- * @see {@link either} for continuing while either schedule still recurs
522
- *
523
- * @category combining
524
- * @since 2.0.0
525
- */
526
- export const both = /*#__PURE__*/dual(2, (self, other) => bothWith(self, other, (left, right) => [left, right]));
527
- /**
528
- * Combines two `Schedule`s by recurring if both of the two schedules want
529
- * to recur, using the maximum of the two durations between recurrences and
530
- * outputting the result of the left schedule (i.e. `self`).
531
- *
532
- * **When to use**
533
- *
534
- * Use when two schedules must both allow recurrence and only the left schedule's
535
- * output is needed.
536
- *
537
- * **Example** (Combining schedules and keeping the left output)
538
- *
539
- * ```ts
540
- * import { Console, Effect, Schedule } from "effect"
541
- *
542
- * // Combine two schedules, keeping left output
543
- * const leftSchedule = Schedule.exponential("100 millis").pipe(
544
- * Schedule.map(() => Effect.succeed("left-result"))
545
- * )
546
- * const rightSchedule = Schedule.spaced("50 millis")
547
- *
548
- * const combined = Schedule.bothLeft(leftSchedule, rightSchedule)
549
- *
550
- * const program = Effect.gen(function*() {
551
- * yield* Effect.repeat(
552
- * Effect.gen(function*() {
553
- * yield* Console.log("Task executed")
554
- * return "task-done"
555
- * }),
556
- * combined.pipe(Schedule.take(3))
557
- * )
558
- * })
559
- * ```
560
- *
561
- * @category combining
562
- * @since 2.0.0
563
- */
564
- export const bothLeft = /*#__PURE__*/dual(2, (self, other) => bothWith(self, other, output => output));
565
- /**
566
- * Combines two `Schedule`s by recurring if both of the two schedules want
567
- * to recur, using the maximum of the two durations between recurrences and
568
- * outputting the result of the right schedule (i.e. `other`).
569
- *
570
- * **When to use**
571
- *
572
- * Use when two schedules must both allow recurrence and only the right
573
- * schedule's output is needed.
574
- *
575
- * **Example** (Combining schedules and keeping the right output)
576
- *
577
- * ```ts
578
- * import { Console, Effect, Schedule } from "effect"
579
- *
580
- * // Combine two schedules, keeping right output
581
- * const leftSchedule = Schedule.exponential("100 millis").pipe(
582
- * Schedule.map(() => Effect.succeed("left-result"))
583
- * )
584
- * const rightSchedule = Schedule.spaced("50 millis").pipe(
585
- * Schedule.map(() => Effect.succeed("right-result"))
586
- * )
587
- *
588
- * const combined = Schedule.bothRight(leftSchedule, rightSchedule)
589
- *
590
- * const program = Effect.gen(function*() {
591
- * yield* Effect.repeat(
592
- * Effect.gen(function*() {
593
- * yield* Console.log("Task executed")
594
- * return "task-done"
595
- * }),
596
- * combined.pipe(Schedule.take(3))
597
- * )
598
- * })
599
- * ```
600
- *
601
- * @category combining
602
- * @since 2.0.0
603
- */
604
- export const bothRight = /*#__PURE__*/dual(2, (self, other) => bothWith(self, other, (_, output) => output));
605
- /**
606
- * Combines two `Schedule`s by recurring if both of the two schedules want
607
- * to recur, using the maximum of the two durations between recurrences and
608
- * outputting the result of the combination of both schedule outputs using the
609
- * specified `combine` function.
610
- *
611
- * **When to use**
612
- *
613
- * Use when two schedules must both allow recurrence and their outputs should be
614
- * combined into a custom value.
615
- *
616
- * **Example** (Combining schedule outputs)
617
- *
618
- * ```ts
619
- * import { Console, Effect, Schedule } from "effect"
620
- *
621
- * // Combine two schedules with custom output combination
622
- * const leftSchedule = Schedule.exponential("100 millis").pipe(
623
- * Schedule.map(() => Effect.succeed("left"))
624
- * )
625
- * const rightSchedule = Schedule.spaced("50 millis").pipe(
626
- * Schedule.map(() => Effect.succeed("right"))
627
- * )
628
- *
629
- * const combined = Schedule.bothWith(
630
- * leftSchedule,
631
- * rightSchedule,
632
- * (left, right) => `${left}-${right}`
633
- * )
634
- *
635
- * const program = Effect.gen(function*() {
636
- * yield* Effect.repeat(
637
- * Effect.gen(function*() {
638
- * yield* Console.log("Task executed")
639
- * return "task-result"
478
+ * return "success"
640
479
  * }),
641
- * combined.pipe(Schedule.take(3))
480
+ * retrySchedule.pipe(
481
+ * Schedule.tap(({ output: duration }) =>
482
+ * Console.log(`Waiting for the slowest schedule: ${duration}`)
483
+ * )
484
+ * )
642
485
  * )
643
486
  * })
644
487
  * ```
645
488
  *
646
489
  * @category combining
647
- * @since 2.0.0
648
- */
649
- export const bothWith = /*#__PURE__*/dual(3, (self, other, combine) => fromStep(effect.map(effect.zip(toStep(self), toStep(other)), ([stepLeft, stepRight]) => (now, input) => Pull.matchEffect(stepLeft(now, input), {
650
- onSuccess: leftResult => stepRight(now, input).pipe(effect.map(rightResult => [combine(leftResult[0], rightResult[0]), Duration.max(leftResult[1], rightResult[1])]), Pull.catchDone(rightDone => Cause.done(combine(leftResult[0], rightDone)))),
651
- onDone: leftDone => stepRight(now, input).pipe(effect.flatMap(rightResult => Cause.done(combine(leftDone, rightResult[0]))), Pull.catchDone(rightDone => Cause.done(combine(leftDone, rightDone)))),
652
- onFailure: effect.failCause
653
- }))));
654
- /**
655
- * Returns a new `Schedule` that follows `self` and outputs the inputs seen so
656
- * far as an array.
657
- *
658
- * **Details**
659
- *
660
- * This does not make the schedule run forever. The collected schedule stops
661
- * when `self` stops and fails when `self` fails.
662
- *
663
- * **Example** (Collecting schedule inputs)
664
- *
665
- * ```ts
666
- * import { Console, Effect, Schedule } from "effect"
667
- *
668
- * // Collect all inputs passed to the schedule
669
- * const inputCollector = Schedule.collectInputs(
670
- * Schedule.spaced("100 millis")
671
- * )
672
- *
673
- * const program = Effect.gen(function*() {
674
- * let counter = 0
675
- * yield* Effect.repeat(
676
- * Effect.gen(function*() {
677
- * counter++
678
- * yield* Console.log(`Iteration ${counter}`)
679
- * return `result-${counter}`
680
- * }),
681
- * inputCollector.pipe(Schedule.take(4))
682
- * )
683
- * })
684
- * ```
685
- *
686
- * @category collecting
687
- * @since 4.0.0
688
- */
689
- export const collectInputs = self => collectWhile(passthrough(self), () => effect.succeed(true));
690
- /**
691
- * Returns a new `Schedule` that follows `self` and outputs the schedule outputs
692
- * seen so far as an array.
693
- *
694
- * **Details**
695
- *
696
- * This does not make the schedule run forever. The collected schedule stops
697
- * when `self` stops and fails when `self` fails.
698
- *
699
- * **Example** (Collecting schedule outputs)
700
- *
701
- * ```ts
702
- * import { Console, Effect, Schedule } from "effect"
703
- *
704
- * // Collect all outputs from the schedule
705
- * const outputCollector = Schedule.collectOutputs(
706
- * Schedule.recurs(4)
707
- * )
708
- *
709
- * const program = Effect.gen(function*() {
710
- * yield* Effect.repeat(
711
- * Effect.gen(function*() {
712
- * yield* Console.log("Task executed")
713
- * return "task-result"
714
- * }),
715
- * outputCollector.pipe(Schedule.take(4))
716
- * )
717
- * })
718
- * ```
719
- *
720
- * @category collecting
721
490
  * @since 4.0.0
722
491
  */
723
- export const collectOutputs = self => collectWhile(self, () => effect.succeed(true));
724
- /**
725
- * Returns a new `Schedule` that recurs as long as the specified `predicate`
726
- * returns `true`, collecting all outputs of the schedule into an array.
727
- *
728
- * **Example** (Collecting outputs while a condition holds)
729
- *
730
- * ```ts
731
- * import { Console, Effect, Schedule } from "effect"
732
- *
733
- * // Collect outputs while condition is met
734
- * const collectWhileSmall = Schedule.collectWhile(
735
- * Schedule.exponential("100 millis"),
736
- * (metadata) =>
737
- * Effect.succeed(metadata.attempt <= 5 && metadata.elapsed < 2000)
738
- * )
739
- *
740
- * const conditionalProgram = Effect.gen(function*() {
741
- * let attempt = 0
742
- *
743
- * const attempts = yield* Effect.repeat(
744
- * Effect.gen(function*() {
745
- * attempt++
746
- * yield* Console.log(`Retry attempt ${attempt}`)
747
- * return `attempt-${attempt}`
748
- * }),
749
- * collectWhileSmall
750
- * )
751
- *
752
- * yield* Console.log(`Collected attempts: [${attempts.join(", ")}]`)
753
- * })
754
- *
755
- * // Collect with effectful predicate
756
- * const collectWithCheck = Schedule.collectWhile(
757
- * Schedule.fixed("1 second"),
758
- * (metadata) =>
759
- * Effect.gen(function*() {
760
- * const shouldContinue = metadata.attempt < 5
761
- * yield* Console.log(
762
- * `Check ${metadata.attempt}: continue = ${shouldContinue}`
763
- * )
764
- * return shouldContinue
765
- * })
766
- * )
767
- *
768
- * const effectfulProgram = Effect.gen(function*() {
769
- * const results = yield* Effect.repeat(
770
- * Effect.succeed("checked"),
771
- * collectWithCheck
772
- * )
773
- *
774
- * yield* Console.log(`Final collection: ${results.length} items`)
775
- * })
776
- *
777
- * // Collect samples with condition
778
- * const samples = [12, 18, 24, 30, 36]
779
- *
780
- * const collectSamples = Schedule.collectWhile(
781
- * Schedule.spaced("200 millis"),
782
- * (metadata) =>
783
- * Effect.succeed(metadata.attempt <= 5 && metadata.elapsed < 2000)
784
- * )
785
- *
786
- * const samplingProgram = Effect.gen(function*() {
787
- * let index = 0
788
- * const collected = yield* Effect.repeat(
789
- * Effect.gen(function*() {
790
- * const sample = samples[index++]
791
- * yield* Console.log(`Sample: ${sample}`)
792
- * return sample
793
- * }),
794
- * collectSamples
795
- * )
796
- *
797
- * const average = collected.reduce((sum, s) => sum + s, 0) / collected.length
798
- * yield* Console.log(
799
- * `Collected ${collected.length} samples, average: ${average.toFixed(1)}`
800
- * )
801
- * })
802
- * ```
803
- *
804
- * @category collecting
805
- * @since 2.0.0
806
- */
807
- export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(while_(self, predicate), () => [], (outputs, output) => {
808
- outputs.push(output);
809
- return outputs;
810
- }));
492
+ export const max = schedules => fromStep(effect.map(effect.all(schedules.map(toStep)), steps => (now, input) => effect.flatMap(effect.forEach(steps, step => Pull.matchEffect(step(now, input), {
493
+ onSuccess: result => effect.succeed(result[1]),
494
+ onDone: () => effect.undefined,
495
+ onFailure: effect.failCause
496
+ })), results => {
497
+ const duration = maxDuration(results);
498
+ if (duration === undefined) {
499
+ return Cause.done(Duration.zero);
500
+ }
501
+ return effect.succeed([duration, duration]);
502
+ })));
503
+ const maxDuration = results => {
504
+ let max = results[0];
505
+ for (let i = 1; i < results.length; i++) {
506
+ max = results[i] && max && Duration.max(max, results[i]);
507
+ if (max === undefined) break;
508
+ }
509
+ return max;
510
+ };
811
511
  /**
812
512
  * Returns a new `Schedule` that recurs on the specified `Cron` schedule and
813
513
  * outputs the duration between recurrences.
@@ -829,8 +529,8 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
829
529
  * return "minute"
830
530
  * }),
831
531
  * everyMinute.pipe(
832
- * Schedule.take(3), // Run only 3 times for demo
833
- * Schedule.tapOutput((duration) =>
532
+ * Schedule.upTo({ times: 3 }), // Run only 3 times for demo
533
+ * Schedule.tap(({ output: duration }) =>
834
534
  * Console.log(`Next execution in: ${duration}`)
835
535
  * )
836
536
  * )
@@ -850,7 +550,7 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
850
550
  * return "backup-done"
851
551
  * }),
852
552
  * dailyBackup.pipe(
853
- * Schedule.take(2) // Run 2 times for demo
553
+ * Schedule.upTo({ times: 2 }) // Run 2 times for demo
854
554
  * )
855
555
  * )
856
556
  * })
@@ -869,7 +569,7 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
869
569
  * yield* Console.log(`Report generated: ${JSON.stringify(report)}`)
870
570
  * return report
871
571
  * }),
872
- * weeklyReport.pipe(Schedule.take(1))
572
+ * weeklyReport.pipe(Schedule.upTo({ times: 1 }))
873
573
  * )
874
574
  * })
875
575
  *
@@ -888,7 +588,7 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
888
588
  * return status
889
589
  * }),
890
590
  * businessHoursCheck.pipe(
891
- * Schedule.take(4) // Demo with 4 checks
591
+ * Schedule.upTo({ times: 4 }) // Demo with 4 checks
892
592
  * )
893
593
  * )
894
594
  * })
@@ -904,13 +604,13 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
904
604
  * yield* Console.log(`Processed ${invoiceCount} invoices`)
905
605
  * return { count: invoiceCount, batch: "2024-01-a" }
906
606
  * }),
907
- * monthlyInvoice.pipe(Schedule.take(1))
607
+ * monthlyInvoice.pipe(Schedule.upTo({ times: 1 }))
908
608
  * )
909
609
  * })
910
610
  *
911
611
  * // Complex cron with error handling
912
612
  * const complexCron = Schedule.cron("0 2,4,6 * * *").pipe(
913
- * Schedule.tapOutput((duration) =>
613
+ * Schedule.tap(({ output: duration }) =>
914
614
  * Console.log(`Scheduled to run again in ${duration}`)
915
615
  * )
916
616
  * )
@@ -927,7 +627,7 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
927
627
  * }
928
628
  * return "success"
929
629
  * }),
930
- * complexCron.pipe(Schedule.take(3))
630
+ * complexCron.pipe(Schedule.upTo({ times: 3 }))
931
631
  * ).pipe(
932
632
  * Effect.catch((error: unknown) =>
933
633
  * Console.log(`Cron task error: ${String(error)}`)
@@ -941,97 +641,17 @@ export const collectWhile = /*#__PURE__*/dual(2, (self, predicate) => reduce(whi
941
641
  */
942
642
  export const cron = (expression, tz) => {
943
643
  const parsed = Cron.isCron(expression) ? Result.succeed(expression) : Cron.parse(expression, tz);
944
- return fromStep(effect.map(effect.fromResult(parsed), cron => (now, _) => effect.sync(() => {
945
- const next = Cron.next(cron, now).getTime();
946
- const duration = Duration.millis(next - now);
947
- return [duration, duration];
948
- })));
644
+ return fromStep(effect.map(effect.fromResult(parsed), cron => (now, _) => {
645
+ if (now === Number.POSITIVE_INFINITY) {
646
+ return Cause.done(Duration.zero);
647
+ }
648
+ return effect.sync(() => {
649
+ const next = Cron.next(cron, now).getTime();
650
+ const duration = Duration.millis(next - now);
651
+ return [duration, duration];
652
+ });
653
+ }));
949
654
  };
950
- /**
951
- * Returns a new schedule that outputs the delay between each occurrence.
952
- *
953
- * **Example** (Extracting schedule delays)
954
- *
955
- * ```ts
956
- * import { Console, Effect, Schedule } from "effect"
957
- *
958
- * // Extract delays from an exponential backoff schedule
959
- * const exponentialDelays = Schedule.delays(
960
- * Schedule.exponential("100 millis").pipe(Schedule.take(5))
961
- * )
962
- *
963
- * const delayProgram = Effect.gen(function*() {
964
- * yield* Effect.repeat(
965
- * Effect.gen(function*() {
966
- * yield* Console.log("Task executed")
967
- * return "task result"
968
- * }),
969
- * exponentialDelays.pipe(
970
- * Schedule.tapOutput((delay) =>
971
- * Console.log(`Waiting ${delay} before next execution`)
972
- * )
973
- * )
974
- * )
975
- * })
976
- *
977
- * // Monitor delays from a Fibonacci schedule
978
- * const fibonacciDelays = Schedule.delays(
979
- * Schedule.fibonacci("200 millis").pipe(Schedule.take(8))
980
- * )
981
- *
982
- * const fibDelayProgram = Effect.gen(function*() {
983
- * yield* Effect.repeat(
984
- * Console.log("Fibonacci task"),
985
- * fibonacciDelays.pipe(
986
- * Schedule.tapOutput((delay) => Console.log(`Fibonacci delay: ${delay}`))
987
- * )
988
- * )
989
- * })
990
- *
991
- * // Extract delays for analysis or logging
992
- * const analyzeDelays = Schedule.delays(
993
- * Schedule.spaced("1 second").pipe(Schedule.take(3))
994
- * ).pipe(
995
- * Schedule.tapOutput((delay) =>
996
- * Effect.gen(function*() {
997
- * yield* Console.log(`Recorded delay: ${delay}`)
998
- * // In real applications, might send to metrics system
999
- * })
1000
- * )
1001
- * )
1002
- *
1003
- * // Combine delays with other schedules for complex timing
1004
- * const adaptiveSchedule = Schedule.unfold(100, (delay) => Effect.succeed(delay * 1.5)).pipe(
1005
- * Schedule.take(6)
1006
- * )
1007
- *
1008
- * const adaptiveDelays = Schedule.delays(adaptiveSchedule)
1009
- *
1010
- * const adaptiveProgram = Effect.gen(function*() {
1011
- * yield* Effect.repeat(
1012
- * Effect.gen(function*() {
1013
- * yield* Console.log("Adaptive task execution")
1014
- * return "completed"
1015
- * }),
1016
- * adaptiveDelays.pipe(
1017
- * Schedule.tapOutput((delay) => Console.log(`Adaptive delay: ${delay}`))
1018
- * )
1019
- * )
1020
- * })
1021
- *
1022
- * // Use delays to implement custom timing logic
1023
- * const customTimingSchedule = Schedule.delays(
1024
- * Schedule.exponential("50 millis").pipe(Schedule.take(4))
1025
- * ).pipe(
1026
- * Schedule.map((delay) => Effect.succeed(`Next execution in ${delay}`)),
1027
- * Schedule.tapOutput((message) => Console.log(message))
1028
- * )
1029
- * ```
1030
- *
1031
- * @category constructors
1032
- * @since 2.0.0
1033
- */
1034
- export const delays = self => fromStep(effect.map(toStep(self), step => (now, input) => Pull.catchDone(effect.map(step(now, input), ([_, duration]) => [duration, duration]), _ => Cause.done(Duration.zero))));
1035
655
  /**
1036
656
  * Returns a schedule that recurs once after the specified duration.
1037
657
  *
@@ -1090,7 +710,7 @@ export const duration = durationInput => {
1090
710
  * return "task done"
1091
711
  * }),
1092
712
  * fiveSecondSchedule.pipe(
1093
- * Schedule.tapOutput((elapsedDuration) =>
713
+ * Schedule.tap(({ output: elapsedDuration }) =>
1094
714
  * Console.log(`Total elapsed: ${elapsedDuration}`)
1095
715
  * )
1096
716
  * )
@@ -1100,10 +720,11 @@ export const duration = durationInput => {
1100
720
  * })
1101
721
  *
1102
722
  * // Combine with other schedules for time-bounded execution
1103
- * const timeAndCountLimited = Schedule.spaced("1 second").pipe(
1104
- * Schedule.both(Schedule.during("10 seconds")), // Stop after 10 seconds OR
1105
- * Schedule.both(Schedule.recurs(15)) // 15 attempts, whichever comes first
1106
- * )
723
+ * const timeAndCountLimited = Schedule.max([
724
+ * Schedule.spaced("1 second"),
725
+ * Schedule.during("10 seconds"), // Stop after 10 seconds OR
726
+ * Schedule.recurs(15) // 15 attempts, whichever comes first
727
+ * ])
1107
728
  *
1108
729
  * // Burst execution within time window
1109
730
  * const burstWindow = Schedule.during("3 seconds")
@@ -1123,9 +744,10 @@ export const duration = durationInput => {
1123
744
  * })
1124
745
  *
1125
746
  * // Timed retry window - retry for up to 30 seconds
1126
- * const timedRetry = Schedule.exponential("200 millis").pipe(
1127
- * Schedule.both(Schedule.during("30 seconds"))
1128
- * )
747
+ * const timedRetry = Schedule.max([
748
+ * Schedule.exponential("200 millis"),
749
+ * Schedule.during("30 seconds")
750
+ * ])
1129
751
  *
1130
752
  * const retryProgram = Effect.gen(function*() {
1131
753
  * let attempt = 0
@@ -1155,162 +777,52 @@ export const duration = durationInput => {
1155
777
  * @category constructors
1156
778
  * @since 4.0.0
1157
779
  */
1158
- export const during = duration => while_(elapsed, ({
1159
- output
1160
- }) => effect.succeed(Duration.isLessThanOrEqualTo(output, Duration.fromInputUnsafe(duration))));
780
+ export const during = duration => {
781
+ const durationMillis = Duration.toMillis(duration);
782
+ return fromStepWithMetadata(effect.succeed(meta => {
783
+ const elapsed = Duration.millis(meta.elapsed);
784
+ return meta.elapsed > durationMillis ? effect.succeed([elapsed, Duration.zero]) : Cause.done(elapsed);
785
+ }));
786
+ };
1161
787
  /**
1162
- * Combines two `Schedule`s by recurring if either of the two schedules wants
1163
- * to recur, using the minimum of the two durations between recurrences and
1164
- * outputting a tuple of the outputs of both schedules.
788
+ * Combines schedules by recurring while at least one schedule wants to recur,
789
+ * using the minimum delay between recurrences and outputting that minimum delay.
1165
790
  *
1166
791
  * **When to use**
1167
792
  *
1168
- * Use when the combined schedule should continue while at least one schedule still recurs.
793
+ * Use when a combined policy should continue while any schedule still recurs,
794
+ * and should wait for the fastest schedule between recurrences.
1169
795
  *
1170
- * **Example** (Combining schedules with either semantics)
796
+ * **Example** (Combining retry schedules by their minimum delay)
1171
797
  *
1172
798
  * ```ts
1173
799
  * import { Console, Data, Effect, Schedule } from "effect"
1174
800
  *
1175
801
  * class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
1176
802
  *
1177
- * // Either continues as long as at least one schedule wants to continue
1178
- * const timeBasedSchedule = Schedule.spaced("2 seconds").pipe(Schedule.take(3))
1179
- * const countBasedSchedule = Schedule.recurs(5)
1180
- *
1181
- * // Continues until both schedules are exhausted (either still wants to recur)
1182
- * const eitherSchedule = Schedule.either(timeBasedSchedule, countBasedSchedule)
1183
- * // Outputs: [time_result, count_result] tuple
803
+ * const retrySchedule = Schedule.min([
804
+ * Schedule.fixed("5 seconds"),
805
+ * Schedule.exponential("5 seconds"),
806
+ * Schedule.spaced("10 seconds")
807
+ * ])
1184
808
  *
1185
809
  * const program = Effect.gen(function*() {
1186
- * const results = yield* Effect.repeat(
1187
- * Effect.gen(function*() {
1188
- * yield* Console.log("Task executed")
1189
- * return "task completed"
1190
- * }),
1191
- * eitherSchedule.pipe(
1192
- * Schedule.tapOutput(([timeResult, countResult]) =>
1193
- * Console.log(`Time: ${timeResult}, Count: ${countResult}`)
1194
- * )
1195
- * )
1196
- * )
1197
- *
1198
- * yield* Console.log(`Total executions: ${results.length}`)
1199
- * })
1200
- *
1201
- * // Either with different delay strategies
1202
- * const aggressiveRetry = Schedule.exponential("100 millis").pipe(
1203
- * Schedule.take(3)
1204
- * )
1205
- * const fallbackRetry = Schedule.fixed("5 seconds").pipe(Schedule.take(2))
1206
- *
1207
- * // Will use the more aggressive retry until it's exhausted, then fallback
1208
- * const combinedRetry = Schedule.either(aggressiveRetry, fallbackRetry)
1209
- *
1210
- * const retryProgram = Effect.gen(function*() {
1211
810
  * let attempt = 0
1212
811
  *
1213
- * const result = yield* Effect.retry(
812
+ * yield* Effect.retry(
1214
813
  * Effect.gen(function*() {
1215
814
  * attempt++
1216
815
  * yield* Console.log(`Retry attempt ${attempt}`)
1217
- *
1218
- * if (attempt < 6) {
816
+ * if (attempt < 3) {
1219
817
  * return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
1220
818
  * }
1221
- *
1222
- * return `Success on attempt ${attempt}`
1223
- * }),
1224
- * combinedRetry
1225
- * )
1226
- *
1227
- * yield* Console.log(`Final result: ${result}`)
1228
- * })
1229
- *
1230
- * // Either provides union semantics (OR logic)
1231
- * // Compare with both, which provides intersection semantics (AND logic)
1232
- * ```
1233
- *
1234
- * @see {@link both} for continuing only while both schedules still recur
1235
- *
1236
- * @category combining
1237
- * @since 2.0.0
1238
- */
1239
- export const either = /*#__PURE__*/dual(2, (self, other) => eitherWith(self, other, (left, right) => [left, right]));
1240
- /**
1241
- * Combines two `Schedule`s by recurring if either of the two schedules wants
1242
- * to recur, using the minimum of the two durations between recurrences and
1243
- * outputting the result of the left schedule (i.e. `self`).
1244
- *
1245
- * **When to use**
1246
- *
1247
- * Use when either schedule may keep recurrence going and only the left
1248
- * schedule's output is needed.
1249
- *
1250
- * **Example** (Combining either schedules and keeping the left output)
1251
- *
1252
- * ```ts
1253
- * import { Console, Effect, Schedule } from "effect"
1254
- *
1255
- * // Combine two schedules with either semantics, keeping left output
1256
- * const primarySchedule = Schedule.exponential("100 millis").pipe(
1257
- * Schedule.map(() => Effect.succeed("primary-result")),
1258
- * Schedule.take(2)
1259
- * )
1260
- * const backupSchedule = Schedule.spaced("500 millis").pipe(
1261
- * Schedule.map(() => Effect.succeed("backup-result"))
1262
- * )
1263
- *
1264
- * const combined = Schedule.eitherLeft(primarySchedule, backupSchedule)
1265
- *
1266
- * const program = Effect.gen(function*() {
1267
- * yield* Effect.repeat(
1268
- * Effect.gen(function*() {
1269
- * yield* Console.log("Task executed")
1270
- * return "task-done"
1271
- * }),
1272
- * combined.pipe(Schedule.take(5))
1273
- * )
1274
- * })
1275
- * ```
1276
- *
1277
- * @category combining
1278
- * @since 4.0.0
1279
- */
1280
- export const eitherLeft = /*#__PURE__*/dual(2, (self, other) => eitherWith(self, other, output => output));
1281
- /**
1282
- * Combines two `Schedule`s by recurring if either of the two schedules wants
1283
- * to recur, using the minimum of the two durations between recurrences and
1284
- * outputting the result of the right schedule (i.e. `other`).
1285
- *
1286
- * **When to use**
1287
- *
1288
- * Use when either schedule may keep recurrence going and only the right
1289
- * schedule's output is needed.
1290
- *
1291
- * **Example** (Combining either schedules and keeping the right output)
1292
- *
1293
- * ```ts
1294
- * import { Console, Effect, Schedule } from "effect"
1295
- *
1296
- * // Combine two schedules with either semantics, keeping right output
1297
- * const primarySchedule = Schedule.exponential("100 millis").pipe(
1298
- * Schedule.map(() => Effect.succeed("primary-result")),
1299
- * Schedule.take(2)
1300
- * )
1301
- * const backupSchedule = Schedule.spaced("500 millis").pipe(
1302
- * Schedule.map(() => Effect.succeed("backup-result"))
1303
- * )
1304
- *
1305
- * const combined = Schedule.eitherRight(primarySchedule, backupSchedule)
1306
- *
1307
- * const program = Effect.gen(function*() {
1308
- * yield* Effect.repeat(
1309
- * Effect.gen(function*() {
1310
- * yield* Console.log("Task executed")
1311
- * return "task-done"
819
+ * return "success"
1312
820
  * }),
1313
- * combined.pipe(Schedule.take(5))
821
+ * retrySchedule.pipe(
822
+ * Schedule.tap(({ output: duration }) =>
823
+ * Console.log(`Waiting for the fastest schedule: ${duration}`)
824
+ * )
825
+ * )
1314
826
  * )
1315
827
  * })
1316
828
  * ```
@@ -1318,89 +830,27 @@ export const eitherLeft = /*#__PURE__*/dual(2, (self, other) => eitherWith(self,
1318
830
  * @category combining
1319
831
  * @since 4.0.0
1320
832
  */
1321
- export const eitherRight = /*#__PURE__*/dual(2, (self, other) => eitherWith(self, other, (_, output) => output));
1322
- /**
1323
- * Combines two `Schedule`s by recurring if either of the two schedules wants
1324
- * to recur, using the minimum of the two durations between recurrences and
1325
- * outputting the result of the combination of both schedule outputs using the
1326
- * specified `combine` function.
1327
- *
1328
- * **When to use**
1329
- *
1330
- * Use when either schedule may keep recurrence going and their outputs should be
1331
- * combined into a custom value.
1332
- *
1333
- * **Example** (Combining either schedule outputs)
1334
- *
1335
- * ```ts
1336
- * import { Console, Effect, Schedule } from "effect"
1337
- *
1338
- * // Combine schedules with either semantics and custom combination
1339
- * const primarySchedule = Schedule.exponential("100 millis").pipe(
1340
- * Schedule.map(() => Effect.succeed("primary")),
1341
- * Schedule.take(2)
1342
- * )
1343
- * const fallbackSchedule = Schedule.spaced("500 millis").pipe(
1344
- * Schedule.map(() => Effect.succeed("fallback"))
1345
- * )
1346
- *
1347
- * const combined = Schedule.eitherWith(
1348
- * primarySchedule,
1349
- * fallbackSchedule,
1350
- * (primary, fallback) => `${primary}+${fallback}`
1351
- * )
1352
- *
1353
- * const program = Effect.gen(function*() {
1354
- * yield* Effect.repeat(
1355
- * Effect.gen(function*() {
1356
- * yield* Console.log("Task executed")
1357
- * return "task-result"
1358
- * }),
1359
- * combined.pipe(Schedule.take(5))
1360
- * )
1361
- * })
1362
- * ```
1363
- *
1364
- * @category combining
1365
- * @since 2.0.0
1366
- */
1367
- export const eitherWith = /*#__PURE__*/dual(3, (self, other, combine) => fromStep(effect.map(effect.zip(toStep(self), toStep(other)), ([stepLeft, stepRight]) => (now, input) => Pull.matchEffect(stepLeft(now, input), {
1368
- onSuccess: leftResult => stepRight(now, input).pipe(effect.map(rightResult => [combine(leftResult[0], rightResult[0]), Duration.min(leftResult[1], rightResult[1])]), Pull.catchDone(rightDone => effect.succeed([combine(leftResult[0], rightDone), leftResult[1]]))),
1369
- onFailure: effect.failCause,
1370
- onDone: leftDone => stepRight(now, input).pipe(effect.map(rightResult => [combine(leftDone, rightResult[0]), rightResult[1]]), Pull.catchDone(rightDone => Cause.done(combine(leftDone, rightDone))))
1371
- }))));
1372
- /**
1373
- * Schedule that always recurs and returns the total elapsed duration since the
1374
- * first recurrence.
1375
- *
1376
- * **Details**
1377
- *
1378
- * This schedule never stops and outputs the cumulative time that has passed since the schedule
1379
- * started executing. Useful for tracking execution time or implementing time-based logic.
1380
- *
1381
- * **Example** (Measuring elapsed schedule time)
1382
- *
1383
- * ```ts
1384
- * import { Console, Duration, Effect, Schedule } from "effect"
1385
- *
1386
- * const program = Effect.gen(function*() {
1387
- * yield* Effect.repeat(
1388
- * Console.log("Running task..."),
1389
- * Schedule.spaced("1 second").pipe(
1390
- * Schedule.both(Schedule.elapsed),
1391
- * Schedule.tapOutput(([count, duration]) =>
1392
- * Console.log(`Run ${count}, elapsed: ${Duration.toMillis(duration)}ms`)
1393
- * ),
1394
- * Schedule.take(5)
1395
- * )
1396
- * )
1397
- * })
1398
- * ```
1399
- *
1400
- * @category constructors
1401
- * @since 2.0.0
1402
- */
1403
- export const elapsed = /*#__PURE__*/fromStepWithMetadata(/*#__PURE__*/effect.succeed(meta => effect.succeed([Duration.millis(meta.elapsed), Duration.zero])));
833
+ export const min = schedules => fromStep(effect.map(effect.all(schedules.map(toStep)), steps => (now, input) => effect.flatMap(effect.forEach(steps, step => Pull.matchEffect(step(now, input), {
834
+ onSuccess: result => effect.succeed(result[1]),
835
+ onDone: () => effect.undefined,
836
+ onFailure: effect.failCause
837
+ })), results => {
838
+ const duration = minDuration(results);
839
+ if (duration === undefined) {
840
+ return Cause.done(Duration.zero);
841
+ }
842
+ return effect.succeed([duration, duration]);
843
+ })));
844
+ const minDuration = results => {
845
+ let min = undefined;
846
+ for (let i = 0; i < results.length; i++) {
847
+ const duration = results[i];
848
+ if (duration !== undefined) {
849
+ min = min === undefined ? duration : Duration.min(min, duration);
850
+ }
851
+ }
852
+ return min;
853
+ };
1404
854
  /**
1405
855
  * Schedule that always recurs, but will wait a certain amount between
1406
856
  * repetitions, given by `base * factor.pow(n)`, where `n` is the number of
@@ -1422,9 +872,10 @@ export const elapsed = /*#__PURE__*/fromStepWithMetadata(/*#__PURE__*/effect.suc
1422
872
  * // Delays: 200ms, 300ms, 450ms, 675ms, 1012ms, ...
1423
873
  *
1424
874
  * // Retry with exponential backoff (limited to 5 attempts)
1425
- * const retryPolicy = Schedule.exponential("50 millis").pipe(
1426
- * Schedule.both(Schedule.recurs(5))
1427
- * )
875
+ * const retryPolicy = Schedule.max([
876
+ * Schedule.exponential("50 millis"),
877
+ * Schedule.recurs(5)
878
+ * ])
1428
879
  *
1429
880
  * const program = Effect.gen(function*() {
1430
881
  * let attempt = 0
@@ -1488,9 +939,11 @@ export const exponential = (base, factor = 2) => {
1488
939
  *
1489
940
  * return `Success on attempt ${attempt}`
1490
941
  * }),
1491
- * Schedule.fibonacci("50 millis").pipe(
1492
- * Schedule.both(Schedule.recurs(6)), // Maximum 6 retries
1493
- * Schedule.tapOutput((delay) => Console.log(`Next retry in ${delay}`))
942
+ * Schedule.max([
943
+ * Schedule.fibonacci("50 millis"),
944
+ * Schedule.recurs(6) // Maximum 6 retries
945
+ * ]).pipe(
946
+ * Schedule.tap(({ output: delay }) => Console.log(`Next retry in ${delay}`))
1494
947
  * )
1495
948
  * )
1496
949
  *
@@ -1504,7 +957,7 @@ export const exponential = (base, factor = 2) => {
1504
957
  * }).pipe(
1505
958
  * Effect.repeat(
1506
959
  * Schedule.fibonacci("200 millis").pipe(
1507
- * Schedule.take(8) // First 8 heartbeats
960
+ * Schedule.upTo({ times: 8 }) // First 8 heartbeats
1508
961
  * )
1509
962
  * )
1510
963
  * )
@@ -1570,7 +1023,7 @@ export const fibonacci = one => {
1570
1023
  * yield* Effect.sleep("200 millis") // simulate health check work
1571
1024
  * return "healthy"
1572
1025
  * }).pipe(
1573
- * Effect.repeat(Schedule.fixed("2 seconds").pipe(Schedule.take(5)))
1026
+ * Effect.repeat(Schedule.fixed("2 seconds").pipe(Schedule.upTo({ times: 5 })))
1574
1027
  * )
1575
1028
  *
1576
1029
  * // Difference between fixed and spaced:
@@ -1587,12 +1040,12 @@ export const fibonacci = one => {
1587
1040
  * // Fixed schedule: if task takes 1.5s but interval is 1s,
1588
1041
  * // next execution happens immediately (no pile-up)
1589
1042
  * const fixedSchedule = longRunningTask.pipe(
1590
- * Effect.repeat(Schedule.fixed("1 second").pipe(Schedule.take(3)))
1043
+ * Effect.repeat(Schedule.fixed("1 second").pipe(Schedule.upTo({ times: 3 })))
1591
1044
  * )
1592
1045
  *
1593
1046
  * // Comparing with spaced (waits 1s AFTER each task)
1594
1047
  * const spacedSchedule = longRunningTask.pipe(
1595
- * Effect.repeat(Schedule.spaced("1 second").pipe(Schedule.take(3)))
1048
+ * Effect.repeat(Schedule.spaced("1 second").pipe(Schedule.upTo({ times: 3 })))
1596
1049
  * )
1597
1050
  *
1598
1051
  * const program = Effect.gen(function*() {
@@ -1632,8 +1085,14 @@ export const fixed = interval => {
1632
1085
  }));
1633
1086
  };
1634
1087
  /**
1635
- * Returns a new `Schedule` that maps the output of this schedule using the
1636
- * specified function.
1088
+ * Returns a new `Schedule` that maps each schedule decision to a new output
1089
+ * using the full schedule metadata.
1090
+ *
1091
+ * **Details**
1092
+ *
1093
+ * The callback receives the schedule input, output, selected delay duration,
1094
+ * current attempt, and elapsed timing information. Return either a plain value
1095
+ * or an `Effect` that produces the new output.
1637
1096
  *
1638
1097
  * **Example** (Mapping schedule outputs)
1639
1098
  *
@@ -1642,17 +1101,17 @@ export const fixed = interval => {
1642
1101
  *
1643
1102
  * // Transform schedule output from number to string
1644
1103
  * const countSchedule = Schedule.recurs(5).pipe(
1645
- * Schedule.map((count) => Effect.succeed(`Execution #${count + 1}`))
1104
+ * Schedule.map(({ output: count }) => Effect.succeed(`Execution #${count + 1}`))
1646
1105
  * )
1647
1106
  *
1648
1107
  * // Map schedule delays to human-readable format
1649
1108
  * const readableDelays = Schedule.exponential("100 millis").pipe(
1650
- * Schedule.map((duration) => Effect.succeed(`Next retry in ${duration}`))
1109
+ * Schedule.map(({ output: delay }) => Effect.succeed(`Next retry in ${delay}`))
1651
1110
  * )
1652
1111
  *
1653
1112
  * // Transform numeric output to structured data
1654
1113
  * const structuredSchedule = Schedule.spaced("1 second").pipe(
1655
- * Schedule.map((recurrence) => Effect.succeed({
1114
+ * Schedule.map(({ output: recurrence }) => Effect.succeed({
1656
1115
  * iteration: recurrence + 1,
1657
1116
  * phase: recurrence < 5 ? "warmup" as const : "steady" as const
1658
1117
  * }))
@@ -1662,8 +1121,8 @@ export const fixed = interval => {
1662
1121
  * const results = yield* Effect.repeat(
1663
1122
  * Effect.succeed("task completed"),
1664
1123
  * structuredSchedule.pipe(
1665
- * Schedule.take(8),
1666
- * Schedule.tapOutput((info) =>
1124
+ * Schedule.upTo({ times: 8 }),
1125
+ * Schedule.tap(({ output: info }) =>
1667
1126
  * Console.log(
1668
1127
  * `${info.phase} phase - iteration ${info.iteration}`
1669
1128
  * )
@@ -1676,7 +1135,7 @@ export const fixed = interval => {
1676
1135
  *
1677
1136
  * // Map with effectful transformation
1678
1137
  * const effectfulMap = Schedule.fixed("2 seconds").pipe(
1679
- * Schedule.map((count) =>
1138
+ * Schedule.map(({ output: count }) =>
1680
1139
  * Effect.gen(function*() {
1681
1140
  * yield* Console.log(`Processing count: ${count}`)
1682
1141
  * return count * 10
@@ -1684,45 +1143,55 @@ export const fixed = interval => {
1684
1143
  * )
1685
1144
  * )
1686
1145
  *
1687
- * // Combine mapping with other schedule operations
1146
+ * // Use timing metadata in the mapped output
1688
1147
  * const complexSchedule = Schedule.fibonacci("100 millis").pipe(
1689
- * Schedule.map((delay) => Effect.succeed(`Delay: ${delay}`))
1148
+ * Schedule.map(({ output: delay, attempt }) =>
1149
+ * Effect.succeed(`Attempt ${attempt} delay: ${delay}`)
1150
+ * )
1690
1151
  * )
1691
1152
  * ```
1692
1153
  *
1693
1154
  * @category mapping
1694
1155
  * @since 2.0.0
1695
1156
  */
1696
- export const map = /*#__PURE__*/dual(2, (self, f) => {
1697
- const handle = Pull.matchEffect({
1157
+ export const map = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(toStep(self), step => {
1158
+ const meta = metadataFn();
1159
+ return (now, input) => Pull.matchEffect(step(now, input), {
1698
1160
  onSuccess: ([output, duration]) => {
1699
- const result = f(output);
1161
+ const result = f({
1162
+ ...meta(now, input),
1163
+ output,
1164
+ duration
1165
+ });
1700
1166
  if (!isEffect(result)) return effect.succeed([result, duration]);
1701
1167
  return effect.map(result, output => [output, duration]);
1702
1168
  },
1703
1169
  onFailure: effect.failCause,
1704
1170
  onDone: output => {
1705
- const result = f(output);
1171
+ const result = f({
1172
+ ...meta(now, input),
1173
+ output,
1174
+ duration: Duration.zero
1175
+ });
1706
1176
  if (!isEffect(result)) return Cause.done(result);
1707
1177
  return effect.flatMap(result, Cause.done);
1708
1178
  }
1709
1179
  });
1710
- return fromStep(effect.map(toStep(self), step => (now, input) => handle(step(now, input))));
1711
- });
1180
+ })));
1712
1181
  /**
1713
1182
  * Returns a new `Schedule` that modifies the delay of the next recurrence
1714
1183
  * of the schedule using the specified effectful function.
1715
1184
  *
1716
- * **Example** (Modifying delays from schedule output)
1185
+ * **Example** (Modifying delays from schedule metadata)
1717
1186
  *
1718
1187
  * ```ts
1719
1188
  * import { Console, Duration, Effect, Schedule } from "effect"
1720
1189
  *
1721
1190
  * // Modify delays based on output - increase delay on high iteration counts
1722
1191
  * const adaptiveDelay = Schedule.recurs(10).pipe(
1723
- * Schedule.modifyDelay((output, delay) => {
1192
+ * Schedule.modifyDelay(({ output, duration }) => {
1724
1193
  * // Double the delay if we're seeing high iteration counts
1725
- * return Effect.succeed(output > 5 ? Duration.times(delay, 2) : delay)
1194
+ * return Effect.succeed(output > 5 ? Duration.times(duration, 2) : duration)
1726
1195
  * })
1727
1196
  * )
1728
1197
  *
@@ -1734,7 +1203,7 @@ export const map = /*#__PURE__*/dual(2, (self, f) => {
1734
1203
  * yield* Console.log(`Attempt ${counter}`)
1735
1204
  * return counter
1736
1205
  * }),
1737
- * adaptiveDelay.pipe(Schedule.take(8))
1206
+ * adaptiveDelay.pipe(Schedule.upTo({ times: 8 }))
1738
1207
  * )
1739
1208
  * })
1740
1209
  * ```
@@ -1742,7 +1211,14 @@ export const map = /*#__PURE__*/dual(2, (self, f) => {
1742
1211
  * @category delays & timeouts
1743
1212
  * @since 2.0.0
1744
1213
  */
1745
- export const modifyDelay = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(toStep(self), step => (now, input) => effect.flatMap(step(now, input), ([output, delay]) => effect.map(f(output, delay), delay => [output, Duration.fromInputUnsafe(delay)])))));
1214
+ export const modifyDelay = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(toStep(self), step => {
1215
+ const meta = metadataFn();
1216
+ return (now, input) => effect.flatMap(step(now, input), ([output, duration]) => effect.map(f({
1217
+ ...meta(now, input),
1218
+ output,
1219
+ duration
1220
+ }), replacement => [output, Duration.fromInputUnsafe(replacement)]));
1221
+ })));
1746
1222
  /**
1747
1223
  * Returns a new `Schedule` that randomly adjusts each recurrence delay.
1748
1224
  *
@@ -1760,8 +1236,10 @@ export const modifyDelay = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map
1760
1236
  * @category delays & timeouts
1761
1237
  * @since 2.0.0
1762
1238
  */
1763
- export const jittered = self => modifyDelay(self, (_, delay) => effect.map(randomNext, random => {
1764
- const millis = Duration.toMillis(Duration.fromInputUnsafe(delay));
1239
+ export const jittered = self => modifyDelay(self, ({
1240
+ duration
1241
+ }) => effect.map(randomNext, random => {
1242
+ const millis = Duration.toMillis(duration);
1765
1243
  return Duration.millis(millis * 0.8 * (1 - random) + millis * 1.2 * random);
1766
1244
  }));
1767
1245
  /**
@@ -1774,7 +1252,7 @@ export const jittered = self => modifyDelay(self, (_, delay) => effect.map(rando
1774
1252
  *
1775
1253
  * // Create a schedule that outputs the inputs instead of original outputs
1776
1254
  * const inputSchedule = Schedule.passthrough(
1777
- * Schedule.exponential("100 millis").pipe(Schedule.take(3))
1255
+ * Schedule.exponential("100 millis").pipe(Schedule.upTo({ times: 3 }))
1778
1256
  * )
1779
1257
  *
1780
1258
  * const program = Effect.gen(function*() {
@@ -1844,9 +1322,10 @@ export const passthrough = self => fromStep(effect.map(toStep(self), step => (no
1844
1322
  * })
1845
1323
  *
1846
1324
  * // Combining recurs with other schedules for sophisticated retry logic
1847
- * const complexRetry = Schedule.exponential("100 millis").pipe(
1848
- * Schedule.both(Schedule.recurs(3)) // At most 3 retries
1849
- * )
1325
+ * const complexRetry = Schedule.max([
1326
+ * Schedule.exponential("100 millis"),
1327
+ * Schedule.recurs(3) // At most 3 retries
1328
+ * ])
1850
1329
  *
1851
1330
  * // Allow ten recurrences after the initial run
1852
1331
  * const tenRecurrences = Effect.gen(function*() {
@@ -1858,11 +1337,11 @@ export const passthrough = self => fromStep(effect.map(toStep(self), step => (no
1858
1337
  *
1859
1338
  * // The schedule outputs the current recurrence count (0-based)
1860
1339
  * const countingSchedule = Schedule.recurs(3).pipe(
1861
- * Schedule.tapOutput((count) => Console.log(`Execution #${count + 1}`))
1340
+ * Schedule.tap(({ output: count }) => Console.log(`Execution #${count + 1}`))
1862
1341
  * )
1863
1342
  * ```
1864
1343
  *
1865
- * @see {@link take} for limiting an existing schedule
1344
+ * @see {@link upTo} for limiting an existing schedule
1866
1345
  *
1867
1346
  * @category constructors
1868
1347
  * @since 2.0.0
@@ -1870,139 +1349,6 @@ export const passthrough = self => fromStep(effect.map(toStep(self), step => (no
1870
1349
  export const recurs = times => while_(forever, ({
1871
1350
  attempt
1872
1351
  }) => effect.succeed(attempt <= times));
1873
- /**
1874
- * Returns a new `Schedule` that combines the outputs of the provided schedule
1875
- * using the specified effectful `combine` function and starting from the
1876
- * specified `initial` state.
1877
- *
1878
- * **Example** (Reducing schedule outputs)
1879
- *
1880
- * ```ts
1881
- * import { Console, Effect, Schedule } from "effect"
1882
- *
1883
- * // Sum up execution counts from a counter schedule
1884
- * const sumSchedule = Schedule.reduce(
1885
- * Schedule.recurs(5),
1886
- * () => 0, // Initial sum
1887
- * (sum, count) => Effect.succeed(sum + count) // Add each count to the sum
1888
- * )
1889
- *
1890
- * const sumProgram = Effect.gen(function*() {
1891
- * const finalSum = yield* Effect.repeat(
1892
- * Effect.gen(function*() {
1893
- * yield* Console.log("Task executed")
1894
- * return "task"
1895
- * }),
1896
- * sumSchedule.pipe(
1897
- * Schedule.tapOutput((sum) => Console.log(`Running sum: ${sum}`))
1898
- * )
1899
- * )
1900
- *
1901
- * yield* Console.log(`Final sum: ${finalSum}`)
1902
- * })
1903
- *
1904
- * // Build a history of execution counts
1905
- * const historySchedule = Schedule.reduce(
1906
- * Schedule.spaced("1 second").pipe(Schedule.take(4)),
1907
- * () => [] as Array<number>, // Initial empty array
1908
- * (history, executionNumber) => Effect.succeed([...history, executionNumber])
1909
- * )
1910
- *
1911
- * const historyProgram = Effect.gen(function*() {
1912
- * const timeline = yield* Effect.repeat(
1913
- * Effect.gen(function*() {
1914
- * yield* Console.log("Recording execution...")
1915
- * return "recorded"
1916
- * }),
1917
- * historySchedule
1918
- * )
1919
- *
1920
- * yield* Console.log(
1921
- * `Execution timeline: ${timeline.join(", ")}`
1922
- * )
1923
- * })
1924
- *
1925
- * // Accumulate metrics with effectful combination
1926
- * const metricsAccumulator = Schedule.reduce(
1927
- * Schedule.recurs(6),
1928
- * () => ({ total: 0, count: 0, max: 0 }),
1929
- * (metrics, executionCount) => Effect.succeed({
1930
- * total: metrics.total + executionCount + 1,
1931
- * count: metrics.count + 1,
1932
- * max: Math.max(metrics.max, executionCount + 1)
1933
- * })
1934
- * )
1935
- *
1936
- * const metricsProgram = Effect.gen(function*() {
1937
- * const finalMetrics = yield* Effect.repeat(
1938
- * Effect.gen(function*() {
1939
- * yield* Console.log("Processing...")
1940
- * return "processed"
1941
- * }),
1942
- * metricsAccumulator
1943
- * )
1944
- *
1945
- * const average = finalMetrics.total / finalMetrics.count
1946
- * yield* Console.log(`Final metrics: ${finalMetrics.count} executions`)
1947
- * yield* Console.log(
1948
- * `Average delay: ${average.toFixed(1)}ms, Max delay: ${finalMetrics.max}ms`
1949
- * )
1950
- * })
1951
- *
1952
- * // Build configuration state over time
1953
- * const configBuilder = Schedule.reduce(
1954
- * Schedule.fixed("500 millis").pipe(Schedule.take(3)),
1955
- * () => ({ retries: 1, timeout: 1000, backoff: 100 }),
1956
- * (config, executionNumber) => Effect.succeed({
1957
- * retries: config.retries + 1,
1958
- * timeout: config.timeout * 1.5,
1959
- * backoff: Math.min(config.backoff * 2, 5000)
1960
- * })
1961
- * )
1962
- *
1963
- * const configProgram = Effect.gen(function*() {
1964
- * const finalConfig = yield* Effect.repeat(
1965
- * Effect.gen(function*() {
1966
- * yield* Console.log("Updating configuration...")
1967
- * return "updated"
1968
- * }),
1969
- * configBuilder.pipe(
1970
- * Schedule.tapOutput((config) =>
1971
- * Console.log(
1972
- * `Config: retries=${config.retries}, timeout=${config.timeout}ms`
1973
- * )
1974
- * )
1975
- * )
1976
- * )
1977
- *
1978
- * yield* Console.log(`Final config: ${JSON.stringify(finalConfig)}`)
1979
- * })
1980
- * ```
1981
- *
1982
- * @category folding
1983
- * @since 2.0.0
1984
- */
1985
- export const reduce = /*#__PURE__*/dual(3, (self, initial, combine) => fromStep(effect.map(toStep(self), step => {
1986
- let state = initial();
1987
- return (now, input) => Pull.matchEffect(step(now, input), {
1988
- onSuccess([output, delay]) {
1989
- const next = combine(state, output);
1990
- if (!isEffect(next)) {
1991
- state = next;
1992
- return effect.succeed([next, delay]);
1993
- }
1994
- return effect.map(next, nextState => {
1995
- state = nextState;
1996
- return [nextState, delay];
1997
- });
1998
- },
1999
- onFailure: effect.failCause,
2000
- onDone(output) {
2001
- const next = combine(state, output);
2002
- return isEffect(next) ? effect.flatMap(next, Cause.done) : Cause.done(next);
2003
- }
2004
- });
2005
- })));
2006
1352
  /**
2007
1353
  * Returns a schedule that recurs continuously, each repetition spaced the
2008
1354
  * specified duration from the last run.
@@ -2033,14 +1379,15 @@ export const reduce = /*#__PURE__*/dual(3, (self, initial, combine) => fromStep(
2033
1379
  * return "Task completed"
2034
1380
  * }).pipe(
2035
1381
  * Effect.repeat(
2036
- * Schedule.spaced("1 second").pipe(Schedule.take(5))
1382
+ * Schedule.spaced("1 second").pipe(Schedule.upTo({ times: 5 }))
2037
1383
  * )
2038
1384
  * )
2039
1385
  *
2040
1386
  * // Simple spaced schedule with limited repetitions
2041
- * const limitedSpaced = Schedule.spaced("100 millis").pipe(
2042
- * Schedule.both(Schedule.recurs(5)) // at most 5 times
2043
- * )
1387
+ * const limitedSpaced = Schedule.max([
1388
+ * Schedule.spaced("100 millis"),
1389
+ * Schedule.recurs(5) // at most 5 times
1390
+ * ])
2044
1391
  *
2045
1392
  * const program = Effect.gen(function*() {
2046
1393
  * yield* Console.log("Starting spaced execution...")
@@ -2079,7 +1426,7 @@ export const spaced = duration => {
2079
1426
  * import { Console, Effect, Schedule } from "effect"
2080
1427
  *
2081
1428
  * const monitoredSchedule = Schedule.exponential("100 millis").pipe(
2082
- * Schedule.take(5),
1429
+ * Schedule.upTo({ times: 5 }),
2083
1430
  * Schedule.tap((metadata) =>
2084
1431
  * Console.log(
2085
1432
  * `Attempt ${metadata.attempt} produced ${metadata.output} ` +
@@ -2106,235 +1453,27 @@ export const tap = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(toStep(
2106
1453
  }));
2107
1454
  })));
2108
1455
  /**
2109
- * Returns a new `Schedule` that allows execution of an effectful function for
2110
- * every input to the schedule, but does not alter the inputs and outputs of
2111
- * the schedule.
2112
- *
2113
- * **Example** (Tapping retry inputs)
2114
- *
2115
- * ```ts
2116
- * import { Console, Data, Effect, Schedule } from "effect"
2117
- *
2118
- * class RetryError extends Data.TaggedError("RetryError")<{ readonly message: string }> {}
2119
- *
2120
- * // Log retry errors for debugging
2121
- * const errorLoggingSchedule = Schedule.exponential("100 millis").pipe(
2122
- * Schedule.take(3),
2123
- * Schedule.tapInput((error: RetryError) =>
2124
- * Console.log(`Retry triggered by error: ${String(error)}`)
2125
- * )
2126
- * )
2127
- *
2128
- * const retryProgram = Effect.gen(function*() {
2129
- * let attempt = 0
2130
- *
2131
- * const result = yield* Effect.retry(
2132
- * Effect.gen(function*() {
2133
- * attempt++
2134
- * if (attempt < 4) {
2135
- * return yield* Effect.fail(new RetryError({ message: `Network timeout on attempt ${attempt}` }))
2136
- * }
2137
- * return `Success on attempt ${attempt}`
2138
- * }),
2139
- * errorLoggingSchedule
2140
- * )
2141
- *
2142
- * yield* Console.log(`Final result: ${result}`)
2143
- * })
2144
- *
2145
- * // Monitor input frequency for metrics
2146
- * const inputMonitoringSchedule = Schedule.spaced("1 second").pipe(
2147
- * Schedule.take(5),
2148
- * Schedule.tapInput((input: unknown) =>
2149
- * Effect.gen(function*() {
2150
- * yield* Console.log(`Input type: ${typeof input}`)
2151
- * // In real applications, might send metrics to monitoring system
2152
- * })
2153
- * )
2154
- * )
2155
- *
2156
- * // Input validation with side effects
2157
- * const validatingSchedule = Schedule.fixed("500 millis").pipe(
2158
- * Schedule.take(4),
2159
- * Schedule.tapInput((input: any) =>
2160
- * Effect.gen(function*() {
2161
- * if (typeof input === "object" && input !== null) {
2162
- * yield* Console.log(`Valid object input: ${JSON.stringify(input)}`)
2163
- * } else {
2164
- * yield* Console.log(`Warning: Non-object input received: ${input}`)
2165
- * }
2166
- * })
2167
- * )
2168
- * )
2169
- *
2170
- * const validationProgram = Effect.gen(function*() {
2171
- * let count = 0
2172
- *
2173
- * yield* Effect.repeat(
2174
- * Effect.gen(function*() {
2175
- * count++
2176
- * yield* Console.log("Task with validation")
2177
- * return { data: `sample-${count}` }
2178
- * }),
2179
- * validatingSchedule
2180
- * )
2181
- * })
2182
- *
2183
- * // Conditional alerting based on input
2184
- * const alertingSchedule = Schedule.exponential("200 millis").pipe(
2185
- * Schedule.take(6),
2186
- * Schedule.tapInput((error: RetryError) =>
2187
- * Effect.gen(function*() {
2188
- * if (String(error).includes("critical")) {
2189
- * yield* Console.log(`Critical error: ${String(error)}`)
2190
- * // In real applications, might trigger alerts or notifications
2191
- * } else {
2192
- * yield* Console.log(`Regular error: ${String(error)}`)
2193
- * }
2194
- * })
2195
- * )
2196
- * )
2197
- *
2198
- * const alertProgram = Effect.gen(function*() {
2199
- * let attempt = 0
2200
- *
2201
- * yield* Effect.retry(
2202
- * Effect.gen(function*() {
2203
- * attempt++
2204
- * const isCritical = attempt === 3
2205
- * const errorType = isCritical
2206
- * ? "critical database failure"
2207
- * : "temporary network issue"
2208
- * return yield* Effect.fail(new RetryError({ message: errorType }))
2209
- * }),
2210
- * alertingSchedule
2211
- * ).pipe(
2212
- * Effect.catch((error: unknown) =>
2213
- * Console.log(`All retries exhausted: ${String(error)}`)
2214
- * )
2215
- * )
2216
- * })
2217
- *
2218
- * // Chain multiple input taps for different purposes
2219
- * const comprehensiveSchedule = Schedule.fibonacci("100 millis").pipe(
2220
- * Schedule.take(5),
2221
- * Schedule.tapInput((error: RetryError) =>
2222
- * Console.log(`Error occurred: ${error._tag}`)
2223
- * ),
2224
- * Schedule.tapInput((error: RetryError) =>
2225
- * String(error).length > 20
2226
- * ? Console.log("Long error message detected")
2227
- * : Effect.void
2228
- * )
2229
- * )
2230
- * ```
2231
- *
2232
- * @category sequencing
2233
- * @since 2.0.0
2234
- */
2235
- export const tapInput = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(toStep(self), step => (now, input) => effect.andThen(f(input), step(now, input)))));
2236
- /**
2237
- * Returns a new `Schedule` that allows execution of an effectful function for
2238
- * every output of the schedule, but does not alter the inputs and outputs of
2239
- * the schedule.
2240
- *
2241
- * **Example** (Tapping schedule outputs)
2242
- *
2243
- * ```ts
2244
- * import { Console, Data, Effect, Schedule } from "effect"
2245
- *
2246
- * class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
2247
- *
2248
- * // Log schedule outputs for debugging/monitoring
2249
- * const monitoredSchedule = Schedule.exponential("100 millis").pipe(
2250
- * Schedule.take(5),
2251
- * Schedule.tapOutput((delay) => Console.log(`Next delay will be: ${delay}`))
2252
- * )
2253
- *
2254
- * const retryProgram = Effect.gen(function*() {
2255
- * let attempt = 0
2256
- *
2257
- * const result = yield* Effect.retry(
2258
- * Effect.gen(function*() {
2259
- * attempt++
2260
- * if (attempt < 4) {
2261
- * return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
2262
- * }
2263
- * return `Success on attempt ${attempt}`
2264
- * }),
2265
- * monitoredSchedule
2266
- * )
2267
- *
2268
- * yield* Console.log(`Final result: ${result}`)
2269
- * })
2270
- *
2271
- * // Tap output for metrics collection
2272
- * const metricsSchedule = Schedule.spaced("1 second").pipe(
2273
- * Schedule.take(10),
2274
- * Schedule.tapOutput((executionCount) =>
2275
- * Effect.gen(function*() {
2276
- * // Simulate metrics collection
2277
- * yield* Console.log(`Recording metric: execution_count=${executionCount}`)
2278
- * // In real code, this might send to monitoring system
2279
- * })
2280
- * )
2281
- * )
2282
- *
2283
- * // Tap output with conditional side effects
2284
- * const alertingSchedule = Schedule.fibonacci("200 millis").pipe(
2285
- * Schedule.take(8),
2286
- * Schedule.tapOutput((delay) =>
2287
- * Effect.gen(function*() {
2288
- * const delayMs = delay.toString()
2289
- * if (delayMs.includes("1000")) { // Alert on delays >= 1 second
2290
- * yield* Console.log(`High delay detected: ${delay}`)
2291
- * }
2292
- * })
2293
- * )
2294
- * )
2295
- *
2296
- * const healthCheckProgram = Effect.gen(function*() {
2297
- * yield* Effect.repeat(
2298
- * Effect.gen(function*() {
2299
- * yield* Console.log("Performing health check...")
2300
- * return "healthy"
2301
- * }),
2302
- * alertingSchedule
2303
- * )
2304
- * })
2305
- *
2306
- * // Chain multiple taps for different purposes
2307
- * const comprehensiveSchedule = Schedule.fixed("500 millis").pipe(
2308
- * Schedule.take(6),
2309
- * Schedule.tapOutput((count) => Console.log(`Execution ${count + 1}`)),
2310
- * Schedule.tapOutput((count) =>
2311
- * count % 3 === 0
2312
- * ? Console.log("Checkpoint reached")
2313
- * : Effect.void
2314
- * )
2315
- * )
2316
- * ```
2317
- *
2318
- * @category sequencing
2319
- * @since 2.0.0
2320
- */
2321
- export const tapOutput = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(toStep(self), step => (now, input) => effect.tap(step(now, input), ([output]) => f(output)))));
2322
- /**
2323
- * Returns a new `Schedule` that takes at most the specified number of outputs
2324
- * from the schedule. Once the specified number of outputs is reached, the
2325
- * schedule will stop.
1456
+ * Returns a new `Schedule` that limits an existing schedule by elapsed
1457
+ * duration, number of outputs, or both.
2326
1458
  *
2327
1459
  * **When to use**
2328
1460
  *
2329
- * Use to limit an existing schedule while preserving its output and delay behavior.
1461
+ * Use to bound an existing schedule while preserving its output and delay
1462
+ * behavior. When both `duration` and `times` are specified, the schedule
1463
+ * stops as soon as either limit is reached.
2330
1464
  *
2331
1465
  * **Gotchas**
2332
1466
  *
2333
- * `take(n)` limits schedule outputs. When used with repeat or retry, the
2334
- * effect is evaluated once before the schedule is stepped, so the total number
2335
- * of evaluations can be one greater than the number of outputs taken.
1467
+ * The `times` option limits schedule outputs. When used with repeat or retry,
1468
+ * the effect is evaluated once before the schedule is stepped, so the total
1469
+ * number of evaluations can be one greater than the configured number of
1470
+ * outputs.
2336
1471
  *
2337
- * **Example** (Taking a limited number of recurrences)
1472
+ * The `duration` option is based on the elapsed time observed by the schedule
1473
+ * step. Long-running effects can cause the duration limit to be detected on the
1474
+ * following schedule step.
1475
+ *
1476
+ * **Example** (Limiting by duration and recurrence count)
2338
1477
  *
2339
1478
  * ```ts
2340
1479
  * import { Console, Data, Effect, Schedule } from "effect"
@@ -2343,7 +1482,7 @@ export const tapOutput = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(t
2343
1482
  *
2344
1483
  * // Limit an infinite schedule to five recurrences
2345
1484
  * const limitedHeartbeat = Schedule.spaced("1 second").pipe(
2346
- * Schedule.take(5) // Will stop after 5 schedule outputs
1485
+ * Schedule.upTo({ times: 5 })
2347
1486
  * )
2348
1487
  *
2349
1488
  * const heartbeatProgram = Effect.gen(function*() {
@@ -2358,9 +1497,12 @@ export const tapOutput = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(t
2358
1497
  * yield* Console.log("Heartbeat sequence completed")
2359
1498
  * })
2360
1499
  *
2361
- * // Limit retry attempts to a specific number
1500
+ * // Limit retry attempts by both count and elapsed time
2362
1501
  * const limitedRetry = Schedule.exponential("100 millis").pipe(
2363
- * Schedule.take(3) // At most 3 retry attempts
1502
+ * Schedule.upTo({
1503
+ * duration: "5 seconds",
1504
+ * times: 3
1505
+ * })
2364
1506
  * )
2365
1507
  *
2366
1508
  * const retryProgram = Effect.gen(function*() {
@@ -2387,138 +1529,22 @@ export const tapOutput = /*#__PURE__*/dual(2, (self, f) => fromStep(effect.map(t
2387
1529
  * )
2388
1530
  * )
2389
1531
  *
2390
- * // Combine take with other schedule operations
2391
- * const samplingSchedule = Schedule.fixed("500 millis").pipe(
2392
- * Schedule.take(10), // Take at most 10 schedule outputs
2393
- * Schedule.map((count) => Effect.succeed(`Sample #${count + 1}`))
1532
+ * // Empty options leave the schedule unchanged
1533
+ * const unchanged = Schedule.fixed("500 millis").pipe(
1534
+ * Schedule.upTo({})
2394
1535
  * )
2395
- *
2396
- * const samplingProgram = Effect.gen(function*() {
2397
- * yield* Effect.repeat(
2398
- * Effect.gen(function*() {
2399
- * const value = "sample"
2400
- * yield* Console.log(`Sampled value: ${value}`)
2401
- * return value
2402
- * }),
2403
- * samplingSchedule.pipe(
2404
- * Schedule.tapOutput((label) => Console.log(`Completed: ${label}`))
2405
- * )
2406
- * )
2407
- * })
2408
1536
  * ```
2409
1537
  *
2410
- * @see {@link recurs} for creating a count-limited schedule
2411
- *
2412
- * @category taking
1538
+ * @category filtering
2413
1539
  * @since 4.0.0
2414
1540
  */
2415
- export const take = /*#__PURE__*/dual(2, (self, n) => while_(self, ({
2416
- attempt
2417
- }) => effect.succeed(attempt <= n)));
2418
- /**
2419
- * Creates a schedule that unfolds a state by repeatedly applying a function,
2420
- * outputting the current state and computing the next state.
2421
- *
2422
- * **Example** (Unfolding schedule state)
2423
- *
2424
- * ```ts
2425
- * import { Console, Effect, Schedule } from "effect"
2426
- *
2427
- * // Counter schedule that increments by 1 each time
2428
- * const counterSchedule = Schedule.unfold(0, (n) => Effect.succeed(n + 1))
2429
- * // Outputs: 0, 1, 2, 3, 4, 5, ...
2430
- *
2431
- * const countingProgram = Effect.gen(function*() {
2432
- * yield* Effect.repeat(
2433
- * Effect.gen(function*() {
2434
- * yield* Console.log("Task executed")
2435
- * return "done"
2436
- * }),
2437
- * counterSchedule.pipe(
2438
- * Schedule.take(5),
2439
- * Schedule.tapOutput((count) => Console.log(`Count: ${count}`))
2440
- * )
2441
- * )
2442
- * })
2443
- *
2444
- * // Fibonacci sequence schedule
2445
- * const fibonacciSchedule = Schedule.unfold(
2446
- * [0, 1] as [number, number],
2447
- * ([a, b]) => Effect.succeed([b, a + b] as [number, number])
2448
- * )
2449
- * // Outputs: [0,1], [1,1], [1,2], [2,3], [3,5], [5,8], ...
2450
- *
2451
- * const fibProgram = Effect.gen(function*() {
2452
- * yield* Effect.repeat(
2453
- * Console.log("Fibonacci step"),
2454
- * fibonacciSchedule.pipe(
2455
- * Schedule.take(8),
2456
- * Schedule.tapOutput(([a, b]) => Console.log(`Fib: ${a}, next: ${b}`))
2457
- * )
2458
- * )
2459
- * })
2460
- *
2461
- * // Effectful unfold - exponential backoff with state
2462
- * const exponentialState = Schedule.unfold(
2463
- * 100,
2464
- * (delayMs) =>
2465
- * Effect.gen(function*() {
2466
- * yield* Console.log(`Current delay: ${delayMs}ms`)
2467
- * return Math.min(delayMs * 2, 5000) // Cap at 5 seconds
2468
- * })
2469
- * )
2470
- *
2471
- * // Deterministic delay adjustment schedule
2472
- * const adjustedDelaySchedule = Schedule.unfold(
2473
- * { delay: 1000, adjustment: 100 },
2474
- * ({ delay, adjustment }) =>
2475
- * Effect.gen(function*() {
2476
- * const nextDelay = Math.max(100, delay + adjustment)
2477
- * yield* Console.log(`Adjusted delay: ${nextDelay}ms`)
2478
- * return { delay: nextDelay, adjustment: adjustment * -1 }
2479
- * })
2480
- * )
2481
- *
2482
- * // State machine schedule
2483
- * type State = "init" | "warming" | "active" | "cooling"
2484
- * const stateMachineSchedule = Schedule.unfold("init" as State, (state) => {
2485
- * switch (state) {
2486
- * case "init":
2487
- * return Effect.succeed("warming" as State)
2488
- * case "warming":
2489
- * return Effect.succeed("active" as State)
2490
- * case "active":
2491
- * return Effect.succeed("cooling" as State)
2492
- * case "cooling":
2493
- * return Effect.succeed("active" as State)
2494
- * }
2495
- * })
2496
- *
2497
- * const stateMachineProgram = Effect.gen(function*() {
2498
- * yield* Effect.repeat(
2499
- * Effect.gen(function*() {
2500
- * yield* Console.log("State machine step")
2501
- * return "step"
2502
- * }),
2503
- * stateMachineSchedule.pipe(
2504
- * Schedule.take(10),
2505
- * Schedule.tapOutput((state) => Console.log(`State: ${state}`))
2506
- * )
2507
- * )
2508
- * })
2509
- * ```
2510
- *
2511
- * @category constructors
2512
- * @since 2.0.0
2513
- */
2514
- export const unfold = (initial, next) => fromStep(effect.sync(() => {
2515
- let state = initial;
2516
- return constant(effect.map(effect.suspend(() => next(state)), nextState => {
2517
- const prev = state;
2518
- state = nextState;
2519
- return [prev, Duration.zero];
2520
- }));
2521
- }));
1541
+ export const upTo = /*#__PURE__*/dual(2, (self, options) => {
1542
+ const duration = options.duration === undefined ? undefined : Duration.fromInputUnsafe(options.duration);
1543
+ return while_(self, ({
1544
+ attempt,
1545
+ elapsed
1546
+ }) => effect.succeed((options.times === undefined || attempt <= options.times) && (duration === undefined || Duration.isLessThanOrEqualTo(Duration.millis(elapsed), duration))));
1547
+ });
2522
1548
  const while_ = /*#__PURE__*/dual(2, (self, predicate) => fromStep(effect.map(toStep(self), step => {
2523
1549
  const meta = metadataFn();
2524
1550
  return (now, input) => effect.flatMap(step(now, input), result => {
@@ -2546,8 +1572,7 @@ export {
2546
1572
  * `Effect<boolean, ...>`, preserves the output and delay when it returns
2547
1573
  * `true`, and stops the schedule when it returns `false`.
2548
1574
  *
2549
- * @see {@link collectWhile} for collecting outputs while using the same predicate
2550
- * @see {@link take} for stopping after a fixed number of schedule outputs
1575
+ * @see {@link upTo} for stopping after a fixed number of schedule outputs
2551
1576
  *
2552
1577
  * @category filtering
2553
1578
  * @since 4.0.0
@@ -2582,7 +1607,7 @@ while_ as while };
2582
1607
  * yield* Console.log("Window task executed")
2583
1608
  * return "window-task"
2584
1609
  * }),
2585
- * windowSchedule.pipe(Schedule.take(4))
1610
+ * windowSchedule.pipe(Schedule.upTo({ times: 4 }))
2586
1611
  * )
2587
1612
  * })
2588
1613
  * ```
@@ -2616,7 +1641,7 @@ export const windowed = interval => {
2616
1641
  * yield* Console.log("Running forever...")
2617
1642
  * return "continuous-task"
2618
1643
  * }),
2619
- * infiniteSchedule.pipe(Schedule.take(5)) // Limit for demo
1644
+ * infiniteSchedule.pipe(Schedule.upTo({ times: 5 })) // Limit for demo
2620
1645
  * )
2621
1646
  * })
2622
1647
  * ```
@@ -2647,37 +1672,6 @@ export {
2647
1672
  * @since 2.0.0
2648
1673
  */
2649
1674
  identity_ as identity };
2650
- /**
2651
- * Ensures that a schedule's input type extends a given type `T`.
2652
- *
2653
- * **When to use**
2654
- *
2655
- * Use when you need a generic helper to prove that an existing schedule can
2656
- * consume a required input type without changing runtime behavior.
2657
- *
2658
- * **Example** (Constraining schedule input types)
2659
- *
2660
- * ```ts
2661
- * import { Schedule } from "effect"
2662
- *
2663
- * declare const StringInputSchedule: Schedule.Schedule<number, string>
2664
- * declare const NumberInputSchedule: Schedule.Schedule<number, number>
2665
- *
2666
- * const satisfiesStringInput = Schedule.satisfiesInputType<string>()
2667
- *
2668
- * // This works because the schedule input type is string.
2669
- * const validSchedule = satisfiesStringInput(StringInputSchedule)
2670
- *
2671
- * // This would cause a TypeScript compilation error:
2672
- * // const invalidSchedule = satisfiesStringInput(NumberInputSchedule)
2673
- * ```
2674
- *
2675
- * @see {@link setInputType} for adapting an input-agnostic schedule
2676
- *
2677
- * @category utility types
2678
- * @since 4.0.0
2679
- */
2680
- export const satisfiesInputType = () => self => self;
2681
1675
  /**
2682
1676
  * Sets the input type of the provided schedule without altering its behavior.
2683
1677
  *
@@ -2700,106 +1694,8 @@ export const satisfiesInputType = () => self => self;
2700
1694
  * )
2701
1695
  * ```
2702
1696
  *
2703
- * @see {@link satisfiesInputType} for checking an existing input type
2704
- *
2705
1697
  * @category utility types
2706
1698
  * @since 4.0.0
2707
1699
  */
2708
1700
  export const setInputType = () => self => self;
2709
- /**
2710
- * Ensures that a schedule's output type extends a given type `T`.
2711
- *
2712
- * **Details**
2713
- *
2714
- * This helper is checked at compile time and does not change the schedule's
2715
- * runtime behavior.
2716
- *
2717
- * **Example** (Constraining schedule output types)
2718
- *
2719
- * ```ts
2720
- * import { Schedule } from "effect"
2721
- *
2722
- * declare const StringOutputSchedule: Schedule.Schedule<string>
2723
- * declare const NumberOutputSchedule: Schedule.Schedule<number>
2724
- *
2725
- * const satisfiesStringOutput = Schedule.satisfiesOutputType<string>()
2726
- *
2727
- * // This works because the schedule output type is string.
2728
- * const validSchedule = satisfiesStringOutput(StringOutputSchedule)
2729
- *
2730
- * // This would cause a TypeScript compilation error:
2731
- * // const invalidSchedule = satisfiesStringOutput(NumberOutputSchedule)
2732
- * ```
2733
- *
2734
- * @category utility types
2735
- * @since 4.0.0
2736
- */
2737
- export const satisfiesOutputType = () => self => self;
2738
- /**
2739
- * Ensures that a schedule's error type extends a given type `T`.
2740
- *
2741
- * **Details**
2742
- *
2743
- * This helper is checked at compile time and does not change the schedule's
2744
- * runtime behavior.
2745
- *
2746
- * **Example** (Constraining schedule error types)
2747
- *
2748
- * ```ts
2749
- * import { Data, Schedule } from "effect"
2750
- *
2751
- * // Create a custom error using Data.TaggedError
2752
- * class CustomError extends Data.TaggedError("CustomError")<{
2753
- * message: string
2754
- * }> {}
2755
- *
2756
- * declare const CustomErrorSchedule: Schedule.Schedule<number, unknown, CustomError>
2757
- * declare const StringErrorSchedule: Schedule.Schedule<number, unknown, string>
2758
- *
2759
- * const satisfiesCustomError = Schedule.satisfiesErrorType<CustomError>()
2760
- *
2761
- * // This works because the schedule error type is CustomError.
2762
- * const validSchedule = satisfiesCustomError(CustomErrorSchedule)
2763
- *
2764
- * // This would cause a TypeScript compilation error:
2765
- * // const invalidSchedule = satisfiesCustomError(StringErrorSchedule)
2766
- * ```
2767
- *
2768
- * @category utility types
2769
- * @since 4.0.0
2770
- */
2771
- export const satisfiesErrorType = () => self => self;
2772
- /**
2773
- * Ensures that a schedule's context type extends a given type `T`.
2774
- *
2775
- * **Details**
2776
- *
2777
- * This helper is checked at compile time and does not change the schedule's
2778
- * runtime behavior.
2779
- *
2780
- * **Example** (Constraining schedule service types)
2781
- *
2782
- * ```ts
2783
- * import { Schedule } from "effect"
2784
- *
2785
- * interface Logger {
2786
- * readonly log: (message: string) => void
2787
- * }
2788
- *
2789
- * declare const LoggerSchedule: Schedule.Schedule<number, unknown, never, Logger>
2790
- * declare const NumberSchedule: Schedule.Schedule<number, unknown, never, number>
2791
- *
2792
- * const satisfiesLogger = Schedule.satisfiesServicesType<Logger>()
2793
- *
2794
- * // This works because the schedule context type is Logger.
2795
- * const validSchedule = satisfiesLogger(LoggerSchedule)
2796
- *
2797
- * // This would cause a TypeScript compilation error:
2798
- * // const invalidSchedule = satisfiesLogger(NumberSchedule)
2799
- * ```
2800
- *
2801
- * @category utility types
2802
- * @since 4.0.0
2803
- */
2804
- export const satisfiesServicesType = () => self => self;
2805
1701
  //# sourceMappingURL=Schedule.js.map