@effect/platform-node 0.21.0 → 0.22.1

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 (65) hide show
  1. package/CommandExecutor/dist/effect-platform-node-CommandExecutor.cjs.dev.js +7 -2
  2. package/CommandExecutor/dist/effect-platform-node-CommandExecutor.cjs.prod.js +7 -2
  3. package/CommandExecutor/dist/effect-platform-node-CommandExecutor.esm.js +7 -2
  4. package/Http/FormData/dist/effect-platform-node-Http-FormData.cjs.dev.js +8 -3
  5. package/Http/FormData/dist/effect-platform-node-Http-FormData.cjs.prod.js +8 -3
  6. package/Http/FormData/dist/effect-platform-node-Http-FormData.esm.js +8 -3
  7. package/Http/NodeClient/dist/effect-platform-node-Http-NodeClient.cjs.dev.js +10 -4
  8. package/Http/NodeClient/dist/effect-platform-node-Http-NodeClient.cjs.prod.js +10 -4
  9. package/Http/NodeClient/dist/effect-platform-node-Http-NodeClient.esm.js +10 -4
  10. package/Http/Server/dist/effect-platform-node-Http-Server.cjs.dev.js +12 -8
  11. package/Http/Server/dist/effect-platform-node-Http-Server.cjs.prod.js +12 -8
  12. package/Http/Server/dist/effect-platform-node-Http-Server.esm.js +12 -8
  13. package/HttpClient/dist/effect-platform-node-HttpClient.cjs.dev.js +10 -4
  14. package/HttpClient/dist/effect-platform-node-HttpClient.cjs.prod.js +10 -4
  15. package/HttpClient/dist/effect-platform-node-HttpClient.esm.js +10 -4
  16. package/HttpServer/dist/effect-platform-node-HttpServer.cjs.dev.js +11 -7
  17. package/HttpServer/dist/effect-platform-node-HttpServer.cjs.prod.js +11 -7
  18. package/HttpServer/dist/effect-platform-node-HttpServer.esm.js +11 -7
  19. package/NodeContext/dist/effect-platform-node-NodeContext.cjs.dev.js +7 -2
  20. package/NodeContext/dist/effect-platform-node-NodeContext.cjs.prod.js +7 -2
  21. package/NodeContext/dist/effect-platform-node-NodeContext.esm.js +7 -2
  22. package/Sink/dist/effect-platform-node-Sink.cjs.dev.js +10 -8
  23. package/Sink/dist/effect-platform-node-Sink.cjs.prod.js +10 -8
  24. package/Sink/dist/effect-platform-node-Sink.esm.js +10 -8
  25. package/Stream/dist/effect-platform-node-Stream.cjs.dev.js +33 -2
  26. package/Stream/dist/effect-platform-node-Stream.cjs.mjs +3 -0
  27. package/Stream/dist/effect-platform-node-Stream.cjs.prod.js +33 -2
  28. package/Stream/dist/effect-platform-node-Stream.esm.js +31 -3
  29. package/dist/{FormData-d91e8016.cjs.prod.js → FormData-33600671.cjs.prod.js} +1 -1
  30. package/dist/{FormData-5ea8a8b6.esm.js → FormData-aba95773.esm.js} +1 -1
  31. package/dist/{FormData-15af6672.cjs.dev.js → FormData-b905ea51.cjs.dev.js} +1 -1
  32. package/dist/{NodeClient-3432a6a8.cjs.prod.js → NodeClient-174ebaf2.cjs.prod.js} +1 -1
  33. package/dist/{NodeClient-ebd71893.cjs.dev.js → NodeClient-86d70074.cjs.dev.js} +1 -1
  34. package/dist/{NodeClient-cd56cae8.esm.js → NodeClient-f1038dc6.esm.js} +1 -1
  35. package/dist/{Server-5dbcee7b.cjs.prod.js → Server-015ebdb2.cjs.prod.js} +2 -2
  36. package/dist/{Server-c08c825c.esm.js → Server-07db176b.esm.js} +2 -2
  37. package/dist/{Server-5f055bfd.cjs.dev.js → Server-d00836e3.cjs.dev.js} +2 -2
  38. package/dist/declarations/src/Sink.d.ts +1 -9
  39. package/dist/declarations/src/Sink.d.ts.map +1 -1
  40. package/dist/declarations/src/Stream.d.ts +34 -2
  41. package/dist/declarations/src/Stream.d.ts.map +1 -1
  42. package/dist/sink-5526bd6c.cjs.prod.js +52 -0
  43. package/dist/sink-a2069d86.cjs.dev.js +52 -0
  44. package/dist/sink-f7795af1.esm.js +28 -0
  45. package/dist/stream-36ca9d0a.esm.js +176 -0
  46. package/dist/stream-c01737c4.cjs.prod.js +210 -0
  47. package/dist/stream-c0c7bc20.cjs.dev.js +210 -0
  48. package/package.json +5 -5
  49. package/src/Sink.ts +1 -9
  50. package/src/Stream.ts +52 -3
  51. package/src/internal/sink.ts +28 -48
  52. package/src/internal/stream.ts +230 -49
  53. package/src/tsconfig.json +48 -0
  54. package/dist/sink-bd7ef408.esm.js +0 -34
  55. package/dist/sink-da49e187.cjs.prod.js +0 -57
  56. package/dist/sink-daf9e0e5.cjs.dev.js +0 -57
  57. package/dist/stream-1456ece0.cjs.dev.js +0 -120
  58. package/dist/stream-860139d3.esm.js +0 -94
  59. package/dist/stream-ef8b6a66.cjs.prod.js +0 -120
  60. /package/dist/{formData-632b1146.cjs.dev.js → formData-00b767b9.cjs.dev.js} +0 -0
  61. /package/dist/{formData-dd75bbe1.esm.js → formData-3a02d09f.esm.js} +0 -0
  62. /package/dist/{formData-ecf6742b.cjs.prod.js → formData-59e5f494.cjs.prod.js} +0 -0
  63. /package/dist/{incomingMessage-86bcf94d.cjs.dev.js → incomingMessage-587c8285.cjs.dev.js} +0 -0
  64. /package/dist/{incomingMessage-11c9bea6.esm.js → incomingMessage-6970f455.esm.js} +0 -0
  65. /package/dist/{incomingMessage-f56be93e.cjs.prod.js → incomingMessage-890fef7a.cjs.prod.js} +0 -0
package/src/Stream.ts CHANGED
@@ -2,10 +2,13 @@
2
2
  * @since 1.0.0
3
3
  */
4
4
  import type { SizeInput } from "@effect/platform/FileSystem"
5
+ import type { Channel } from "effect/Channel"
6
+ import type { Chunk } from "effect/Chunk"
5
7
  import type { Effect } from "effect/Effect"
6
8
  import type { LazyArg } from "effect/Function"
7
9
  import type { Stream } from "effect/Stream"
8
- import type { Readable } from "stream"
10
+ import type { Duplex, Readable } from "stream"
11
+ import type { PlatformError } from "./Error"
9
12
  import * as internal from "./internal/stream"
10
13
 
11
14
  /**
@@ -17,16 +20,62 @@ export interface FromReadableOptions {
17
20
  readonly chunkSize?: SizeInput
18
21
  }
19
22
 
23
+ /**
24
+ * @category model
25
+ * @since 1.0.0
26
+ */
27
+ export interface FromWritableOptions {
28
+ readonly endOnDone?: boolean
29
+ readonly encoding?: BufferEncoding
30
+ }
31
+
20
32
  /**
21
33
  * @category constructors
22
34
  * @since 1.0.0
23
35
  */
24
- export const fromReadable: <E, A>(
36
+ export const fromReadable: <E, A = Uint8Array>(
25
37
  evaluate: LazyArg<Readable>,
26
38
  onError: (error: unknown) => E,
27
- options?: FromReadableOptions
39
+ { chunkSize }?: FromReadableOptions
28
40
  ) => Stream<never, E, A> = internal.fromReadable
29
41
 
42
+ /**
43
+ * @category constructors
44
+ * @since 1.0.0
45
+ */
46
+ export const fromDuplex: <IE, E, I = Uint8Array, O = Uint8Array>(
47
+ evaluate: LazyArg<Duplex>,
48
+ onError: (error: unknown) => E,
49
+ options?: FromReadableOptions & FromWritableOptions
50
+ ) => Channel<never, IE, Chunk<I>, unknown, IE | E, Chunk<O>, void> = internal.fromDuplex
51
+
52
+ /**
53
+ * @category combinators
54
+ * @since 1.0.0
55
+ */
56
+ export const pipeThroughDuplex: {
57
+ <E2, B = Uint8Array>(
58
+ duplex: LazyArg<Duplex>,
59
+ onError: (error: unknown) => E2,
60
+ options?: FromReadableOptions & FromWritableOptions
61
+ ): <R, E, A>(self: Stream<R, E, A>) => Stream<R, E2 | E, B>
62
+ <R, E, A, E2, B = Uint8Array>(
63
+ self: Stream<R, E, A>,
64
+ duplex: LazyArg<Duplex>,
65
+ onError: (error: unknown) => E2,
66
+ options?: FromReadableOptions & FromWritableOptions
67
+ ): Stream<R, E | E2, B>
68
+ } = internal.pipeThroughDuplex
69
+
70
+ /**
71
+ * @category combinators
72
+ * @since 1.0.0
73
+ */
74
+ export const pipeThroughSimple: {
75
+ (duplex: LazyArg<Duplex>): <R, E>(self: Stream<R, E, string | Uint8Array>) => Stream<R, E | PlatformError, Uint8Array>
76
+ <R, E>(self: Stream<R, E, string | Uint8Array>, duplex: LazyArg<Duplex>): Stream<R, PlatformError | E, Uint8Array>
77
+ } = internal.pipeThroughSimple
78
+
30
79
  /**
31
80
  * @since 1.0.0
32
81
  * @category conversions
@@ -1,61 +1,41 @@
1
+ import * as Channel from "effect/Channel"
2
+ import type * as Chunk from "effect/Chunk"
1
3
  import * as Effect from "effect/Effect"
2
4
  import type { LazyArg } from "effect/Function"
3
- import { pipe } from "effect/Function"
4
5
  import * as Sink from "effect/Sink"
5
6
  import type { Writable } from "node:stream"
6
- import type { FromWritableOptions } from "../Sink"
7
+ import type { FromWritableOptions } from "../Stream"
8
+ import { writeEffect } from "./stream"
7
9
 
8
10
  /** @internal */
9
- export const fromWritable = <E, A>(
11
+ export const fromWritable = <E, A = Uint8Array>(
10
12
  evaluate: LazyArg<Writable>,
11
13
  onError: (error: unknown) => E,
12
- { encoding, endOnClose = true }: FromWritableOptions = {}
14
+ options: FromWritableOptions = {}
13
15
  ): Sink.Sink<never, E, A, never, void> =>
14
- endOnClose ?
15
- makeSinkWithRelease<E, A>(evaluate, onError, encoding) :
16
- makeSink<E, A>(evaluate, onError, encoding)
16
+ Sink.suspend(() => Sink.fromChannel(writeChannel(evaluate(), onError, options)))
17
17
 
18
- const makeSink = <E, A>(stream: LazyArg<Writable>, onError: (error: unknown) => E, encoding?: BufferEncoding) =>
19
- pipe(
20
- Effect.sync(stream),
21
- Effect.map((stream) => Sink.forEach(write<E, A>(stream, onError, encoding))),
22
- Sink.unwrap
23
- )
24
-
25
- const makeSinkWithRelease = <E, A>(
26
- stream: LazyArg<Writable>,
27
- onError: (error: unknown) => E,
28
- encoding?: BufferEncoding
29
- ) =>
30
- pipe(
31
- Effect.acquireRelease(Effect.sync(stream), endWritable),
32
- Effect.map((stream) => Sink.forEach(write<E, A>(stream, onError, encoding))),
33
- Sink.unwrapScoped
34
- )
35
-
36
- const endWritable = (stream: Writable) =>
37
- Effect.async<never, never, void>((resume) => {
38
- if (stream.closed) {
39
- resume(Effect.unit)
40
- return
41
- }
42
-
43
- stream.end(() => resume(Effect.unit))
44
- })
45
-
46
- const write = <E, A>(stream: Writable, onError: (error: unknown) => E, encoding?: BufferEncoding) => (_: A) =>
47
- Effect.async<never, E, void>((resume) => {
48
- const cb = (err?: Error | null) => {
49
- if (err) {
50
- resume(Effect.fail(onError(err)))
51
- } else {
18
+ const writeChannel = <IE, OE, A>(
19
+ writable: Writable,
20
+ onError: (error: unknown) => OE,
21
+ { encoding, endOnDone = true }: FromWritableOptions = {}
22
+ ): Channel.Channel<never, IE, Chunk.Chunk<A>, unknown, IE | OE, Chunk.Chunk<never>, void> => {
23
+ const write = writeEffect(writable, onError, encoding)
24
+ const close = endOnDone ?
25
+ Effect.async<never, never, void>((resume) => {
26
+ if (writable.closed) {
52
27
  resume(Effect.unit)
28
+ } else {
29
+ writable.end(() => resume(Effect.unit))
53
30
  }
54
- }
31
+ }) :
32
+ Channel.unit
55
33
 
56
- if (encoding) {
57
- stream.write(_, encoding, cb)
58
- } else {
59
- stream.write(_, cb)
60
- }
61
- })
34
+ const loop: Channel.Channel<never, IE, Chunk.Chunk<A>, unknown, OE | IE, Chunk.Chunk<never>, void> = Channel
35
+ .readWithCause({
36
+ onInput: (chunk: Chunk.Chunk<A>) => Channel.flatMap(Channel.fromEffect(write(chunk)), () => loop),
37
+ onFailure: (cause) => Channel.zipRight(close, Channel.failCause(cause)),
38
+ onDone: (_done) => close
39
+ })
40
+ return loop
41
+ }
@@ -1,62 +1,26 @@
1
1
  import type { SizeInput } from "@effect/platform/FileSystem"
2
+ import * as Channel from "effect/Channel"
3
+ import type * as AsyncInput from "effect/ChannelSingleProducerAsyncInput"
4
+ import * as Chunk from "effect/Chunk"
2
5
  import * as Effect from "effect/Effect"
6
+ import * as Either from "effect/Either"
7
+ import * as Exit from "effect/Exit"
3
8
  import type { LazyArg } from "effect/Function"
4
- import { pipe } from "effect/Function"
5
- import * as Option from "effect/Option"
9
+ import { dual, pipe } from "effect/Function"
10
+ import * as Queue from "effect/Queue"
6
11
  import * as Stream from "effect/Stream"
7
- import type { Readable } from "node:stream"
8
- import type { FromReadableOptions } from "../Stream"
12
+ import type { Duplex, Readable, Writable } from "node:stream"
13
+ import { type PlatformError, SystemError } from "../Error"
14
+ import type { FromReadableOptions, FromWritableOptions } from "../Stream"
9
15
 
10
16
  /** @internal */
11
- export const fromReadable = <E, A>(
17
+ export const fromReadable = <E, A = Uint8Array>(
12
18
  evaluate: LazyArg<Readable>,
13
19
  onError: (error: unknown) => E,
14
20
  { chunkSize }: FromReadableOptions = {}
15
21
  ): Stream.Stream<never, E, A> =>
16
- pipe(
17
- Effect.acquireRelease(Effect.sync(evaluate), (stream) =>
18
- Effect.sync(() => {
19
- stream.removeAllListeners()
20
-
21
- if (!stream.closed) {
22
- stream.destroy()
23
- }
24
- })),
25
- Effect.map((stream) =>
26
- Stream.async<never, E, Readable>((emit) => {
27
- stream.once("error", (err) => {
28
- emit.fail(onError(err))
29
- })
30
-
31
- // The 'close' event is emitted after a process has ended and the stdio
32
- // streams of a child process have been closed. This is distinct from
33
- // the 'exit' event, since multiple processes might share the same
34
- // stdio streams. The 'close' event will always emit after 'exit' was
35
- // already emitted, or 'error' if the child failed to spawn.
36
- stream.once("close", () => {
37
- emit.end()
38
- })
39
-
40
- stream.on("readable", () => {
41
- emit.single(stream)
42
- })
43
-
44
- if (stream.readable) {
45
- emit.single(stream)
46
- }
47
- }, 1)
48
- ),
49
- Stream.unwrapScoped,
50
- Stream.flatMap((_) => Stream.repeatEffectOption(readChunk<A>(_, chunkSize)))
51
- )
52
-
53
- const readChunk = <A>(
54
- stream: Readable,
55
- size: SizeInput | undefined
56
- ): Effect.Effect<never, Option.Option<never>, A> =>
57
- pipe(
58
- Effect.sync(() => (size ? stream.read(Number(size)) : stream.read()) as A | null),
59
- Effect.flatMap((_) => (_ ? Effect.succeed(_) : Effect.fail(Option.none())))
22
+ Stream.fromChannel(
23
+ readChannel<E, A>(evaluate, onError, chunkSize ? Number(chunkSize) : undefined)
60
24
  )
61
25
 
62
26
  /** @internal */
@@ -141,3 +105,220 @@ export const toUint8Array = <E>(
141
105
  })
142
106
  )
143
107
  }
108
+
109
+ /** @internal */
110
+ export const fromDuplex = <IE, E, I = Uint8Array, O = Uint8Array>(
111
+ evaluate: LazyArg<Duplex>,
112
+ onError: (error: unknown) => E,
113
+ options: FromReadableOptions & FromWritableOptions = {}
114
+ ): Channel.Channel<never, IE, Chunk.Chunk<I>, unknown, IE | E, Chunk.Chunk<O>, void> =>
115
+ Channel.acquireUseRelease(
116
+ Effect.tap(
117
+ Effect.zip(
118
+ Effect.sync(evaluate),
119
+ Queue.unbounded<Either.Either<Exit.Exit<IE | E, void>, void>>()
120
+ ),
121
+ ([duplex, queue]) => readableOffer(duplex, queue, onError)
122
+ ),
123
+ ([duplex, queue]) =>
124
+ Channel.embedInput(
125
+ readableTake(duplex, queue, options.chunkSize ? Number(options.chunkSize) : undefined),
126
+ writeInput(duplex, queue, onError, options)
127
+ ),
128
+ ([duplex, queue]) =>
129
+ Effect.zipRight(
130
+ Effect.sync(() => {
131
+ duplex.removeAllListeners()
132
+ if (!duplex.closed) {
133
+ duplex.destroy()
134
+ }
135
+ }),
136
+ Queue.shutdown(queue)
137
+ )
138
+ )
139
+
140
+ /** @internal */
141
+ export const pipeThroughDuplex = dual<
142
+ <E2, B = Uint8Array>(
143
+ duplex: LazyArg<Duplex>,
144
+ onError: (error: unknown) => E2,
145
+ options?: FromReadableOptions & FromWritableOptions
146
+ ) => <R, E, A>(self: Stream.Stream<R, E, A>) => Stream.Stream<R, E | E2, B>,
147
+ <R, E, A, E2, B = Uint8Array>(
148
+ self: Stream.Stream<R, E, A>,
149
+ duplex: LazyArg<Duplex>,
150
+ onError: (error: unknown) => E2,
151
+ options?: FromReadableOptions & FromWritableOptions
152
+ ) => Stream.Stream<R, E | E2, B>
153
+ >(
154
+ (args) => Stream.StreamTypeId in args[0],
155
+ (self, duplex, onError, options) =>
156
+ Stream.pipeThroughChannelOrFail(
157
+ self,
158
+ fromDuplex(duplex, onError, options)
159
+ )
160
+ )
161
+
162
+ /** @internal */
163
+ export const pipeThroughSimple = dual<
164
+ (
165
+ duplex: LazyArg<Duplex>
166
+ ) => <R, E>(self: Stream.Stream<R, E, string | Uint8Array>) => Stream.Stream<R, E | PlatformError, Uint8Array>,
167
+ <R, E>(
168
+ self: Stream.Stream<R, E, string | Uint8Array>,
169
+ duplex: LazyArg<Duplex>
170
+ ) => Stream.Stream<R, E | PlatformError, Uint8Array>
171
+ >(
172
+ 2,
173
+ (self, duplex) =>
174
+ Stream.pipeThroughChannelOrFail(
175
+ self,
176
+ fromDuplex(duplex, (error) =>
177
+ SystemError({
178
+ module: "Stream",
179
+ method: "pipeThroughSimple",
180
+ pathOrDescriptor: "",
181
+ reason: "Unknown",
182
+ message: String(error)
183
+ }))
184
+ )
185
+ )
186
+
187
+ const readChannel = <E, A = Uint8Array>(
188
+ evaluate: LazyArg<Readable>,
189
+ onError: (error: unknown) => E,
190
+ chunkSize: number | undefined
191
+ ): Channel.Channel<never, unknown, unknown, unknown, E, Chunk.Chunk<A>, void> =>
192
+ Channel.acquireUseRelease(
193
+ Effect.tap(
194
+ Effect.zip(
195
+ Effect.sync(evaluate),
196
+ Queue.unbounded<Either.Either<Exit.Exit<E, void>, void>>()
197
+ ),
198
+ ([readable, queue]) => readableOffer(readable, queue, onError)
199
+ ),
200
+ ([readable, queue]) => readableTake(readable, queue, chunkSize),
201
+ ([readable, queue]) =>
202
+ Effect.zipRight(
203
+ Effect.sync(() => {
204
+ readable.removeAllListeners()
205
+ if (!readable.closed) {
206
+ readable.destroy()
207
+ }
208
+ }),
209
+ Queue.shutdown(queue)
210
+ )
211
+ )
212
+
213
+ const writeInput = <IE, E, A>(
214
+ writable: Writable,
215
+ queue: Queue.Queue<Either.Either<Exit.Exit<IE | E, void>, void>>,
216
+ onError: (error: unknown) => E,
217
+ { encoding, endOnDone = true }: FromWritableOptions = {}
218
+ ): AsyncInput.AsyncInputProducer<IE, Chunk.Chunk<A>, unknown> => {
219
+ const write = writeEffect(writable, onError, encoding)
220
+ const close = endOnDone ?
221
+ Effect.async<never, never, void>((resume) => {
222
+ if (writable.closed) {
223
+ resume(Effect.unit)
224
+ } else {
225
+ writable.end(() => resume(Effect.unit))
226
+ }
227
+ }) :
228
+ Effect.unit
229
+ return {
230
+ awaitRead: () => Effect.unit,
231
+ emit: (chunk) =>
232
+ Effect.catchAllCause(
233
+ write(chunk),
234
+ (cause) => Queue.offer(queue, Either.left(Exit.failCause(cause)))
235
+ ),
236
+ error: (cause) =>
237
+ Effect.zipRight(
238
+ close,
239
+ Queue.offer(queue, Either.left(Exit.failCause(cause)))
240
+ ),
241
+ done: (_) => close
242
+ }
243
+ }
244
+
245
+ /** @internal */
246
+ export const writeEffect =
247
+ <E, A>(writable: Writable, onError: (error: unknown) => E, encoding?: BufferEncoding) => (chunk: Chunk.Chunk<A>) =>
248
+ Effect.async<never, E, void>((resume) => {
249
+ const iterator = chunk[Symbol.iterator]()
250
+ function loop() {
251
+ const item = iterator.next()
252
+ if (item.done) {
253
+ resume(Effect.unit)
254
+ } else if (encoding) {
255
+ writable.write(item.value, encoding, onDone)
256
+ } else {
257
+ writable.write(item.value, onDone)
258
+ }
259
+ }
260
+ function onDone(err: unknown) {
261
+ if (err) {
262
+ resume(Effect.fail(onError(err)))
263
+ } else {
264
+ loop()
265
+ }
266
+ }
267
+ loop()
268
+ })
269
+
270
+ const readableOffer = <E>(
271
+ readable: Readable,
272
+ queue: Queue.Queue<Either.Either<Exit.Exit<E, void>, void>>,
273
+ onError: (error: unknown) => E
274
+ ) =>
275
+ Effect.sync(() => {
276
+ readable.on("readable", () => {
277
+ const size = queue.unsafeSize()
278
+ if (size._tag === "Some" && size.value <= 0) {
279
+ queue.unsafeOffer(Either.right(void 0))
280
+ }
281
+ })
282
+ readable.on("error", (err) => {
283
+ queue.unsafeOffer(Either.left(Exit.fail(onError(err))))
284
+ })
285
+ readable.on("end", () => {
286
+ queue.unsafeOffer(Either.left(Exit.unit))
287
+ })
288
+ if (readable.readable) {
289
+ queue.unsafeOffer(Either.right(void 0))
290
+ }
291
+ })
292
+
293
+ const readableTake = <E, A>(
294
+ readable: Readable,
295
+ queue: Queue.Queue<Either.Either<Exit.Exit<E, void>, void>>,
296
+ chunkSize: number | undefined
297
+ ) => {
298
+ const read = readChunkChannel<A>(readable, chunkSize)
299
+ const loop: Channel.Channel<never, unknown, unknown, unknown, E, Chunk.Chunk<A>, void> = pipe(
300
+ Channel.fromEffect(Queue.take(queue)),
301
+ Channel.flatMap(Either.match({
302
+ onLeft: Channel.fromEffect,
303
+ onRight: (_) => Channel.flatMap(read, () => loop)
304
+ }))
305
+ )
306
+ return loop
307
+ }
308
+
309
+ const readChunkChannel = <A>(
310
+ readable: Readable,
311
+ chunkSize: number | undefined
312
+ ) =>
313
+ Channel.flatMap(
314
+ Channel.sync(() => {
315
+ const arr: Array<A> = []
316
+ let chunk = readable.read(chunkSize)
317
+ while (chunk !== null) {
318
+ arr.push(chunk)
319
+ chunk = readable.read(chunkSize)
320
+ }
321
+ return Chunk.unsafeFromArray(arr)
322
+ }),
323
+ Channel.write
324
+ )
@@ -0,0 +1,48 @@
1
+ {
2
+ "compilerOptions": {
3
+ "moduleDetection": "force",
4
+ "downlevelIteration": true,
5
+ "resolveJsonModule": true,
6
+ "esModuleInterop": true,
7
+ "skipLibCheck": true,
8
+ "emitDecoratorMetadata": true,
9
+ "experimentalDecorators": true,
10
+ "preserveSymlinks": true,
11
+ "moduleResolution": "NodeNext",
12
+ "lib": [
13
+ "ES2021",
14
+ "DOM",
15
+ "DOM.Iterable"
16
+ ],
17
+ "sourceMap": true,
18
+ "strict": true,
19
+ "noImplicitReturns": false,
20
+ "noUnusedLocals": true,
21
+ "noUnusedParameters": false,
22
+ "noFallthroughCasesInSwitch": true,
23
+ "noEmitOnError": false,
24
+ "allowJs": false,
25
+ "checkJs": false,
26
+ "forceConsistentCasingInFileNames": true,
27
+ "stripInternal": true,
28
+ "noImplicitAny": true,
29
+ "noImplicitThis": true,
30
+ "noUncheckedIndexedAccess": false,
31
+ "strictNullChecks": true,
32
+ "target": "ES2021",
33
+ "module": "NodeNext",
34
+ "incremental": true,
35
+ "removeComments": false,
36
+ "paths": {
37
+ "@effect/platform-node": [
38
+ "./index.ts"
39
+ ],
40
+ "@effect/platform-node/*": [
41
+ "./*.ts"
42
+ ]
43
+ }
44
+ },
45
+ "include": [
46
+ "**/*"
47
+ ]
48
+ }
@@ -1,34 +0,0 @@
1
- import * as Effect from 'effect/Effect';
2
- import { pipe } from 'effect/Function';
3
- import * as Sink from 'effect/Sink';
4
-
5
- /** @internal */
6
- const fromWritable = (evaluate, onError, {
7
- encoding,
8
- endOnClose = true
9
- } = {}) => endOnClose ? makeSinkWithRelease(evaluate, onError, encoding) : makeSink(evaluate, onError, encoding);
10
- const makeSink = (stream, onError, encoding) => pipe(Effect.sync(stream), Effect.map(stream => Sink.forEach(write(stream, onError, encoding))), Sink.unwrap);
11
- const makeSinkWithRelease = (stream, onError, encoding) => pipe(Effect.acquireRelease(Effect.sync(stream), endWritable), Effect.map(stream => Sink.forEach(write(stream, onError, encoding))), Sink.unwrapScoped);
12
- const endWritable = stream => Effect.async(resume => {
13
- if (stream.closed) {
14
- resume(Effect.unit);
15
- return;
16
- }
17
- stream.end(() => resume(Effect.unit));
18
- });
19
- const write = (stream, onError, encoding) => _ => Effect.async(resume => {
20
- const cb = err => {
21
- if (err) {
22
- resume(Effect.fail(onError(err)));
23
- } else {
24
- resume(Effect.unit);
25
- }
26
- };
27
- if (encoding) {
28
- stream.write(_, encoding, cb);
29
- } else {
30
- stream.write(_, cb);
31
- }
32
- });
33
-
34
- export { fromWritable as f };
@@ -1,57 +0,0 @@
1
- 'use strict';
2
-
3
- var Effect = require('effect/Effect');
4
- var Function = require('effect/Function');
5
- var Sink = require('effect/Sink');
6
-
7
- function _interopNamespace(e) {
8
- if (e && e.__esModule) return e;
9
- var n = Object.create(null);
10
- if (e) {
11
- Object.keys(e).forEach(function (k) {
12
- if (k !== 'default') {
13
- var d = Object.getOwnPropertyDescriptor(e, k);
14
- Object.defineProperty(n, k, d.get ? d : {
15
- enumerable: true,
16
- get: function () { return e[k]; }
17
- });
18
- }
19
- });
20
- }
21
- n["default"] = e;
22
- return Object.freeze(n);
23
- }
24
-
25
- var Effect__namespace = /*#__PURE__*/_interopNamespace(Effect);
26
- var Sink__namespace = /*#__PURE__*/_interopNamespace(Sink);
27
-
28
- /** @internal */
29
- const fromWritable = (evaluate, onError, {
30
- encoding,
31
- endOnClose = true
32
- } = {}) => endOnClose ? makeSinkWithRelease(evaluate, onError, encoding) : makeSink(evaluate, onError, encoding);
33
- const makeSink = (stream, onError, encoding) => Function.pipe(Effect__namespace.sync(stream), Effect__namespace.map(stream => Sink__namespace.forEach(write(stream, onError, encoding))), Sink__namespace.unwrap);
34
- const makeSinkWithRelease = (stream, onError, encoding) => Function.pipe(Effect__namespace.acquireRelease(Effect__namespace.sync(stream), endWritable), Effect__namespace.map(stream => Sink__namespace.forEach(write(stream, onError, encoding))), Sink__namespace.unwrapScoped);
35
- const endWritable = stream => Effect__namespace.async(resume => {
36
- if (stream.closed) {
37
- resume(Effect__namespace.unit);
38
- return;
39
- }
40
- stream.end(() => resume(Effect__namespace.unit));
41
- });
42
- const write = (stream, onError, encoding) => _ => Effect__namespace.async(resume => {
43
- const cb = err => {
44
- if (err) {
45
- resume(Effect__namespace.fail(onError(err)));
46
- } else {
47
- resume(Effect__namespace.unit);
48
- }
49
- };
50
- if (encoding) {
51
- stream.write(_, encoding, cb);
52
- } else {
53
- stream.write(_, cb);
54
- }
55
- });
56
-
57
- exports.fromWritable = fromWritable;
@@ -1,57 +0,0 @@
1
- 'use strict';
2
-
3
- var Effect = require('effect/Effect');
4
- var Function = require('effect/Function');
5
- var Sink = require('effect/Sink');
6
-
7
- function _interopNamespace(e) {
8
- if (e && e.__esModule) return e;
9
- var n = Object.create(null);
10
- if (e) {
11
- Object.keys(e).forEach(function (k) {
12
- if (k !== 'default') {
13
- var d = Object.getOwnPropertyDescriptor(e, k);
14
- Object.defineProperty(n, k, d.get ? d : {
15
- enumerable: true,
16
- get: function () { return e[k]; }
17
- });
18
- }
19
- });
20
- }
21
- n["default"] = e;
22
- return Object.freeze(n);
23
- }
24
-
25
- var Effect__namespace = /*#__PURE__*/_interopNamespace(Effect);
26
- var Sink__namespace = /*#__PURE__*/_interopNamespace(Sink);
27
-
28
- /** @internal */
29
- const fromWritable = (evaluate, onError, {
30
- encoding,
31
- endOnClose = true
32
- } = {}) => endOnClose ? makeSinkWithRelease(evaluate, onError, encoding) : makeSink(evaluate, onError, encoding);
33
- const makeSink = (stream, onError, encoding) => Function.pipe(Effect__namespace.sync(stream), Effect__namespace.map(stream => Sink__namespace.forEach(write(stream, onError, encoding))), Sink__namespace.unwrap);
34
- const makeSinkWithRelease = (stream, onError, encoding) => Function.pipe(Effect__namespace.acquireRelease(Effect__namespace.sync(stream), endWritable), Effect__namespace.map(stream => Sink__namespace.forEach(write(stream, onError, encoding))), Sink__namespace.unwrapScoped);
35
- const endWritable = stream => Effect__namespace.async(resume => {
36
- if (stream.closed) {
37
- resume(Effect__namespace.unit);
38
- return;
39
- }
40
- stream.end(() => resume(Effect__namespace.unit));
41
- });
42
- const write = (stream, onError, encoding) => _ => Effect__namespace.async(resume => {
43
- const cb = err => {
44
- if (err) {
45
- resume(Effect__namespace.fail(onError(err)));
46
- } else {
47
- resume(Effect__namespace.unit);
48
- }
49
- };
50
- if (encoding) {
51
- stream.write(_, encoding, cb);
52
- } else {
53
- stream.write(_, cb);
54
- }
55
- });
56
-
57
- exports.fromWritable = fromWritable;