effect 4.0.0-beta.50 → 4.0.0-beta.52

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 (135) hide show
  1. package/dist/BigDecimal.d.ts.map +1 -1
  2. package/dist/BigDecimal.js +18 -14
  3. package/dist/BigDecimal.js.map +1 -1
  4. package/dist/BigInt.d.ts.map +1 -1
  5. package/dist/BigInt.js +4 -4
  6. package/dist/BigInt.js.map +1 -1
  7. package/dist/Brand.d.ts +2 -4
  8. package/dist/Brand.d.ts.map +1 -1
  9. package/dist/Brand.js.map +1 -1
  10. package/dist/Data.js +2 -2
  11. package/dist/Data.js.map +1 -1
  12. package/dist/Duration.js +1 -1
  13. package/dist/Duration.js.map +1 -1
  14. package/dist/Schema.d.ts +77 -10
  15. package/dist/Schema.d.ts.map +1 -1
  16. package/dist/Schema.js +119 -18
  17. package/dist/Schema.js.map +1 -1
  18. package/dist/SchemaAST.d.ts +6 -0
  19. package/dist/SchemaAST.d.ts.map +1 -1
  20. package/dist/SchemaAST.js +216 -229
  21. package/dist/SchemaAST.js.map +1 -1
  22. package/dist/SchemaGetter.d.ts +3 -5
  23. package/dist/SchemaGetter.d.ts.map +1 -1
  24. package/dist/SchemaGetter.js +3 -2
  25. package/dist/SchemaGetter.js.map +1 -1
  26. package/dist/SchemaIssue.d.ts.map +1 -1
  27. package/dist/SchemaIssue.js +29 -11
  28. package/dist/SchemaIssue.js.map +1 -1
  29. package/dist/SchemaParser.js +14 -2
  30. package/dist/SchemaParser.js.map +1 -1
  31. package/dist/index.d.ts +3 -0
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/internal/effect.js +142 -65
  36. package/dist/internal/effect.js.map +1 -1
  37. package/dist/internal/schema/representation.js +1 -2
  38. package/dist/internal/schema/representation.js.map +1 -1
  39. package/dist/internal/schema/schema.d.ts.map +1 -1
  40. package/dist/internal/schema/schema.js +37 -0
  41. package/dist/internal/schema/schema.js.map +1 -1
  42. package/dist/unstable/ai/McpServer.d.ts.map +1 -1
  43. package/dist/unstable/ai/McpServer.js +7 -0
  44. package/dist/unstable/ai/McpServer.js.map +1 -1
  45. package/dist/unstable/cli/index.d.ts +2 -0
  46. package/dist/unstable/cli/index.d.ts.map +1 -1
  47. package/dist/unstable/cli/index.js +2 -0
  48. package/dist/unstable/cli/index.js.map +1 -1
  49. package/dist/unstable/cluster/Runners.d.ts.map +1 -1
  50. package/dist/unstable/cluster/Runners.js +3 -2
  51. package/dist/unstable/cluster/Runners.js.map +1 -1
  52. package/dist/unstable/cluster/SqlMessageStorage.d.ts.map +1 -1
  53. package/dist/unstable/cluster/SqlMessageStorage.js +1 -0
  54. package/dist/unstable/cluster/SqlMessageStorage.js.map +1 -1
  55. package/dist/unstable/cluster/SqlRunnerStorage.d.ts.map +1 -1
  56. package/dist/unstable/cluster/SqlRunnerStorage.js +6 -6
  57. package/dist/unstable/cluster/SqlRunnerStorage.js.map +1 -1
  58. package/dist/unstable/eventlog/SqlEventJournal.d.ts.map +1 -1
  59. package/dist/unstable/eventlog/SqlEventJournal.js +9 -8
  60. package/dist/unstable/eventlog/SqlEventJournal.js.map +1 -1
  61. package/dist/unstable/eventlog/SqlEventLogServerEncrypted.d.ts.map +1 -1
  62. package/dist/unstable/eventlog/SqlEventLogServerEncrypted.js +6 -5
  63. package/dist/unstable/eventlog/SqlEventLogServerEncrypted.js.map +1 -1
  64. package/dist/unstable/eventlog/SqlEventLogServerUnencrypted.d.ts.map +1 -1
  65. package/dist/unstable/eventlog/SqlEventLogServerUnencrypted.js +6 -5
  66. package/dist/unstable/eventlog/SqlEventLogServerUnencrypted.js.map +1 -1
  67. package/dist/unstable/httpapi/HttpApi.js.map +1 -1
  68. package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
  69. package/dist/unstable/httpapi/HttpApiBuilder.js +11 -6
  70. package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
  71. package/dist/unstable/httpapi/HttpApiClient.d.ts +5 -6
  72. package/dist/unstable/httpapi/HttpApiClient.d.ts.map +1 -1
  73. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  74. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts +17 -18
  75. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts.map +1 -1
  76. package/dist/unstable/httpapi/HttpApiEndpoint.js +1 -2
  77. package/dist/unstable/httpapi/HttpApiEndpoint.js.map +1 -1
  78. package/dist/unstable/httpapi/HttpApiError.d.ts +28 -8
  79. package/dist/unstable/httpapi/HttpApiError.d.ts.map +1 -1
  80. package/dist/unstable/httpapi/HttpApiError.js +28 -15
  81. package/dist/unstable/httpapi/HttpApiError.js.map +1 -1
  82. package/dist/unstable/httpapi/HttpApiMiddleware.d.ts +4 -3
  83. package/dist/unstable/httpapi/HttpApiMiddleware.d.ts.map +1 -1
  84. package/dist/unstable/httpapi/HttpApiMiddleware.js +2 -2
  85. package/dist/unstable/httpapi/HttpApiMiddleware.js.map +1 -1
  86. package/dist/unstable/httpapi/OpenApi.d.ts +1 -10
  87. package/dist/unstable/httpapi/OpenApi.d.ts.map +1 -1
  88. package/dist/unstable/httpapi/OpenApi.js +2 -11
  89. package/dist/unstable/httpapi/OpenApi.js.map +1 -1
  90. package/dist/unstable/observability/OtlpMetrics.js +1 -1
  91. package/dist/unstable/observability/OtlpMetrics.js.map +1 -1
  92. package/dist/unstable/observability/internal/protobuf.js +4 -4
  93. package/dist/unstable/observability/internal/protobuf.js.map +1 -1
  94. package/dist/unstable/rpc/RpcSerialization.d.ts +11 -0
  95. package/dist/unstable/rpc/RpcSerialization.d.ts.map +1 -1
  96. package/dist/unstable/rpc/RpcSerialization.js +14 -9
  97. package/dist/unstable/rpc/RpcSerialization.js.map +1 -1
  98. package/package.json +1 -1
  99. package/src/BigDecimal.ts +20 -16
  100. package/src/BigInt.ts +4 -4
  101. package/src/Brand.ts +2 -4
  102. package/src/Data.ts +1 -1
  103. package/src/Duration.ts +1 -1
  104. package/src/Schema.ts +183 -23
  105. package/src/SchemaAST.ts +315 -267
  106. package/src/SchemaGetter.ts +4 -6
  107. package/src/SchemaIssue.ts +28 -15
  108. package/src/SchemaParser.ts +8 -2
  109. package/src/index.ts +3 -0
  110. package/src/internal/effect.ts +196 -69
  111. package/src/internal/schema/representation.ts +1 -2
  112. package/src/internal/schema/schema.ts +43 -0
  113. package/src/unstable/ai/McpServer.ts +8 -0
  114. package/src/unstable/cli/index.ts +2 -0
  115. package/src/unstable/cluster/Runners.ts +8 -5
  116. package/src/unstable/cluster/SqlMessageStorage.ts +1 -0
  117. package/src/unstable/cluster/SqlRunnerStorage.ts +12 -6
  118. package/src/unstable/eventlog/SqlEventJournal.ts +10 -2
  119. package/src/unstable/eventlog/SqlEventLogServerEncrypted.ts +8 -3
  120. package/src/unstable/eventlog/SqlEventLogServerUnencrypted.ts +9 -3
  121. package/src/unstable/httpapi/HttpApi.ts +1 -1
  122. package/src/unstable/httpapi/HttpApiBuilder.ts +13 -6
  123. package/src/unstable/httpapi/HttpApiClient.ts +5 -6
  124. package/src/unstable/httpapi/HttpApiEndpoint.ts +6 -7
  125. package/src/unstable/httpapi/HttpApiError.ts +43 -22
  126. package/src/unstable/httpapi/HttpApiMiddleware.ts +6 -5
  127. package/src/unstable/httpapi/OpenApi.ts +3 -15
  128. package/src/unstable/observability/OtlpMetrics.ts +1 -1
  129. package/src/unstable/observability/internal/protobuf.ts +4 -4
  130. package/src/unstable/rpc/RpcSerialization.ts +41 -36
  131. package/dist/internal/schema/to-codec.d.ts +0 -2
  132. package/dist/internal/schema/to-codec.d.ts.map +0 -1
  133. package/dist/internal/schema/to-codec.js +0 -126
  134. package/dist/internal/schema/to-codec.js.map +0 -1
  135. package/src/internal/schema/to-codec.ts +0 -138
@@ -483,7 +483,8 @@ export function onSome<T, E, R = never>(
483
483
  * - `undefined` or `true` — value is valid, passes through.
484
484
  * - `false` or a `string` — value is invalid, fails with an `Issue`.
485
485
  * - An `Issue` object — fails with that issue directly.
486
- * - `{ path, message }` — fails with a nested path issue.
486
+ * - `{ path, issue }` — fails with a nested path issue (`issue` may be a
487
+ * message string or a full {@link Issue.Issue}).
487
488
  * - Does not transform the value — input and output types are the same.
488
489
  *
489
490
  * **Example** (Effectful validation)
@@ -505,17 +506,14 @@ export function onSome<T, E, R = never>(
505
506
  */
506
507
  export function checkEffect<T, R = never>(
507
508
  f: (input: T, options: AST.ParseOptions) => Effect.Effect<
508
- undefined | boolean | string | Issue.Issue | {
509
- readonly path: ReadonlyArray<PropertyKey>
510
- readonly message: string
511
- },
509
+ undefined | boolean | Schema.FilterIssue,
512
510
  never,
513
511
  R
514
512
  >
515
513
  ): Getter<T, T, R> {
516
514
  return onSome((t, options) => {
517
515
  return f(t, options).pipe(Effect.flatMapEager((out) => {
518
- const issue = Issue.make(t, out)
516
+ const issue = Issue.makeSingle(t, out)
519
517
  return issue ?
520
518
  Effect.fail(issue) :
521
519
  Effect.succeed(Option.some(t))
@@ -79,6 +79,7 @@
79
79
  * @since 4.0.0
80
80
  */
81
81
  import type { StandardSchemaV1 } from "@standard-schema/spec"
82
+ import * as Arr from "./Array.ts"
82
83
  import { format, formatPath, type Formatter as FormatterI } from "./Formatter.ts"
83
84
  import * as InternalAnnotations from "./internal/schema/annotations.ts"
84
85
  import * as Option from "./Option.ts"
@@ -867,30 +868,42 @@ export function getActual(issue: Issue): Option.Option<unknown> {
867
868
  }
868
869
  }
869
870
 
870
- /** @internal */
871
- export function make(
872
- input: unknown,
873
- out: undefined | boolean | string | Issue | {
874
- readonly path: ReadonlyArray<PropertyKey>
875
- readonly message: string
871
+ function makeFilterIssue(input: unknown, entry: Schema.FilterIssue): Issue {
872
+ if (isIssue(entry)) {
873
+ return entry
876
874
  }
877
- ) {
878
- if (isIssue(out)) {
879
- return out
875
+ if (typeof entry === "string") {
876
+ return new InvalidValue(Option.some(input), { message: entry })
880
877
  }
878
+ const inner = typeof entry.issue === "string"
879
+ ? new InvalidValue(Option.some(input), { message: entry.issue })
880
+ : entry.issue
881
+ return new Pointer(entry.path, inner)
882
+ }
883
+
884
+ /** @internal */
885
+ export function makeSingle(input: unknown, out: undefined | boolean | Schema.FilterIssue): Issue | undefined {
881
886
  if (out === undefined) {
882
887
  return undefined
883
888
  }
884
889
  if (typeof out === "boolean") {
885
890
  return out ? undefined : new InvalidValue(Option.some(input))
886
891
  }
887
- if (typeof out === "string") {
888
- return new InvalidValue(Option.some(input), { message: out })
892
+ return makeFilterIssue(input, out)
893
+ }
894
+
895
+ /** @internal */
896
+ export function make(input: unknown, ast: AST.AST, out: Schema.FilterOutput): Issue | undefined {
897
+ if (Array.isArray(out)) {
898
+ if (Arr.isReadonlyArrayNonEmpty(out)) {
899
+ if (out.length === 1) {
900
+ return makeFilterIssue(input, out[0])
901
+ }
902
+ return new Composite(ast, Option.some(input), Arr.map(out, (entry) => makeFilterIssue(input, entry)))
903
+ }
904
+ return undefined
889
905
  }
890
- return new Pointer(
891
- out.path,
892
- new InvalidValue(Option.some(input), { message: out.message })
893
- )
906
+ return makeSingle(input, out as undefined | boolean | Schema.FilterIssue)
894
907
  }
895
908
 
896
909
  /**
@@ -417,16 +417,22 @@ export interface Parser {
417
417
  const recur = memoize(
418
418
  (ast: AST.AST): Parser => {
419
419
  let parser: Parser
420
+ const astOptions = InternalAnnotations.resolve(ast)?.["parseOptions"]
420
421
  if (!ast.context && !ast.encoding && !ast.checks) {
421
422
  return (ou, options) => {
422
423
  parser ??= ast.getParser(recur)
423
- return parser(ou, InternalAnnotations.resolve(ast)?.["parseOptions"] ?? options)
424
+ if (astOptions) {
425
+ options = { ...options, ...astOptions }
426
+ }
427
+ return parser(ou, options)
424
428
  }
425
429
  }
426
430
  const isStructural = AST.isArrays(ast) || AST.isObjects(ast) ||
427
431
  (AST.isDeclaration(ast) && ast.typeParameters.length > 0)
428
432
  return (ou, options) => {
429
- options = InternalAnnotations.resolve(ast)?.["parseOptions"] ?? options
433
+ if (astOptions) {
434
+ options = { ...options, ...astOptions }
435
+ }
430
436
  const encoding = ast.encoding
431
437
  let srou: Effect.Effect<Option.Option<unknown>, Issue.Issue, unknown> | undefined
432
438
  if (encoding) {
package/src/index.ts CHANGED
@@ -3528,6 +3528,7 @@ export * as SchemaAST from "./SchemaAST.ts"
3528
3528
  * - Parse/stringify JSON → {@link parseJson}, {@link stringifyJson}
3529
3529
  * - Encode/decode Base64 → {@link encodeBase64}, {@link decodeBase64}, {@link decodeBase64String}
3530
3530
  * - Encode/decode Hex → {@link encodeHex}, {@link decodeHex}, {@link decodeHexString}
3531
+ * - Encode/decode URI components → {@link encodeUriComponent}, {@link decodeUriComponent}
3531
3532
  * - Parse DateTime → {@link dateTimeUtcFromInput}
3532
3533
  * - Decode/encode FormData → {@link decodeFormData}, {@link encodeFormData}
3533
3534
  * - Decode/encode URLSearchParams → {@link decodeURLSearchParams}, {@link encodeURLSearchParams}
@@ -3795,6 +3796,8 @@ export * as SchemaRepresentation from "./SchemaRepresentation.ts"
3795
3796
  * - Wrap nullable/optional as Option → {@link optionFromNullOr}, {@link optionFromOptionalKey}, {@link optionFromOptional}
3796
3797
  * - Parse URLs → {@link urlFromString}
3797
3798
  * - Base64 ↔ Uint8Array → {@link uint8ArrayFromBase64String}
3799
+ * - Base64 ↔ string → {@link stringFromBase64String}
3800
+ * - URI component ↔ string → {@link stringFromUriComponent}
3798
3801
  * - JSON string ↔ unknown → {@link fromJsonString}
3799
3802
  * - FormData/URLSearchParams ↔ unknown → {@link fromFormData}, {@link fromURLSearchParams}
3800
3803
  * - Check if a value is a Transformation → {@link isTransformation}
@@ -58,7 +58,6 @@ import {
58
58
  contA,
59
59
  contAll,
60
60
  contE,
61
- Die,
62
61
  evaluate,
63
62
  exitDie,
64
63
  exitFail,
@@ -4457,72 +4456,8 @@ export const forEach: {
4457
4456
  const out: Array<B> | undefined = options?.discard
4458
4457
  ? undefined
4459
4458
  : new Array(length)
4460
- let index = 0
4461
- const annotations = fiberStackAnnotations(parent)
4462
-
4463
- return callback((resume) => {
4464
- const fibers = new Set<Fiber.Fiber<unknown, unknown>>()
4465
- const failures: Array<Cause.Reason<E>> = []
4466
- let failed = false
4467
- let inProgress = 0
4468
- let doneCount = 0
4469
- let pumping = false
4470
- let interrupted = false
4471
- function pump() {
4472
- pumping = true
4473
- while (inProgress < concurrency && index < length) {
4474
- const currentIndex = index
4475
- const item = items[currentIndex]
4476
- index++
4477
- inProgress++
4478
- try {
4479
- const child = forkUnsafe(parent, f(item, currentIndex), true, true, "inherit")
4480
- fibers.add(child)
4481
- child.addObserver((exit) => {
4482
- if (interrupted) {
4483
- return
4484
- }
4485
- fibers.delete(child)
4486
- if (exit._tag === "Failure") {
4487
- if (!failed) {
4488
- failed = true
4489
- length = index
4490
- failures.push(...exit.cause.reasons)
4491
- fibers.forEach((fiber) => fiber.interruptUnsafe(parent.id, annotations))
4492
- } else {
4493
- for (const f of exit.cause.reasons) {
4494
- if (f._tag === "Interrupt") continue
4495
- failures.push(f)
4496
- }
4497
- }
4498
- } else if (out !== undefined) {
4499
- out[currentIndex] = exit.value
4500
- }
4501
- doneCount++
4502
- inProgress--
4503
- if (doneCount === length) {
4504
- resume(failures.length > 0 ? exitFailCause(causeFromReasons(failures)) : succeed(out))
4505
- } else if (!pumping && !failed && inProgress < concurrency) {
4506
- pump()
4507
- }
4508
- })
4509
- } catch (err) {
4510
- failed = true
4511
- length = index
4512
- failures.push(new Die(err))
4513
- fibers.forEach((fiber) => fiber.interruptUnsafe(parent.id, annotations))
4514
- }
4515
- }
4516
- pumping = false
4517
- }
4518
- pump()
4519
-
4520
- return suspend(() => {
4521
- interrupted = true
4522
- index = length
4523
- return fiberInterruptAll(fibers)
4524
- })
4525
- })
4459
+ const eff = forEachConcurrent({ f, out }, items, { concurrency })
4460
+ return eff ? as(eff, out as any) : succeed(out as any)
4526
4461
  }))
4527
4462
 
4528
4463
  const forEachSequential = <A, B, E, R>(
@@ -4550,6 +4485,188 @@ const forEachSequential = <A, B, E, R>(
4550
4485
  )
4551
4486
  })
4552
4487
 
4488
+ const iterateEagerImpl = <S, A, X, E, R, E2>(options: {
4489
+ readonly onItem: (state: S, item: A, index: number) => Effect.Effect<X, E, R>
4490
+ readonly step: (state: NoInfer<S>, item: A, exit: Exit.Exit<X, E>, index: number) => Exit.Exit<void, E2> | void
4491
+ }): (
4492
+ initialState: S,
4493
+ items: ReadonlyArray<A>,
4494
+ options?: {
4495
+ readonly concurrency?: number | undefined
4496
+ readonly start?: number | undefined
4497
+ readonly end?: number | undefined
4498
+ }
4499
+ ) => Effect.Effect<void, E | E2, R> | undefined => {
4500
+ const onItem = options.onItem
4501
+ const step = options.step
4502
+
4503
+ return (
4504
+ state: S,
4505
+ items: ReadonlyArray<A>,
4506
+ opts: {
4507
+ readonly concurrency?: number | undefined
4508
+ readonly start?: number | undefined
4509
+ readonly end?: number | undefined
4510
+ } | undefined
4511
+ ): Effect.Effect<void, E | E2, R> | undefined => {
4512
+ let index = opts?.start ?? 0
4513
+ const end = opts?.end ?? items.length
4514
+ const concurrency = opts?.concurrency ?? 1
4515
+ let done = false
4516
+ let parentFiber: Fiber.Fiber<any, any> | undefined
4517
+ let fibers: Set<Fiber.Fiber<any, any>> | undefined
4518
+ let resume: ((effect: Effect.Effect<void, E | E2, R>) => void) | undefined
4519
+ let interrupted = false
4520
+ let terminal: Exit.Exit<void, E | E2> | void
4521
+ let effect: Effect.Effect<X, E, R> | undefined
4522
+
4523
+ const go = (): Effect.Effect<void, E | E2, R> | undefined => {
4524
+ let paused = false
4525
+ for (; !terminal && index < end; index++) {
4526
+ const item = items[index]
4527
+ const eff = effect ?? onItem(state, item, index)
4528
+
4529
+ // fast case (already an exit)
4530
+ if (effectIsExit(eff)) {
4531
+ terminal = step(state, item, eff, index)
4532
+ if (terminal) break
4533
+
4534
+ // Use flatMap for concurrency of 1
4535
+ } else if (concurrency === 1) {
4536
+ return flatMap(exit(eff), (exit) => {
4537
+ terminal = step(state, item, exit, index)
4538
+ index++
4539
+ return terminal ?? go() ?? void_
4540
+ })
4541
+
4542
+ // We have an effect, so enter "async" mode
4543
+ } else if (!parentFiber) {
4544
+ return callback((cb) => {
4545
+ parentFiber = getCurrentFiber()!
4546
+ effect = eff
4547
+ resume = cb
4548
+ const result = go()
4549
+ if (result) return cb(result)
4550
+ return suspend(() => {
4551
+ terminal = exitVoid
4552
+ interrupted = true
4553
+ return fibers ? fiberInterruptAll(fibers) : void_
4554
+ })
4555
+ })
4556
+
4557
+ // Fork the effect with concurrency > 1
4558
+ } else {
4559
+ // Clear the temporary effect from capturing the parentFiber
4560
+ effect = undefined
4561
+
4562
+ const fiber = forkUnsafe(parentFiber, eff, true, true, "inherit")
4563
+ if (fiber._exit) {
4564
+ terminal = step(state, item, fiber._exit, index)
4565
+ if (terminal) break
4566
+ continue
4567
+ }
4568
+
4569
+ // Add the fiber to the Set
4570
+ if (fibers) fibers.add(fiber)
4571
+ else fibers = new Set([fiber])
4572
+
4573
+ const currentIndex = index
4574
+ fiber.addObserver((exit) => {
4575
+ fibers!.delete(fiber)
4576
+ if (terminal) {
4577
+ if (!interrupted && exit._tag === "Failure") {
4578
+ for (const reason of exit.cause.reasons) {
4579
+ if (reason._tag === "Interrupt") continue
4580
+ else if (terminal._tag === "Failure") {
4581
+ ;(terminal.cause.reasons as Array<any>).push(reason)
4582
+ } else {
4583
+ terminal = exitFailCause(causeFromReasons([reason]))
4584
+ }
4585
+ }
4586
+ }
4587
+ } else {
4588
+ const result = step(state, item, exit, currentIndex)
4589
+ if (result) {
4590
+ terminal = result._tag === "Failure"
4591
+ ? exitFailCause(causeFromReasons(result.cause.reasons.slice()))
4592
+ : result
4593
+ go()
4594
+ }
4595
+ }
4596
+
4597
+ if (paused) {
4598
+ const eff = go()
4599
+ if (eff) resume!(eff)
4600
+ } else if (done && fibers!.size === 0) {
4601
+ resume!(terminal ?? void_)
4602
+ }
4603
+ })
4604
+
4605
+ // Check if we have reached the concurrency limit
4606
+ if (fibers.size < concurrency) continue
4607
+ paused = true
4608
+ index++
4609
+ return
4610
+ }
4611
+ }
4612
+
4613
+ done = true
4614
+
4615
+ if (terminal) {
4616
+ if (fibers && fibers.size > 0) {
4617
+ const annotations = fiberStackAnnotations(parentFiber!)
4618
+ fibers.forEach((f) => f.interruptUnsafe(parentFiber!.id, annotations))
4619
+ return
4620
+ }
4621
+ if (resume || terminal._tag === "Failure") {
4622
+ return terminal
4623
+ }
4624
+ } else if (resume) {
4625
+ if (!fibers) {
4626
+ return exitVoid
4627
+ } else if (fibers.size === 0) {
4628
+ resume(void_)
4629
+ }
4630
+ }
4631
+ }
4632
+
4633
+ return go()
4634
+ }
4635
+ }
4636
+
4637
+ /** @internal */
4638
+ export const iterateEager = <S, A>(): <X, E, R, E2>(options: {
4639
+ readonly onItem: (state: S, item: A, index: number) => Effect.Effect<X, E, R>
4640
+ readonly step: (state: NoInfer<S>, item: A, exit: Exit.Exit<X, E>, index: number) => Exit.Exit<void, E2> | void
4641
+ }) => (
4642
+ initialState: S,
4643
+ items: ReadonlyArray<A>,
4644
+ options?: {
4645
+ readonly concurrency?: number | undefined
4646
+ readonly start?: number | undefined
4647
+ readonly end?: number | undefined
4648
+ }
4649
+ ) => Effect.Effect<void, E | E2, R> | undefined => iterateEagerImpl
4650
+
4651
+ const forEachConcurrent = iterateEagerImpl({
4652
+ onItem(
4653
+ state: {
4654
+ readonly f: (a: any, i: number) => Effect.Effect<any, any, any>
4655
+ readonly out: Array<any> | undefined
4656
+ },
4657
+ item,
4658
+ index
4659
+ ) {
4660
+ return state.f(item, index)
4661
+ },
4662
+ step(state, _, exit, index) {
4663
+ if (exit._tag === "Failure") return exit
4664
+ else if (state.out) {
4665
+ state.out[index] = exit.value
4666
+ }
4667
+ }
4668
+ })
4669
+
4553
4670
  /* @internal */
4554
4671
  export const filterOrElse: {
4555
4672
  <A, C, E2, R2, B extends A>(
@@ -4862,7 +4979,7 @@ export const forkUnsafe = <FA, FE, A, E, R>(
4862
4979
  immediate = false,
4863
4980
  daemon = false,
4864
4981
  uninterruptible: boolean | "inherit" = false
4865
- ): Fiber.Fiber<A, E> => {
4982
+ ): FiberImpl<A, E> => {
4866
4983
  const interruptible = uninterruptible === "inherit" ? parent.interruptible : !uninterruptible
4867
4984
  const child = new FiberImpl<A, E>(parent.context, interruptible)
4868
4985
  if (immediate) {
@@ -5332,7 +5449,7 @@ export const makeSpanUnsafe = <XA, XE>(
5332
5449
  parent,
5333
5450
  annotations: options?.annotations ?? Context.empty(),
5334
5451
  links,
5335
- startTime: timingEnabled ? clock.currentTimeNanosUnsafe() : 0n,
5452
+ startTime: timingEnabled ? clock.currentTimeNanosUnsafe() : BigInt(0),
5336
5453
  kind: options?.kind ?? "internal",
5337
5454
  root: options?.root ?? Option.isNone(parent),
5338
5455
  sampled: options?.sampled ??
@@ -6022,6 +6139,7 @@ const prettyLoggerTty = (options: {
6022
6139
  return loggerMake<unknown, void>(
6023
6140
  ({ cause, date, fiber, logLevel, message: message_ }) => {
6024
6141
  const console = fiber.getRef(ConsoleRef)
6142
+ // oxlint-disable-next-line no-console
6025
6143
  const log = fiber.getRef(LogToStderr) ? console.error : console.log
6026
6144
 
6027
6145
  const message = Array.isArray(message_) ? message_.slice() : [message_]
@@ -6047,6 +6165,7 @@ const prettyLoggerTty = (options: {
6047
6165
  }
6048
6166
 
6049
6167
  log(firstLine)
6168
+ // oxlint-disable-next-line no-console
6050
6169
  if (!processIsBun) console.group()
6051
6170
 
6052
6171
  if (cause.reasons.length > 0) {
@@ -6064,6 +6183,7 @@ const prettyLoggerTty = (options: {
6064
6183
  log(color(`${key}:`, colors.bold, colors.white), redact(value))
6065
6184
  }
6066
6185
 
6186
+ // oxlint-disable-next-line no-console
6067
6187
  if (!processIsBun) console.groupEnd()
6068
6188
  }
6069
6189
  )
@@ -6110,14 +6230,17 @@ const prettyLoggerBrowser = (options: {
6110
6230
  }
6111
6231
  }
6112
6232
 
6233
+ // oxlint-disable-next-line no-console
6113
6234
  console.groupCollapsed(firstLine, ...firstParams)
6114
6235
 
6115
6236
  if (cause.reasons.length > 0) {
6237
+ // oxlint-disable-next-line no-console
6116
6238
  console.error(causePretty(cause))
6117
6239
  }
6118
6240
 
6119
6241
  if (messageIndex < message.length) {
6120
6242
  for (; messageIndex < message.length; messageIndex++) {
6243
+ // oxlint-disable-next-line no-console
6121
6244
  console.log(redact(message[messageIndex]))
6122
6245
  }
6123
6246
  }
@@ -6126,12 +6249,15 @@ const prettyLoggerBrowser = (options: {
6126
6249
  for (const [key, value] of Object.entries(annotations)) {
6127
6250
  const redacted = redact(value)
6128
6251
  if (options.colors) {
6252
+ // oxlint-disable-next-line no-console
6129
6253
  console.log(`%c${key}:`, "color:gray", redacted)
6130
6254
  } else {
6255
+ // oxlint-disable-next-line no-console
6131
6256
  console.log(`${key}:`, redacted)
6132
6257
  }
6133
6258
  }
6134
6259
 
6260
+ // oxlint-disable-next-line no-console
6135
6261
  console.groupEnd()
6136
6262
  }
6137
6263
  )
@@ -6154,6 +6280,7 @@ export const defaultLogger = loggerMake<unknown, void>(({ cause, date, fiber, lo
6154
6280
  message_.push(annotations)
6155
6281
  }
6156
6282
  const console = fiber.getRef(ConsoleRef)
6283
+ // oxlint-disable-next-line no-console
6157
6284
  const log = fiber.getRef(LogToStderr) ? console.error : console.log
6158
6285
  log(`[${defaultDateFormat(date)}] ${logLevel.toUpperCase()} (#${fiber.id})${spanString}:`, ...message_)
6159
6286
  })
@@ -11,7 +11,6 @@ import * as AST from "../../SchemaAST.ts"
11
11
  import type * as SchemaRepresentation from "../../SchemaRepresentation.ts"
12
12
  import * as InternalAnnotations from "./annotations.ts"
13
13
  import * as InternalSchema from "./schema.ts"
14
- import * as InternalToCodec from "./to-codec.ts"
15
14
 
16
15
  /** @internal */
17
16
  export function fromAST(ast: AST.AST): SchemaRepresentation.Document {
@@ -213,7 +212,7 @@ export function fromASTs(asts: readonly [AST.AST, ...Array<AST.AST>]): SchemaRep
213
212
  ...annotations
214
213
  }
215
214
  case "Union": {
216
- const types = InternalToCodec.jsonReorder(last.types)
215
+ const types = InternalSchema.jsonReorder(last.types)
217
216
  return {
218
217
  _tag: last._tag,
219
218
  types: types.map((ast) => recur(ast)),
@@ -42,6 +42,7 @@ export function make<S extends Schema.Top>(ast: S["ast"], options?: object): S {
42
42
  /** @internal */
43
43
  export const SchemaErrorTypeId = "~effect/Schema/SchemaError"
44
44
 
45
+ // not internal
45
46
  export class SchemaError {
46
47
  readonly [SchemaErrorTypeId] = SchemaErrorTypeId
47
48
  readonly _tag = "SchemaError"
@@ -57,3 +58,45 @@ export class SchemaError {
57
58
  return `SchemaError(${this.message})`
58
59
  }
59
60
  }
61
+
62
+ /** @internal */
63
+ export const jsonReorder = makeReorder(getJsonPriority)
64
+
65
+ function getJsonPriority(ast: AST.AST): number {
66
+ switch (ast._tag) {
67
+ case "BigInt":
68
+ case "Symbol":
69
+ case "UniqueSymbol":
70
+ return 0
71
+ default:
72
+ return 1
73
+ }
74
+ }
75
+
76
+ /** @internal */
77
+ export function makeReorder(getPriority: (ast: AST.AST) => number) {
78
+ return (types: ReadonlyArray<AST.AST>): ReadonlyArray<AST.AST> => {
79
+ // Create a map of original indices for O(1) lookup
80
+ const indexMap = new Map<AST.AST, number>()
81
+ for (let i = 0; i < types.length; i++) {
82
+ indexMap.set(AST.toEncoded(types[i]), i)
83
+ }
84
+
85
+ // Create a sorted copy of the types array
86
+ const sortedTypes = [...types].sort((a, b) => {
87
+ a = AST.toEncoded(a)
88
+ b = AST.toEncoded(b)
89
+ const pa = getPriority(a)
90
+ const pb = getPriority(b)
91
+ if (pa !== pb) return pa - pb
92
+ // If priorities are equal, maintain original order (stable sort)
93
+ return indexMap.get(a)! - indexMap.get(b)!
94
+ })
95
+
96
+ // Check if order changed by comparing arrays
97
+ const orderChanged = sortedTypes.some((ast, index) => ast !== types[index])
98
+
99
+ if (!orderChanged) return types
100
+ return sortedTypes
101
+ }
102
+ }
@@ -383,6 +383,14 @@ export const run: (options: {
383
383
  const initializePayload = getInitializedClient(clientSessions, client.id, headers)
384
384
  const isInitialize = rpc._tag === "initialize"
385
385
  if (!isInitialize && !initializePayload) {
386
+ const fiber = Fiber.getCurrent()!
387
+ const httpRequest = Context.getOrUndefined(fiber.context, HttpServerRequest.HttpServerRequest)
388
+ if (httpRequest) {
389
+ appendPreResponseHandlerUnsafe(
390
+ httpRequest,
391
+ () => Effect.succeed(HttpServerResponse.empty({ status: 404 }))
392
+ )
393
+ }
386
394
  return Effect.die(new Error(`Mcp-Session-Id does not exist`))
387
395
  }
388
396
  return Effect.provideService(
@@ -25,6 +25,8 @@ export * as CliOutput from "./CliOutput.ts"
25
25
  export * as Command from "./Command.ts"
26
26
 
27
27
  /**
28
+ * Shell completion descriptors and script generation for the unstable CLI API.
29
+ *
28
30
  * @since 4.0.0
29
31
  */
30
32
  export * as Completions from "./Completions.ts"
@@ -589,11 +589,14 @@ export const makeRpc: Effect.Effect<
589
589
  return Effect.void
590
590
  }
591
591
  const envelope = message.envelope
592
- return RcMap.get(clients, address.value).pipe(
593
- Effect.flatMap((client) => client.Notify({ envelope })),
594
- Effect.scoped,
595
- Effect.ignore
596
- )
592
+ const encode: Effect.Effect<Envelope.AckChunk | Envelope.Interrupt | Envelope.PartialRequest> =
593
+ message._tag === "OutgoingRequest" ? Effect.orDie(Message.serializeRequest(message)) : Effect.succeed(envelope)
594
+ return Effect.flatMap(encode, (envelope) =>
595
+ RcMap.get(clients, address.value).pipe(
596
+ Effect.flatMap((client) => client.Notify({ envelope })),
597
+ Effect.scoped,
598
+ Effect.ignore
599
+ ))
597
600
  },
598
601
  onRunnerUnavailable: (address) => RcMap.invalidate(clients, address)
599
602
  })
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @since 4.0.0
3
3
  */
4
+ // eslint-disable effect/no-bigint-literals
4
5
  import * as Arr from "../../Array.ts"
5
6
  import * as Effect from "../../Effect.ts"
6
7
  import * as Layer from "../../Layer.ts"
@@ -536,7 +536,8 @@ export const make = Effect.fnUntraced(function*(options: {
536
536
  shardIds.length > 0 ?
537
537
  Effect.andThen(refreshShards(address, shardIds)) :
538
538
  Effect.as([]),
539
- PersistenceError.refail
539
+ PersistenceError.refail,
540
+ withTracerDisabled
540
541
  ),
541
542
 
542
543
  release: sql.onDialectOrElse({
@@ -544,7 +545,8 @@ export const make = Effect.fnUntraced(function*(options: {
544
545
  if (disableAdvisoryLocks) {
545
546
  return (address: string, shardId: string) =>
546
547
  sql`DELETE FROM ${locksTableSql} WHERE address = ${address} AND shard_id = ${shardId}`.pipe(
547
- PersistenceError.refail
548
+ PersistenceError.refail,
549
+ withTracerDisabled
548
550
  )
549
551
  }
550
552
  return Effect.fnUntraced(
@@ -564,14 +566,16 @@ export const make = Effect.fnUntraced(function*(options: {
564
566
  },
565
567
  Effect.onError(() => lockConn!.rebuildUnsafe()),
566
568
  Effect.asVoid,
567
- PersistenceError.refail
569
+ PersistenceError.refail,
570
+ withTracerDisabled
568
571
  )
569
572
  },
570
573
  mysql: () => {
571
574
  if (disableAdvisoryLocks) {
572
575
  return (address: string, shardId: string) =>
573
576
  sql`DELETE FROM ${locksTableSql} WHERE address = ${address} AND shard_id = ${shardId}`.pipe(
574
- PersistenceError.refail
577
+ PersistenceError.refail,
578
+ withTracerDisabled
575
579
  )
576
580
  }
577
581
  return Effect.fnUntraced(
@@ -589,12 +593,14 @@ export const make = Effect.fnUntraced(function*(options: {
589
593
  },
590
594
  Effect.onError(() => lockConn!.rebuildUnsafe()),
591
595
  Effect.asVoid,
592
- PersistenceError.refail
596
+ PersistenceError.refail,
597
+ withTracerDisabled
593
598
  )
594
599
  },
595
600
  orElse: () => (address, shardId) =>
596
601
  sql`DELETE FROM ${locksTableSql} WHERE address = ${address} AND shard_id = ${shardId}`.pipe(
597
- PersistenceError.refail
602
+ PersistenceError.refail,
603
+ withTracerDisabled
598
604
  )
599
605
  }),
600
606