effect 4.0.0-beta.97 → 4.0.0-beta.99

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 (221) hide show
  1. package/README.md +1 -3
  2. package/dist/Array.js +1 -1
  3. package/dist/Array.js.map +1 -1
  4. package/dist/Graph.d.ts +1187 -196
  5. package/dist/Graph.d.ts.map +1 -1
  6. package/dist/Graph.js +1031 -283
  7. package/dist/Graph.js.map +1 -1
  8. package/dist/Iterable.d.ts.map +1 -1
  9. package/dist/Iterable.js +41 -1
  10. package/dist/Iterable.js.map +1 -1
  11. package/dist/LayerRef.d.ts +4 -6
  12. package/dist/LayerRef.d.ts.map +1 -1
  13. package/dist/LayerRef.js +4 -6
  14. package/dist/LayerRef.js.map +1 -1
  15. package/dist/Number.d.ts.map +1 -1
  16. package/dist/Number.js +28 -10
  17. package/dist/Number.js.map +1 -1
  18. package/dist/Schema.d.ts +22 -22
  19. package/dist/Schema.d.ts.map +1 -1
  20. package/dist/Schema.js +37 -34
  21. package/dist/Schema.js.map +1 -1
  22. package/dist/SchemaAST.d.ts.map +1 -1
  23. package/dist/SchemaAST.js +25 -10
  24. package/dist/SchemaAST.js.map +1 -1
  25. package/dist/SchemaError.d.ts +53 -0
  26. package/dist/SchemaError.d.ts.map +1 -0
  27. package/dist/SchemaError.js +61 -0
  28. package/dist/SchemaError.js.map +1 -0
  29. package/dist/SchemaGetter.d.ts.map +1 -1
  30. package/dist/SchemaGetter.js +17 -12
  31. package/dist/SchemaGetter.js.map +1 -1
  32. package/dist/SchemaRepresentation.d.ts.map +1 -1
  33. package/dist/SchemaRepresentation.js +186 -224
  34. package/dist/SchemaRepresentation.js.map +1 -1
  35. package/dist/index.d.ts +8 -0
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +8 -0
  38. package/dist/index.js.map +1 -1
  39. package/dist/internal/effect.js +35 -11
  40. package/dist/internal/effect.js.map +1 -1
  41. package/dist/internal/schema/equivalence.js +1 -2
  42. package/dist/internal/schema/equivalence.js.map +1 -1
  43. package/dist/internal/schema/representation.js +1 -3
  44. package/dist/internal/schema/representation.js.map +1 -1
  45. package/dist/internal/schema/schema.d.ts +0 -13
  46. package/dist/internal/schema/schema.d.ts.map +1 -1
  47. package/dist/internal/schema/schema.js +4 -29
  48. package/dist/internal/schema/schema.js.map +1 -1
  49. package/dist/unstable/ai/Tool.d.ts.map +1 -1
  50. package/dist/unstable/ai/Tool.js +11 -13
  51. package/dist/unstable/ai/Tool.js.map +1 -1
  52. package/dist/unstable/cli/CliConfig.d.ts +76 -0
  53. package/dist/unstable/cli/CliConfig.d.ts.map +1 -0
  54. package/dist/unstable/cli/CliConfig.js +63 -0
  55. package/dist/unstable/cli/CliConfig.js.map +1 -0
  56. package/dist/unstable/cli/CliError.d.ts +8 -16
  57. package/dist/unstable/cli/CliError.d.ts.map +1 -1
  58. package/dist/unstable/cli/CliError.js +11 -16
  59. package/dist/unstable/cli/CliError.js.map +1 -1
  60. package/dist/unstable/cli/Command.d.ts +40 -4
  61. package/dist/unstable/cli/Command.d.ts.map +1 -1
  62. package/dist/unstable/cli/Command.js +63 -6
  63. package/dist/unstable/cli/Command.js.map +1 -1
  64. package/dist/unstable/cli/GlobalFlag.d.ts +24 -5
  65. package/dist/unstable/cli/GlobalFlag.d.ts.map +1 -1
  66. package/dist/unstable/cli/GlobalFlag.js +26 -10
  67. package/dist/unstable/cli/GlobalFlag.js.map +1 -1
  68. package/dist/unstable/cli/Param.js +6 -2
  69. package/dist/unstable/cli/Param.js.map +1 -1
  70. package/dist/unstable/cli/index.d.ts +4 -0
  71. package/dist/unstable/cli/index.d.ts.map +1 -1
  72. package/dist/unstable/cli/index.js +4 -0
  73. package/dist/unstable/cli/index.js.map +1 -1
  74. package/dist/unstable/cli/internal/ansi.d.ts.map +1 -1
  75. package/dist/unstable/cli/internal/ansi.js +2 -0
  76. package/dist/unstable/cli/internal/ansi.js.map +1 -1
  77. package/dist/unstable/cli/internal/parser.js +11 -2
  78. package/dist/unstable/cli/internal/parser.js.map +1 -1
  79. package/dist/unstable/cli/internal/wizard.d.ts +13 -0
  80. package/dist/unstable/cli/internal/wizard.d.ts.map +1 -0
  81. package/dist/unstable/cli/internal/wizard.js +212 -0
  82. package/dist/unstable/cli/internal/wizard.js.map +1 -0
  83. package/dist/unstable/cluster/EntityProxyServer.d.ts +1 -1
  84. package/dist/unstable/cluster/EntityProxyServer.d.ts.map +1 -1
  85. package/dist/unstable/cluster/EntityProxyServer.js +2 -4
  86. package/dist/unstable/cluster/EntityProxyServer.js.map +1 -1
  87. package/dist/unstable/cluster/RunnerStorage.js +1 -1
  88. package/dist/unstable/cluster/RunnerStorage.js.map +1 -1
  89. package/dist/unstable/cluster/internal/entityManager.js +15 -12
  90. package/dist/unstable/cluster/internal/entityManager.js.map +1 -1
  91. package/dist/unstable/http/Multipart.d.ts.map +1 -1
  92. package/dist/unstable/http/Multipart.js +3 -1
  93. package/dist/unstable/http/Multipart.js.map +1 -1
  94. package/dist/unstable/httpapi/HttpApi.d.ts +36 -15
  95. package/dist/unstable/httpapi/HttpApi.d.ts.map +1 -1
  96. package/dist/unstable/httpapi/HttpApi.js +19 -20
  97. package/dist/unstable/httpapi/HttpApi.js.map +1 -1
  98. package/dist/unstable/httpapi/HttpApiBuilder.d.ts +51 -62
  99. package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
  100. package/dist/unstable/httpapi/HttpApiBuilder.js +68 -58
  101. package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
  102. package/dist/unstable/httpapi/HttpApiClient.d.ts +53 -53
  103. package/dist/unstable/httpapi/HttpApiClient.d.ts.map +1 -1
  104. package/dist/unstable/httpapi/HttpApiClient.js +40 -30
  105. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  106. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts +165 -164
  107. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts.map +1 -1
  108. package/dist/unstable/httpapi/HttpApiEndpoint.js +31 -19
  109. package/dist/unstable/httpapi/HttpApiEndpoint.js.map +1 -1
  110. package/dist/unstable/httpapi/HttpApiError.d.ts +22 -0
  111. package/dist/unstable/httpapi/HttpApiError.d.ts.map +1 -1
  112. package/dist/unstable/httpapi/HttpApiError.js +31 -0
  113. package/dist/unstable/httpapi/HttpApiError.js.map +1 -1
  114. package/dist/unstable/httpapi/HttpApiGroup.d.ts +55 -30
  115. package/dist/unstable/httpapi/HttpApiGroup.d.ts.map +1 -1
  116. package/dist/unstable/httpapi/HttpApiGroup.js +22 -29
  117. package/dist/unstable/httpapi/HttpApiGroup.js.map +1 -1
  118. package/dist/unstable/httpapi/HttpApiMiddleware.d.ts +8 -8
  119. package/dist/unstable/httpapi/HttpApiMiddleware.d.ts.map +1 -1
  120. package/dist/unstable/httpapi/HttpApiMiddleware.js.map +1 -1
  121. package/dist/unstable/httpapi/HttpApiScalar.d.ts +2 -2
  122. package/dist/unstable/httpapi/HttpApiScalar.d.ts.map +1 -1
  123. package/dist/unstable/httpapi/HttpApiScalar.js +4 -3
  124. package/dist/unstable/httpapi/HttpApiScalar.js.map +1 -1
  125. package/dist/unstable/httpapi/HttpApiSchema.d.ts +8 -0
  126. package/dist/unstable/httpapi/HttpApiSchema.d.ts.map +1 -1
  127. package/dist/unstable/httpapi/HttpApiSchema.js.map +1 -1
  128. package/dist/unstable/httpapi/HttpApiSwagger.d.ts +1 -1
  129. package/dist/unstable/httpapi/HttpApiSwagger.d.ts.map +1 -1
  130. package/dist/unstable/httpapi/HttpApiSwagger.js.map +1 -1
  131. package/dist/unstable/httpapi/HttpApiTest.d.ts +4 -4
  132. package/dist/unstable/httpapi/HttpApiTest.d.ts.map +1 -1
  133. package/dist/unstable/httpapi/HttpApiTest.js +9 -8
  134. package/dist/unstable/httpapi/HttpApiTest.js.map +1 -1
  135. package/dist/unstable/httpapi/OpenApi.d.ts +1 -1
  136. package/dist/unstable/httpapi/OpenApi.d.ts.map +1 -1
  137. package/dist/unstable/httpapi/OpenApi.js +77 -37
  138. package/dist/unstable/httpapi/OpenApi.js.map +1 -1
  139. package/dist/unstable/httpapi/internal/html.js +6 -2
  140. package/dist/unstable/httpapi/internal/html.js.map +1 -1
  141. package/dist/unstable/httpapi/internal/mediaType.d.ts +2 -0
  142. package/dist/unstable/httpapi/internal/mediaType.d.ts.map +1 -0
  143. package/dist/unstable/httpapi/internal/mediaType.js +7 -0
  144. package/dist/unstable/httpapi/internal/mediaType.js.map +1 -0
  145. package/dist/unstable/persistence/PersistedQueue.d.ts.map +1 -1
  146. package/dist/unstable/persistence/PersistedQueue.js +16 -12
  147. package/dist/unstable/persistence/PersistedQueue.js.map +1 -1
  148. package/dist/unstable/persistence/Redis.d.ts.map +1 -1
  149. package/dist/unstable/persistence/Redis.js +5 -3
  150. package/dist/unstable/persistence/Redis.js.map +1 -1
  151. package/dist/unstable/reactivity/Atom.js +1 -1
  152. package/dist/unstable/reactivity/Atom.js.map +1 -1
  153. package/dist/unstable/reactivity/AtomHttpApi.d.ts +7 -7
  154. package/dist/unstable/reactivity/AtomHttpApi.d.ts.map +1 -1
  155. package/dist/unstable/reactivity/AtomHttpApi.js +3 -2
  156. package/dist/unstable/reactivity/AtomHttpApi.js.map +1 -1
  157. package/dist/unstable/rpc/RpcServer.d.ts +3 -1
  158. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  159. package/dist/unstable/rpc/RpcServer.js +6 -3
  160. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  161. package/dist/unstable/sql/SqlClient.d.ts +1 -2
  162. package/dist/unstable/sql/SqlClient.d.ts.map +1 -1
  163. package/dist/unstable/sql/SqlClient.js.map +1 -1
  164. package/dist/unstable/workflow/DurableDeferred.js +1 -1
  165. package/dist/unstable/workflow/DurableDeferred.js.map +1 -1
  166. package/dist/unstable/workflow/WorkflowProxyServer.d.ts +1 -1
  167. package/dist/unstable/workflow/WorkflowProxyServer.d.ts.map +1 -1
  168. package/dist/unstable/workflow/WorkflowProxyServer.js +1 -2
  169. package/dist/unstable/workflow/WorkflowProxyServer.js.map +1 -1
  170. package/package.json +3 -3
  171. package/src/Array.ts +1 -1
  172. package/src/Graph.ts +2967 -457
  173. package/src/Iterable.ts +32 -2
  174. package/src/LayerRef.ts +4 -6
  175. package/src/Number.ts +29 -10
  176. package/src/Schema.ts +43 -35
  177. package/src/SchemaAST.ts +25 -13
  178. package/src/SchemaError.ts +64 -0
  179. package/src/SchemaGetter.ts +22 -16
  180. package/src/SchemaRepresentation.ts +165 -202
  181. package/src/index.ts +10 -0
  182. package/src/internal/effect.ts +48 -25
  183. package/src/internal/schema/equivalence.ts +1 -2
  184. package/src/internal/schema/representation.ts +4 -4
  185. package/src/internal/schema/schema.ts +4 -37
  186. package/src/unstable/ai/Tool.ts +13 -16
  187. package/src/unstable/cli/CliConfig.ts +85 -0
  188. package/src/unstable/cli/CliError.ts +27 -16
  189. package/src/unstable/cli/Command.ts +90 -14
  190. package/src/unstable/cli/GlobalFlag.ts +46 -29
  191. package/src/unstable/cli/Param.ts +15 -3
  192. package/src/unstable/cli/index.ts +5 -0
  193. package/src/unstable/cli/internal/ansi.ts +3 -0
  194. package/src/unstable/cli/internal/parser.ts +14 -2
  195. package/src/unstable/cli/internal/wizard.ts +283 -0
  196. package/src/unstable/cluster/EntityProxyServer.ts +15 -17
  197. package/src/unstable/cluster/RunnerStorage.ts +1 -1
  198. package/src/unstable/cluster/internal/entityManager.ts +48 -34
  199. package/src/unstable/http/Multipart.ts +3 -1
  200. package/src/unstable/httpapi/HttpApi.ts +72 -47
  201. package/src/unstable/httpapi/HttpApiBuilder.ts +320 -217
  202. package/src/unstable/httpapi/HttpApiClient.ts +196 -151
  203. package/src/unstable/httpapi/HttpApiEndpoint.ts +251 -447
  204. package/src/unstable/httpapi/HttpApiError.ts +33 -0
  205. package/src/unstable/httpapi/HttpApiGroup.ts +95 -74
  206. package/src/unstable/httpapi/HttpApiMiddleware.ts +10 -7
  207. package/src/unstable/httpapi/HttpApiScalar.ts +15 -12
  208. package/src/unstable/httpapi/HttpApiSchema.ts +8 -0
  209. package/src/unstable/httpapi/HttpApiSwagger.ts +2 -2
  210. package/src/unstable/httpapi/HttpApiTest.ts +15 -14
  211. package/src/unstable/httpapi/OpenApi.ts +74 -36
  212. package/src/unstable/httpapi/internal/html.ts +9 -2
  213. package/src/unstable/httpapi/internal/mediaType.ts +6 -0
  214. package/src/unstable/persistence/PersistedQueue.ts +16 -14
  215. package/src/unstable/persistence/Redis.ts +9 -4
  216. package/src/unstable/reactivity/Atom.ts +1 -1
  217. package/src/unstable/reactivity/AtomHttpApi.ts +164 -162
  218. package/src/unstable/rpc/RpcServer.ts +10 -4
  219. package/src/unstable/sql/SqlClient.ts +1 -2
  220. package/src/unstable/workflow/DurableDeferred.ts +1 -1
  221. 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
  */
@@ -851,10 +851,12 @@ export const fiberInterruptAll = <A extends Iterable<Fiber.Fiber<any, any>>>(
851
851
  ): Effect.Effect<void> =>
852
852
  withFiber((parent) => {
853
853
  const annotations = fiberStackAnnotations(parent)
854
+ let fiberArr = Arr.empty<Fiber.Fiber<any, any>>()
854
855
  for (const fiber of fibers) {
855
856
  fiber.interruptUnsafe(parent.id, annotations)
857
+ fiberArr.push(fiber)
856
858
  }
857
- return asVoid(fiberAwaitAll(fibers))
859
+ return asVoid(fiberAwaitAll(fiberArr))
858
860
  })
859
861
 
860
862
  /** @internal */
@@ -867,8 +869,12 @@ export const fiberInterruptAllAs: {
867
869
  ): Effect.Effect<void> =>
868
870
  withFiber((parent) => {
869
871
  const annotations = fiberStackAnnotations(parent)
870
- for (const fiber of fibers) fiber.interruptUnsafe(fiberId, annotations)
871
- return asVoid(fiberAwaitAll(fibers))
872
+ const fiberArr = Arr.empty<Fiber.Fiber<any, any>>()
873
+ for (const fiber of fibers) {
874
+ fiber.interruptUnsafe(fiberId, annotations)
875
+ fiberArr.push(fiber)
876
+ }
877
+ return asVoid(fiberAwaitAll(fiberArr))
872
878
  }))
873
879
 
874
880
  /** @internal */
@@ -4585,17 +4591,20 @@ const forEachSequential = <A, B, E, R>(
4585
4591
  )
4586
4592
  })
4587
4593
 
4594
+ type IterateEagerOptions = {
4595
+ readonly concurrency?: number | undefined
4596
+ readonly start?: number | undefined
4597
+ readonly end?: number | undefined
4598
+ readonly orderedStep?: boolean | undefined
4599
+ }
4600
+
4588
4601
  const iterateEagerImpl = <S, A, X, E, R, E2>(options: {
4589
4602
  readonly onItem: (state: S, item: A, index: number) => Effect.Effect<X, E, R>
4590
4603
  readonly step: (state: NoInfer<S>, item: A, exit: Exit.Exit<X, E>, index: number) => Exit.Exit<void, E2> | void
4591
4604
  }): (
4592
4605
  initialState: S,
4593
4606
  items: ReadonlyArray<A>,
4594
- options?: {
4595
- readonly concurrency?: number | undefined
4596
- readonly start?: number | undefined
4597
- readonly end?: number | undefined
4598
- }
4607
+ options?: IterateEagerOptions
4599
4608
  ) => Effect.Effect<void, E | E2, R> | undefined => {
4600
4609
  const onItem = options.onItem
4601
4610
  const step = options.step
@@ -4603,15 +4612,12 @@ const iterateEagerImpl = <S, A, X, E, R, E2>(options: {
4603
4612
  return (
4604
4613
  state: S,
4605
4614
  items: ReadonlyArray<A>,
4606
- opts: {
4607
- readonly concurrency?: number | undefined
4608
- readonly start?: number | undefined
4609
- readonly end?: number | undefined
4610
- } | undefined
4615
+ opts: IterateEagerOptions | undefined
4611
4616
  ): Effect.Effect<void, E | E2, R> | undefined => {
4612
4617
  let index = opts?.start ?? 0
4613
4618
  const end = opts?.end ?? items.length
4614
4619
  const concurrency = opts?.concurrency ?? 1
4620
+ const orderedStep = opts?.orderedStep === true && concurrency > 1
4615
4621
  let done = false
4616
4622
  let parentFiber: Fiber.Fiber<any, any> | undefined
4617
4623
  let fibers: Set<Fiber.Fiber<any, any>> | undefined
@@ -4619,6 +4625,22 @@ const iterateEagerImpl = <S, A, X, E, R, E2>(options: {
4619
4625
  let interrupted = false
4620
4626
  let terminal: Exit.Exit<void, E | E2> | void
4621
4627
  let effect: Effect.Effect<X, E, R> | undefined
4628
+ let nextIndex = index
4629
+ const exits: Array<Exit.Exit<X, E> | undefined> | undefined = orderedStep ? new Array(end) : undefined
4630
+
4631
+ const runStep = (item: A, exit: Exit.Exit<X, E>, currentIndex: number): Exit.Exit<void, E | E2> | void => {
4632
+ if (!orderedStep) return step(state, item, exit, currentIndex)
4633
+ if (terminal) return terminal
4634
+ exits![currentIndex] = exit
4635
+ while (nextIndex < end) {
4636
+ const nextExit = exits![nextIndex]
4637
+ if (nextExit === undefined) return
4638
+ exits![nextIndex] = undefined
4639
+ const index = nextIndex++
4640
+ const result = step(state, items[index], nextExit, index)
4641
+ if (result) return result
4642
+ }
4643
+ }
4622
4644
 
4623
4645
  const go = (): Effect.Effect<void, E | E2, R> | undefined => {
4624
4646
  let paused = false
@@ -4628,13 +4650,13 @@ const iterateEagerImpl = <S, A, X, E, R, E2>(options: {
4628
4650
 
4629
4651
  // fast case (already an exit)
4630
4652
  if (effectIsExit(eff)) {
4631
- terminal = step(state, item, eff, index)
4653
+ terminal = runStep(item, eff, index)
4632
4654
  if (terminal) break
4633
4655
 
4634
4656
  // Use flatMap for concurrency of 1
4635
4657
  } else if (concurrency === 1) {
4636
4658
  return flatMap(exit(eff), (exit) => {
4637
- terminal = step(state, item, exit, index)
4659
+ terminal = runStep(item, exit, index)
4638
4660
  index++
4639
4661
  return terminal ?? go() ?? void_
4640
4662
  })
@@ -4661,7 +4683,7 @@ const iterateEagerImpl = <S, A, X, E, R, E2>(options: {
4661
4683
 
4662
4684
  const fiber = forkUnsafe(parentFiber, eff, true, true, "inherit")
4663
4685
  if (fiber._exit) {
4664
- terminal = step(state, item, fiber._exit, index)
4686
+ terminal = runStep(item, fiber._exit, index)
4665
4687
  if (terminal) break
4666
4688
  continue
4667
4689
  }
@@ -4685,7 +4707,7 @@ const iterateEagerImpl = <S, A, X, E, R, E2>(options: {
4685
4707
  }
4686
4708
  }
4687
4709
  } else {
4688
- const result = step(state, item, exit, currentIndex)
4710
+ const result = runStep(item, exit, currentIndex)
4689
4711
  if (result) {
4690
4712
  terminal = result._tag === "Failure"
4691
4713
  ? exitFailCause(causeFromReasons(result.cause.reasons.slice()))
@@ -4741,11 +4763,7 @@ export const iterateEager = <S, A>(): <X, E, R, E2>(options: {
4741
4763
  }) => (
4742
4764
  initialState: S,
4743
4765
  items: ReadonlyArray<A>,
4744
- options?: {
4745
- readonly concurrency?: number | undefined
4746
- readonly start?: number | undefined
4747
- readonly end?: number | undefined
4748
- }
4766
+ options?: IterateEagerOptions
4749
4767
  ) => Effect.Effect<void, E | E2, R> | undefined => iterateEagerImpl
4750
4768
 
4751
4769
  const forEachConcurrent = iterateEagerImpl({
@@ -5835,11 +5853,16 @@ class ClockImpl implements Clock.Clock {
5835
5853
  }
5836
5854
  readonly currentTimeNanos: Effect.Effect<bigint> = sync(() => this.currentTimeNanosUnsafe())
5837
5855
  sleep(duration: Duration.Duration): Effect.Effect<void> {
5838
- const millis = Duration.toMillis(duration)
5856
+ return this.sleepMillis(Duration.toMillis(duration))
5857
+ }
5858
+ private sleepMillis(millis: number): Effect.Effect<void> {
5839
5859
  if (millis <= 0) return yieldNow
5860
+ else if (!Number.isFinite(millis)) return never
5840
5861
  return callback((resume) => {
5841
- if (millis > MAX_TIMER_MILLIS) return
5842
- const handle = setTimeout(() => resume(void_), millis)
5862
+ const continuation = millis > MAX_TIMER_MILLIS
5863
+ ? this.sleepMillis(millis - MAX_TIMER_MILLIS)
5864
+ : void_
5865
+ const handle = setTimeout(() => resume(continuation), Math.min(millis, MAX_TIMER_MILLIS))
5843
5866
  return sync(() => clearTimeout(handle))
5844
5867
  })
5845
5868
  }
@@ -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
  }