1import { assert, describe, it } from "@effect/vitest"
2import { Deferred, Effect, Fiber, Schema, SchemaParser } from "effect"
3import { SchemaJITCompiler } from "effect/schema"
4
5describe("compiled construction concurrency", () => {
6 for (const product of ["Struct", "Tuple"] as const) {
7 it.effect(`${product} preserves bounded concurrency and runs defaults once`, () =>
8 Effect.gen(function*() {
9 const started = yield* Effect.forEach([0, 1, 2], () => Deferred.make<void>())
10 const releases = yield* Effect.forEach([0, 1, 2], () => Deferred.make<void>())
11 const calls = [0, 0, 0]
12 const fields = [0, 1, 2].map((index) =>
13 Schema.Number.pipe(Schema.withConstructorDefault(Effect.gen(function*() {
14 calls[index]++
15 yield* Deferred.succeed(started[index], undefined)
16 yield* Deferred.await(releases[index])
17 return index
18 })))
19 )
20 const schema: Schema.Codec<unknown> = product === "Struct"
21 ? Schema.Struct({ a: fields[0], b: fields[1], c: fields[2] })
22 : Schema.Tuple(fields)
23 SchemaJITCompiler.enable(schema.ast)
24 const fiber = yield* SchemaParser.makeEffect(schema)(product === "Struct" ? {} : [], {
25 parseOptions: { concurrency: 2 }
26 }).pipe(Effect.forkChild)
27 yield* Deferred.await(started[0])
28 yield* Deferred.await(started[1])
29 assert.strictEqual(yield* Deferred.isDone(started[2]), false)
30 yield* Deferred.succeed(releases[0], undefined)
31 yield* Deferred.await(started[2])
32 yield* Deferred.succeed(releases[1], undefined)
33 yield* Deferred.succeed(releases[2], undefined)
34 assert.deepStrictEqual(yield* Fiber.join(fiber), product === "Struct" ? { a: 0, b: 1, c: 2 } : [0, 1, 2])
35 assert.deepStrictEqual(calls, [1, 1, 1])
36 }))
37 }
38})