effect 3.7.2 → 3.8.0

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 (246) hide show
  1. package/Mailbox/package.json +6 -0
  2. package/dist/cjs/Deferred.js.map +1 -1
  3. package/dist/cjs/Duration.js +99 -35
  4. package/dist/cjs/Duration.js.map +1 -1
  5. package/dist/cjs/Effect.js +30 -3
  6. package/dist/cjs/Effect.js.map +1 -1
  7. package/dist/cjs/Fiber.js.map +1 -1
  8. package/dist/cjs/FiberRef.js.map +1 -1
  9. package/dist/cjs/Iterable.js +0 -1
  10. package/dist/cjs/Iterable.js.map +1 -1
  11. package/dist/cjs/List.js +0 -2
  12. package/dist/cjs/List.js.map +1 -1
  13. package/dist/cjs/Logger.js +29 -1
  14. package/dist/cjs/Logger.js.map +1 -1
  15. package/dist/cjs/Mailbox.js +95 -0
  16. package/dist/cjs/Mailbox.js.map +1 -0
  17. package/dist/cjs/Micro.js +1 -0
  18. package/dist/cjs/Micro.js.map +1 -1
  19. package/dist/cjs/MutableHashMap.js +13 -1
  20. package/dist/cjs/MutableHashMap.js.map +1 -1
  21. package/dist/cjs/Number.js +20 -1
  22. package/dist/cjs/Number.js.map +1 -1
  23. package/dist/cjs/Queue.js.map +1 -1
  24. package/dist/cjs/RcMap.js +6 -1
  25. package/dist/cjs/RcMap.js.map +1 -1
  26. package/dist/cjs/RcRef.js.map +1 -1
  27. package/dist/cjs/Ref.js.map +1 -1
  28. package/dist/cjs/Stream.js +11 -2
  29. package/dist/cjs/Stream.js.map +1 -1
  30. package/dist/cjs/SubscriptionRef.js.map +1 -1
  31. package/dist/cjs/SynchronizedRef.js.map +1 -1
  32. package/dist/cjs/TestClock.js +8 -2
  33. package/dist/cjs/TestClock.js.map +1 -1
  34. package/dist/cjs/index.js +4 -2
  35. package/dist/cjs/index.js.map +1 -1
  36. package/dist/cjs/internal/core.js +32 -25
  37. package/dist/cjs/internal/core.js.map +1 -1
  38. package/dist/cjs/internal/defaultServices/console.js.map +1 -1
  39. package/dist/cjs/internal/defaultServices.js +8 -5
  40. package/dist/cjs/internal/defaultServices.js.map +1 -1
  41. package/dist/cjs/internal/effect/circular.js +81 -8
  42. package/dist/cjs/internal/effect/circular.js.map +1 -1
  43. package/dist/cjs/internal/fiber.js +51 -26
  44. package/dist/cjs/internal/fiber.js.map +1 -1
  45. package/dist/cjs/internal/fiberRefs.js.map +1 -1
  46. package/dist/cjs/internal/fiberRuntime.js +126 -97
  47. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  48. package/dist/cjs/internal/groupBy.js +6 -1
  49. package/dist/cjs/internal/groupBy.js.map +1 -1
  50. package/dist/cjs/internal/hashMap/node.js +0 -1
  51. package/dist/cjs/internal/hashMap/node.js.map +1 -1
  52. package/dist/cjs/internal/hashMap.js +0 -1
  53. package/dist/cjs/internal/hashMap.js.map +1 -1
  54. package/dist/cjs/internal/layer.js +3 -3
  55. package/dist/cjs/internal/layer.js.map +1 -1
  56. package/dist/cjs/internal/logger.js +4 -1
  57. package/dist/cjs/internal/logger.js.map +1 -1
  58. package/dist/cjs/internal/mailbox.js +408 -0
  59. package/dist/cjs/internal/mailbox.js.map +1 -0
  60. package/dist/cjs/internal/managedRuntime.js +1 -1
  61. package/dist/cjs/internal/managedRuntime.js.map +1 -1
  62. package/dist/cjs/internal/pubsub.js +6 -1
  63. package/dist/cjs/internal/pubsub.js.map +1 -1
  64. package/dist/cjs/internal/queue.js +6 -1
  65. package/dist/cjs/internal/queue.js.map +1 -1
  66. package/dist/cjs/internal/rcMap.js +7 -1
  67. package/dist/cjs/internal/rcMap.js.map +1 -1
  68. package/dist/cjs/internal/rcRef.js +10 -6
  69. package/dist/cjs/internal/rcRef.js.map +1 -1
  70. package/dist/cjs/internal/ref.js +7 -7
  71. package/dist/cjs/internal/ref.js.map +1 -1
  72. package/dist/cjs/internal/runtime.js +1 -1
  73. package/dist/cjs/internal/runtime.js.map +1 -1
  74. package/dist/cjs/internal/stream.js +7 -2
  75. package/dist/cjs/internal/stream.js.map +1 -1
  76. package/dist/cjs/internal/subscriptionRef.js +7 -8
  77. package/dist/cjs/internal/subscriptionRef.js.map +1 -1
  78. package/dist/cjs/internal/version.js +1 -1
  79. package/dist/dts/Deferred.d.ts +21 -2
  80. package/dist/dts/Deferred.d.ts.map +1 -1
  81. package/dist/dts/Duration.d.ts +38 -1
  82. package/dist/dts/Duration.d.ts.map +1 -1
  83. package/dist/dts/Effect.d.ts +45 -0
  84. package/dist/dts/Effect.d.ts.map +1 -1
  85. package/dist/dts/Fiber.d.ts +69 -2
  86. package/dist/dts/Fiber.d.ts.map +1 -1
  87. package/dist/dts/FiberRef.d.ts +21 -2
  88. package/dist/dts/FiberRef.d.ts.map +1 -1
  89. package/dist/dts/List.d.ts.map +1 -1
  90. package/dist/dts/Logger.d.ts +28 -0
  91. package/dist/dts/Logger.d.ts.map +1 -1
  92. package/dist/dts/Mailbox.d.ts +220 -0
  93. package/dist/dts/Mailbox.d.ts.map +1 -0
  94. package/dist/dts/Micro.d.ts.map +1 -1
  95. package/dist/dts/MutableHashMap.d.ts +5 -0
  96. package/dist/dts/MutableHashMap.d.ts.map +1 -1
  97. package/dist/dts/Number.d.ts +19 -0
  98. package/dist/dts/Number.d.ts.map +1 -1
  99. package/dist/dts/Queue.d.ts +40 -1
  100. package/dist/dts/Queue.d.ts.map +1 -1
  101. package/dist/dts/RcMap.d.ts +5 -0
  102. package/dist/dts/RcMap.d.ts.map +1 -1
  103. package/dist/dts/RcRef.d.ts +22 -2
  104. package/dist/dts/RcRef.d.ts.map +1 -1
  105. package/dist/dts/Ref.d.ts +22 -2
  106. package/dist/dts/Ref.d.ts.map +1 -1
  107. package/dist/dts/ScheduleDecision.d.ts.map +1 -1
  108. package/dist/dts/Stream.d.ts +30 -0
  109. package/dist/dts/Stream.d.ts.map +1 -1
  110. package/dist/dts/SubscriptionRef.d.ts +20 -0
  111. package/dist/dts/SubscriptionRef.d.ts.map +1 -1
  112. package/dist/dts/SynchronizedRef.d.ts +20 -0
  113. package/dist/dts/SynchronizedRef.d.ts.map +1 -1
  114. package/dist/dts/TestClock.d.ts.map +1 -1
  115. package/dist/dts/index.d.ts +5 -0
  116. package/dist/dts/index.d.ts.map +1 -1
  117. package/dist/dts/internal/core.d.ts.map +1 -1
  118. package/dist/dts/internal/fiber.d.ts.map +1 -1
  119. package/dist/dts/internal/fiberRuntime.d.ts.map +1 -1
  120. package/dist/dts/internal/logger.d.ts.map +1 -1
  121. package/dist/dts/internal/mailbox.d.ts +2 -0
  122. package/dist/dts/internal/mailbox.d.ts.map +1 -0
  123. package/dist/dts/internal/stream.d.ts +22 -0
  124. package/dist/dts/internal/stream.d.ts.map +1 -1
  125. package/dist/esm/Deferred.js.map +1 -1
  126. package/dist/esm/Duration.js +92 -33
  127. package/dist/esm/Duration.js.map +1 -1
  128. package/dist/esm/Effect.js +27 -0
  129. package/dist/esm/Effect.js.map +1 -1
  130. package/dist/esm/Fiber.js.map +1 -1
  131. package/dist/esm/FiberRef.js.map +1 -1
  132. package/dist/esm/Iterable.js +0 -1
  133. package/dist/esm/Iterable.js.map +1 -1
  134. package/dist/esm/List.js +0 -2
  135. package/dist/esm/List.js.map +1 -1
  136. package/dist/esm/Logger.js +28 -0
  137. package/dist/esm/Logger.js.map +1 -1
  138. package/dist/esm/Mailbox.js +85 -0
  139. package/dist/esm/Mailbox.js.map +1 -0
  140. package/dist/esm/Micro.js +1 -0
  141. package/dist/esm/Micro.js.map +1 -1
  142. package/dist/esm/MutableHashMap.js +11 -0
  143. package/dist/esm/MutableHashMap.js.map +1 -1
  144. package/dist/esm/Number.js +19 -0
  145. package/dist/esm/Number.js.map +1 -1
  146. package/dist/esm/Queue.js.map +1 -1
  147. package/dist/esm/RcMap.js +5 -0
  148. package/dist/esm/RcMap.js.map +1 -1
  149. package/dist/esm/RcRef.js.map +1 -1
  150. package/dist/esm/Ref.js.map +1 -1
  151. package/dist/esm/Stream.js +9 -0
  152. package/dist/esm/Stream.js.map +1 -1
  153. package/dist/esm/SubscriptionRef.js.map +1 -1
  154. package/dist/esm/SynchronizedRef.js.map +1 -1
  155. package/dist/esm/TestClock.js +8 -2
  156. package/dist/esm/TestClock.js.map +1 -1
  157. package/dist/esm/index.js +5 -0
  158. package/dist/esm/index.js.map +1 -1
  159. package/dist/esm/internal/core.js +33 -26
  160. package/dist/esm/internal/core.js.map +1 -1
  161. package/dist/esm/internal/defaultServices/console.js.map +1 -1
  162. package/dist/esm/internal/defaultServices.js +6 -4
  163. package/dist/esm/internal/defaultServices.js.map +1 -1
  164. package/dist/esm/internal/effect/circular.js +77 -6
  165. package/dist/esm/internal/effect/circular.js.map +1 -1
  166. package/dist/esm/internal/fiber.js +51 -26
  167. package/dist/esm/internal/fiber.js.map +1 -1
  168. package/dist/esm/internal/fiberRefs.js.map +1 -1
  169. package/dist/esm/internal/fiberRuntime.js +124 -96
  170. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  171. package/dist/esm/internal/groupBy.js +6 -1
  172. package/dist/esm/internal/groupBy.js.map +1 -1
  173. package/dist/esm/internal/hashMap/node.js +0 -1
  174. package/dist/esm/internal/hashMap/node.js.map +1 -1
  175. package/dist/esm/internal/hashMap.js +0 -1
  176. package/dist/esm/internal/hashMap.js.map +1 -1
  177. package/dist/esm/internal/layer.js +3 -3
  178. package/dist/esm/internal/layer.js.map +1 -1
  179. package/dist/esm/internal/logger.js +3 -0
  180. package/dist/esm/internal/logger.js.map +1 -1
  181. package/dist/esm/internal/mailbox.js +395 -0
  182. package/dist/esm/internal/mailbox.js.map +1 -0
  183. package/dist/esm/internal/managedRuntime.js +1 -1
  184. package/dist/esm/internal/managedRuntime.js.map +1 -1
  185. package/dist/esm/internal/pubsub.js +6 -1
  186. package/dist/esm/internal/pubsub.js.map +1 -1
  187. package/dist/esm/internal/queue.js +6 -1
  188. package/dist/esm/internal/queue.js.map +1 -1
  189. package/dist/esm/internal/rcMap.js +5 -0
  190. package/dist/esm/internal/rcMap.js.map +1 -1
  191. package/dist/esm/internal/rcRef.js +10 -6
  192. package/dist/esm/internal/rcRef.js.map +1 -1
  193. package/dist/esm/internal/ref.js +7 -7
  194. package/dist/esm/internal/ref.js.map +1 -1
  195. package/dist/esm/internal/runtime.js +1 -1
  196. package/dist/esm/internal/runtime.js.map +1 -1
  197. package/dist/esm/internal/stream.js +5 -0
  198. package/dist/esm/internal/stream.js.map +1 -1
  199. package/dist/esm/internal/subscriptionRef.js +7 -8
  200. package/dist/esm/internal/subscriptionRef.js.map +1 -1
  201. package/dist/esm/internal/version.js +1 -1
  202. package/package.json +9 -1
  203. package/src/Deferred.ts +21 -2
  204. package/src/Duration.ts +112 -35
  205. package/src/Effect.ts +52 -0
  206. package/src/Fiber.ts +78 -2
  207. package/src/FiberRef.ts +21 -2
  208. package/src/Iterable.ts +1 -1
  209. package/src/List.ts +0 -2
  210. package/src/Logger.ts +30 -0
  211. package/src/Mailbox.ts +236 -0
  212. package/src/Micro.ts +1 -0
  213. package/src/MutableHashMap.ts +12 -0
  214. package/src/Number.ts +23 -0
  215. package/src/Queue.ts +42 -1
  216. package/src/RcMap.ts +6 -0
  217. package/src/RcRef.ts +24 -2
  218. package/src/Ref.ts +22 -2
  219. package/src/Stream.ts +36 -0
  220. package/src/SubscriptionRef.ts +22 -0
  221. package/src/SynchronizedRef.ts +20 -0
  222. package/src/TestClock.ts +10 -2
  223. package/src/index.ts +6 -0
  224. package/src/internal/core.ts +31 -28
  225. package/src/internal/defaultServices/console.ts +1 -0
  226. package/src/internal/defaultServices.ts +9 -10
  227. package/src/internal/effect/circular.ts +83 -6
  228. package/src/internal/fiber.ts +56 -29
  229. package/src/internal/fiberRefs.ts +1 -2
  230. package/src/internal/fiberRuntime.ts +134 -103
  231. package/src/internal/groupBy.ts +7 -1
  232. package/src/internal/hashMap/node.ts +1 -1
  233. package/src/internal/hashMap.ts +1 -1
  234. package/src/internal/layer.ts +3 -3
  235. package/src/internal/logger.ts +4 -0
  236. package/src/internal/mailbox.ts +461 -0
  237. package/src/internal/managedRuntime.ts +1 -1
  238. package/src/internal/pubsub.ts +9 -2
  239. package/src/internal/queue.ts +7 -1
  240. package/src/internal/rcMap.ts +8 -0
  241. package/src/internal/rcRef.ts +10 -6
  242. package/src/internal/ref.ts +7 -7
  243. package/src/internal/runtime.ts +1 -1
  244. package/src/internal/stream.ts +53 -0
  245. package/src/internal/subscriptionRef.ts +7 -8
  246. package/src/internal/version.ts +1 -1
package/src/Mailbox.ts ADDED
@@ -0,0 +1,236 @@
1
+ /**
2
+ * @since 3.8.0
3
+ * @experimental
4
+ */
5
+ import type { Cause, NoSuchElementException } from "./Cause.js"
6
+ import type { Channel } from "./Channel.js"
7
+ import type { Chunk } from "./Chunk.js"
8
+ import type { Effect } from "./Effect.js"
9
+ import type { Exit } from "./Exit.js"
10
+ import type { Inspectable } from "./Inspectable.js"
11
+ import * as internal from "./internal/mailbox.js"
12
+ import type { Option } from "./Option.js"
13
+ import { hasProperty } from "./Predicate.js"
14
+ import type { Stream } from "./Stream.js"
15
+
16
+ /**
17
+ * @since 3.8.0
18
+ * @experimental
19
+ * @category type ids
20
+ */
21
+ export const TypeId: unique symbol = internal.TypeId
22
+
23
+ /**
24
+ * @since 3.8.0
25
+ * @experimental
26
+ * @category type ids
27
+ */
28
+ export type TypeId = typeof TypeId
29
+
30
+ /**
31
+ * @since 3.8.0
32
+ * @experimental
33
+ * @category type ids
34
+ */
35
+ export const ReadonlyTypeId: unique symbol = internal.ReadonlyTypeId
36
+
37
+ /**
38
+ * @since 3.8.0
39
+ * @experimental
40
+ * @category type ids
41
+ */
42
+ export type ReadonlyTypeId = typeof ReadonlyTypeId
43
+
44
+ /**
45
+ * @since 3.8.0
46
+ * @experimental
47
+ * @category guards
48
+ */
49
+ export const isMailbox = <A = unknown, E = unknown>(u: unknown): u is Mailbox<A, E> => hasProperty(u, TypeId)
50
+
51
+ /**
52
+ * @since 3.8.0
53
+ * @experimental
54
+ * @category guards
55
+ */
56
+ export const isReadonlyMailbox = <A = unknown, E = unknown>(u: unknown): u is ReadonlyMailbox<A, E> =>
57
+ hasProperty(u, ReadonlyTypeId)
58
+
59
+ /**
60
+ * A `Mailbox` is a queue that can be signaled to be done or failed.
61
+ *
62
+ * @since 3.8.0
63
+ * @experimental
64
+ * @category models
65
+ */
66
+ export interface Mailbox<in out A, in out E = never> extends ReadonlyMailbox<A, E> {
67
+ readonly [TypeId]: TypeId
68
+ /**
69
+ * Add a message to the mailbox. Returns `false` if the mailbox is done.
70
+ */
71
+ readonly offer: (message: A) => Effect<boolean>
72
+ /**
73
+ * Add a message to the mailbox. Returns `false` if the mailbox is done.
74
+ */
75
+ readonly unsafeOffer: (message: A) => boolean
76
+ /**
77
+ * Add multiple messages to the mailbox. Returns the remaining messages that
78
+ * were not added.
79
+ */
80
+ readonly offerAll: (messages: Iterable<A>) => Effect<Chunk<A>>
81
+ /**
82
+ * Add multiple messages to the mailbox. Returns the remaining messages that
83
+ * were not added.
84
+ */
85
+ readonly unsafeOfferAll: (messages: Iterable<A>) => Chunk<A>
86
+ /**
87
+ * Fail the mailbox with an error. If the mailbox is already done, `false` is
88
+ * returned.
89
+ */
90
+ readonly fail: (error: E) => Effect<boolean>
91
+ /**
92
+ * Fail the mailbox with a cause. If the mailbox is already done, `false` is
93
+ * returned.
94
+ */
95
+ readonly failCause: (cause: Cause<E>) => Effect<boolean>
96
+ /**
97
+ * Signal that the mailbox is complete. If the mailbox is already done, `false` is
98
+ * returned.
99
+ */
100
+ readonly end: Effect<boolean>
101
+ /**
102
+ * Signal that the mailbox is done. If the mailbox is already done, `false` is
103
+ * returned.
104
+ */
105
+ readonly done: (exit: Exit<void, E>) => Effect<boolean>
106
+ /**
107
+ * Signal that the mailbox is done. If the mailbox is already done, `false` is
108
+ * returned.
109
+ */
110
+ readonly unsafeDone: (exit: Exit<void, E>) => boolean
111
+ /**
112
+ * Shutdown the mailbox, canceling any pending operations.
113
+ * If the mailbox is already done, `false` is returned.
114
+ */
115
+ readonly shutdown: Effect<boolean>
116
+ }
117
+
118
+ /**
119
+ * A `ReadonlyMailbox` represents a mailbox that can only be read from.
120
+ *
121
+ * @since 3.8.0
122
+ * @experimental
123
+ * @category models
124
+ */
125
+ export interface ReadonlyMailbox<out A, out E = never>
126
+ extends Effect<readonly [messages: Chunk<A>, done: boolean], E>, Inspectable
127
+ {
128
+ readonly [ReadonlyTypeId]: ReadonlyTypeId
129
+ /**
130
+ * Take all messages from the mailbox, returning an empty Chunk if the mailbox
131
+ * is empty or done.
132
+ */
133
+ readonly clear: Effect<Chunk<A>, E>
134
+ /**
135
+ * Take all messages from the mailbox, or wait for messages to be available.
136
+ *
137
+ * If the mailbox is done, the `done` flag will be `true`. If the mailbox
138
+ * fails, the Effect will fail with the error.
139
+ */
140
+ readonly takeAll: Effect<readonly [messages: Chunk<A>, done: boolean], E>
141
+ /**
142
+ * Take a specified number of messages from the mailbox. It will only take
143
+ * up to the capacity of the mailbox.
144
+ *
145
+ * If the mailbox is done, the `done` flag will be `true`. If the mailbox
146
+ * fails, the Effect will fail with the error.
147
+ */
148
+ readonly takeN: (n: number) => Effect<readonly [messages: Chunk<A>, done: boolean], E>
149
+ /**
150
+ * Take a single message from the mailbox, or wait for a message to be
151
+ * available.
152
+ *
153
+ * If the mailbox is done, it will fail with `NoSuchElementException`. If the
154
+ * mailbox fails, the Effect will fail with the error.
155
+ */
156
+ readonly take: Effect<A, E | NoSuchElementException>
157
+ /** Wait for the mailbox to be done. */
158
+ readonly await: Effect<void, E>
159
+ /**
160
+ * Check the size of the mailbox.
161
+ *
162
+ * If the mailbox is complete, it will return `None`.
163
+ */
164
+ readonly size: Effect<Option<number>>
165
+ /**
166
+ * Check the size of the mailbox.
167
+ *
168
+ * If the mailbox is complete, it will return `None`.
169
+ */
170
+ readonly unsafeSize: () => Option<number>
171
+ }
172
+
173
+ /**
174
+ * A `Mailbox` is a queue that can be signaled to be done or failed.
175
+ *
176
+ * @since 3.8.0
177
+ * @experimental
178
+ * @category constructors
179
+ * @example
180
+ * import { Effect, Mailbox } from "effect"
181
+ *
182
+ * Effect.gen(function*() {
183
+ * const mailbox = yield* Mailbox.make<number, string>()
184
+ *
185
+ * // add messages to the mailbox
186
+ * yield* mailbox.offer(1)
187
+ * yield* mailbox.offer(2)
188
+ * yield* mailbox.offerAll([3, 4, 5])
189
+ *
190
+ * // take messages from the mailbox
191
+ * const [messages, done] = yield* mailbox.takeAll
192
+ * assert.deepStrictEqual(messages, [1, 2, 3, 4, 5])
193
+ * assert.strictEqual(done, false)
194
+ *
195
+ * // signal that the mailbox is done
196
+ * yield* mailbox.end
197
+ * const [messages2, done2] = yield* mailbox.takeAll
198
+ * assert.deepStrictEqual(messages2, [])
199
+ * assert.strictEqual(done2, true)
200
+ *
201
+ * // signal that the mailbox has failed
202
+ * yield* mailbox.fail("boom")
203
+ * })
204
+ */
205
+ export const make: <A, E = never>(capacity?: number | undefined) => Effect<Mailbox<A, E>> = internal.make
206
+
207
+ /**
208
+ * Run an `Effect` into a `Mailbox`, where success ends the mailbox and failure
209
+ * fails the mailbox.
210
+ *
211
+ * @since 3.8.0
212
+ * @experimental
213
+ * @category combinators
214
+ */
215
+ export const into: {
216
+ <A, E>(self: Mailbox<A, E>): <AX, EX extends E, RX>(effect: Effect<AX, EX, RX>) => Effect<boolean, never, RX>
217
+ <AX, E, EX extends E, RX, A>(effect: Effect<AX, EX, RX>, self: Mailbox<A, E>): Effect<boolean, never, RX>
218
+ } = internal.into
219
+
220
+ /**
221
+ * Create a `Channel` from a `Mailbox`.
222
+ *
223
+ * @since 3.8.0
224
+ * @experimental
225
+ * @category conversions
226
+ */
227
+ export const toChannel: <A, E>(self: ReadonlyMailbox<A, E>) => Channel<Chunk<A>, unknown, E> = internal.toChannel
228
+
229
+ /**
230
+ * Create a `Stream` from a `Mailbox`.
231
+ *
232
+ * @since 3.8.0
233
+ * @experimental
234
+ * @category conversions
235
+ */
236
+ export const toStream: <A, E>(self: ReadonlyMailbox<A, E>) => Stream<A, E> = internal.toStream
package/src/Micro.ts CHANGED
@@ -2497,6 +2497,7 @@ export const ignore = <A, E, R>(self: Micro<A, E, R>): Micro<void, never, R> =>
2497
2497
  */
2498
2498
  export const ignoreLogged = <A, E, R>(self: Micro<A, E, R>): Micro<void, never, R> =>
2499
2499
  matchEffect(self, {
2500
+ // eslint-disable-next-line no-console
2500
2501
  onFailure: (error) => sync(() => console.error(error)),
2501
2502
  onSuccess: (_) => void_
2502
2503
  })
@@ -159,6 +159,18 @@ export const get: {
159
159
  return getFromBucket(self, bucket, key)
160
160
  })
161
161
 
162
+ /**
163
+ * @since 3.8.0
164
+ * @category elements
165
+ */
166
+ export const keys = <K, V>(self: MutableHashMap<K, V>): Array<K> => {
167
+ const keys: Array<K> = []
168
+ for (const [key] of self) {
169
+ keys.push(key)
170
+ }
171
+ return keys
172
+ }
173
+
162
174
  const getFromBucket = <K, V>(
163
175
  self: MutableHashMap<K, V>,
164
176
  bucket: NonEmptyArray<readonly [K & Equal.Equal, V]>,
package/src/Number.ts CHANGED
@@ -492,3 +492,26 @@ export const parse = (s: string): Option<number> => {
492
492
  ? option.none
493
493
  : option.some(n)
494
494
  }
495
+
496
+ /**
497
+ * Returns the number rounded with the given precision.
498
+ *
499
+ * @param self - The number to round
500
+ * @param precision - The precision
501
+ *
502
+ * @example
503
+ * import { round } from "effect/Number"
504
+ *
505
+ * assert.deepStrictEqual(round(1.1234, 2), 1.12)
506
+ * assert.deepStrictEqual(round(1.567, 2), 1.57)
507
+ *
508
+ * @category math
509
+ * @since 3.8.0
510
+ */
511
+ export const round: {
512
+ (precision: number): (self: number) => number
513
+ (self: number, precision: number): number
514
+ } = dual(2, (self: number, precision: number): number => {
515
+ const factor = Math.pow(10, precision)
516
+ return Math.round(self * factor) / factor
517
+ })
package/src/Queue.ts CHANGED
@@ -10,6 +10,7 @@ import type * as MutableRef from "./MutableRef.js"
10
10
  import type * as Option from "./Option.js"
11
11
  import type { Pipeable } from "./Pipeable.js"
12
12
  import type * as Types from "./Types.js"
13
+ import type * as Unify from "./Unify.js"
13
14
 
14
15
  /**
15
16
  * @since 2.0.0
@@ -74,6 +75,26 @@ export interface Queue<in out A> extends Enqueue<A>, Dequeue<A>, Pipeable {
74
75
  readonly shutdownFlag: MutableRef.MutableRef<boolean>
75
76
  /** @internal */
76
77
  readonly strategy: Strategy<A>
78
+
79
+ readonly [Unify.typeSymbol]?: unknown
80
+ readonly [Unify.unifySymbol]?: QueueUnify<this>
81
+ readonly [Unify.ignoreSymbol]?: QueueUnifyIgnore
82
+ }
83
+
84
+ /**
85
+ * @category models
86
+ * @since 3.8.0
87
+ */
88
+ export interface QueueUnify<A extends { [Unify.typeSymbol]?: any }> extends DequeueUnify<A> {
89
+ Queue?: () => Extract<A[Unify.typeSymbol], Queue<any>>
90
+ }
91
+
92
+ /**
93
+ * @category models
94
+ * @since 3.8.0
95
+ */
96
+ export interface QueueUnifyIgnore extends DequeueUnifyIgnore {
97
+ Dequeue?: true
77
98
  }
78
99
 
79
100
  /**
@@ -113,7 +134,7 @@ export interface Enqueue<in A> extends Queue.EnqueueVariance<A>, BaseQueue, Pipe
113
134
  * @since 2.0.0
114
135
  * @category models
115
136
  */
116
- export interface Dequeue<out A> extends Queue.DequeueVariance<A>, BaseQueue, Pipeable {
137
+ export interface Dequeue<out A> extends Effect.Effect<A>, Queue.DequeueVariance<A>, BaseQueue, Pipeable {
117
138
  /**
118
139
  * Takes the oldest value in the queue. If the queue is empty, this will return
119
140
  * a computation that resumes when an item has been added to the queue.
@@ -137,6 +158,26 @@ export interface Dequeue<out A> extends Queue.DequeueVariance<A>, BaseQueue, Pip
137
158
  * suspends until at least the minimum number of elements have been collected.
138
159
  */
139
160
  takeBetween(min: number, max: number): Effect.Effect<Chunk.Chunk<A>>
161
+
162
+ readonly [Unify.typeSymbol]?: unknown
163
+ readonly [Unify.unifySymbol]?: DequeueUnify<this>
164
+ readonly [Unify.ignoreSymbol]?: DequeueUnifyIgnore
165
+ }
166
+
167
+ /**
168
+ * @category models
169
+ * @since 3.8.0
170
+ */
171
+ export interface DequeueUnify<A extends { [Unify.typeSymbol]?: any }> extends Effect.EffectUnify<A> {
172
+ Dequeue?: () => A[Unify.typeSymbol] extends Dequeue<infer A0> | infer _ ? Dequeue<A0> : never
173
+ }
174
+
175
+ /**
176
+ * @category models
177
+ * @since 3.8.0
178
+ */
179
+ export interface DequeueUnifyIgnore extends Effect.EffectUnifyIgnore {
180
+ Effect?: true
140
181
  }
141
182
 
142
183
  /**
package/src/RcMap.ts CHANGED
@@ -101,3 +101,9 @@ export const get: {
101
101
  <K>(key: K): <A, E>(self: RcMap<K, A, E>) => Effect.Effect<A, E, Scope.Scope>
102
102
  <K, A, E>(self: RcMap<K, A, E>, key: K): Effect.Effect<A, E, Scope.Scope>
103
103
  } = internal.get
104
+
105
+ /**
106
+ * @since 3.8.0
107
+ * @category combinators
108
+ */
109
+ export const keys: <K, A, E>(self: RcMap<K, A, E>) => Effect.Effect<Array<K>, E> = internal.keys
package/src/RcRef.ts CHANGED
@@ -4,9 +4,10 @@
4
4
  import type * as Duration from "./Duration.js"
5
5
  import type * as Effect from "./Effect.js"
6
6
  import * as internal from "./internal/rcRef.js"
7
- import { type Pipeable } from "./Pipeable.js"
7
+ import type * as Readable from "./Readable.js"
8
8
  import type * as Scope from "./Scope.js"
9
9
  import type * as Types from "./Types.js"
10
+ import type * as Unify from "./Unify.js"
10
11
 
11
12
  /**
12
13
  * @since 3.5.0
@@ -24,10 +25,31 @@ export type TypeId = typeof TypeId
24
25
  * @since 3.5.0
25
26
  * @category models
26
27
  */
27
- export interface RcRef<out A, out E = never> extends Pipeable {
28
+ export interface RcRef<out A, out E = never>
29
+ extends Effect.Effect<A, E, Scope.Scope>, Readable.Readable<A, E, Scope.Scope>
30
+ {
28
31
  readonly [TypeId]: RcRef.Variance<A, E>
32
+ readonly [Unify.typeSymbol]?: unknown
33
+ readonly [Unify.unifySymbol]?: RcRefUnify<this>
34
+ readonly [Unify.ignoreSymbol]?: RcRefUnifyIgnore
29
35
  }
30
36
 
37
+ /**
38
+ * @category models
39
+ * @since 3.8.0
40
+ */
41
+ export interface RcRefUnify<A extends { [Unify.typeSymbol]?: any }> extends Effect.EffectUnify<A> {
42
+ RcRef?: () => A[Unify.typeSymbol] extends RcRef<infer A0, infer E0> | infer _ ? RcRef<A0, E0>
43
+ : never
44
+ }
45
+
46
+ /**
47
+ * @category models
48
+ * @since 3.8.0
49
+ */
50
+ export interface RcRefUnifyIgnore extends Effect.EffectUnifyIgnore {
51
+ Effect?: true
52
+ }
31
53
  /**
32
54
  * @since 3.5.0
33
55
  * @category models
package/src/Ref.ts CHANGED
@@ -4,8 +4,9 @@
4
4
  import type * as Effect from "./Effect.js"
5
5
  import * as internal from "./internal/ref.js"
6
6
  import type * as Option from "./Option.js"
7
- import type { Readable } from "./Readable.js"
7
+ import type * as Readable from "./Readable.js"
8
8
  import type * as Types from "./Types.js"
9
+ import type * as Unify from "./Unify.js"
9
10
 
10
11
  /**
11
12
  * @since 2.0.0
@@ -23,8 +24,27 @@ export type RefTypeId = typeof RefTypeId
23
24
  * @since 2.0.0
24
25
  * @category models
25
26
  */
26
- export interface Ref<in out A> extends Ref.Variance<A>, Readable<A> {
27
+ export interface Ref<in out A> extends Ref.Variance<A>, Effect.Effect<A>, Readable.Readable<A> {
27
28
  modify<B>(f: (a: A) => readonly [B, A]): Effect.Effect<B>
29
+ readonly [Unify.typeSymbol]?: unknown
30
+ readonly [Unify.unifySymbol]?: RefUnify<this>
31
+ readonly [Unify.ignoreSymbol]?: RefUnifyIgnore
32
+ }
33
+
34
+ /**
35
+ * @category models
36
+ * @since 3.8.0
37
+ */
38
+ export interface RefUnify<A extends { [Unify.typeSymbol]?: any }> extends Effect.EffectUnify<A> {
39
+ Ref?: () => Extract<A[Unify.typeSymbol], Ref<any>>
40
+ }
41
+
42
+ /**
43
+ * @category models
44
+ * @since 3.8.0
45
+ */
46
+ export interface RefUnifyIgnore extends Effect.EffectUnifyIgnore {
47
+ Effect?: true
28
48
  }
29
49
 
30
50
  /**
package/src/Stream.ts CHANGED
@@ -549,6 +549,42 @@ export const broadcast: {
549
549
  ): Effect.Effect<TupleOf<N, Stream<A, E>>, never, Scope.Scope | R>
550
550
  } = internal.broadcast
551
551
 
552
+ /**
553
+ * Returns a new Stream that multicasts the original Stream, subscribing to it as soon as the first consumer subscribes.
554
+ * As long as there is at least one consumer, the upstream will continue running and emitting data.
555
+ * When all consumers have exited, the upstream will be finalized.
556
+ *
557
+ * @since 3.8.0
558
+ * @category utils
559
+ */
560
+ export const share: {
561
+ <A, E>(
562
+ config: {
563
+ readonly capacity: "unbounded"
564
+ readonly replay?: number | undefined
565
+ readonly idleTimeToLive?: Duration.DurationInput | undefined
566
+ } | {
567
+ readonly capacity: number
568
+ readonly strategy?: "sliding" | "dropping" | "suspend" | undefined
569
+ readonly replay?: number | undefined
570
+ readonly idleTimeToLive?: Duration.DurationInput | undefined
571
+ }
572
+ ): <R>(self: Stream<A, E, R>) => Effect.Effect<Stream<A, E>, never, R | Scope.Scope>
573
+ <A, E, R>(
574
+ self: Stream<A, E, R>,
575
+ config: {
576
+ readonly capacity: "unbounded"
577
+ readonly replay?: number | undefined
578
+ readonly idleTimeToLive?: Duration.DurationInput | undefined
579
+ } | {
580
+ readonly capacity: number
581
+ readonly strategy?: "sliding" | "dropping" | "suspend" | undefined
582
+ readonly replay?: number | undefined
583
+ readonly idleTimeToLive?: Duration.DurationInput | undefined
584
+ }
585
+ ): Effect.Effect<Stream<A, E>, never, R | Scope.Scope>
586
+ } = internal.share
587
+
552
588
  /**
553
589
  * Fan out the stream, producing a dynamic number of streams that have the
554
590
  * same elements as this stream. The driver stream will only ever advance the
@@ -10,6 +10,7 @@ import type * as Stream from "./Stream.js"
10
10
  import type { Subscribable } from "./Subscribable.js"
11
11
  import * as Synchronized from "./SynchronizedRef.js"
12
12
  import type * as Types from "./Types.js"
13
+ import type * as Unify from "./Unify.js"
13
14
 
14
15
  /**
15
16
  * @since 2.0.0
@@ -44,6 +45,27 @@ export interface SubscriptionRef<in out A>
44
45
  * to that value.
45
46
  */
46
47
  readonly changes: Stream.Stream<A>
48
+ readonly [Unify.typeSymbol]?: unknown
49
+ readonly [Unify.unifySymbol]?: SubscriptionRefUnify<this>
50
+ readonly [Unify.ignoreSymbol]?: SubscriptionRefUnifyIgnore
51
+ }
52
+
53
+ /**
54
+ * @category models
55
+ * @since 3.8.0
56
+ */
57
+ export interface SubscriptionRefUnify<A extends { [Unify.typeSymbol]?: any }>
58
+ extends Synchronized.SynchronizedRefUnify<A>
59
+ {
60
+ SubscriptionRef?: () => Extract<A[Unify.typeSymbol], SubscriptionRef<any>>
61
+ }
62
+
63
+ /**
64
+ * @category models
65
+ * @since 3.8.0
66
+ */
67
+ export interface SubscriptionRefUnifyIgnore extends Synchronized.SynchronizedRefUnifyIgnore {
68
+ SynchronizedRef?: true
47
69
  }
48
70
 
49
71
  /**
@@ -8,6 +8,7 @@ import * as internal from "./internal/synchronizedRef.js"
8
8
  import type * as Option from "./Option.js"
9
9
  import type * as Ref from "./Ref.js"
10
10
  import type * as Types from "./Types.js"
11
+ import type * as Unify from "./Unify.js"
11
12
 
12
13
  /**
13
14
  * @since 2.0.0
@@ -27,6 +28,25 @@ export type SynchronizedRefTypeId = typeof SynchronizedRefTypeId
27
28
  */
28
29
  export interface SynchronizedRef<in out A> extends SynchronizedRef.Variance<A>, Ref.Ref<A> {
29
30
  modifyEffect<B, E, R>(f: (a: A) => Effect.Effect<readonly [B, A], E, R>): Effect.Effect<B, E, R>
31
+ readonly [Unify.typeSymbol]?: unknown
32
+ readonly [Unify.unifySymbol]?: SynchronizedRefUnify<this>
33
+ readonly [Unify.ignoreSymbol]?: SynchronizedRefUnifyIgnore
34
+ }
35
+
36
+ /**
37
+ * @category models
38
+ * @since 3.8.0
39
+ */
40
+ export interface SynchronizedRefUnify<A extends { [Unify.typeSymbol]?: any }> extends Ref.RefUnify<A> {
41
+ SynchronizedRef?: () => Extract<A[Unify.typeSymbol], SynchronizedRef<any>>
42
+ }
43
+
44
+ /**
45
+ * @category models
46
+ * @since 3.8.0
47
+ */
48
+ export interface SynchronizedRefUnifyIgnore extends Ref.RefUnifyIgnore {
49
+ Ref?: true
30
50
  }
31
51
 
32
52
  /**
package/src/TestClock.ts CHANGED
@@ -304,13 +304,21 @@ export class TestClockImpl implements TestClock {
304
304
  return Option.none()
305
305
  })
306
306
  }
307
+
308
+ private yieldTimer = core.async<void>((resume) => {
309
+ const timer = setTimeout(() => {
310
+ resume(core.void)
311
+ }, 0)
312
+ return core.sync(() => clearTimeout(timer))
313
+ })
314
+
307
315
  /**
308
316
  * Returns whether all descendants of this fiber are done or suspended.
309
317
  */
310
318
  suspended(): Effect.Effect<HashMap.HashMap<FiberId.FiberId, FiberStatus.FiberStatus>, void> {
311
319
  return pipe(
312
320
  this.freeze(),
313
- core.zip(this.live.provide(pipe(effect.sleep(Duration.millis(5)), core.zipRight(this.freeze())))),
321
+ core.zip(pipe(this.yieldTimer, core.zipRight(this.freeze()))),
314
322
  core.flatMap(([first, last]) =>
315
323
  Equal.equals(first, last) ?
316
324
  core.succeed(first) :
@@ -328,7 +336,7 @@ export class TestClockImpl implements TestClock {
328
336
  pipe(
329
337
  this.suspended(),
330
338
  core.zipWith(
331
- pipe(this.live.provide(effect.sleep(Duration.millis(10))), core.zipRight(this.suspended())),
339
+ pipe(this.yieldTimer, core.zipRight(this.suspended())),
332
340
  Equal.equals
333
341
  ),
334
342
  effect.filterOrFail(identity, constVoid),
package/src/index.ts CHANGED
@@ -409,6 +409,12 @@ export * as LogSpan from "./LogSpan.js"
409
409
  */
410
410
  export * as Logger from "./Logger.js"
411
411
 
412
+ /**
413
+ * @since 3.8.0
414
+ * @experimental
415
+ */
416
+ export * as Mailbox from "./Mailbox.js"
417
+
412
418
  /**
413
419
  * @since 2.0.0
414
420
  */