@effect/platform 0.69.13 → 0.69.14
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.
- package/dist/cjs/HttpApiClient.js +5 -1
- package/dist/cjs/HttpApiClient.js.map +1 -1
- package/dist/cjs/HttpApiEndpoint.js.map +1 -1
- package/dist/cjs/Socket.js +96 -116
- package/dist/cjs/Socket.js.map +1 -1
- package/dist/dts/HttpApiClient.d.ts +2 -1
- package/dist/dts/HttpApiClient.d.ts.map +1 -1
- package/dist/dts/HttpApiEndpoint.d.ts +6 -2
- package/dist/dts/HttpApiEndpoint.d.ts.map +1 -1
- package/dist/dts/Socket.d.ts +2 -2
- package/dist/dts/Socket.d.ts.map +1 -1
- package/dist/esm/HttpApiClient.js +5 -1
- package/dist/esm/HttpApiClient.js.map +1 -1
- package/dist/esm/HttpApiEndpoint.js.map +1 -1
- package/dist/esm/Socket.js +96 -116
- package/dist/esm/Socket.js.map +1 -1
- package/package.json +2 -2
- package/src/HttpApiClient.ts +11 -5
- package/src/HttpApiEndpoint.ts +4 -2
- package/src/Socket.ts +245 -263
package/src/Socket.ts
CHANGED
|
@@ -189,46 +189,40 @@ export const toChannelMap = <IE, A>(
|
|
|
189
189
|
void,
|
|
190
190
|
unknown
|
|
191
191
|
> =>
|
|
192
|
-
Effect.
|
|
193
|
-
Effect.
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
(
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
Effect.interruptible
|
|
227
|
-
)
|
|
228
|
-
),
|
|
229
|
-
Effect.map(({ input, mailbox }) => Channel.embedInput(Mailbox.toChannel(mailbox), input)),
|
|
230
|
-
Channel.unwrapScoped
|
|
231
|
-
)
|
|
192
|
+
Effect.gen(function*() {
|
|
193
|
+
const scope = yield* Effect.scope
|
|
194
|
+
const mailbox = yield* Mailbox.make<A, SocketError | IE>()
|
|
195
|
+
const writeScope = yield* Scope.fork(scope, ExecutionStrategy.sequential)
|
|
196
|
+
const write = yield* Scope.extend(self.writer, writeScope)
|
|
197
|
+
const input: AsyncProducer.AsyncInputProducer<IE, Chunk.Chunk<Uint8Array | string | CloseEvent>, unknown> = {
|
|
198
|
+
awaitRead: () => Effect.void,
|
|
199
|
+
emit(chunk) {
|
|
200
|
+
return Effect.catchAllCause(
|
|
201
|
+
Effect.forEach(chunk, write, { discard: true }),
|
|
202
|
+
(cause) => mailbox.failCause(cause)
|
|
203
|
+
)
|
|
204
|
+
},
|
|
205
|
+
error(error) {
|
|
206
|
+
return Effect.zipRight(
|
|
207
|
+
Scope.close(writeScope, Exit.void),
|
|
208
|
+
mailbox.failCause(error)
|
|
209
|
+
)
|
|
210
|
+
},
|
|
211
|
+
done() {
|
|
212
|
+
return Scope.close(writeScope, Exit.void)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
yield* self.runRaw((data) => {
|
|
217
|
+
mailbox.unsafeOffer(f(data))
|
|
218
|
+
}).pipe(
|
|
219
|
+
Mailbox.into(mailbox),
|
|
220
|
+
Effect.forkIn(scope),
|
|
221
|
+
Effect.interruptible
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
return Channel.embedInput(Mailbox.toChannel(mailbox), input)
|
|
225
|
+
}).pipe(Channel.unwrapScoped)
|
|
232
226
|
|
|
233
227
|
/**
|
|
234
228
|
* @since 1.0.0
|
|
@@ -393,139 +387,132 @@ export const makeWebSocket = (url: string | Effect.Effect<string>, options?: {
|
|
|
393
387
|
* @since 1.0.0
|
|
394
388
|
* @category constructors
|
|
395
389
|
*/
|
|
396
|
-
export const fromWebSocket = <
|
|
397
|
-
acquire: Effect.Effect<globalThis.WebSocket, SocketError,
|
|
390
|
+
export const fromWebSocket = <RO>(
|
|
391
|
+
acquire: Effect.Effect<globalThis.WebSocket, SocketError, RO>,
|
|
398
392
|
options?: {
|
|
399
393
|
readonly closeCodeIsError?: (code: number) => boolean
|
|
400
394
|
readonly openTimeout?: DurationInput
|
|
401
395
|
}
|
|
402
|
-
): Effect.Effect<Socket, never, Exclude<
|
|
403
|
-
Effect.withFiberRuntime<Socket, never, Exclude<
|
|
404
|
-
Effect.
|
|
405
|
-
Queue.dropping<Uint8Array | string | CloseEvent>(
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
Effect.andThen((buffer) => handler(new Uint8Array(buffer))),
|
|
424
|
-
run
|
|
425
|
-
)
|
|
426
|
-
}
|
|
427
|
-
const result = handler(event.data)
|
|
428
|
-
if (Effect.isEffect(result)) {
|
|
429
|
-
run(result)
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
function onError(cause: Event) {
|
|
433
|
-
ws.removeEventListener("message", onMessage)
|
|
434
|
-
ws.removeEventListener("close", onClose)
|
|
435
|
-
Deferred.unsafeDone(
|
|
436
|
-
fiberSet.deferred,
|
|
437
|
-
Effect.fail(new SocketGenericError({ reason: open ? "Read" : "Open", cause }))
|
|
438
|
-
)
|
|
439
|
-
}
|
|
440
|
-
function onClose(event: globalThis.CloseEvent) {
|
|
441
|
-
ws.removeEventListener("message", onMessage)
|
|
442
|
-
ws.removeEventListener("error", onError)
|
|
443
|
-
Deferred.unsafeDone(
|
|
444
|
-
fiberSet.deferred,
|
|
445
|
-
Effect.fail(
|
|
446
|
-
new SocketCloseError({
|
|
447
|
-
reason: "Close",
|
|
448
|
-
code: event.code,
|
|
449
|
-
closeReason: event.reason
|
|
450
|
-
})
|
|
451
|
-
)
|
|
452
|
-
)
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
ws.addEventListener("close", onClose, { once: true })
|
|
456
|
-
ws.addEventListener("error", onError, { once: true })
|
|
457
|
-
ws.addEventListener("message", onMessage)
|
|
458
|
-
|
|
459
|
-
if (ws.readyState !== 1) {
|
|
460
|
-
const openDeferred = Deferred.unsafeMake<void>(fiber.id())
|
|
461
|
-
ws.addEventListener("open", () => {
|
|
462
|
-
open = true
|
|
463
|
-
Deferred.unsafeDone(openDeferred, Effect.void)
|
|
464
|
-
}, { once: true })
|
|
465
|
-
return Deferred.await(openDeferred).pipe(
|
|
466
|
-
Effect.timeoutFail({
|
|
467
|
-
duration: options?.openTimeout ?? 10000,
|
|
468
|
-
onTimeout: () =>
|
|
469
|
-
new SocketGenericError({ reason: "OpenTimeout", cause: "timeout waiting for \"open\"" })
|
|
470
|
-
}),
|
|
471
|
-
Effect.raceFirst(FiberSet.join(fiberSet))
|
|
472
|
-
)
|
|
473
|
-
}
|
|
474
|
-
open = true
|
|
475
|
-
return Effect.void
|
|
476
|
-
}),
|
|
477
|
-
Effect.tap(({ fiberSet, ws }) =>
|
|
478
|
-
Queue.take(sendQueue).pipe(
|
|
479
|
-
Effect.tap((chunk) =>
|
|
480
|
-
isCloseEvent(chunk) ?
|
|
481
|
-
Effect.failSync(() => {
|
|
482
|
-
ws.close(chunk.code, chunk.reason)
|
|
483
|
-
return new SocketCloseError({
|
|
484
|
-
reason: "Close",
|
|
485
|
-
code: chunk.code,
|
|
486
|
-
closeReason: chunk.reason
|
|
487
|
-
})
|
|
488
|
-
}) :
|
|
489
|
-
Effect.try({
|
|
490
|
-
try: () => ws.send(chunk),
|
|
491
|
-
catch: (cause) => new SocketGenericError({ reason: "Write", cause })
|
|
492
|
-
})
|
|
493
|
-
),
|
|
494
|
-
Effect.forever,
|
|
495
|
-
FiberSet.run(fiberSet)
|
|
396
|
+
): Effect.Effect<Socket, never, Exclude<RO, Scope.Scope>> =>
|
|
397
|
+
Effect.withFiberRuntime<Socket, never, Exclude<RO, Scope.Scope>>((fiber) =>
|
|
398
|
+
Effect.gen(function*() {
|
|
399
|
+
const sendQueue = yield* Queue.dropping<Uint8Array | string | CloseEvent>(
|
|
400
|
+
fiber.getFiberRef(currentSendQueueCapacity)
|
|
401
|
+
)
|
|
402
|
+
const acquireContext = fiber.currentContext as Context.Context<RO>
|
|
403
|
+
const closeCodeIsError = options?.closeCodeIsError ?? defaultCloseCodeIsError
|
|
404
|
+
|
|
405
|
+
const runRaw = <_, E, R>(handler: (_: string | Uint8Array) => Effect.Effect<_, E, R> | void) =>
|
|
406
|
+
Effect.gen(function*() {
|
|
407
|
+
const fiberSet = yield* FiberSet.make<any, E | SocketError>()
|
|
408
|
+
const ws = yield* acquire
|
|
409
|
+
const run = yield* Effect.provideService(FiberSet.runtime(fiberSet)<R>(), WebSocket, ws)
|
|
410
|
+
let open = false
|
|
411
|
+
|
|
412
|
+
function onMessage(event: MessageEvent) {
|
|
413
|
+
if (event.data instanceof Blob) {
|
|
414
|
+
return Effect.promise(() => event.data.arrayBuffer() as Promise<ArrayBuffer>).pipe(
|
|
415
|
+
Effect.andThen((buffer) => handler(new Uint8Array(buffer))),
|
|
416
|
+
run
|
|
496
417
|
)
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
418
|
+
}
|
|
419
|
+
const result = handler(event.data)
|
|
420
|
+
if (Effect.isEffect(result)) {
|
|
421
|
+
run(result)
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
function onError(cause: Event) {
|
|
425
|
+
ws.removeEventListener("message", onMessage)
|
|
426
|
+
ws.removeEventListener("close", onClose)
|
|
427
|
+
Deferred.unsafeDone(
|
|
428
|
+
fiberSet.deferred,
|
|
429
|
+
Effect.fail(new SocketGenericError({ reason: open ? "Read" : "Open", cause }))
|
|
430
|
+
)
|
|
431
|
+
}
|
|
432
|
+
function onClose(event: globalThis.CloseEvent) {
|
|
433
|
+
ws.removeEventListener("message", onMessage)
|
|
434
|
+
ws.removeEventListener("error", onError)
|
|
435
|
+
Deferred.unsafeDone(
|
|
436
|
+
fiberSet.deferred,
|
|
437
|
+
Effect.fail(
|
|
438
|
+
new SocketCloseError({
|
|
439
|
+
reason: "Close",
|
|
440
|
+
code: event.code,
|
|
441
|
+
closeReason: event.reason
|
|
442
|
+
})
|
|
503
443
|
)
|
|
444
|
+
)
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
ws.addEventListener("close", onClose, { once: true })
|
|
448
|
+
ws.addEventListener("error", onError, { once: true })
|
|
449
|
+
ws.addEventListener("message", onMessage)
|
|
450
|
+
|
|
451
|
+
if (ws.readyState !== 1) {
|
|
452
|
+
const openDeferred = Deferred.unsafeMake<void>(fiber.id())
|
|
453
|
+
ws.addEventListener("open", () => {
|
|
454
|
+
open = true
|
|
455
|
+
Deferred.unsafeDone(openDeferred, Effect.void)
|
|
456
|
+
}, { once: true })
|
|
457
|
+
yield* Deferred.await(openDeferred).pipe(
|
|
458
|
+
Effect.timeoutFail({
|
|
459
|
+
duration: options?.openTimeout ?? 10000,
|
|
460
|
+
onTimeout: () =>
|
|
461
|
+
new SocketGenericError({ reason: "OpenTimeout", cause: "timeout waiting for \"open\"" })
|
|
462
|
+
}),
|
|
463
|
+
Effect.raceFirst(FiberSet.join(fiberSet))
|
|
464
|
+
)
|
|
465
|
+
}
|
|
466
|
+
open = true
|
|
467
|
+
yield* Queue.take(sendQueue).pipe(
|
|
468
|
+
Effect.tap((chunk) =>
|
|
469
|
+
isCloseEvent(chunk) ?
|
|
470
|
+
Effect.failSync(() => {
|
|
471
|
+
ws.close(chunk.code, chunk.reason)
|
|
472
|
+
return new SocketCloseError({
|
|
473
|
+
reason: "Close",
|
|
474
|
+
code: chunk.code,
|
|
475
|
+
closeReason: chunk.reason
|
|
476
|
+
})
|
|
477
|
+
}) :
|
|
478
|
+
Effect.try({
|
|
479
|
+
try: () => ws.send(chunk),
|
|
480
|
+
catch: (cause) => new SocketGenericError({ reason: "Write", cause })
|
|
481
|
+
})
|
|
504
482
|
),
|
|
505
|
-
Effect.
|
|
506
|
-
|
|
507
|
-
Effect.interruptible
|
|
483
|
+
Effect.forever,
|
|
484
|
+
FiberSet.run(fiberSet)
|
|
508
485
|
)
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
? handler(encoder.encode(data))
|
|
515
|
-
: handler(data)
|
|
486
|
+
return yield* FiberSet.join(fiberSet).pipe(
|
|
487
|
+
Effect.catchIf(
|
|
488
|
+
SocketCloseError.isClean((_) => !closeCodeIsError(_)),
|
|
489
|
+
(_) => Effect.void
|
|
490
|
+
)
|
|
516
491
|
)
|
|
492
|
+
}).pipe(
|
|
493
|
+
Effect.mapInputContext((input: Context.Context<R | Scope.Scope>) => Context.merge(acquireContext, input)),
|
|
494
|
+
Effect.scoped,
|
|
495
|
+
Effect.interruptible
|
|
496
|
+
)
|
|
517
497
|
|
|
518
|
-
|
|
519
|
-
|
|
498
|
+
const encoder = new TextEncoder()
|
|
499
|
+
const run = <_, E, R>(handler: (_: Uint8Array) => Effect.Effect<_, E, R> | void) =>
|
|
500
|
+
runRaw((data) =>
|
|
501
|
+
typeof data === "string"
|
|
502
|
+
? handler(encoder.encode(data))
|
|
503
|
+
: handler(data)
|
|
504
|
+
)
|
|
520
505
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
506
|
+
const write = (chunk: Uint8Array | string | CloseEvent) => Queue.offer(sendQueue, chunk)
|
|
507
|
+
const writer = Effect.succeed(write)
|
|
508
|
+
|
|
509
|
+
return Socket.of({
|
|
510
|
+
[TypeId]: TypeId,
|
|
511
|
+
run,
|
|
512
|
+
runRaw,
|
|
513
|
+
writer
|
|
514
|
+
})
|
|
515
|
+
})
|
|
529
516
|
)
|
|
530
517
|
|
|
531
518
|
/**
|
|
@@ -586,115 +573,110 @@ export interface InputTransformStream {
|
|
|
586
573
|
*/
|
|
587
574
|
export const fromTransformStream = <R>(acquire: Effect.Effect<InputTransformStream, SocketError, R>, options?: {
|
|
588
575
|
readonly closeCodeIsError?: (code: number) => boolean
|
|
589
|
-
}): Effect.Effect<Socket, never, Exclude<R, Scope.Scope>> =>
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
Queue.dropping<Uint8Array | string | CloseEvent | typeof EOF>(
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
576
|
+
}): Effect.Effect<Socket, never, Exclude<R, Scope.Scope>> =>
|
|
577
|
+
Effect.withFiberRuntime<Socket, never, Exclude<R, Scope.Scope>>((fiber) =>
|
|
578
|
+
Effect.gen(function*() {
|
|
579
|
+
const EOF = Symbol()
|
|
580
|
+
const sendQueue = yield* Queue.dropping<Uint8Array | string | CloseEvent | typeof EOF>(
|
|
581
|
+
fiber.getFiberRef(currentSendQueueCapacity)
|
|
582
|
+
)
|
|
583
|
+
const acquireContext = fiber.currentContext as Context.Context<R>
|
|
584
|
+
const closeCodeIsError = options?.closeCodeIsError ?? defaultCloseCodeIsError
|
|
585
|
+
const runRaw = <_, E, R>(handler: (_: string | Uint8Array) => Effect.Effect<_, E, R> | void) =>
|
|
586
|
+
Effect.gen(function*() {
|
|
587
|
+
const stream = yield* acquire
|
|
588
|
+
const reader = yield* Effect.acquireRelease(
|
|
589
|
+
Effect.sync(() => stream.readable.getReader()),
|
|
590
|
+
(reader) =>
|
|
591
|
+
Effect.promise(() => reader.cancel()).pipe(
|
|
592
|
+
Effect.tap(() => {
|
|
593
|
+
reader.releaseLock()
|
|
594
|
+
})
|
|
595
|
+
)
|
|
596
|
+
)
|
|
597
|
+
const writer = yield* Effect.acquireRelease(
|
|
598
|
+
Effect.sync(() => stream.writable.getWriter()),
|
|
599
|
+
(reader) => Effect.sync(() => reader.releaseLock())
|
|
600
|
+
)
|
|
601
|
+
const fiberSet = yield* FiberSet.make<any, E | SocketError>()
|
|
602
|
+
const encoder = new TextEncoder()
|
|
603
|
+
yield* Queue.take(sendQueue).pipe(
|
|
604
|
+
Effect.tap((chunk) => {
|
|
605
|
+
if (
|
|
606
|
+
chunk === EOF ||
|
|
607
|
+
isCloseEvent(chunk)
|
|
608
|
+
) {
|
|
609
|
+
return Effect.zipRight(
|
|
610
|
+
Effect.promise(() => writer.close()),
|
|
611
|
+
chunk === EOF ? Effect.interrupt : Effect.fail(
|
|
612
|
+
new SocketCloseError({
|
|
613
|
+
reason: "Close",
|
|
614
|
+
code: chunk.code,
|
|
615
|
+
closeReason: chunk.reason
|
|
607
616
|
})
|
|
608
617
|
)
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
Effect.
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
const encoder = new TextEncoder()
|
|
618
|
-
return Queue.take(sendQueue).pipe(
|
|
619
|
-
Effect.tap((chunk) => {
|
|
620
|
-
if (
|
|
621
|
-
chunk === EOF ||
|
|
622
|
-
isCloseEvent(chunk)
|
|
623
|
-
) {
|
|
624
|
-
return Effect.zipRight(
|
|
625
|
-
Effect.promise(() => writer.close()),
|
|
626
|
-
chunk === EOF ? Effect.interrupt : Effect.fail(
|
|
627
|
-
new SocketCloseError({
|
|
628
|
-
reason: "Close",
|
|
629
|
-
code: chunk.code,
|
|
630
|
-
closeReason: chunk.reason
|
|
631
|
-
})
|
|
632
|
-
)
|
|
633
|
-
)
|
|
618
|
+
)
|
|
619
|
+
}
|
|
620
|
+
return Effect.try({
|
|
621
|
+
try: () => {
|
|
622
|
+
if (typeof chunk === "string") {
|
|
623
|
+
writer.write(encoder.encode(chunk))
|
|
624
|
+
} else {
|
|
625
|
+
writer.write(chunk)
|
|
634
626
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
writer.write(encoder.encode(chunk))
|
|
639
|
-
} else {
|
|
640
|
-
writer.write(chunk)
|
|
641
|
-
}
|
|
642
|
-
},
|
|
643
|
-
catch: (cause) => new SocketGenericError({ reason: "Write", cause })
|
|
644
|
-
})
|
|
645
|
-
}),
|
|
646
|
-
Effect.forever,
|
|
647
|
-
FiberSet.run(fiberSet)
|
|
648
|
-
)
|
|
627
|
+
},
|
|
628
|
+
catch: (cause) => new SocketGenericError({ reason: "Write", cause })
|
|
629
|
+
})
|
|
649
630
|
}),
|
|
650
|
-
Effect.
|
|
651
|
-
|
|
652
|
-
try: () => reader.read(),
|
|
653
|
-
catch: (cause) => new SocketGenericError({ reason: "Read", cause })
|
|
654
|
-
}).pipe(
|
|
655
|
-
Effect.tap((result) => {
|
|
656
|
-
if (result.done) {
|
|
657
|
-
return Effect.fail(new SocketCloseError({ reason: "Close", code: 1000 }))
|
|
658
|
-
}
|
|
659
|
-
return handler(result.value)
|
|
660
|
-
}),
|
|
661
|
-
Effect.forever,
|
|
662
|
-
FiberSet.run(fiberSet)
|
|
663
|
-
)
|
|
664
|
-
),
|
|
665
|
-
Effect.tap(({ fiberSet }) =>
|
|
666
|
-
Effect.catchIf(
|
|
667
|
-
FiberSet.join(fiberSet),
|
|
668
|
-
SocketCloseError.isClean((_) => !closeCodeIsError(_)),
|
|
669
|
-
(_) => Effect.void
|
|
670
|
-
)
|
|
671
|
-
),
|
|
672
|
-
Effect.mapInputContext((input: Context.Context<R | Scope.Scope>) => Context.merge(acquireContext, input)),
|
|
673
|
-
Effect.scoped,
|
|
674
|
-
Effect.interruptible
|
|
631
|
+
Effect.forever,
|
|
632
|
+
FiberSet.run(fiberSet)
|
|
675
633
|
)
|
|
676
634
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
635
|
+
yield* Effect.tryPromise({
|
|
636
|
+
try: () => reader.read(),
|
|
637
|
+
catch: (cause) => new SocketGenericError({ reason: "Read", cause })
|
|
638
|
+
}).pipe(
|
|
639
|
+
Effect.tap((result) => {
|
|
640
|
+
if (result.done) {
|
|
641
|
+
return Effect.fail(new SocketCloseError({ reason: "Close", code: 1000 }))
|
|
642
|
+
}
|
|
643
|
+
return handler(result.value)
|
|
644
|
+
}),
|
|
645
|
+
Effect.forever,
|
|
646
|
+
FiberSet.run(fiberSet)
|
|
683
647
|
)
|
|
684
648
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
649
|
+
return yield* FiberSet.join(fiberSet).pipe(
|
|
650
|
+
Effect.catchIf(
|
|
651
|
+
SocketCloseError.isClean((_) => !closeCodeIsError(_)),
|
|
652
|
+
(_) => Effect.void
|
|
653
|
+
)
|
|
654
|
+
)
|
|
655
|
+
}).pipe(
|
|
656
|
+
Effect.mapInputContext((input: Context.Context<R | Scope.Scope>) => Context.merge(acquireContext, input)),
|
|
657
|
+
Effect.scoped,
|
|
658
|
+
Effect.interruptible
|
|
689
659
|
)
|
|
690
660
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
661
|
+
const encoder = new TextEncoder()
|
|
662
|
+
const run = <_, E, R>(handler: (_: Uint8Array) => Effect.Effect<_, E, R> | void) =>
|
|
663
|
+
runRaw((data) =>
|
|
664
|
+
typeof data === "string"
|
|
665
|
+
? handler(encoder.encode(data))
|
|
666
|
+
: handler(data)
|
|
667
|
+
)
|
|
668
|
+
|
|
669
|
+
const write = (chunk: Uint8Array | string | CloseEvent) => Queue.offer(sendQueue, chunk)
|
|
670
|
+
const writer = Effect.acquireRelease(
|
|
671
|
+
Effect.succeed(write),
|
|
672
|
+
() => Queue.offer(sendQueue, EOF)
|
|
673
|
+
)
|
|
674
|
+
|
|
675
|
+
return Socket.of({
|
|
676
|
+
[TypeId]: TypeId,
|
|
677
|
+
run,
|
|
678
|
+
runRaw,
|
|
679
|
+
writer
|
|
680
|
+
})
|
|
681
|
+
})
|
|
699
682
|
)
|
|
700
|
-
}
|