effect 4.0.0-beta.97 → 4.0.0-beta.98

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 (166) hide show
  1. package/dist/LayerRef.d.ts +4 -6
  2. package/dist/LayerRef.d.ts.map +1 -1
  3. package/dist/LayerRef.js +4 -6
  4. package/dist/LayerRef.js.map +1 -1
  5. package/dist/Number.d.ts.map +1 -1
  6. package/dist/Number.js +28 -10
  7. package/dist/Number.js.map +1 -1
  8. package/dist/Schema.d.ts +22 -22
  9. package/dist/Schema.d.ts.map +1 -1
  10. package/dist/Schema.js +36 -33
  11. package/dist/Schema.js.map +1 -1
  12. package/dist/SchemaAST.d.ts.map +1 -1
  13. package/dist/SchemaAST.js +25 -10
  14. package/dist/SchemaAST.js.map +1 -1
  15. package/dist/SchemaError.d.ts +53 -0
  16. package/dist/SchemaError.d.ts.map +1 -0
  17. package/dist/SchemaError.js +61 -0
  18. package/dist/SchemaError.js.map +1 -0
  19. package/dist/SchemaGetter.d.ts.map +1 -1
  20. package/dist/SchemaGetter.js +17 -12
  21. package/dist/SchemaGetter.js.map +1 -1
  22. package/dist/SchemaRepresentation.d.ts.map +1 -1
  23. package/dist/SchemaRepresentation.js +186 -224
  24. package/dist/SchemaRepresentation.js.map +1 -1
  25. package/dist/index.d.ts +8 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +8 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/internal/effect.js +26 -8
  30. package/dist/internal/effect.js.map +1 -1
  31. package/dist/internal/schema/equivalence.js +1 -2
  32. package/dist/internal/schema/equivalence.js.map +1 -1
  33. package/dist/internal/schema/representation.js +1 -3
  34. package/dist/internal/schema/representation.js.map +1 -1
  35. package/dist/internal/schema/schema.d.ts +0 -13
  36. package/dist/internal/schema/schema.d.ts.map +1 -1
  37. package/dist/internal/schema/schema.js +4 -29
  38. package/dist/internal/schema/schema.js.map +1 -1
  39. package/dist/unstable/ai/McpSchema.d.ts +128 -128
  40. package/dist/unstable/ai/McpSchema.d.ts.map +1 -1
  41. package/dist/unstable/cli/CliError.d.ts +8 -16
  42. package/dist/unstable/cli/CliError.d.ts.map +1 -1
  43. package/dist/unstable/cli/CliError.js +8 -16
  44. package/dist/unstable/cli/CliError.js.map +1 -1
  45. package/dist/unstable/cli/Command.d.ts +4 -3
  46. package/dist/unstable/cli/Command.d.ts.map +1 -1
  47. package/dist/unstable/cli/Command.js +3 -3
  48. package/dist/unstable/cli/Command.js.map +1 -1
  49. package/dist/unstable/cli/GlobalFlag.d.ts +6 -8
  50. package/dist/unstable/cli/GlobalFlag.d.ts.map +1 -1
  51. package/dist/unstable/cli/GlobalFlag.js +6 -6
  52. package/dist/unstable/cli/GlobalFlag.js.map +1 -1
  53. package/dist/unstable/cluster/EntityProxyServer.d.ts +1 -1
  54. package/dist/unstable/cluster/EntityProxyServer.d.ts.map +1 -1
  55. package/dist/unstable/cluster/EntityProxyServer.js +2 -4
  56. package/dist/unstable/cluster/EntityProxyServer.js.map +1 -1
  57. package/dist/unstable/cluster/internal/entityManager.js +15 -12
  58. package/dist/unstable/cluster/internal/entityManager.js.map +1 -1
  59. package/dist/unstable/httpapi/HttpApi.d.ts +36 -15
  60. package/dist/unstable/httpapi/HttpApi.d.ts.map +1 -1
  61. package/dist/unstable/httpapi/HttpApi.js +19 -20
  62. package/dist/unstable/httpapi/HttpApi.js.map +1 -1
  63. package/dist/unstable/httpapi/HttpApiBuilder.d.ts +51 -62
  64. package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
  65. package/dist/unstable/httpapi/HttpApiBuilder.js +68 -58
  66. package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
  67. package/dist/unstable/httpapi/HttpApiClient.d.ts +53 -53
  68. package/dist/unstable/httpapi/HttpApiClient.d.ts.map +1 -1
  69. package/dist/unstable/httpapi/HttpApiClient.js +40 -30
  70. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  71. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts +165 -164
  72. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts.map +1 -1
  73. package/dist/unstable/httpapi/HttpApiEndpoint.js +31 -19
  74. package/dist/unstable/httpapi/HttpApiEndpoint.js.map +1 -1
  75. package/dist/unstable/httpapi/HttpApiError.d.ts +22 -0
  76. package/dist/unstable/httpapi/HttpApiError.d.ts.map +1 -1
  77. package/dist/unstable/httpapi/HttpApiError.js +31 -0
  78. package/dist/unstable/httpapi/HttpApiError.js.map +1 -1
  79. package/dist/unstable/httpapi/HttpApiGroup.d.ts +55 -30
  80. package/dist/unstable/httpapi/HttpApiGroup.d.ts.map +1 -1
  81. package/dist/unstable/httpapi/HttpApiGroup.js +22 -29
  82. package/dist/unstable/httpapi/HttpApiGroup.js.map +1 -1
  83. package/dist/unstable/httpapi/HttpApiMiddleware.d.ts +8 -8
  84. package/dist/unstable/httpapi/HttpApiMiddleware.d.ts.map +1 -1
  85. package/dist/unstable/httpapi/HttpApiMiddleware.js.map +1 -1
  86. package/dist/unstable/httpapi/HttpApiScalar.d.ts +2 -2
  87. package/dist/unstable/httpapi/HttpApiScalar.d.ts.map +1 -1
  88. package/dist/unstable/httpapi/HttpApiScalar.js +4 -3
  89. package/dist/unstable/httpapi/HttpApiScalar.js.map +1 -1
  90. package/dist/unstable/httpapi/HttpApiSchema.d.ts +8 -0
  91. package/dist/unstable/httpapi/HttpApiSchema.d.ts.map +1 -1
  92. package/dist/unstable/httpapi/HttpApiSchema.js.map +1 -1
  93. package/dist/unstable/httpapi/HttpApiSwagger.d.ts +1 -1
  94. package/dist/unstable/httpapi/HttpApiSwagger.d.ts.map +1 -1
  95. package/dist/unstable/httpapi/HttpApiSwagger.js.map +1 -1
  96. package/dist/unstable/httpapi/HttpApiTest.d.ts +4 -4
  97. package/dist/unstable/httpapi/HttpApiTest.d.ts.map +1 -1
  98. package/dist/unstable/httpapi/HttpApiTest.js +9 -8
  99. package/dist/unstable/httpapi/HttpApiTest.js.map +1 -1
  100. package/dist/unstable/httpapi/OpenApi.d.ts +1 -1
  101. package/dist/unstable/httpapi/OpenApi.d.ts.map +1 -1
  102. package/dist/unstable/httpapi/OpenApi.js +77 -37
  103. package/dist/unstable/httpapi/OpenApi.js.map +1 -1
  104. package/dist/unstable/httpapi/internal/html.js +6 -2
  105. package/dist/unstable/httpapi/internal/html.js.map +1 -1
  106. package/dist/unstable/httpapi/internal/mediaType.d.ts +2 -0
  107. package/dist/unstable/httpapi/internal/mediaType.d.ts.map +1 -0
  108. package/dist/unstable/httpapi/internal/mediaType.js +7 -0
  109. package/dist/unstable/httpapi/internal/mediaType.js.map +1 -0
  110. package/dist/unstable/persistence/PersistedQueue.d.ts.map +1 -1
  111. package/dist/unstable/persistence/PersistedQueue.js +16 -12
  112. package/dist/unstable/persistence/PersistedQueue.js.map +1 -1
  113. package/dist/unstable/reactivity/Atom.js +1 -1
  114. package/dist/unstable/reactivity/Atom.js.map +1 -1
  115. package/dist/unstable/reactivity/AtomHttpApi.d.ts +7 -7
  116. package/dist/unstable/reactivity/AtomHttpApi.d.ts.map +1 -1
  117. package/dist/unstable/reactivity/AtomHttpApi.js +3 -2
  118. package/dist/unstable/reactivity/AtomHttpApi.js.map +1 -1
  119. package/dist/unstable/rpc/RpcServer.d.ts +3 -1
  120. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  121. package/dist/unstable/rpc/RpcServer.js +6 -3
  122. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  123. package/dist/unstable/workflow/DurableDeferred.js +1 -1
  124. package/dist/unstable/workflow/DurableDeferred.js.map +1 -1
  125. package/dist/unstable/workflow/WorkflowProxyServer.d.ts +1 -1
  126. package/dist/unstable/workflow/WorkflowProxyServer.d.ts.map +1 -1
  127. package/dist/unstable/workflow/WorkflowProxyServer.js +1 -2
  128. package/dist/unstable/workflow/WorkflowProxyServer.js.map +1 -1
  129. package/package.json +1 -1
  130. package/src/LayerRef.ts +4 -6
  131. package/src/Number.ts +29 -10
  132. package/src/Schema.ts +42 -34
  133. package/src/SchemaAST.ts +25 -13
  134. package/src/SchemaError.ts +64 -0
  135. package/src/SchemaGetter.ts +22 -16
  136. package/src/SchemaRepresentation.ts +165 -202
  137. package/src/index.ts +10 -0
  138. package/src/internal/effect.ts +39 -22
  139. package/src/internal/schema/equivalence.ts +1 -2
  140. package/src/internal/schema/representation.ts +4 -4
  141. package/src/internal/schema/schema.ts +4 -37
  142. package/src/unstable/cli/CliError.ts +24 -16
  143. package/src/unstable/cli/Command.ts +8 -8
  144. package/src/unstable/cli/GlobalFlag.ts +22 -33
  145. package/src/unstable/cluster/EntityProxyServer.ts +15 -17
  146. package/src/unstable/cluster/internal/entityManager.ts +48 -34
  147. package/src/unstable/httpapi/HttpApi.ts +72 -47
  148. package/src/unstable/httpapi/HttpApiBuilder.ts +320 -217
  149. package/src/unstable/httpapi/HttpApiClient.ts +196 -151
  150. package/src/unstable/httpapi/HttpApiEndpoint.ts +251 -447
  151. package/src/unstable/httpapi/HttpApiError.ts +33 -0
  152. package/src/unstable/httpapi/HttpApiGroup.ts +95 -74
  153. package/src/unstable/httpapi/HttpApiMiddleware.ts +10 -7
  154. package/src/unstable/httpapi/HttpApiScalar.ts +15 -12
  155. package/src/unstable/httpapi/HttpApiSchema.ts +8 -0
  156. package/src/unstable/httpapi/HttpApiSwagger.ts +2 -2
  157. package/src/unstable/httpapi/HttpApiTest.ts +15 -14
  158. package/src/unstable/httpapi/OpenApi.ts +74 -36
  159. package/src/unstable/httpapi/internal/html.ts +9 -2
  160. package/src/unstable/httpapi/internal/mediaType.ts +6 -0
  161. package/src/unstable/persistence/PersistedQueue.ts +16 -14
  162. package/src/unstable/reactivity/Atom.ts +1 -1
  163. package/src/unstable/reactivity/AtomHttpApi.ts +164 -162
  164. package/src/unstable/rpc/RpcServer.ts +10 -4
  165. package/src/unstable/workflow/DurableDeferred.ts +1 -1
  166. package/src/unstable/workflow/WorkflowProxyServer.ts +11 -12
@@ -18,6 +18,7 @@ import { collectBrands } from "./internal/schema/annotations.ts"
18
18
  import * as InternalRepresentation from "./internal/schema/representation.ts"
19
19
  import { unescapeToken } from "./JsonPointer.ts"
20
20
  import type * as JsonSchema from "./JsonSchema.ts"
21
+ import { remainder } from "./Number.ts"
21
22
  import * as Option from "./Option.ts"
22
23
  import * as Predicate from "./Predicate.ts"
23
24
  import * as Rec from "./Record.ts"
@@ -3038,63 +3039,37 @@ export function fromJsonSchemaDocument(document: JsonSchema.Document<"draft-2020
3038
3039
  export function fromJsonSchemaMultiDocument(document: JsonSchema.MultiDocument<"draft-2020-12">, options?: {
3039
3040
  readonly onEnter?: ((js: JsonSchema.JsonSchema) => JsonSchema.JsonSchema) | undefined
3040
3041
  }): MultiDocument {
3041
- let visited: Set<string>
3042
+ let definitionIdentifier: string | undefined
3042
3043
  const references: Record<string, Representation> = {}
3043
3044
 
3044
- type Slot = {
3045
- // 0 = not started, 1 = building, 2 = done
3046
- state: 0 | 1 | 2
3047
- value: Exclude<Representation, { _tag: "Reference" }> | undefined
3048
- }
3045
+ type ResolvedReference = Exclude<Representation, { _tag: "Reference" }>
3046
+ const resolvedReferences = new Map<string, ResolvedReference | null>()
3049
3047
 
3050
- const slots = new Map<string, Slot>()
3051
-
3052
- function getSlot(identifier: string): Slot {
3053
- const existing = slots.get(identifier)
3054
- if (existing) return existing
3055
-
3056
- // Create the slot *before* resolving, so self-references can see it.
3057
- const slot: Slot = {
3058
- state: 0,
3059
- value: undefined
3060
- }
3061
- slots.set(identifier, slot)
3062
- return slot
3063
- }
3064
-
3065
- function resolveReference($ref: string): Exclude<Representation, { _tag: "Reference" }> {
3048
+ function resolveReference($ref: string): ResolvedReference {
3066
3049
  const definition = document.definitions[$ref]
3067
3050
  if (definition === undefined) {
3068
3051
  throw new Error(`Reference ${$ref} not found`)
3069
3052
  }
3070
3053
 
3071
- const slot = getSlot($ref)
3072
-
3073
- if (slot.state === 2) {
3074
- // Already built: return the built schema directly
3075
- return slot.value!
3076
- }
3077
-
3078
- if (slot.state === 1) {
3079
- // Circular: we're currently building this identifier.
3054
+ const resolved = resolvedReferences.get($ref)
3055
+ if (resolved === null) {
3080
3056
  throw new Error(`Circular reference detected: ${$ref}`)
3081
3057
  }
3058
+ if (resolved !== undefined) return resolved
3082
3059
 
3083
- // First time: build it.
3084
- slot.state = 1
3060
+ resolvedReferences.set($ref, null)
3085
3061
  const value = recur(definition)
3086
-
3087
- slot.value = value._tag === "Reference" ? resolveReference(value.$ref) : value
3088
- slot.state = 2
3089
- return slot.value
3062
+ const out = value._tag === "Reference" ? resolveReference(value.$ref) : value
3063
+ resolvedReferences.set($ref, out)
3064
+ return out
3090
3065
  }
3091
3066
 
3092
- Object.entries(document.definitions).forEach(([identifier, definition]) => {
3093
- visited = new Set<string>([identifier])
3067
+ for (const [identifier, definition] of Object.entries(document.definitions)) {
3068
+ definitionIdentifier = identifier
3094
3069
  references[identifier] = unknownToJson(recur(definition))
3095
- })
3070
+ }
3096
3071
 
3097
- visited = new Set<string>()
3072
+ definitionIdentifier = undefined
3098
3073
  const representations = Arr.map(document.schemas, (schema) => unknownToJson(recur(schema)))
3099
3074
  return {
3100
3075
  representations,
@@ -3143,7 +3118,7 @@ export function fromJsonSchemaMultiDocument(document: JsonSchema.MultiDocument<"
3143
3118
  const $ref = js.$ref.slice(2).split("/").at(-1)
3144
3119
  if ($ref !== undefined) {
3145
3120
  const reference: Reference = { _tag: "Reference", $ref: unescapeToken($ref) }
3146
- if (visited.has($ref)) {
3121
+ if (definitionIdentifier === $ref) {
3147
3122
  return { _tag: "Suspend", thunk: reference, checks: [] }
3148
3123
  } else {
3149
3124
  return reference
@@ -3250,168 +3225,159 @@ export function fromJsonSchemaMultiDocument(document: JsonSchema.MultiDocument<"
3250
3225
  return combine(resolveReference(a.$ref), b)
3251
3226
  case "Never":
3252
3227
  return a
3253
- case "Unknown":
3254
- switch (b._tag) {
3255
- case "Reference":
3256
- return combine(a, resolveReference(b.$ref))
3257
- default:
3258
- return { ...b, ...combineAnnotations(a.annotations, b.annotations) }
3259
- }
3228
+ case "Unknown": {
3229
+ const resolved = b._tag === "Reference" ? resolveReference(b.$ref) : b
3230
+ return { ...resolved, ...combineAnnotations(a.annotations, resolved.annotations) }
3231
+ }
3260
3232
  case "Null":
3261
- switch (b._tag) {
3262
- case "Unknown":
3263
- case "Null":
3264
- return { ...a, ...combineAnnotations(a.annotations, b.annotations) }
3265
- case "Union":
3266
- return combine(b, a)
3267
- case "Reference":
3268
- return combine(a, resolveReference(b.$ref))
3269
- default:
3270
- return never
3271
- }
3272
3233
  case "String":
3273
- switch (b._tag) {
3274
- case "Unknown":
3275
- return { ...a, ...combineAnnotations(a.annotations, b.annotations) }
3276
- case "String": {
3277
- const checks = combineChecks(a.checks, b.checks, b.annotations)
3278
- return {
3279
- _tag: "String",
3280
- checks: checks ?? a.checks,
3281
- ...combineAnnotations(a.annotations, checks ? undefined : b.annotations)
3282
- }
3283
- }
3284
- case "Literal":
3285
- return typeof b.literal === "string" ? { ...b, ...combineAnnotations(a.annotations, b.annotations) } : never
3286
- case "Union":
3287
- return combine(b, a)
3288
- case "Reference":
3289
- return combine(a, resolveReference(b.$ref))
3290
- default:
3291
- return never
3292
- }
3293
3234
  case "Number":
3294
- switch (b._tag) {
3295
- case "Unknown":
3296
- return { ...a, ...combineAnnotations(a.annotations, b.annotations) }
3297
- case "Number": {
3298
- const checks = combineNumberChecks(a.checks, b.checks, b.annotations)
3299
- return {
3300
- _tag: "Number",
3301
- checks: checks ?? a.checks,
3302
- ...combineAnnotations(a.annotations, checks ? undefined : b.annotations)
3303
- }
3304
- }
3305
- case "Literal":
3306
- return typeof b.literal === "number" ? { ...b, ...combineAnnotations(a.annotations, b.annotations) } : never
3307
- case "Union":
3308
- return combine(b, a)
3309
- case "Reference":
3310
- return combine(a, resolveReference(b.$ref))
3311
- default:
3312
- return never
3235
+ case "Boolean":
3236
+ case "Literal":
3237
+ case "Arrays":
3238
+ case "Objects":
3239
+ case "Union":
3240
+ break
3241
+ }
3242
+
3243
+ if (b._tag === "Reference") {
3244
+ return combine(a, resolveReference(b.$ref))
3245
+ }
3246
+ if (b._tag === "Unknown") {
3247
+ return { ...a, ...combineAnnotations(a.annotations, b.annotations) }
3248
+ }
3249
+ if (a._tag === "Union") {
3250
+ const types = a.types.map((s) => combine(s, b)).filter((s) => s !== never)
3251
+ if (types.length === 0) return never
3252
+ return {
3253
+ _tag: "Union",
3254
+ types,
3255
+ mode: a.mode,
3256
+ ...makeAnnotations(a.annotations)
3257
+ }
3258
+ }
3259
+ if (b._tag === "Union") {
3260
+ return combine(b, a)
3261
+ }
3262
+
3263
+ switch (a._tag) {
3264
+ case "Null":
3265
+ return b._tag === "Null" ? { ...a, ...combineAnnotations(a.annotations, b.annotations) } : never
3266
+ case "String": {
3267
+ if (b._tag === "Literal") {
3268
+ return satisfiesLiteral(a, b) ? { ...b, ...combineAnnotations(a.annotations, b.annotations) } : never
3269
+ }
3270
+ if (b._tag !== "String") return never
3271
+ const checks = combineChecks(a.checks, b.checks, b.annotations)
3272
+ return {
3273
+ _tag: "String",
3274
+ checks: checks ?? a.checks,
3275
+ ...combineAnnotations(a.annotations, checks ? undefined : b.annotations)
3276
+ }
3277
+ }
3278
+ case "Number": {
3279
+ if (b._tag === "Literal") {
3280
+ return satisfiesLiteral(a, b) ? { ...b, ...combineAnnotations(a.annotations, b.annotations) } : never
3281
+ }
3282
+ if (b._tag !== "Number") return never
3283
+ const checks = combineNumberChecks(a.checks, b.checks, b.annotations)
3284
+ return {
3285
+ _tag: "Number",
3286
+ checks: checks ?? a.checks,
3287
+ ...combineAnnotations(a.annotations, checks ? undefined : b.annotations)
3313
3288
  }
3289
+ }
3314
3290
  case "Boolean":
3315
- switch (b._tag) {
3316
- case "Unknown":
3317
- return { ...a, ...combineAnnotations(a.annotations, b.annotations) }
3318
- case "Boolean":
3319
- return { _tag: "Boolean", ...combineAnnotations(a.annotations, b.annotations) }
3320
- case "Literal":
3321
- return typeof b.literal === "boolean"
3322
- ? { ...b, ...combineAnnotations(a.annotations, b.annotations) }
3323
- : never
3324
- case "Union":
3325
- return combine(b, a)
3326
- case "Reference":
3327
- return combine(a, resolveReference(b.$ref))
3328
- default:
3329
- return never
3291
+ if (b._tag === "Boolean") {
3292
+ return { _tag: "Boolean", ...combineAnnotations(a.annotations, b.annotations) }
3330
3293
  }
3294
+ return b._tag === "Literal" && typeof b.literal === "boolean"
3295
+ ? { ...b, ...combineAnnotations(a.annotations, b.annotations) }
3296
+ : never
3331
3297
  case "Literal":
3332
3298
  switch (b._tag) {
3333
- case "Unknown":
3334
- return { ...a, ...combineAnnotations(a.annotations, b.annotations) }
3335
3299
  case "Literal":
3336
3300
  return a.literal === b.literal
3337
3301
  ? { ...a, ...combineAnnotations(a.annotations, b.annotations) }
3338
3302
  : never
3339
3303
  case "String":
3340
- return typeof a.literal === "string" ? { ...a, ...combineAnnotations(a.annotations, b.annotations) } : never
3341
3304
  case "Number":
3342
- return typeof a.literal === "number" ? { ...a, ...combineAnnotations(a.annotations, b.annotations) } : never
3305
+ return satisfiesLiteral(b, a) ? { ...a, ...combineAnnotations(a.annotations, b.annotations) } : never
3343
3306
  case "Boolean":
3344
3307
  return typeof a.literal === "boolean"
3345
3308
  ? { ...a, ...combineAnnotations(a.annotations, b.annotations) }
3346
3309
  : never
3347
- case "Union":
3348
- return combine(b, a)
3349
- case "Reference":
3350
- return combine(a, resolveReference(b.$ref))
3351
3310
  default:
3352
3311
  return never
3353
3312
  }
3354
- case "Arrays":
3355
- switch (b._tag) {
3356
- case "Unknown":
3357
- return { ...a, ...combineAnnotations(a.annotations, b.annotations) }
3358
- case "Arrays": {
3359
- const checks = combineArraysChecks(a.checks, b.checks, b.annotations)
3360
- return {
3361
- _tag: "Arrays",
3362
- elements: combineElements(a.elements, b.elements),
3363
- rest: combineRest(a.rest, b.rest),
3364
- checks: checks ?? a.checks,
3365
- ...combineAnnotations(a.annotations, checks ? undefined : b.annotations)
3366
- }
3367
- }
3368
- case "Union":
3369
- return combine(b, a)
3370
- case "Reference":
3371
- return combine(a, resolveReference(b.$ref))
3372
- default:
3373
- return never
3374
- }
3375
- case "Objects":
3376
- switch (b._tag) {
3377
- case "Unknown":
3378
- return { ...a, ...combineAnnotations(a.annotations, b.annotations) }
3379
- case "Objects": {
3380
- const checks = combineChecks(a.checks, b.checks, b.annotations)
3381
- return {
3382
- _tag: "Objects",
3383
- propertySignatures: combinePropertySignatures(a.propertySignatures, b.propertySignatures),
3384
- indexSignatures: combineIndexSignatures(a.indexSignatures, b.indexSignatures),
3385
- checks: checks ?? a.checks,
3386
- ...combineAnnotations(a.annotations, checks ? undefined : b.annotations)
3387
- }
3388
- }
3389
- case "Union":
3390
- return combine(b, a)
3391
- case "Reference":
3392
- return combine(a, resolveReference(b.$ref))
3393
- default:
3394
- return never
3313
+ case "Arrays": {
3314
+ if (b._tag !== "Arrays") return never
3315
+ const arrays = combineArrays(a, b)
3316
+ if (arrays === undefined) return never
3317
+ const checks = combineArraysChecks(a.checks, b.checks, b.annotations)
3318
+ return {
3319
+ _tag: "Arrays",
3320
+ elements: arrays.elements,
3321
+ rest: arrays.rest,
3322
+ checks: checks ?? a.checks,
3323
+ ...combineAnnotations(a.annotations, checks ? undefined : b.annotations)
3395
3324
  }
3396
- case "Union": {
3397
- switch (b._tag) {
3398
- case "Unknown":
3399
- return { ...a, ...combineAnnotations(a.annotations, b.annotations) }
3400
- default: {
3401
- const types = a.types.map((s) => combine(s, b)).filter((s) => s !== never)
3402
- if (types.length === 0) return never
3403
- return {
3404
- _tag: "Union",
3405
- types,
3406
- mode: a.mode,
3407
- ...makeAnnotations(a.annotations)
3408
- }
3409
- }
3325
+ }
3326
+ case "Objects": {
3327
+ if (b._tag !== "Objects") return never
3328
+ const checks = combineChecks(a.checks, b.checks, b.annotations)
3329
+ return {
3330
+ _tag: "Objects",
3331
+ propertySignatures: combinePropertySignatures(a.propertySignatures, b.propertySignatures),
3332
+ indexSignatures: combineIndexSignatures(a.indexSignatures, b.indexSignatures),
3333
+ checks: checks ?? a.checks,
3334
+ ...combineAnnotations(a.annotations, checks ? undefined : b.annotations)
3410
3335
  }
3411
3336
  }
3337
+ default:
3338
+ return never
3339
+ }
3340
+ }
3341
+
3342
+ function satisfiesPrimitiveCheck(check: Check<Meta>, value: unknown): boolean {
3343
+ if (check._tag === "FilterGroup") {
3344
+ return check.checks.every((check) => satisfiesPrimitiveCheck(check, value))
3345
+ }
3346
+ const meta = check.meta
3347
+ switch (meta._tag) {
3348
+ case "isMinLength":
3349
+ return typeof value === "string" && value.length >= meta.minLength
3350
+ case "isMaxLength":
3351
+ return typeof value === "string" && value.length <= meta.maxLength
3352
+ case "isPattern":
3353
+ return typeof value === "string" && meta.regExp.test(value)
3354
+ case "isFinite":
3355
+ return typeof value === "number" && globalThis.Number.isFinite(value)
3356
+ case "isInt":
3357
+ return typeof value === "number" && globalThis.Number.isSafeInteger(value)
3358
+ case "isMultipleOf":
3359
+ return typeof value === "number" && remainder(value, meta.divisor) === 0
3360
+ case "isGreaterThan":
3361
+ return typeof value === "number" && value > meta.exclusiveMinimum
3362
+ case "isGreaterThanOrEqualTo":
3363
+ return typeof value === "number" && value >= meta.minimum
3364
+ case "isLessThan":
3365
+ return typeof value === "number" && value < meta.exclusiveMaximum
3366
+ case "isLessThanOrEqualTo":
3367
+ return typeof value === "number" && value <= meta.maximum
3368
+ default:
3369
+ return false
3412
3370
  }
3413
3371
  }
3414
3372
 
3373
+ function satisfiesLiteral(type: String | Number, literal: Literal): boolean {
3374
+ const value = literal.literal
3375
+ if (type._tag === "String" ? typeof value !== "string" : typeof value !== "number") {
3376
+ return false
3377
+ }
3378
+ return type.checks.every((check) => satisfiesPrimitiveCheck(check, value))
3379
+ }
3380
+
3415
3381
  function collectProperties(js: JsonSchema.JsonSchema): Array<PropertySignature> {
3416
3382
  const properties: Record<string, unknown> = Predicate.isObject(js.properties) ? js.properties : {}
3417
3383
  const required = Array.isArray(js.required) ? js.required : []
@@ -3446,35 +3412,32 @@ export function fromJsonSchemaMultiDocument(document: JsonSchema.MultiDocument<"
3446
3412
  return out
3447
3413
  }
3448
3414
 
3449
- function combineElements(a: ReadonlyArray<Element>, b: ReadonlyArray<Element>): Array<Element> {
3450
- const len = Math.max(a.length, b.length)
3451
- let out: Array<Element> = []
3415
+ function combineArrays(a: Arrays, b: Arrays): Pick<Arrays, "elements" | "rest"> | undefined {
3416
+ const elements: Array<Element> = []
3417
+ const len = Math.max(a.elements.length, b.elements.length)
3452
3418
  for (let i = 0; i < len; i++) {
3453
- out.push({
3454
- isOptional: a[i].isOptional && b[i].isOptional,
3455
- type: combine(a[i].type, b[i].type)
3456
- })
3457
- }
3458
- if (a.length > len) {
3459
- out = [...out, ...a.slice(len)]
3460
- } else if (b.length > len) {
3461
- out = [...out, ...b.slice(len)]
3419
+ const ae = a.elements[i]
3420
+ const be = b.elements[i]
3421
+ const isOptional = ae?.isOptional !== false && be?.isOptional !== false
3422
+ const at = ae?.type ?? a.rest[0]
3423
+ const bt = be?.type ?? b.rest[0]
3424
+ if (at === undefined || bt === undefined) {
3425
+ return isOptional ? { elements, rest: [] } : undefined
3426
+ }
3427
+ const type = combine(at, bt)
3428
+ if (type === never) {
3429
+ return isOptional ? { elements, rest: [] } : undefined
3430
+ }
3431
+ elements.push({ isOptional, type })
3462
3432
  }
3463
- return out
3464
- }
3465
3433
 
3466
- function combineRest(a: ReadonlyArray<Representation>, b: ReadonlyArray<Representation>): Array<Representation> {
3467
- const len = Math.max(a.length, b.length)
3468
- let out: Array<Representation> = []
3469
- for (let i = 0; i < len; i++) {
3470
- out.push(combine(a[i], b[i]))
3434
+ const ar = a.rest[0]
3435
+ const br = b.rest[0]
3436
+ if (ar === undefined || br === undefined) {
3437
+ return { elements, rest: [] }
3471
3438
  }
3472
- if (a.length > len) {
3473
- out = [...out, ...a.slice(len)]
3474
- } else if (b.length > len) {
3475
- out = [...out, ...b.slice(len)]
3476
- }
3477
- return out
3439
+ const rest = combine(ar, br)
3440
+ return { elements, rest: rest === never ? [] : [rest] }
3478
3441
  }
3479
3442
 
3480
3443
  function combinePropertySignatures(
package/src/index.ts CHANGED
@@ -296,6 +296,11 @@ export * as Layer from "./Layer.ts"
296
296
  */
297
297
  export * as LayerMap from "./LayerMap.ts"
298
298
 
299
+ /**
300
+ * @since 4.0.0
301
+ */
302
+ export * as LayerRef from "./LayerRef.ts"
303
+
299
304
  /**
300
305
  * @since 2.0.0
301
306
  */
@@ -521,6 +526,11 @@ export * as Schema from "./Schema.ts"
521
526
  */
522
527
  export * as SchemaAST from "./SchemaAST.ts"
523
528
 
529
+ /**
530
+ * @since 4.0.0
531
+ */
532
+ export * as SchemaError from "./SchemaError.ts"
533
+
524
534
  /**
525
535
  * @since 4.0.0
526
536
  */
@@ -4585,17 +4585,20 @@ const forEachSequential = <A, B, E, R>(
4585
4585
  )
4586
4586
  })
4587
4587
 
4588
+ type IterateEagerOptions = {
4589
+ readonly concurrency?: number | undefined
4590
+ readonly start?: number | undefined
4591
+ readonly end?: number | undefined
4592
+ readonly orderedStep?: boolean | undefined
4593
+ }
4594
+
4588
4595
  const iterateEagerImpl = <S, A, X, E, R, E2>(options: {
4589
4596
  readonly onItem: (state: S, item: A, index: number) => Effect.Effect<X, E, R>
4590
4597
  readonly step: (state: NoInfer<S>, item: A, exit: Exit.Exit<X, E>, index: number) => Exit.Exit<void, E2> | void
4591
4598
  }): (
4592
4599
  initialState: S,
4593
4600
  items: ReadonlyArray<A>,
4594
- options?: {
4595
- readonly concurrency?: number | undefined
4596
- readonly start?: number | undefined
4597
- readonly end?: number | undefined
4598
- }
4601
+ options?: IterateEagerOptions
4599
4602
  ) => Effect.Effect<void, E | E2, R> | undefined => {
4600
4603
  const onItem = options.onItem
4601
4604
  const step = options.step
@@ -4603,15 +4606,12 @@ const iterateEagerImpl = <S, A, X, E, R, E2>(options: {
4603
4606
  return (
4604
4607
  state: S,
4605
4608
  items: ReadonlyArray<A>,
4606
- opts: {
4607
- readonly concurrency?: number | undefined
4608
- readonly start?: number | undefined
4609
- readonly end?: number | undefined
4610
- } | undefined
4609
+ opts: IterateEagerOptions | undefined
4611
4610
  ): Effect.Effect<void, E | E2, R> | undefined => {
4612
4611
  let index = opts?.start ?? 0
4613
4612
  const end = opts?.end ?? items.length
4614
4613
  const concurrency = opts?.concurrency ?? 1
4614
+ const orderedStep = opts?.orderedStep === true && concurrency > 1
4615
4615
  let done = false
4616
4616
  let parentFiber: Fiber.Fiber<any, any> | undefined
4617
4617
  let fibers: Set<Fiber.Fiber<any, any>> | undefined
@@ -4619,6 +4619,22 @@ const iterateEagerImpl = <S, A, X, E, R, E2>(options: {
4619
4619
  let interrupted = false
4620
4620
  let terminal: Exit.Exit<void, E | E2> | void
4621
4621
  let effect: Effect.Effect<X, E, R> | undefined
4622
+ let nextIndex = index
4623
+ const exits: Array<Exit.Exit<X, E> | undefined> | undefined = orderedStep ? new Array(end) : undefined
4624
+
4625
+ const runStep = (item: A, exit: Exit.Exit<X, E>, currentIndex: number): Exit.Exit<void, E | E2> | void => {
4626
+ if (!orderedStep) return step(state, item, exit, currentIndex)
4627
+ if (terminal) return terminal
4628
+ exits![currentIndex] = exit
4629
+ while (nextIndex < end) {
4630
+ const nextExit = exits![nextIndex]
4631
+ if (nextExit === undefined) return
4632
+ exits![nextIndex] = undefined
4633
+ const index = nextIndex++
4634
+ const result = step(state, items[index], nextExit, index)
4635
+ if (result) return result
4636
+ }
4637
+ }
4622
4638
 
4623
4639
  const go = (): Effect.Effect<void, E | E2, R> | undefined => {
4624
4640
  let paused = false
@@ -4628,13 +4644,13 @@ const iterateEagerImpl = <S, A, X, E, R, E2>(options: {
4628
4644
 
4629
4645
  // fast case (already an exit)
4630
4646
  if (effectIsExit(eff)) {
4631
- terminal = step(state, item, eff, index)
4647
+ terminal = runStep(item, eff, index)
4632
4648
  if (terminal) break
4633
4649
 
4634
4650
  // Use flatMap for concurrency of 1
4635
4651
  } else if (concurrency === 1) {
4636
4652
  return flatMap(exit(eff), (exit) => {
4637
- terminal = step(state, item, exit, index)
4653
+ terminal = runStep(item, exit, index)
4638
4654
  index++
4639
4655
  return terminal ?? go() ?? void_
4640
4656
  })
@@ -4661,7 +4677,7 @@ const iterateEagerImpl = <S, A, X, E, R, E2>(options: {
4661
4677
 
4662
4678
  const fiber = forkUnsafe(parentFiber, eff, true, true, "inherit")
4663
4679
  if (fiber._exit) {
4664
- terminal = step(state, item, fiber._exit, index)
4680
+ terminal = runStep(item, fiber._exit, index)
4665
4681
  if (terminal) break
4666
4682
  continue
4667
4683
  }
@@ -4685,7 +4701,7 @@ const iterateEagerImpl = <S, A, X, E, R, E2>(options: {
4685
4701
  }
4686
4702
  }
4687
4703
  } else {
4688
- const result = step(state, item, exit, currentIndex)
4704
+ const result = runStep(item, exit, currentIndex)
4689
4705
  if (result) {
4690
4706
  terminal = result._tag === "Failure"
4691
4707
  ? exitFailCause(causeFromReasons(result.cause.reasons.slice()))
@@ -4741,11 +4757,7 @@ export const iterateEager = <S, A>(): <X, E, R, E2>(options: {
4741
4757
  }) => (
4742
4758
  initialState: S,
4743
4759
  items: ReadonlyArray<A>,
4744
- options?: {
4745
- readonly concurrency?: number | undefined
4746
- readonly start?: number | undefined
4747
- readonly end?: number | undefined
4748
- }
4760
+ options?: IterateEagerOptions
4749
4761
  ) => Effect.Effect<void, E | E2, R> | undefined => iterateEagerImpl
4750
4762
 
4751
4763
  const forEachConcurrent = iterateEagerImpl({
@@ -5835,11 +5847,16 @@ class ClockImpl implements Clock.Clock {
5835
5847
  }
5836
5848
  readonly currentTimeNanos: Effect.Effect<bigint> = sync(() => this.currentTimeNanosUnsafe())
5837
5849
  sleep(duration: Duration.Duration): Effect.Effect<void> {
5838
- const millis = Duration.toMillis(duration)
5850
+ return this.sleepMillis(Duration.toMillis(duration))
5851
+ }
5852
+ private sleepMillis(millis: number): Effect.Effect<void> {
5839
5853
  if (millis <= 0) return yieldNow
5854
+ else if (!Number.isFinite(millis)) return never
5840
5855
  return callback((resume) => {
5841
- if (millis > MAX_TIMER_MILLIS) return
5842
- const handle = setTimeout(() => resume(void_), millis)
5856
+ const continuation = millis > MAX_TIMER_MILLIS
5857
+ ? this.sleepMillis(millis - MAX_TIMER_MILLIS)
5858
+ : void_
5859
+ const handle = setTimeout(() => resume(continuation), Math.min(millis, MAX_TIMER_MILLIS))
5843
5860
  return sync(() => clearTimeout(handle))
5844
5861
  })
5845
5862
  }
@@ -78,8 +78,7 @@ function recur(ast: SchemaAST.AST, path: ReadonlyArray<PropertyKey>): Equivalenc
78
78
  // handle post rest elements
79
79
  // ---------------------------------------------
80
80
  for (let j = 0; j < tail.length; j++) {
81
- i += j
82
- if (!tail[j](a[i], b[i])) {
81
+ if (!tail[j](a[i + j], b[i + j])) {
83
82
  return false
84
83
  }
85
84
  }
@@ -95,12 +95,12 @@ export function fromASTs(asts: readonly [SchemaAST.AST, ...Array<SchemaAST.AST>]
95
95
  return out
96
96
  }
97
97
 
98
- function getEncodedSchema(last: SchemaAST.Declaration): SchemaAST.AST {
98
+ function getEncodedSchema(last: SchemaAST.Declaration): SchemaAST.Declaration | SchemaAST.Null {
99
99
  const getLink = last.annotations?.toCodecJson ?? last.annotations?.toCodec
100
100
  if (Predicate.isFunction(getLink)) {
101
- const tps = last.typeParameters.map((tp) => InternalSchema.make(SchemaAST.toEncoded(tp)))
102
- const link = getLink(tps)
103
- return SchemaAST.replaceEncoding(last, [link])
101
+ return SchemaAST.replaceEncoding(last, [
102
+ getLink(last.typeParameters.map((tp) => InternalSchema.make(SchemaAST.toEncoded(tp))))
103
+ ])
104
104
  }
105
105
  return SchemaAST.null
106
106
  }