@effect/platform 0.34.0 → 0.36.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 (52) hide show
  1. package/Transferable/package.json +6 -0
  2. package/dist/cjs/Http/Server.js +6 -1
  3. package/dist/cjs/Http/Server.js.map +1 -1
  4. package/dist/cjs/Transferable.js +26 -0
  5. package/dist/cjs/Transferable.js.map +1 -0
  6. package/dist/cjs/Worker.js +16 -1
  7. package/dist/cjs/Worker.js.map +1 -1
  8. package/dist/cjs/WorkerRunner.js +6 -1
  9. package/dist/cjs/WorkerRunner.js.map +1 -1
  10. package/dist/cjs/internal/http/server.js +5 -2
  11. package/dist/cjs/internal/http/server.js.map +1 -1
  12. package/dist/cjs/internal/worker.js +63 -1
  13. package/dist/cjs/internal/worker.js.map +1 -1
  14. package/dist/cjs/internal/workerRunner.js +42 -1
  15. package/dist/cjs/internal/workerRunner.js.map +1 -1
  16. package/dist/dts/Http/Server.d.ts +18 -8
  17. package/dist/dts/Http/Server.d.ts.map +1 -1
  18. package/dist/dts/Transferable.d.ts +21 -0
  19. package/dist/dts/Transferable.d.ts.map +1 -0
  20. package/dist/dts/Worker.d.ts +72 -0
  21. package/dist/dts/Worker.d.ts.map +1 -1
  22. package/dist/dts/WorkerRunner.d.ts +11 -0
  23. package/dist/dts/WorkerRunner.d.ts.map +1 -1
  24. package/dist/esm/Http/Server.js +5 -0
  25. package/dist/esm/Http/Server.js.map +1 -1
  26. package/dist/esm/Transferable.js +19 -0
  27. package/dist/esm/Transferable.js.map +1 -0
  28. package/dist/esm/Worker.js +15 -0
  29. package/dist/esm/Worker.js.map +1 -1
  30. package/dist/esm/WorkerRunner.js +5 -0
  31. package/dist/esm/WorkerRunner.js.map +1 -1
  32. package/dist/esm/internal/http/server.js +4 -1
  33. package/dist/esm/internal/http/server.js.map +1 -1
  34. package/dist/esm/internal/worker.js +59 -0
  35. package/dist/esm/internal/worker.js.map +1 -1
  36. package/dist/esm/internal/workerRunner.js +40 -0
  37. package/dist/esm/internal/workerRunner.js.map +1 -1
  38. package/package.json +10 -10
  39. package/src/Http/Server.ts +31 -21
  40. package/src/Transferable.ts +28 -0
  41. package/src/Worker.ts +110 -0
  42. package/src/WorkerRunner.ts +26 -0
  43. package/src/internal/http/server.ts +60 -11
  44. package/src/internal/worker.ts +111 -0
  45. package/src/internal/workerRunner.ts +69 -0
  46. package/dist/cjs/index.js +0 -60
  47. package/dist/cjs/index.js.map +0 -1
  48. package/dist/dts/index.d.ts +0 -57
  49. package/dist/dts/index.d.ts.map +0 -1
  50. package/dist/esm/index.js +0 -57
  51. package/dist/esm/index.js.map +0 -1
  52. package/src/index.ts +0 -69
@@ -3,11 +3,11 @@
3
3
  */
4
4
  import type * as Context from "effect/Context"
5
5
  import type * as Effect from "effect/Effect"
6
+ import type * as Layer from "effect/Layer"
6
7
  import type * as Scope from "effect/Scope"
7
8
  import * as internal from "../internal/http/server.js"
8
9
  import type * as App from "./App.js"
9
10
  import type * as Middleware from "./Middleware.js"
10
- import type * as Error from "./ServerError.js"
11
11
  import type * as ServerRequest from "./ServerRequest.js"
12
12
 
13
13
  /**
@@ -31,16 +31,16 @@ export interface Server {
31
31
  readonly serve: {
32
32
  <R, E>(httpApp: App.Default<R, E>): Effect.Effect<
33
33
  Exclude<R, ServerRequest.ServerRequest> | Scope.Scope,
34
- Error.ServeError,
35
- never
34
+ never,
35
+ void
36
36
  >
37
37
  <R, E, App extends App.Default<any, any>>(
38
38
  httpApp: App.Default<R, E>,
39
39
  middleware: Middleware.Middleware.Applied<R, E, App>
40
40
  ): Effect.Effect<
41
41
  Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest> | Scope.Scope,
42
- Error.ServeError,
43
- never
42
+ never,
43
+ void
44
44
  >
45
45
  }
46
46
  readonly address: Address
@@ -94,7 +94,7 @@ export const make: (
94
94
  readonly serve: (
95
95
  httpApp: App.Default<never, unknown>,
96
96
  middleware?: Middleware.Middleware
97
- ) => Effect.Effect<Scope.Scope, Error.ServeError, never>
97
+ ) => Effect.Effect<Scope.Scope, never, void>
98
98
  readonly address: Address
99
99
  }
100
100
  ) => Server = internal.make
@@ -104,31 +104,41 @@ export const make: (
104
104
  * @category accessors
105
105
  */
106
106
  export const serve: {
107
+ (): <R, E>(httpApp: App.Default<R, E>) => Layer.Layer<Server | Exclude<R, ServerRequest.ServerRequest>, never, never>
108
+ <R, E, App extends App.Default<any, any>>(
109
+ middleware: Middleware.Middleware.Applied<R, E, App>
110
+ ): (
111
+ httpApp: App.Default<R, E>
112
+ ) => Layer.Layer<Server | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest>, never, never>
113
+ <R, E>(httpApp: App.Default<R, E>): Layer.Layer<Server | Exclude<R, ServerRequest.ServerRequest>, never, never>
114
+ <R, E, App extends App.Default<any, any>>(
115
+ httpApp: App.Default<R, E>,
116
+ middleware: Middleware.Middleware.Applied<R, E, App>
117
+ ): Layer.Layer<Server | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest>, never, never>
118
+ } = internal.serve
119
+
120
+ /**
121
+ * @since 1.0.0
122
+ * @category accessors
123
+ */
124
+ export const serveEffect: {
107
125
  (): <R, E>(
108
126
  httpApp: App.Default<R, E>
109
- ) => Effect.Effect<
110
- Server | Scope.Scope | Exclude<R, ServerRequest.ServerRequest>,
111
- Error.ServeError,
112
- never
113
- >
127
+ ) => Effect.Effect<Scope.Scope | Server | Exclude<R, ServerRequest.ServerRequest>, never, void>
114
128
  <R, E, App extends App.Default<any, any>>(
115
129
  middleware: Middleware.Middleware.Applied<R, E, App>
116
130
  ): (
117
131
  httpApp: App.Default<R, E>
118
132
  ) => Effect.Effect<
119
- Server | Scope.Scope | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest>,
120
- Error.ServeError,
121
- never
133
+ Scope.Scope | Server | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest>,
134
+ never,
135
+ void
122
136
  >
123
137
  <R, E>(
124
138
  httpApp: App.Default<R, E>
125
- ): Effect.Effect<Server | Scope.Scope | Exclude<R, ServerRequest.ServerRequest>, Error.ServeError, never>
139
+ ): Effect.Effect<Scope.Scope | Server | Exclude<R, ServerRequest.ServerRequest>, never, void>
126
140
  <R, E, App extends App.Default<any, any>>(
127
141
  httpApp: App.Default<R, E>,
128
142
  middleware: Middleware.Middleware.Applied<R, E, App>
129
- ): Effect.Effect<
130
- Server | Scope.Scope | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest>,
131
- Error.ServeError,
132
- never
133
- >
134
- } = internal.serve
143
+ ): Effect.Effect<Scope.Scope | Server | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest>, never, void>
144
+ } = internal.serveEffect
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @since 1.0.0
3
+ */
4
+
5
+ /**
6
+ * @since 1.0.0
7
+ * @category symbols
8
+ */
9
+ export const symbol = Symbol.for("@effect/platform/Transferable")
10
+
11
+ /**
12
+ * @since 1.0.0
13
+ * @category models
14
+ */
15
+ export interface Transferable {
16
+ readonly [symbol]: () => ReadonlyArray<globalThis.Transferable>
17
+ }
18
+
19
+ /**
20
+ * @since 1.0.0
21
+ * @category accessors
22
+ */
23
+ export const get = (u: unknown): ReadonlyArray<globalThis.Transferable> => {
24
+ if (typeof u === "object" && u !== null && symbol in u) {
25
+ return (u as Transferable)[symbol]()
26
+ }
27
+ return []
28
+ }
package/src/Worker.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  /**
2
2
  * @since 1.0.0
3
3
  */
4
+ import type * as ParseResult from "@effect/schema/ParseResult"
5
+ import type * as Schema from "@effect/schema/Schema"
6
+ import type * as Serializable from "@effect/schema/Serializable"
4
7
  import type * as Context from "effect/Context"
5
8
  import type * as Duration from "effect/Duration"
6
9
  import type * as Effect from "effect/Effect"
@@ -210,3 +213,110 @@ export const makePoolLayer: <W>(
210
213
  tag: Context.Tag<Tag, WorkerPool<I, E, O>>,
211
214
  options: WorkerPool.Options<I, W>
212
215
  ) => Layer.Layer<never, never, Tag> = internal.makePoolLayer
216
+
217
+ /**
218
+ * @since 1.0.0
219
+ * @category models
220
+ */
221
+ export interface SerializedWorker<I extends Schema.TaggedRequest.Any> {
222
+ readonly id: number
223
+ readonly join: Effect.Effect<never, WorkerError, never>
224
+ readonly execute: <Req extends I>(
225
+ message: Req
226
+ ) => Req extends Serializable.WithResult<infer _IE, infer E, infer _IA, infer A>
227
+ ? Stream.Stream<never, E | WorkerError | ParseResult.ParseError, A>
228
+ : never
229
+ readonly executeEffect: <Req extends I>(
230
+ message: Req
231
+ ) => Req extends Serializable.WithResult<infer _IE, infer E, infer _IA, infer A>
232
+ ? Effect.Effect<never, E | WorkerError | ParseResult.ParseError, A>
233
+ : never
234
+ }
235
+
236
+ /**
237
+ * @since 1.0.0
238
+ * @category models
239
+ */
240
+ export declare namespace SerializedWorker {
241
+ /**
242
+ * @since 1.0.0
243
+ * @category models
244
+ */
245
+ export interface Options<I, W = unknown> {
246
+ readonly spawn: (id: number) => W
247
+ readonly permits?: number
248
+ readonly queue?: WorkerQueue<I>
249
+ }
250
+ }
251
+
252
+ /**
253
+ * @since 1.0.0
254
+ * @category models
255
+ */
256
+ export interface SerializedWorkerPool<I extends Schema.TaggedRequest.Any> {
257
+ readonly backing: Pool.Pool<WorkerError, SerializedWorker<I>>
258
+ readonly broadcast: <Req extends I>(
259
+ message: Req
260
+ ) => Req extends Serializable.WithResult<infer _IE, infer E, infer _IA, infer _A>
261
+ ? Effect.Effect<never, E | WorkerError | ParseResult.ParseError, void>
262
+ : never
263
+ readonly execute: <Req extends I>(
264
+ message: Req
265
+ ) => Req extends Serializable.WithResult<infer _IE, infer E, infer _IA, infer A>
266
+ ? Stream.Stream<never, E | WorkerError | ParseResult.ParseError, A>
267
+ : never
268
+ readonly executeEffect: <Req extends I>(
269
+ message: Req
270
+ ) => Req extends Serializable.WithResult<infer _IE, infer E, infer _IA, infer A>
271
+ ? Effect.Effect<never, E | WorkerError | ParseResult.ParseError, A>
272
+ : never
273
+ }
274
+
275
+ /**
276
+ * @since 1.0.0
277
+ * @category models
278
+ */
279
+ export declare namespace SerializedWorkerPool {
280
+ /**
281
+ * @since 1.0.0
282
+ * @category models
283
+ */
284
+ export type Options<I, W = unknown> =
285
+ & SerializedWorker.Options<I, W>
286
+ & ({
287
+ readonly onCreate?: (worker: Worker<I, unknown, unknown>) => Effect.Effect<never, WorkerError, void>
288
+ readonly size: number
289
+ } | {
290
+ readonly onCreate?: (worker: Worker<I, unknown, unknown>) => Effect.Effect<never, WorkerError, void>
291
+ readonly minSize: number
292
+ readonly maxSize: number
293
+ readonly timeToLive: Duration.DurationInput
294
+ })
295
+ }
296
+
297
+ /**
298
+ * @since 1.0.0
299
+ * @category constructors
300
+ */
301
+ export const makeSerialized: <I extends Schema.TaggedRequest.Any, W = unknown>(
302
+ options: SerializedWorker.Options<I, W>
303
+ ) => Effect.Effect<WorkerManager | Scope.Scope, WorkerError, SerializedWorker<I>> = internal.makeSerialized
304
+
305
+ /**
306
+ * @since 1.0.0
307
+ * @category constructors
308
+ */
309
+ export const makePoolSerialized: <W>() => <I extends Schema.TaggedRequest.Any>(
310
+ options: SerializedWorkerPool.Options<I, W>
311
+ ) => Effect.Effect<WorkerManager | Scope.Scope, never, SerializedWorkerPool<I>> = internal.makePoolSerialized
312
+
313
+ /**
314
+ * @since 1.0.0
315
+ * @category layers
316
+ */
317
+ export const makePoolSerializedLayer: <W>(
318
+ managerLayer: Layer.Layer<never, never, WorkerManager>
319
+ ) => <Tag, I extends Schema.TaggedRequest.Any>(
320
+ tag: Context.Tag<Tag, SerializedWorkerPool<I>>,
321
+ options: SerializedWorkerPool.Options<I, W>
322
+ ) => Layer.Layer<never, never, Tag> = internal.makePoolSerializedLayer
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * @since 1.0.0
3
3
  */
4
+ import type * as Schema from "@effect/schema/Schema"
5
+ import type * as Serializable from "@effect/schema/Serializable"
4
6
  import type * as Context from "effect/Context"
5
7
  import type * as Effect from "effect/Effect"
6
8
  import type * as Fiber from "effect/Fiber"
@@ -82,3 +84,27 @@ export const make: <I, R, E, O>(
82
84
  process: (request: I) => Stream.Stream<R, E, O> | Effect.Effect<R, E, O>,
83
85
  options?: Runner.Options<O> | undefined
84
86
  ) => Effect.Effect<Scope.Scope | R | PlatformRunner, WorkerError, never> = internal.make
87
+
88
+ /**
89
+ * @since 1.0.0
90
+ * @category constructors
91
+ */
92
+ export const makeSerialized: <
93
+ I,
94
+ A extends Schema.TaggedRequest.Any,
95
+ Handlers extends {
96
+ readonly [K in A["_tag"]]: Extract<A, { readonly _tag: K }> extends
97
+ Serializable.SerializableWithResult<infer _IS, infer S, infer _IE, infer E, infer _IO, infer O>
98
+ ? (_: S) => Stream.Stream<any, E, O> | Effect.Effect<any, E, O> :
99
+ never
100
+ }
101
+ >(
102
+ schema: Schema.Schema<I, A>,
103
+ handlers: Handlers
104
+ ) => Effect.Effect<
105
+ | PlatformRunner
106
+ | Scope.Scope
107
+ | (ReturnType<Handlers[keyof Handlers]> extends Stream.Stream<infer R, infer _E, infer _A> ? R : never),
108
+ WorkerError,
109
+ never
110
+ > = internal.makeSerialized
@@ -1,11 +1,11 @@
1
1
  import * as Context from "effect/Context"
2
2
  import * as Effect from "effect/Effect"
3
3
  import { dual } from "effect/Function"
4
+ import * as Layer from "effect/Layer"
4
5
  import type * as Scope from "effect/Scope"
5
6
  import type * as App from "../../Http/App.js"
6
7
  import type * as Middleware from "../../Http/Middleware.js"
7
8
  import type * as Server from "../../Http/Server.js"
8
- import type * as Error from "../../Http/ServerError.js"
9
9
  import type * as ServerRequest from "../../Http/ServerRequest.js"
10
10
 
11
11
  /** @internal */
@@ -27,40 +27,89 @@ export const make = (
27
27
  readonly serve: (
28
28
  httpApp: App.Default<never, unknown>,
29
29
  middleware?: Middleware.Middleware
30
- ) => Effect.Effect<Scope.Scope, Error.ServeError, never>
30
+ ) => Effect.Effect<Scope.Scope, never, void>
31
31
  readonly address: Server.Address
32
32
  }
33
33
  ): Server.Server => Object.assign(Object.create(serverProto), options)
34
34
 
35
35
  /** @internal */
36
36
  export const serve = dual<
37
+ {
38
+ (): <R, E>(
39
+ httpApp: App.Default<R, E>
40
+ ) => Layer.Layer<
41
+ Server.Server | Exclude<R, ServerRequest.ServerRequest>,
42
+ never,
43
+ never
44
+ >
45
+ <R, E, App extends App.Default<any, any>>(middleware: Middleware.Middleware.Applied<R, E, App>): (
46
+ httpApp: App.Default<R, E>
47
+ ) => Layer.Layer<
48
+ Server.Server | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest>,
49
+ never,
50
+ never
51
+ >
52
+ },
53
+ {
54
+ <R, E>(
55
+ httpApp: App.Default<R, E>
56
+ ): Layer.Layer<Server.Server | Exclude<R, ServerRequest.ServerRequest>, never, never>
57
+ <R, E, App extends App.Default<any, any>>(
58
+ httpApp: App.Default<R, E>,
59
+ middleware: Middleware.Middleware.Applied<R, E, App>
60
+ ): Layer.Layer<
61
+ Server.Server | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest>,
62
+ never,
63
+ never
64
+ >
65
+ }
66
+ >(
67
+ (args) => Effect.isEffect(args[0]),
68
+ <R, E, App extends App.Default<any, any>>(
69
+ httpApp: App.Default<R, E>,
70
+ middleware?: Middleware.Middleware.Applied<R, E, App>
71
+ ): Layer.Layer<
72
+ Server.Server | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest>,
73
+ never,
74
+ never
75
+ > =>
76
+ Layer.scopedDiscard(
77
+ Effect.flatMap(
78
+ serverTag,
79
+ (server) => server.serve(httpApp, middleware!)
80
+ )
81
+ ) as any
82
+ )
83
+
84
+ /** @internal */
85
+ export const serveEffect = dual<
37
86
  {
38
87
  (): <R, E>(
39
88
  httpApp: App.Default<R, E>
40
89
  ) => Effect.Effect<
41
90
  Server.Server | Scope.Scope | Exclude<R, ServerRequest.ServerRequest>,
42
- Error.ServeError,
43
- never
91
+ never,
92
+ void
44
93
  >
45
94
  <R, E, App extends App.Default<any, any>>(middleware: Middleware.Middleware.Applied<R, E, App>): (
46
95
  httpApp: App.Default<R, E>
47
96
  ) => Effect.Effect<
48
97
  Server.Server | Scope.Scope | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest>,
49
- Error.ServeError,
50
- never
98
+ never,
99
+ void
51
100
  >
52
101
  },
53
102
  {
54
103
  <R, E>(
55
104
  httpApp: App.Default<R, E>
56
- ): Effect.Effect<Server.Server | Scope.Scope | Exclude<R, ServerRequest.ServerRequest>, Error.ServeError, never>
105
+ ): Effect.Effect<Server.Server | Scope.Scope | Exclude<R, ServerRequest.ServerRequest>, never, void>
57
106
  <R, E, App extends App.Default<any, any>>(
58
107
  httpApp: App.Default<R, E>,
59
108
  middleware: Middleware.Middleware.Applied<R, E, App>
60
109
  ): Effect.Effect<
61
110
  Server.Server | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest> | Scope.Scope,
62
- Error.ServeError,
63
- never
111
+ never,
112
+ void
64
113
  >
65
114
  }
66
115
  >(
@@ -70,8 +119,8 @@ export const serve = dual<
70
119
  middleware: Middleware.Middleware.Applied<R, E, App>
71
120
  ): Effect.Effect<
72
121
  Server.Server | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest> | Scope.Scope,
73
- Error.ServeError,
74
- never
122
+ never,
123
+ void
75
124
  > =>
76
125
  Effect.flatMap(
77
126
  serverTag,
@@ -1,3 +1,5 @@
1
+ import * as Schema from "@effect/schema/Schema"
2
+ import * as Serializable from "@effect/schema/Serializable"
1
3
  import * as Cause from "effect/Cause"
2
4
  import * as Channel from "effect/Channel"
3
5
  import * as Chunk from "effect/Chunk"
@@ -10,7 +12,9 @@ import { identity, pipe } from "effect/Function"
10
12
  import * as Layer from "effect/Layer"
11
13
  import * as Pool from "effect/Pool"
12
14
  import * as Queue from "effect/Queue"
15
+ import type * as Scope from "effect/Scope"
13
16
  import * as Stream from "effect/Stream"
17
+ import * as Transferable from "../Transferable.js"
14
18
  import type * as Worker from "../Worker.js"
15
19
  import type { WorkerError } from "../WorkerError.js"
16
20
 
@@ -284,3 +288,110 @@ export const makePoolLayer = <W>(managerLayer: Layer.Layer<never, never, Worker.
284
288
  tag: Context.Tag<Tag, Worker.WorkerPool<I, E, O>>,
285
289
  options: Worker.WorkerPool.Options<I, W>
286
290
  ) => Layer.scoped(tag, makePool<W>()(options)).pipe(Layer.provide(managerLayer))
291
+
292
+ /** @internal */
293
+ export const makeSerialized = <
294
+ I extends Schema.TaggedRequest.Any,
295
+ W = unknown
296
+ >(
297
+ options: Worker.SerializedWorker.Options<I, W>
298
+ ): Effect.Effect<Worker.WorkerManager | Scope.Scope, WorkerError, Worker.SerializedWorker<I>> =>
299
+ Effect.gen(function*(_) {
300
+ const manager = yield* _(WorkerManager)
301
+ const backing = yield* _(
302
+ manager.spawn({
303
+ ...options,
304
+ transfers(message) {
305
+ return Transferable.get(message)
306
+ }
307
+ })
308
+ )
309
+ const execute = <Req extends I>(message: Req) => {
310
+ const parseSuccess = Schema.decode(Serializable.successSchema(message as any))
311
+ const parseFailure = Schema.decode(Serializable.failureSchema(message as any))
312
+ return pipe(
313
+ Serializable.serialize(message),
314
+ Stream.flatMap((message) => backing.execute(message)),
315
+ Stream.catchAll((error) => Effect.flatMap(parseFailure(error), Effect.fail)),
316
+ Stream.mapEffect(parseSuccess)
317
+ )
318
+ }
319
+ const executeEffect = <Req extends I>(message: Req) => {
320
+ const parseSuccess = Schema.decode(Serializable.successSchema(message as any))
321
+ const parseFailure = Schema.decode(Serializable.failureSchema(message as any))
322
+ return pipe(
323
+ Serializable.serialize(message),
324
+ Effect.flatMap((message) => backing.executeEffect(message)),
325
+ Effect.matchEffect({
326
+ onFailure: (error) => Effect.flatMap(parseFailure(error), Effect.fail),
327
+ onSuccess: parseSuccess
328
+ })
329
+ )
330
+ }
331
+ return identity<Worker.SerializedWorker<I>>({
332
+ id: backing.id,
333
+ join: backing.join,
334
+ execute: execute as any,
335
+ executeEffect: executeEffect as any
336
+ })
337
+ })
338
+
339
+ /** @internal */
340
+ export const makePoolSerialized = <W>() =>
341
+ <I extends Schema.TaggedRequest.Any>(
342
+ options: Worker.SerializedWorkerPool.Options<I, W>
343
+ ) =>
344
+ Effect.gen(function*(_) {
345
+ const manager = yield* _(WorkerManager)
346
+ const workers = new Set<Worker.SerializedWorker<I>>()
347
+ const acquire = pipe(
348
+ makeSerialized<I, W>(options),
349
+ Effect.tap((worker) => Effect.sync(() => workers.add(worker))),
350
+ Effect.tap((worker) => Effect.addFinalizer(() => Effect.sync(() => workers.delete(worker)))),
351
+ options.onCreate ? Effect.tap(options.onCreate) : identity,
352
+ Effect.provideService(WorkerManager, manager)
353
+ )
354
+ const backing = yield* _(
355
+ "timeToLive" in options ?
356
+ Pool.makeWithTTL({
357
+ acquire,
358
+ min: options.minSize,
359
+ max: options.maxSize,
360
+ timeToLive: options.timeToLive
361
+ }) :
362
+ Pool.make({
363
+ acquire,
364
+ size: options.size
365
+ })
366
+ )
367
+ const pool: Worker.SerializedWorkerPool<I> = {
368
+ backing,
369
+ broadcast: <Req extends I>(message: Req) =>
370
+ Effect.forEach(workers, (worker) => worker.executeEffect(message), {
371
+ concurrency: "unbounded",
372
+ discard: true
373
+ }) as any,
374
+ execute: <Req extends I>(message: Req) =>
375
+ Stream.unwrap(
376
+ Effect.map(
377
+ Effect.scoped(backing.get),
378
+ (worker) => worker.execute(message)
379
+ )
380
+ ) as any,
381
+ executeEffect: <Req extends I>(message: Req) =>
382
+ Effect.flatMap(
383
+ Effect.scoped(backing.get),
384
+ (worker) => worker.executeEffect(message)
385
+ ) as any
386
+ }
387
+
388
+ return pool
389
+ })
390
+
391
+ /** @internal */
392
+ export const makePoolSerializedLayer =
393
+ <W>(managerLayer: Layer.Layer<never, never, Worker.WorkerManager>) =>
394
+ <Tag, I extends Schema.TaggedRequest.Any>(
395
+ tag: Context.Tag<Tag, Worker.SerializedWorkerPool<I>>,
396
+ options: Worker.SerializedWorkerPool.Options<I, W>
397
+ ) => Layer.scoped(tag, makePoolSerialized<W>()(options)).pipe(Layer.provide(managerLayer))
@@ -1,11 +1,16 @@
1
+ import * as Schema from "@effect/schema/Schema"
2
+ import * as Serializable from "@effect/schema/Serializable"
1
3
  import * as Cause from "effect/Cause"
2
4
  import * as Context from "effect/Context"
3
5
  import * as Effect from "effect/Effect"
4
6
  import * as Either from "effect/Either"
5
7
  import * as Fiber from "effect/Fiber"
6
8
  import { pipe } from "effect/Function"
9
+ import * as Predicate from "effect/Predicate"
7
10
  import * as Queue from "effect/Queue"
11
+ import type * as Scope from "effect/Scope"
8
12
  import * as Stream from "effect/Stream"
13
+ import * as Transferable from "../Transferable.js"
9
14
  import type * as Worker from "../Worker.js"
10
15
  import type * as WorkerError from "../WorkerError.js"
11
16
  import type * as WorkerRunner from "../WorkerRunner.js"
@@ -90,3 +95,67 @@ export const make = <I, R, E, O>(
90
95
  ], { concurrency: "unbounded", discard: true }) as Effect.Effect<R, WorkerError.WorkerError, never>
91
96
  )
92
97
  })
98
+
99
+ /** @internal */
100
+ export const makeSerialized = <
101
+ I,
102
+ A extends Schema.TaggedRequest.Any,
103
+ const Handlers extends {
104
+ readonly [K in A["_tag"]]: Extract<A, { readonly _tag: K }> extends
105
+ Serializable.SerializableWithResult<infer _IS, infer S, infer _IE, infer E, infer _IO, infer O>
106
+ ? (_: S) => Stream.Stream<any, E, O> | Effect.Effect<any, E, O> :
107
+ never
108
+ }
109
+ >(
110
+ schema: Schema.Schema<I, A>,
111
+ handlers: Handlers
112
+ ): Effect.Effect<
113
+ | WorkerRunner.PlatformRunner
114
+ | Scope.Scope
115
+ | (ReturnType<Handlers[keyof Handlers]> extends Stream.Stream<infer R, infer _E, infer _A> ? R : never),
116
+ WorkerError.WorkerError,
117
+ never
118
+ > => {
119
+ const parseRequest = Schema.decode(schema)
120
+ const effectTags = new Set<string>()
121
+ return make((request: I) => {
122
+ if (Predicate.hasProperty(request, "_tag") && effectTags.has(request._tag as string)) {
123
+ return Effect.flatMap(parseRequest(request), (request: A) => {
124
+ const handler =
125
+ (handlers as unknown as Record<string, (req: unknown) => Effect.Effect<never, any, any>>)[request._tag]
126
+ if (!handler) {
127
+ return Effect.dieMessage(`No handler for ${request._tag}`)
128
+ }
129
+ const encodeSuccess = Schema.encode(Serializable.successSchema(request as any))
130
+ return pipe(
131
+ Effect.matchEffect(handler(request), {
132
+ onFailure: (error) => Effect.flatMap(Serializable.serializeFailure(request as any, error), Effect.fail),
133
+ onSuccess: encodeSuccess
134
+ })
135
+ )
136
+ })
137
+ }
138
+
139
+ return Stream.flatMap(parseRequest(request), (request: A) => {
140
+ const handler =
141
+ (handlers as unknown as Record<string, (req: unknown) => Stream.Stream<never, any, any>>)[request._tag]
142
+ if (!handler) {
143
+ return Stream.dieMessage(`No handler for ${request._tag}`)
144
+ }
145
+ const encodeSuccess = Schema.encode(Serializable.successSchema(request as any))
146
+ const stream = handler(request)
147
+ if (Effect.isEffect(stream)) {
148
+ effectTags.add(request._tag)
149
+ }
150
+ return pipe(
151
+ stream,
152
+ Stream.catchAll((error) => Effect.flatMap(Serializable.serializeFailure(request as any, error), Effect.fail)),
153
+ Stream.mapEffect(encodeSuccess)
154
+ )
155
+ })
156
+ }, {
157
+ transfers(message) {
158
+ return Transferable.get(message)
159
+ }
160
+ })
161
+ }
package/dist/cjs/index.js DELETED
@@ -1,60 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.WorkerRunner = exports.WorkerError = exports.Worker = exports.Terminal = exports.Runtime = exports.Path = exports.KeyValueStore = exports.HttpServer = exports.HttpClient = exports.FileSystem = exports.Error = exports.Effectify = exports.CommandExecutor = exports.Command = void 0;
7
- var _Command = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Command.js"));
8
- exports.Command = _Command;
9
- var _CommandExecutor = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./CommandExecutor.js"));
10
- exports.CommandExecutor = _CommandExecutor;
11
- var _Effectify = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Effectify.js"));
12
- exports.Effectify = _Effectify;
13
- var _Error = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Error.js"));
14
- exports.Error = _Error;
15
- var _FileSystem = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./FileSystem.js"));
16
- exports.FileSystem = _FileSystem;
17
- var _HttpClient = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./HttpClient.js"));
18
- exports.HttpClient = _HttpClient;
19
- var _HttpServer = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./HttpServer.js"));
20
- exports.HttpServer = _HttpServer;
21
- var _KeyValueStore = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./KeyValueStore.js"));
22
- exports.KeyValueStore = _KeyValueStore;
23
- var _Path = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Path.js"));
24
- exports.Path = _Path;
25
- var _Runtime = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Runtime.js"));
26
- exports.Runtime = _Runtime;
27
- var _Terminal = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Terminal.js"));
28
- exports.Terminal = _Terminal;
29
- var _Worker = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./Worker.js"));
30
- exports.Worker = _Worker;
31
- var _WorkerError = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./WorkerError.js"));
32
- exports.WorkerError = _WorkerError;
33
- var _WorkerRunner = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("./WorkerRunner.js"));
34
- exports.WorkerRunner = _WorkerRunner;
35
- function _getRequireWildcardCache(e) {
36
- if ("function" != typeof WeakMap) return null;
37
- var r = new WeakMap(),
38
- t = new WeakMap();
39
- return (_getRequireWildcardCache = function (e) {
40
- return e ? t : r;
41
- })(e);
42
- }
43
- function _interopRequireWildcard(e, r) {
44
- if (!r && e && e.__esModule) return e;
45
- if (null === e || "object" != typeof e && "function" != typeof e) return {
46
- default: e
47
- };
48
- var t = _getRequireWildcardCache(r);
49
- if (t && t.has(e)) return t.get(e);
50
- var n = {
51
- __proto__: null
52
- },
53
- a = Object.defineProperty && Object.getOwnPropertyDescriptor;
54
- for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) {
55
- var i = a ? Object.getOwnPropertyDescriptor(e, u) : null;
56
- i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u];
57
- }
58
- return n.default = e, t && t.set(e, n), n;
59
- }
60
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":""}