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
@@ -0,0 +1,461 @@
1
+ import * as Arr from "../Array.js"
2
+ import type { Cause } from "../Cause.js"
3
+ import { NoSuchElementException } from "../Cause.js"
4
+ import type { Channel } from "../Channel.js"
5
+ import * as Chunk from "../Chunk.js"
6
+ import type { Effect } from "../Effect.js"
7
+ import * as Effectable from "../Effectable.js"
8
+ import type { Exit } from "../Exit.js"
9
+ import { dual } from "../Function.js"
10
+ import * as Inspectable from "../Inspectable.js"
11
+ import * as Iterable from "../Iterable.js"
12
+ import type * as Api from "../Mailbox.js"
13
+ import * as Option from "../Option.js"
14
+ import { pipeArguments } from "../Pipeable.js"
15
+ import { hasProperty } from "../Predicate.js"
16
+ import type { Scheduler } from "../Scheduler.js"
17
+ import type { Stream } from "../Stream.js"
18
+ import * as channel from "./channel.js"
19
+ import * as coreChannel from "./core-stream.js"
20
+ import * as core from "./core.js"
21
+ import * as stream from "./stream.js"
22
+
23
+ /** @internal */
24
+ export const TypeId: Api.TypeId = Symbol.for("effect/Mailbox") as Api.TypeId
25
+
26
+ /** @internal */
27
+ export const ReadonlyTypeId: Api.ReadonlyTypeId = Symbol.for("effect/Mailbox/ReadonlyMailbox") as Api.ReadonlyTypeId
28
+
29
+ /** @internal */
30
+ export const isMailbox = (u: unknown): u is Api.Mailbox<unknown, unknown> => hasProperty(u, TypeId)
31
+
32
+ /** @internal */
33
+ export const isReadonlyMailbox = (u: unknown): u is Api.ReadonlyMailbox<unknown, unknown> =>
34
+ hasProperty(u, ReadonlyTypeId)
35
+
36
+ type MailboxState<A, E> = {
37
+ readonly _tag: "Open"
38
+ readonly takers: Set<(_: Effect<void, E>) => void>
39
+ readonly offers: Set<OfferEntry<A>>
40
+ readonly awaiters: Set<(_: Effect<void, E>) => void>
41
+ } | {
42
+ readonly _tag: "Closing"
43
+ readonly takers: Set<(_: Effect<void, E>) => void>
44
+ readonly offers: Set<OfferEntry<A>>
45
+ readonly awaiters: Set<(_: Effect<void, E>) => void>
46
+ readonly exit: Exit<void, E>
47
+ } | {
48
+ readonly _tag: "Done"
49
+ readonly exit: Exit<void, E>
50
+ }
51
+
52
+ type OfferEntry<A> = {
53
+ readonly _tag: "Array"
54
+ readonly remaining: Array<A>
55
+ offset: number
56
+ readonly resume: (_: Effect<Chunk.Chunk<A>>) => void
57
+ } | {
58
+ readonly _tag: "Single"
59
+ readonly message: A
60
+ readonly resume: (_: Effect<boolean>) => void
61
+ }
62
+
63
+ const empty = Chunk.empty()
64
+ const exitEmpty = core.exitSucceed(empty)
65
+ const exitFalse = core.exitSucceed(false)
66
+ const exitTrue = core.exitSucceed(true)
67
+ const constDone = [empty, true] as const
68
+
69
+ class MailboxImpl<A, E> extends Effectable.Class<readonly [messages: Chunk.Chunk<A>, done: boolean], E>
70
+ implements Api.Mailbox<A, E>
71
+ {
72
+ readonly [TypeId]: Api.TypeId = TypeId
73
+ readonly [ReadonlyTypeId]: Api.ReadonlyTypeId = ReadonlyTypeId
74
+ private state: MailboxState<A, E> = {
75
+ _tag: "Open",
76
+ takers: new Set(),
77
+ offers: new Set(),
78
+ awaiters: new Set()
79
+ }
80
+ private messages: Array<A> = []
81
+ private messagesChunk = Chunk.empty<A>()
82
+ constructor(
83
+ readonly scheduler: Scheduler,
84
+ readonly capacity: number
85
+ ) {
86
+ super()
87
+ }
88
+
89
+ offer(message: A): Effect<boolean> {
90
+ return core.suspend(() => {
91
+ if (this.state._tag !== "Open") {
92
+ return exitFalse
93
+ } else if (this.messages.length + this.messagesChunk.length >= this.capacity) {
94
+ return this.offerRemainingSingle(message)
95
+ }
96
+ this.messages.push(message)
97
+ this.scheduleReleaseTaker()
98
+ return exitTrue
99
+ })
100
+ }
101
+ unsafeOffer(message: A): boolean {
102
+ if (this.state._tag !== "Open") {
103
+ return false
104
+ } else if (this.messages.length + this.messagesChunk.length >= this.capacity) {
105
+ return false
106
+ }
107
+ this.messages.push(message)
108
+ this.scheduleReleaseTaker()
109
+ return true
110
+ }
111
+ offerAll(messages: Iterable<A>): Effect<Chunk.Chunk<A>> {
112
+ return core.suspend(() => {
113
+ if (this.state._tag !== "Open") {
114
+ return core.succeed(Chunk.fromIterable(messages))
115
+ }
116
+ const remaining = this.unsafeOfferAllArray(messages)
117
+ if (remaining.length === 0) {
118
+ return exitEmpty
119
+ }
120
+ return this.offerRemainingArray(remaining)
121
+ })
122
+ }
123
+ unsafeOfferAll(messages: Iterable<A>): Chunk.Chunk<A> {
124
+ return Chunk.unsafeFromArray(this.unsafeOfferAllArray(messages))
125
+ }
126
+ unsafeOfferAllArray(messages: Iterable<A>): Array<A> {
127
+ if (this.state._tag !== "Open") {
128
+ return Arr.fromIterable(messages)
129
+ } else if (this.capacity === Number.POSITIVE_INFINITY) {
130
+ if (this.messages.length > 0) {
131
+ this.messagesChunk = Chunk.appendAll(this.messagesChunk, Chunk.unsafeFromArray(this.messages))
132
+ }
133
+ if (Chunk.isChunk(messages)) {
134
+ this.messagesChunk = Chunk.appendAll(this.messagesChunk, messages)
135
+ } else {
136
+ this.messages = Arr.fromIterable(messages)
137
+ }
138
+ this.scheduleReleaseTaker()
139
+ return []
140
+ }
141
+ const free = this.capacity - this.messages.length - this.messagesChunk.length
142
+ if (free === 0) {
143
+ return Arr.fromIterable(messages)
144
+ }
145
+ const remaining: Array<A> = []
146
+ let i = 0
147
+ for (const message of messages) {
148
+ if (i < free) {
149
+ this.messages.push(message)
150
+ } else {
151
+ remaining.push(message)
152
+ }
153
+ i++
154
+ }
155
+ this.scheduleReleaseTaker()
156
+ return remaining
157
+ }
158
+ fail(error: E) {
159
+ return this.done(core.exitFail(error))
160
+ }
161
+ failCause(cause: Cause<E>) {
162
+ return this.done(core.exitFailCause(cause))
163
+ }
164
+ unsafeDone(exit: Exit<void, E>): boolean {
165
+ if (this.state._tag !== "Open") {
166
+ return false
167
+ } else if (this.state.offers.size === 0 && this.messages.length === 0 && this.messagesChunk.length === 0) {
168
+ this.finalize(exit)
169
+ return true
170
+ }
171
+ this.state = { ...this.state, _tag: "Closing", exit }
172
+ return true
173
+ }
174
+ shutdown: Effect<boolean> = core.sync(() => {
175
+ if (this.state._tag === "Done") {
176
+ return true
177
+ }
178
+ this.messages = []
179
+ this.messagesChunk = empty
180
+ const offers = this.state.offers
181
+ this.finalize(this.state._tag === "Open" ? core.exitVoid : this.state.exit)
182
+ if (offers.size > 0) {
183
+ for (const entry of offers) {
184
+ if (entry._tag === "Single") {
185
+ entry.resume(exitFalse)
186
+ } else {
187
+ entry.resume(core.exitSucceed(Chunk.unsafeFromArray(entry.remaining.slice(entry.offset))))
188
+ }
189
+ }
190
+ offers.clear()
191
+ }
192
+ return true
193
+ })
194
+ done(exit: Exit<void, E>) {
195
+ return core.sync(() => this.unsafeDone(exit))
196
+ }
197
+ end = this.done(core.exitVoid)
198
+ clear: Effect<Chunk.Chunk<A>, E> = core.suspend(() => {
199
+ if (this.state._tag === "Done") {
200
+ return core.exitAs(this.state.exit, empty)
201
+ }
202
+ const messages = this.unsafeTakeAll()
203
+ this.releaseCapacity()
204
+ return core.succeed(messages)
205
+ })
206
+ takeAll: Effect<readonly [messages: Chunk.Chunk<A>, done: boolean], E> = core.suspend(() => {
207
+ if (this.state._tag === "Done") {
208
+ return core.exitAs(this.state.exit, constDone)
209
+ }
210
+ const messages = this.unsafeTakeAll()
211
+ if (messages.length === 0) {
212
+ return core.zipRight(this.awaitTake, this.takeAll)
213
+ }
214
+ return core.succeed([messages, this.releaseCapacity()])
215
+ })
216
+ takeN(n: number): Effect<readonly [messages: Chunk.Chunk<A>, done: boolean], E> {
217
+ return core.suspend(() => {
218
+ if (this.state._tag === "Done") {
219
+ return core.exitAs(this.state.exit, constDone)
220
+ } else if (n <= 0) {
221
+ return core.succeed([empty, false])
222
+ }
223
+ n = Math.min(n, this.capacity)
224
+ let messages: Chunk.Chunk<A>
225
+ if (n <= this.messagesChunk.length) {
226
+ messages = Chunk.take(this.messagesChunk, n)
227
+ this.messagesChunk = Chunk.drop(this.messagesChunk, n)
228
+ } else if (n <= this.messages.length + this.messagesChunk.length) {
229
+ this.messagesChunk = Chunk.appendAll(this.messagesChunk, Chunk.unsafeFromArray(this.messages))
230
+ this.messages = []
231
+ messages = Chunk.take(this.messagesChunk, n)
232
+ this.messagesChunk = Chunk.drop(this.messagesChunk, n)
233
+ } else {
234
+ return core.zipRight(this.awaitTake, this.takeN(n))
235
+ }
236
+ return core.succeed([messages, this.releaseCapacity()])
237
+ })
238
+ }
239
+ take: Effect<A, E | NoSuchElementException> = core.suspend(() => {
240
+ if (this.state._tag === "Done") {
241
+ return core.exitZipRight(this.state.exit, core.exitFail(new NoSuchElementException()))
242
+ }
243
+ let message: A
244
+ if (this.messagesChunk.length > 0) {
245
+ message = Chunk.unsafeHead(this.messagesChunk)
246
+ this.messagesChunk = Chunk.drop(this.messagesChunk, 1)
247
+ } else if (this.messages.length > 0) {
248
+ message = this.messages[0]
249
+ this.messagesChunk = Chunk.drop(Chunk.unsafeFromArray(this.messages), 1)
250
+ this.messages = []
251
+ } else {
252
+ return core.zipRight(this.awaitTake, this.take)
253
+ }
254
+ this.releaseCapacity()
255
+ return core.succeed(message)
256
+ })
257
+ await: Effect<void, E> = core.unsafeAsync<void, E>((resume) => {
258
+ if (this.state._tag === "Done") {
259
+ return resume(this.state.exit)
260
+ }
261
+ this.state.awaiters.add(resume)
262
+ return core.sync(() => {
263
+ if (this.state._tag !== "Done") {
264
+ this.state.awaiters.delete(resume)
265
+ }
266
+ })
267
+ })
268
+ unsafeSize(): Option.Option<number> {
269
+ const size = this.messages.length + this.messagesChunk.length
270
+ return this.state._tag === "Done" ? Option.none() : Option.some(size)
271
+ }
272
+ size = core.sync(() => this.unsafeSize())
273
+
274
+ commit() {
275
+ return this.takeAll
276
+ }
277
+ pipe() {
278
+ return pipeArguments(this, arguments)
279
+ }
280
+ toJSON() {
281
+ return {
282
+ _id: "effect/Mailbox",
283
+ state: this.state._tag,
284
+ size: this.unsafeSize().toJSON()
285
+ }
286
+ }
287
+ toString(): string {
288
+ return Inspectable.format(this)
289
+ }
290
+ [Inspectable.NodeInspectSymbol]() {
291
+ return Inspectable.format(this)
292
+ }
293
+
294
+ private offerRemainingSingle(message: A) {
295
+ return core.unsafeAsync<boolean>((resume) => {
296
+ if (this.state._tag !== "Open") {
297
+ return resume(exitFalse)
298
+ }
299
+ const entry: OfferEntry<A> = { _tag: "Single", message, resume }
300
+ this.state.offers.add(entry)
301
+ return core.sync(() => {
302
+ if (this.state._tag === "Open") {
303
+ this.state.offers.delete(entry)
304
+ }
305
+ })
306
+ })
307
+ }
308
+ private offerRemainingArray(remaining: Array<A>) {
309
+ return core.unsafeAsync<Chunk.Chunk<A>>((resume) => {
310
+ if (this.state._tag !== "Open") {
311
+ return resume(core.exitSucceed(Chunk.unsafeFromArray(remaining)))
312
+ }
313
+ const entry: OfferEntry<A> = { _tag: "Array", remaining, offset: 0, resume }
314
+ this.state.offers.add(entry)
315
+ return core.sync(() => {
316
+ if (this.state._tag === "Open") {
317
+ this.state.offers.delete(entry)
318
+ }
319
+ })
320
+ })
321
+ }
322
+ private releaseCapacity(): boolean {
323
+ if (this.state._tag === "Done") {
324
+ return this.state.exit._tag === "Success"
325
+ } else if (this.state.offers.size === 0) {
326
+ if (this.state._tag === "Closing" && this.messages.length === 0 && this.messagesChunk.length === 0) {
327
+ this.finalize(this.state.exit)
328
+ return this.state.exit._tag === "Success"
329
+ }
330
+ return false
331
+ }
332
+ let n = this.capacity - this.messages.length - this.messagesChunk.length
333
+ for (const entry of this.state.offers) {
334
+ if (n === 0) return false
335
+ else if (entry._tag === "Single") {
336
+ this.messages.push(entry.message)
337
+ n--
338
+ entry.resume(exitTrue)
339
+ this.state.offers.delete(entry)
340
+ } else {
341
+ for (; entry.offset < entry.remaining.length; entry.offset++) {
342
+ if (n === 0) return false
343
+ this.messages.push(entry.remaining[entry.offset])
344
+ n--
345
+ }
346
+ entry.resume(exitEmpty)
347
+ this.state.offers.delete(entry)
348
+ }
349
+ }
350
+ return false
351
+ }
352
+ private awaitTake = core.unsafeAsync<void, E>((resume) => {
353
+ if (this.state._tag === "Done") {
354
+ return resume(this.state.exit)
355
+ }
356
+ this.state.takers.add(resume)
357
+ return core.sync(() => {
358
+ if (this.state._tag !== "Done") {
359
+ this.state.takers.delete(resume)
360
+ }
361
+ })
362
+ })
363
+
364
+ private scheduleRunning = false
365
+ private scheduleReleaseTaker() {
366
+ if (this.scheduleRunning) {
367
+ return
368
+ }
369
+ this.scheduleRunning = true
370
+ this.scheduler.scheduleTask(this.releaseTaker, 0)
371
+ }
372
+ private releaseTaker = () => {
373
+ this.scheduleRunning = false
374
+ if (this.state._tag === "Done") {
375
+ return
376
+ } else if (this.state.takers.size === 0) {
377
+ return
378
+ }
379
+ const taker = Iterable.unsafeHead(this.state.takers)
380
+ this.state.takers.delete(taker)
381
+ taker(core.exitVoid)
382
+ }
383
+
384
+ private unsafeTakeAll() {
385
+ if (this.messagesChunk.length > 0) {
386
+ const messages = this.messages.length > 0 ?
387
+ Chunk.appendAll(this.messagesChunk, Chunk.unsafeFromArray(this.messages)) :
388
+ this.messagesChunk
389
+ this.messagesChunk = empty
390
+ this.messages = []
391
+ return messages
392
+ } else if (this.messages.length > 0) {
393
+ const messages = Chunk.unsafeFromArray(this.messages)
394
+ this.messages = []
395
+ return messages
396
+ }
397
+ return empty
398
+ }
399
+
400
+ private finalize(exit: Exit<void, E>) {
401
+ if (this.state._tag === "Done") {
402
+ return
403
+ }
404
+ const openState = this.state
405
+ this.state = { _tag: "Done", exit }
406
+ for (const taker of openState.takers) {
407
+ taker(exit)
408
+ }
409
+ openState.takers.clear()
410
+ for (const awaiter of openState.awaiters) {
411
+ awaiter(exit)
412
+ }
413
+ openState.awaiters.clear()
414
+ }
415
+ }
416
+
417
+ /** @internal */
418
+ export const make = <A, E = never>(capacity?: number | undefined): Effect<Api.Mailbox<A, E>> =>
419
+ core.withFiberRuntime((fiber) =>
420
+ core.succeed(
421
+ new MailboxImpl<A, E>(
422
+ fiber.currentScheduler,
423
+ capacity ?? Number.POSITIVE_INFINITY
424
+ )
425
+ )
426
+ )
427
+
428
+ /** @internal */
429
+ export const into: {
430
+ <A, E>(
431
+ self: Api.Mailbox<A, E>
432
+ ): <AX, EX extends E, RX>(effect: Effect<AX, EX, RX>) => Effect<boolean, never, RX>
433
+ <AX, E, EX extends E, RX, A>(
434
+ effect: Effect<AX, EX, RX>,
435
+ self: Api.Mailbox<A, E>
436
+ ): Effect<boolean, never, RX>
437
+ } = dual(
438
+ 2,
439
+ <AX, E, EX extends E, RX, A>(
440
+ effect: Effect<AX, EX, RX>,
441
+ self: Api.Mailbox<A, E>
442
+ ): Effect<boolean, never, RX> =>
443
+ core.uninterruptibleMask((restore) =>
444
+ core.matchCauseEffect(restore(effect), {
445
+ onFailure: (cause) => self.failCause(cause),
446
+ onSuccess: (_) => self.end
447
+ })
448
+ )
449
+ )
450
+
451
+ /** @internal */
452
+ export const toChannel = <A, E>(self: Api.ReadonlyMailbox<A, E>): Channel<Chunk.Chunk<A>, unknown, E> => {
453
+ const loop: Channel<Chunk.Chunk<A>, unknown, E> = coreChannel.flatMap(self.takeAll, ([messages, done]) =>
454
+ done
455
+ ? messages.length === 0 ? coreChannel.void : coreChannel.write(messages)
456
+ : channel.zipRight(coreChannel.write(messages), loop))
457
+ return loop
458
+ }
459
+
460
+ /** @internal */
461
+ export const toStream = <A, E>(self: Api.ReadonlyMailbox<A, E>): Stream<A, E> => stream.fromChannel(toChannel(self))
@@ -26,7 +26,7 @@ function provide<R, ER, A, E>(
26
26
  (rt) =>
27
27
  core.withFiberRuntime((fiber) => {
28
28
  fiber.setFiberRefs(rt.fiberRefs)
29
- fiber._runtimeFlags = rt.runtimeFlags
29
+ fiber.currentRuntimeFlags = rt.runtimeFlags
30
30
  return core.provideContext(effect, rt.context)
31
31
  })
32
32
  )
@@ -1,6 +1,7 @@
1
1
  import * as Chunk from "../Chunk.js"
2
2
  import type * as Deferred from "../Deferred.js"
3
3
  import type * as Effect from "../Effect.js"
4
+ import * as Effectable from "../Effectable.js"
4
5
  import { dual, pipe } from "../Function.js"
5
6
  import * as MutableQueue from "../MutableQueue.js"
6
7
  import * as MutableRef from "../MutableRef.js"
@@ -909,7 +910,7 @@ class UnboundedPubSubSubscription<in out A> implements Subscription<A> {
909
910
  }
910
911
 
911
912
  /** @internal */
912
- class SubscriptionImpl<in out A> implements Queue.Dequeue<A> {
913
+ class SubscriptionImpl<in out A> extends Effectable.Class<A> implements Queue.Dequeue<A> {
913
914
  [queue.DequeueTypeId] = queue.dequeueVariance
914
915
 
915
916
  constructor(
@@ -921,7 +922,13 @@ class SubscriptionImpl<in out A> implements Queue.Dequeue<A> {
921
922
  readonly shutdownFlag: MutableRef.MutableRef<boolean>,
922
923
  readonly strategy: PubSubStrategy<A>,
923
924
  readonly replayWindow: ReplayWindow<A>
924
- ) {}
925
+ ) {
926
+ super()
927
+ }
928
+
929
+ commit() {
930
+ return this.take
931
+ }
925
932
 
926
933
  pipe() {
927
934
  return pipeArguments(this, arguments)
@@ -2,6 +2,7 @@ import * as Arr from "../Array.js"
2
2
  import * as Chunk from "../Chunk.js"
3
3
  import type * as Deferred from "../Deferred.js"
4
4
  import type * as Effect from "../Effect.js"
5
+ import * as Effectable from "../Effectable.js"
5
6
  import { dual, pipe } from "../Function.js"
6
7
  import * as MutableQueue from "../MutableQueue.js"
7
8
  import * as MutableRef from "../MutableRef.js"
@@ -63,7 +64,7 @@ export const dequeueVariance = {
63
64
  }
64
65
 
65
66
  /** @internal */
66
- class QueueImpl<in out A> implements Queue.Queue<A> {
67
+ class QueueImpl<in out A> extends Effectable.Class<A> implements Queue.Queue<A> {
67
68
  readonly [EnqueueTypeId] = enqueueVariance
68
69
  readonly [DequeueTypeId] = dequeueVariance
69
70
 
@@ -79,12 +80,17 @@ class QueueImpl<in out A> implements Queue.Queue<A> {
79
80
  /** @internal */
80
81
  readonly strategy: Queue.Strategy<A>
81
82
  ) {
83
+ super()
82
84
  }
83
85
 
84
86
  pipe() {
85
87
  return pipeArguments(this, arguments)
86
88
  }
87
89
 
90
+ commit() {
91
+ return this.take
92
+ }
93
+
88
94
  capacity(): number {
89
95
  return this.queue.capacity()
90
96
  }
@@ -211,3 +211,11 @@ export const get: {
211
211
  )
212
212
  }
213
213
  )
214
+
215
+ /** @internal */
216
+ export const keys = <K, A, E>(self: RcMap.RcMap<K, A, E>): Effect<Array<K>> => {
217
+ const impl = self as RcMapImpl<K, A, E>
218
+ return core.suspend(() =>
219
+ impl.state._tag === "Closed" ? core.interrupt : core.succeed(MutableHashMap.keys(impl.state.map))
220
+ )
221
+ }
@@ -1,10 +1,11 @@
1
1
  import * as Context from "../Context.js"
2
2
  import * as Duration from "../Duration.js"
3
3
  import type { Effect } from "../Effect.js"
4
+ import * as Effectable from "../Effectable.js"
4
5
  import type { RuntimeFiber } from "../Fiber.js"
5
6
  import { identity } from "../Function.js"
6
- import { pipeArguments } from "../Pipeable.js"
7
7
  import type * as RcRef from "../RcRef.js"
8
+ import * as Readable from "../Readable.js"
8
9
  import type * as Scope from "../Scope.js"
9
10
  import * as coreEffect from "./core-effect.js"
10
11
  import * as core from "./core.js"
@@ -42,8 +43,9 @@ const variance: RcRef.RcRef.Variance<any, any> = {
42
43
  _E: identity
43
44
  }
44
45
 
45
- class RcRefImpl<A, E> implements RcRef.RcRef<A, E> {
46
- readonly [TypeId]: RcRef.RcRef.Variance<A, E>
46
+ class RcRefImpl<A, E> extends Effectable.Class<A, E, Scope.Scope> implements RcRef.RcRef<A, E> {
47
+ readonly [TypeId]: RcRef.RcRef.Variance<A, E> = variance
48
+ readonly [Readable.TypeId]: Readable.TypeId = Readable.TypeId
47
49
 
48
50
  state: State<A> = stateEmpty
49
51
  readonly semaphore = circular.unsafeMakeSemaphore(1)
@@ -54,11 +56,13 @@ class RcRefImpl<A, E> implements RcRef.RcRef<A, E> {
54
56
  readonly scope: Scope.Scope,
55
57
  readonly idleTimeToLive: Duration.Duration | undefined
56
58
  ) {
57
- this[TypeId] = variance
59
+ super()
60
+ this.get = get(this)
58
61
  }
62
+ readonly get: Effect<A, E, Scope.Scope>
59
63
 
60
- pipe() {
61
- return pipeArguments(this, arguments)
64
+ commit() {
65
+ return this.get
62
66
  }
63
67
  }
64
68
 
@@ -1,8 +1,8 @@
1
1
  import type * as Effect from "../Effect.js"
2
+ import * as Effectable from "../Effectable.js"
2
3
  import { dual } from "../Function.js"
3
4
  import * as MutableRef from "../MutableRef.js"
4
5
  import * as Option from "../Option.js"
5
- import { pipeArguments } from "../Pipeable.js"
6
6
  import * as Readable from "../Readable.js"
7
7
  import type * as Ref from "../Ref.js"
8
8
  import * as core from "./core.js"
@@ -16,11 +16,14 @@ export const refVariance = {
16
16
  _A: (_: any) => _
17
17
  }
18
18
 
19
- class RefImpl<in out A> implements Ref.Ref<A> {
19
+ class RefImpl<in out A> extends Effectable.Class<A> implements Ref.Ref<A> {
20
+ commit() {
21
+ return this.get
22
+ }
20
23
  readonly [RefTypeId] = refVariance
21
- readonly [Readable.TypeId]: Readable.TypeId
24
+ readonly [Readable.TypeId]: Readable.TypeId = Readable.TypeId
22
25
  constructor(readonly ref: MutableRef.MutableRef<A>) {
23
- this[Readable.TypeId] = Readable.TypeId
26
+ super()
24
27
  this.get = core.sync(() => MutableRef.get(this.ref))
25
28
  }
26
29
  readonly get: Effect.Effect<A>
@@ -34,9 +37,6 @@ class RefImpl<in out A> implements Ref.Ref<A> {
34
37
  return b
35
38
  })
36
39
  }
37
- pipe() {
38
- return pipeArguments(this, arguments)
39
- }
40
40
  }
41
41
 
42
42
  /** @internal */
@@ -74,7 +74,7 @@ export const unsafeFork = <R>(runtime: Runtime.Runtime<R>) =>
74
74
  )
75
75
  }
76
76
 
77
- const supervisor = fiberRuntime._supervisor
77
+ const supervisor = fiberRuntime.currentSupervisor
78
78
 
79
79
  // we can compare by reference here as _supervisor.none is wrapped with globalValue
80
80
  if (supervisor !== _supervisor.none) {