@@ -10,6 +10,7 @@ import * as Either from "../Either.js"
10
10
import * as Equal from "../Equal.js"
11
11
import * as Exit from "../Exit.js"
12
12
import * as Fiber from "../Fiber.js"
13
+ import * as FiberRef from "../FiberRef.js"
13
14
import type { LazyArg } from "../Function.js"
14
15
import { constTrue , dual , identity , pipe } from "../Function.js"
15
16
import * as Layer from "../Layer.js"
@@ -597,6 +598,51 @@ export const asyncEffect = <A, E = never, R = never>(
597
598
fromChannel
598
599
)
599
600
601
+ const queueFromBufferOptionsPush = < A , E > (
602
+ options ?: { readonly bufferSize : "unbounded" } | {
603
+ readonly bufferSize ?: number | undefined
604
+ readonly strategy ?: "dropping" | "sliding" | undefined
605
+ } | undefined
606
+ ) : Effect . Effect < Queue . Queue < Array < A > | Exit . Exit < void , E > > > => {
607
+ if ( options ?. bufferSize === "unbounded" || ( options ?. bufferSize === undefined && options ?. strategy === undefined ) ) {
608
+ return Queue . unbounded ( )
609
+ }
610
+ switch ( options ?. strategy ) {
611
+ case "sliding" :
612
+ return Queue . sliding ( options . bufferSize ?? 16 )
613
+ default :
614
+ return Queue . dropping ( options ?. bufferSize ?? 16 )
615
+ }
616
+ }
617
+
618
+ /** @internal */
619
+ export const asyncPush = < A , E = never , R = never > (
620
+ register : ( emit : Emit . EmitOpsPush < E , A > ) => Effect . Effect < unknown , never , R | Scope . Scope > ,
621
+ options ?: {
622
+ readonly bufferSize : "unbounded"
623
+ } | {
624
+ readonly bufferSize ?: number | undefined
625
+ readonly strategy ?: "dropping" | "sliding" | undefined
626
+ } | undefined
627
+ ) : Stream . Stream < A , E , Exclude < R , Scope . Scope > > =>
628
+ Effect . acquireRelease (
629
+ queueFromBufferOptionsPush < A , E > ( options ) ,
630
+ Queue . shutdown
631
+ ) . pipe (
632
+ Effect . tap ( ( queue ) =>
633
+ FiberRef . getWith ( FiberRef . currentScheduler , ( scheduler ) => register ( emit . makePush ( queue , scheduler ) ) )
634
+ ) ,
635
+ Effect . map ( ( queue ) => {
636
+ const loop : Channel . Channel < Chunk . Chunk < A > , unknown , E > = core . flatMap ( Queue . take ( queue ) , ( item ) =>
637
+ Exit . isExit ( item )
638
+ ? Exit . isSuccess ( item ) ? core . void : core . failCause ( item . cause )
639
+ : channel . zipRight ( core . write ( Chunk . unsafeFromArray ( item ) ) , loop ) )
640
+ return loop
641
+ } ) ,
642
+ channel . unwrapScoped ,
643
+ fromChannel
644
+ )
645
+
600
646
/** @internal */
601
647
export const asyncScoped = < A , E = never , R = never > (
602
648
register : ( emit : Emit . Emit < R , E , A , void > ) => Effect . Effect < unknown , E , R | Scope . Scope > ,
@@ -8341,23 +8387,11 @@ export const fromEventListener = <A = unknown>(
8341
8387
readonly capture ?: boolean
8342
8388
readonly passive ?: boolean
8343
8389
readonly once ?: boolean
8390
+ readonly bufferSize ?: number | "unbounded" | undefined
8344
8391
} | undefined
8345
8392
) : Stream . Stream < A > =>
8346
- _async < A > ( ( emit ) => {
8347
- let batch : Array < A > = [ ]
8348
- let taskRunning = false
8349
- function cb ( e : A ) {
8350
- batch . push ( e )
8351
- if ( ! taskRunning ) {
8352
- taskRunning = true
8353
- queueMicrotask ( ( ) => {
8354
- const events = batch
8355
- batch = [ ]
8356
- taskRunning = false
8357
- emit . chunk ( Chunk . unsafeFromArray ( events ) )
8358
- } )
8359
- }
8360
- }
8361
- target . addEventListener ( type , cb as any , options )
8362
- return Effect . sync ( ( ) => target . removeEventListener ( type , cb , options ) )
8363
- } , "unbounded" )
8393
+ asyncPush < A > ( ( emit ) =>
8394
+ Effect . acquireRelease (
8395
+ Effect . sync ( ( ) => target . addEventListener ( type , emit . single as any , options ) ) ,
8396
+ ( ) => Effect . sync ( ( ) => target . removeEventListener ( type , emit . single , options ) )
8397
+ ) , { bufferSize : typeof options === "object" ? options . bufferSize : undefined } )
0 commit comments