effect-app 4.0.0-beta.27 → 4.0.0-beta.271

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 (342) hide show
  1. package/CHANGELOG.md +1269 -0
  2. package/dist/Array.d.ts +2 -1
  3. package/dist/Array.d.ts.map +1 -1
  4. package/dist/Array.js +4 -4
  5. package/dist/Chunk.d.ts.map +1 -1
  6. package/dist/Config/SecretURL.d.ts +3 -1
  7. package/dist/Config/SecretURL.d.ts.map +1 -1
  8. package/dist/Config/SecretURL.js +3 -6
  9. package/dist/Config/internal/configSecretURL.d.ts.map +1 -1
  10. package/dist/Config/internal/configSecretURL.js +2 -2
  11. package/dist/Config.d.ts +2 -0
  12. package/dist/Config.d.ts.map +1 -0
  13. package/dist/Config.js +8 -0
  14. package/dist/ConfigProvider.d.ts +2 -0
  15. package/dist/ConfigProvider.d.ts.map +1 -0
  16. package/dist/ConfigProvider.js +6 -0
  17. package/dist/{ServiceMap.d.ts → Context.d.ts} +18 -20
  18. package/dist/Context.d.ts.map +1 -0
  19. package/dist/Context.js +67 -0
  20. package/dist/Effect.d.ts +10 -9
  21. package/dist/Effect.d.ts.map +1 -1
  22. package/dist/Effect.js +5 -8
  23. package/dist/Emailer.d.ts +51 -0
  24. package/dist/Emailer.d.ts.map +1 -0
  25. package/dist/Emailer.js +7 -0
  26. package/dist/Function.d.ts.map +1 -1
  27. package/dist/Layer.d.ts +10 -6
  28. package/dist/Layer.d.ts.map +1 -1
  29. package/dist/Layer.js +3 -2
  30. package/dist/Model/Repository/Registry.d.ts +22 -0
  31. package/dist/Model/Repository/Registry.d.ts.map +1 -0
  32. package/dist/Model/Repository/Registry.js +18 -0
  33. package/dist/Model/Repository/ext.d.ts +60 -0
  34. package/dist/Model/Repository/ext.d.ts.map +1 -0
  35. package/dist/Model/Repository/ext.js +122 -0
  36. package/dist/Model/Repository/internal/internal.d.ts +63 -0
  37. package/dist/Model/Repository/internal/internal.d.ts.map +1 -0
  38. package/dist/Model/Repository/internal/internal.js +430 -0
  39. package/dist/Model/Repository/legacy.d.ts +21 -0
  40. package/dist/Model/Repository/legacy.d.ts.map +1 -0
  41. package/dist/Model/Repository/legacy.js +2 -0
  42. package/dist/Model/Repository/makeRepo.d.ts +54 -0
  43. package/dist/Model/Repository/makeRepo.d.ts.map +1 -0
  44. package/dist/Model/Repository/makeRepo.js +27 -0
  45. package/dist/Model/Repository/service.d.ts +121 -0
  46. package/dist/Model/Repository/service.d.ts.map +1 -0
  47. package/dist/Model/Repository/service.js +2 -0
  48. package/dist/Model/Repository/validation.d.ts +58 -0
  49. package/dist/Model/Repository/validation.d.ts.map +1 -0
  50. package/dist/Model/Repository/validation.js +32 -0
  51. package/dist/Model/Repository.d.ts +7 -0
  52. package/dist/Model/Repository.d.ts.map +1 -0
  53. package/dist/Model/Repository.js +7 -0
  54. package/dist/Model/dsl.d.ts +33 -0
  55. package/dist/Model/dsl.d.ts.map +1 -0
  56. package/dist/Model/dsl.js +43 -0
  57. package/dist/Model/filter/filterApi.d.ts +30 -0
  58. package/dist/Model/filter/filterApi.d.ts.map +1 -0
  59. package/dist/Model/filter/filterApi.js +2 -0
  60. package/dist/Model/filter/types/errors.d.ts +29 -0
  61. package/dist/Model/filter/types/errors.d.ts.map +1 -0
  62. package/dist/Model/filter/types/errors.js +2 -0
  63. package/dist/Model/filter/types/fields.d.ts +15 -0
  64. package/dist/Model/filter/types/fields.d.ts.map +1 -0
  65. package/dist/Model/filter/types/fields.js +2 -0
  66. package/dist/Model/filter/types/path/common.d.ts +316 -0
  67. package/dist/Model/filter/types/path/common.d.ts.map +1 -0
  68. package/dist/Model/filter/types/path/common.js +2 -0
  69. package/dist/Model/filter/types/path/eager.d.ts +94 -0
  70. package/dist/Model/filter/types/path/eager.d.ts.map +1 -0
  71. package/dist/Model/filter/types/path/eager.js +36 -0
  72. package/dist/Model/filter/types/path/index.d.ts +4 -0
  73. package/dist/Model/filter/types/path/index.d.ts.map +1 -0
  74. package/dist/Model/filter/types/path/index.js +3 -0
  75. package/dist/Model/filter/types/utils.d.ts +79 -0
  76. package/dist/Model/filter/types/utils.d.ts.map +1 -0
  77. package/dist/Model/filter/types/utils.js +2 -0
  78. package/dist/Model/filter/types/validator.d.ts +30 -0
  79. package/dist/Model/filter/types/validator.d.ts.map +1 -0
  80. package/dist/Model/filter/types/validator.js +2 -0
  81. package/dist/Model/filter/types.d.ts +5 -0
  82. package/dist/Model/filter/types.d.ts.map +1 -0
  83. package/dist/Model/filter/types.js +7 -0
  84. package/dist/Model/query/dsl.d.ts +493 -0
  85. package/dist/Model/query/dsl.d.ts.map +1 -0
  86. package/dist/Model/query/dsl.js +376 -0
  87. package/dist/Model/query/new-kid-interpreter.d.ts +136 -0
  88. package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -0
  89. package/dist/Model/query/new-kid-interpreter.js +336 -0
  90. package/dist/Model/query.d.ts +15 -0
  91. package/dist/Model/query.d.ts.map +1 -0
  92. package/dist/Model/query.js +3 -0
  93. package/dist/Model.d.ts +5 -0
  94. package/dist/Model.d.ts.map +1 -0
  95. package/dist/Model.js +5 -0
  96. package/dist/NonEmptySet.d.ts +3 -1
  97. package/dist/NonEmptySet.d.ts.map +1 -1
  98. package/dist/NonEmptySet.js +2 -2
  99. package/dist/Option.d.ts +1 -0
  100. package/dist/Option.d.ts.map +1 -1
  101. package/dist/Option.js +3 -1
  102. package/dist/Pure.d.ts +7 -5
  103. package/dist/Pure.d.ts.map +1 -1
  104. package/dist/Pure.js +17 -14
  105. package/dist/QueueMaker.d.ts +13 -0
  106. package/dist/QueueMaker.d.ts.map +1 -0
  107. package/dist/QueueMaker.js +4 -0
  108. package/dist/RequestContext.d.ts +208 -0
  109. package/dist/RequestContext.d.ts.map +1 -0
  110. package/dist/RequestContext.js +54 -0
  111. package/dist/Schema/Class.d.ts +157 -19
  112. package/dist/Schema/Class.d.ts.map +1 -1
  113. package/dist/Schema/Class.js +214 -17
  114. package/dist/Schema/FastCheck.d.ts.map +1 -1
  115. package/dist/Schema/SchemaParser.d.ts +5 -0
  116. package/dist/Schema/SchemaParser.d.ts.map +1 -0
  117. package/dist/Schema/SchemaParser.js +6 -0
  118. package/dist/Schema/SpecialJsonSchema.d.ts +34 -0
  119. package/dist/Schema/SpecialJsonSchema.d.ts.map +1 -0
  120. package/dist/Schema/SpecialJsonSchema.js +118 -0
  121. package/dist/Schema/SpecialOpenApi.d.ts +32 -0
  122. package/dist/Schema/SpecialOpenApi.d.ts.map +1 -0
  123. package/dist/Schema/SpecialOpenApi.js +123 -0
  124. package/dist/Schema/brand.d.ts +4 -2
  125. package/dist/Schema/brand.d.ts.map +1 -1
  126. package/dist/Schema/brand.js +3 -1
  127. package/dist/Schema/email.d.ts.map +1 -1
  128. package/dist/Schema/email.js +7 -4
  129. package/dist/Schema/ext.d.ts +338 -55
  130. package/dist/Schema/ext.d.ts.map +1 -1
  131. package/dist/Schema/ext.js +358 -53
  132. package/dist/Schema/moreStrings.d.ts +82 -36
  133. package/dist/Schema/moreStrings.d.ts.map +1 -1
  134. package/dist/Schema/moreStrings.js +49 -42
  135. package/dist/Schema/numbers.d.ts +34 -21
  136. package/dist/Schema/numbers.d.ts.map +1 -1
  137. package/dist/Schema/numbers.js +55 -12
  138. package/dist/Schema/phoneNumber.d.ts.map +1 -1
  139. package/dist/Schema/phoneNumber.js +6 -3
  140. package/dist/Schema/strings.d.ts +18 -4
  141. package/dist/Schema/strings.d.ts.map +1 -1
  142. package/dist/Schema/strings.js +1 -5
  143. package/dist/Schema.d.ts +213 -7
  144. package/dist/Schema.d.ts.map +1 -1
  145. package/dist/Schema.js +190 -11
  146. package/dist/Set.d.ts +4 -1
  147. package/dist/Set.d.ts.map +1 -1
  148. package/dist/Set.js +3 -2
  149. package/dist/Store.d.ts +170 -0
  150. package/dist/Store.d.ts.map +1 -0
  151. package/dist/Store.js +121 -0
  152. package/dist/_ext/Array.d.ts +1 -1
  153. package/dist/_ext/Array.d.ts.map +1 -1
  154. package/dist/_ext/Array.js +4 -2
  155. package/dist/_ext/misc.d.ts +4 -1
  156. package/dist/_ext/misc.d.ts.map +1 -1
  157. package/dist/_ext/misc.js +4 -2
  158. package/dist/_ext/ord.ext.d.ts +2 -1
  159. package/dist/_ext/ord.ext.d.ts.map +1 -1
  160. package/dist/_ext/ord.ext.js +2 -2
  161. package/dist/client/InvalidationKeys.d.ts +29 -0
  162. package/dist/client/InvalidationKeys.d.ts.map +1 -0
  163. package/dist/client/InvalidationKeys.js +33 -0
  164. package/dist/client/apiClientFactory.d.ts +19 -31
  165. package/dist/client/apiClientFactory.d.ts.map +1 -1
  166. package/dist/client/apiClientFactory.js +104 -34
  167. package/dist/client/clientFor.d.ts +52 -18
  168. package/dist/client/clientFor.d.ts.map +1 -1
  169. package/dist/client/clientFor.js +9 -1
  170. package/dist/client/errors.d.ts +82 -27
  171. package/dist/client/errors.d.ts.map +1 -1
  172. package/dist/client/errors.js +75 -19
  173. package/dist/client/makeClient.d.ts +494 -32
  174. package/dist/client/makeClient.d.ts.map +1 -1
  175. package/dist/client/makeClient.js +66 -24
  176. package/dist/client.d.ts +1 -0
  177. package/dist/client.d.ts.map +1 -1
  178. package/dist/client.js +2 -1
  179. package/dist/faker.d.ts.map +1 -1
  180. package/dist/http/Request.d.ts +1 -1
  181. package/dist/http/Request.d.ts.map +1 -1
  182. package/dist/http/Request.js +2 -2
  183. package/dist/ids.d.ts +42 -14
  184. package/dist/ids.d.ts.map +1 -1
  185. package/dist/ids.js +30 -5
  186. package/dist/index.d.ts +6 -7
  187. package/dist/index.d.ts.map +1 -1
  188. package/dist/index.js +8 -8
  189. package/dist/middleware.d.ts +13 -7
  190. package/dist/middleware.d.ts.map +1 -1
  191. package/dist/middleware.js +14 -8
  192. package/dist/rpc/Invalidation.d.ts +420 -0
  193. package/dist/rpc/Invalidation.d.ts.map +1 -0
  194. package/dist/rpc/Invalidation.js +168 -0
  195. package/dist/rpc/MiddlewareMaker.d.ts +11 -7
  196. package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
  197. package/dist/rpc/MiddlewareMaker.js +59 -38
  198. package/dist/rpc/RpcContextMap.d.ts +3 -3
  199. package/dist/rpc/RpcContextMap.d.ts.map +1 -1
  200. package/dist/rpc/RpcContextMap.js +4 -4
  201. package/dist/rpc/RpcMiddleware.d.ts +14 -10
  202. package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
  203. package/dist/rpc/RpcMiddleware.js +1 -1
  204. package/dist/rpc.d.ts +1 -1
  205. package/dist/rpc.d.ts.map +1 -1
  206. package/dist/rpc.js +2 -2
  207. package/dist/runtime.d.ts +19 -0
  208. package/dist/runtime.d.ts.map +1 -0
  209. package/dist/runtime.js +40 -0
  210. package/dist/setupRequest.d.ts +19 -0
  211. package/dist/setupRequest.d.ts.map +1 -0
  212. package/dist/setupRequest.js +69 -0
  213. package/dist/toast.d.ts +51 -0
  214. package/dist/toast.d.ts.map +1 -0
  215. package/dist/toast.js +34 -0
  216. package/dist/transform.d.ts +1 -1
  217. package/dist/transform.d.ts.map +1 -1
  218. package/dist/transform.js +4 -5
  219. package/dist/utils/effectify.d.ts +1 -1
  220. package/dist/utils/effectify.d.ts.map +1 -1
  221. package/dist/utils/effectify.js +2 -2
  222. package/dist/utils/extend.d.ts.map +1 -1
  223. package/dist/utils/gen.d.ts +4 -4
  224. package/dist/utils/gen.d.ts.map +1 -1
  225. package/dist/utils/logLevel.d.ts +2 -2
  226. package/dist/utils/logLevel.d.ts.map +1 -1
  227. package/dist/utils/logger.d.ts +4 -3
  228. package/dist/utils/logger.d.ts.map +1 -1
  229. package/dist/utils/logger.js +4 -4
  230. package/dist/utils.d.ts +34 -39
  231. package/dist/utils.d.ts.map +1 -1
  232. package/dist/utils.js +33 -37
  233. package/dist/validation/validators.d.ts.map +1 -1
  234. package/dist/validation.d.ts.map +1 -1
  235. package/dist/withToast.d.ts +30 -0
  236. package/dist/withToast.d.ts.map +1 -0
  237. package/dist/withToast.js +64 -0
  238. package/package.json +22 -247
  239. package/src/Array.ts +5 -5
  240. package/src/Chunk.ts +3 -3
  241. package/src/Config/SecretURL.ts +6 -3
  242. package/src/Config/internal/configSecretURL.ts +2 -2
  243. package/src/Config.ts +7 -0
  244. package/src/ConfigProvider.ts +5 -0
  245. package/src/{ServiceMap.ts → Context.ts} +56 -63
  246. package/src/Effect.ts +14 -16
  247. package/src/Emailer.ts +51 -0
  248. package/src/Inputify.type.ts +1 -1
  249. package/src/Layer.ts +11 -7
  250. package/src/Model/Repository/Registry.ts +35 -0
  251. package/src/Model/Repository/ext.ts +375 -0
  252. package/src/Model/Repository/internal/internal.ts +741 -0
  253. package/src/Model/Repository/legacy.ts +29 -0
  254. package/src/Model/Repository/makeRepo.ts +145 -0
  255. package/src/Model/Repository/service.ts +676 -0
  256. package/src/Model/Repository/validation.ts +31 -0
  257. package/src/Model/Repository.ts +6 -0
  258. package/src/Model/dsl.ts +129 -0
  259. package/src/Model/filter/filterApi.ts +60 -0
  260. package/src/Model/filter/types/errors.ts +47 -0
  261. package/src/Model/filter/types/fields.ts +50 -0
  262. package/src/Model/filter/types/path/common.ts +404 -0
  263. package/src/Model/filter/types/path/eager.ts +329 -0
  264. package/src/Model/filter/types/path/index.ts +4 -0
  265. package/src/Model/filter/types/utils.ts +128 -0
  266. package/src/Model/filter/types/validator.ts +46 -0
  267. package/src/Model/filter/types.ts +6 -0
  268. package/src/Model/query/dsl.ts +2694 -0
  269. package/src/Model/query/new-kid-interpreter.ts +484 -0
  270. package/src/Model/query.ts +13 -0
  271. package/src/Model.ts +4 -0
  272. package/src/NonEmptySet.ts +6 -4
  273. package/src/Option.ts +2 -0
  274. package/src/Pure.ts +22 -20
  275. package/src/QueueMaker.ts +19 -0
  276. package/src/RequestContext.ts +95 -0
  277. package/src/Schema/Class.ts +517 -59
  278. package/src/Schema/SchemaParser.ts +12 -0
  279. package/src/Schema/SpecialJsonSchema.ts +139 -0
  280. package/src/Schema/SpecialOpenApi.ts +130 -0
  281. package/src/Schema/brand.ts +22 -2
  282. package/src/Schema/email.ts +9 -4
  283. package/src/Schema/ext.ts +446 -91
  284. package/src/Schema/moreStrings.ts +147 -68
  285. package/src/Schema/numbers.ts +97 -28
  286. package/src/Schema/phoneNumber.ts +9 -5
  287. package/src/Schema/strings.ts +23 -14
  288. package/src/Schema.ts +389 -25
  289. package/src/Set.ts +6 -2
  290. package/src/Store.ts +277 -0
  291. package/src/_ext/Array.ts +4 -2
  292. package/src/_ext/misc.ts +4 -1
  293. package/src/_ext/ord.ext.ts +2 -1
  294. package/src/client/InvalidationKeys.ts +50 -0
  295. package/src/client/apiClientFactory.ts +234 -135
  296. package/src/client/clientFor.ts +105 -34
  297. package/src/client/errors.ts +100 -29
  298. package/src/client/makeClient.ts +594 -73
  299. package/src/client.ts +5 -4
  300. package/src/http/Request.ts +3 -3
  301. package/src/http.ts +1 -1
  302. package/src/ids.ts +33 -6
  303. package/src/index.ts +20 -23
  304. package/src/middleware.ts +13 -9
  305. package/src/rpc/Invalidation.ts +261 -0
  306. package/src/rpc/MiddlewareMaker.ts +88 -80
  307. package/src/rpc/README.md +2 -2
  308. package/src/rpc/RpcContextMap.ts +7 -6
  309. package/src/rpc/RpcMiddleware.ts +19 -13
  310. package/src/rpc.ts +4 -4
  311. package/src/runtime.ts +56 -0
  312. package/src/setupRequest.ts +134 -0
  313. package/src/toast.ts +54 -0
  314. package/src/transform.ts +4 -4
  315. package/src/utils/effectify.ts +1 -1
  316. package/src/utils/gen.ts +8 -8
  317. package/src/utils/logLevel.ts +1 -1
  318. package/src/utils/logger.ts +4 -3
  319. package/src/utils.ts +85 -158
  320. package/src/validation.ts +2 -2
  321. package/src/withToast.ts +133 -0
  322. package/test/dist/rpc.test.d.ts.map +1 -1
  323. package/test/dist/secretURL.test.d.ts.map +1 -0
  324. package/test/dist/special.test.d.ts.map +1 -0
  325. package/test/moreStrings.test.ts +1 -1
  326. package/test/rpc.test.ts +46 -6
  327. package/test/schema.test.ts +459 -30
  328. package/test/secretURL.test.ts +160 -0
  329. package/test/special.test.ts +1026 -0
  330. package/test/utils.test.ts +7 -7
  331. package/tsconfig.base.json +6 -5
  332. package/tsconfig.json +3 -1
  333. package/tsconfig.json.bak +2 -2
  334. package/tsconfig.src.json +29 -29
  335. package/tsconfig.test.json +2 -2
  336. package/dist/Operations.d.ts +0 -123
  337. package/dist/Operations.d.ts.map +0 -1
  338. package/dist/Operations.js +0 -29
  339. package/dist/ServiceMap.d.ts.map +0 -1
  340. package/dist/ServiceMap.js +0 -91
  341. package/eslint.config.mjs +0 -26
  342. package/src/Operations.ts +0 -55
@@ -1,95 +1,553 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { pipe, Struct as Struct2 } from "effect"
3
- import type { Struct } from "effect/Schema"
2
+ import type * as Cause from "effect/Cause"
3
+ import * as Effect from "effect/Effect"
4
+ import * as Option from "effect/Option"
4
5
  import * as S from "effect/Schema"
6
+ import * as SchemaAST from "effect/SchemaAST"
7
+ import * as SchemaIssue from "effect/SchemaIssue"
8
+ import { copyOrigin } from "../utils.ts"
9
+ import { concurrencyUnbounded } from "./ext.ts"
10
+ import * as SchemaParser from "./SchemaParser.ts"
5
11
 
6
12
  type ClassAnnotations<Self> = S.Annotations.Declaration<Self, readonly [any]>
7
13
 
8
- export interface EnhancedClass<Self, SchemaS extends S.Top & { readonly fields: Struct.Fields }, Inherited>
9
- extends S.Class<Self, SchemaS, Inherited>, /* Reason for enhancement */ PropsExtensions<SchemaS["fields"]>
14
+ export interface EnhancedClass<Self, SchemaS extends S.Top & { readonly fields: S.Struct.Fields }, Inherited>
15
+ extends S.Class<Self, SchemaS, Inherited>
10
16
  {
17
+ /**
18
+ * See `copyOrigin` docs in `utils.ts` for return-type design details.
19
+ */
20
+ readonly copy: ReturnType<typeof copyOrigin<new(_: any) => Self>>
11
21
  }
12
22
  type MissingSelfGeneric<Usage extends string, Params extends string = ""> =
13
23
  `Missing \`Self\` generic - use \`class Self extends ${Usage}<Self>()(${Params}{ ... })\``
14
24
 
15
- export interface PropsExtensions<Fields> {
16
- // include: <NewProps extends S.Struct.Fields>(
17
- // fnc: (fields: Fields) => NewProps
18
- // ) => NewProps
19
- pick: <P extends keyof Fields>(...keys: readonly P[]) => Pick<Fields, P>
20
- omit: <P extends keyof Fields>(...keys: readonly P[]) => Omit<Fields, P>
21
- }
22
-
23
- type HasFields<Fields extends Struct.Fields> = {
25
+ type HasFields<Fields extends S.Struct.Fields> = {
24
26
  readonly fields: Fields
25
27
  } | {
26
28
  readonly from: HasFields<Fields>
27
29
  }
28
30
 
29
- export const Class: <Self = never>(identifier: string) => <Fields extends S.Struct.Fields>(
31
+ type ClassOptions = {
32
+ readonly strict?: boolean
33
+ }
34
+
35
+ export declare const ExtendedSchemaNoEncoded: unique symbol
36
+
37
+ export type ExtendedSchemaNoEncoded = typeof ExtendedSchemaNoEncoded
38
+
39
+ type WithEncoded<SchemaS extends S.Top, Encoded> = Omit<SchemaS, "Encoded"> & { readonly Encoded: Encoded }
40
+
41
+ type ExtendedSchema<SchemaS extends S.Top, Encoded> = [Encoded] extends [ExtendedSchemaNoEncoded] ? SchemaS
42
+ : WithEncoded<SchemaS, Encoded>
43
+
44
+ export type Class<Self, S extends S.Top & { readonly fields: S.Struct.Fields }, Inherited> = EnhancedClass<
45
+ Self,
46
+ S,
47
+ Inherited
48
+ >
49
+
50
+ /**
51
+ * Build a modified Declaration that accepts struct-matching values during
52
+ * encoding, given the original Declaration and the class's fields.
53
+ */
54
+ function makeRelaxedDeclaration(
55
+ ast: SchemaAST.Declaration,
56
+ fields: S.Struct.Fields,
57
+ cls: any
58
+ ): SchemaAST.Declaration {
59
+ const parseOptions = ast.annotations?.["parseOptions"] as SchemaAST.ParseOptions | undefined
60
+ const structSchema = S.Struct(fields)
61
+ const annotatedStruct = parseOptions ? S.toType(structSchema).annotate({ parseOptions }) : S.toType(structSchema)
62
+ const decodeStruct = SchemaParser.decodeUnknownEffect(annotatedStruct)
63
+
64
+ return new SchemaAST.Declaration(
65
+ ast.typeParameters,
66
+ () => (input: unknown, self: SchemaAST.Declaration, options: SchemaAST.ParseOptions) => {
67
+ if (input instanceof cls) {
68
+ return Effect.succeed(input)
69
+ }
70
+ if (input !== null && typeof input === "object") {
71
+ return decodeStruct(input, options)
72
+ }
73
+ return Effect.fail(new SchemaIssue.InvalidType(self, Option.some(input)))
74
+ },
75
+ ast.annotations,
76
+ ast.checks,
77
+ ast.encoding,
78
+ ast.context
79
+ )
80
+ }
81
+
82
+ // ---------------------------------------------------------------------------
83
+ // Class — like Schema.Class but with relaxed encoding
84
+ // ---------------------------------------------------------------------------
85
+
86
+ /**
87
+ * Like `Schema.Class`, but the resulting class accepts plain objects matching
88
+ * the struct schema during encoding — not only `instanceof` or type-id
89
+ * checks.
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * import * as Schema from "effect/Schema"
94
+ * import { Class } from "./Class.ts"
95
+ *
96
+ * class A extends Class<A>("A")({ a: Schema.String }) {}
97
+ *
98
+ * // Construction works as normal:
99
+ * new A({ a: "hello" })
100
+ *
101
+ * // Encoding accepts plain objects:
102
+ * Schema.encodeUnknownSync(A)({ a: "hello" }) // { a: "hello" }
103
+ * ```
104
+ */
105
+ export const Class: <Self = never, Encoded = ExtendedSchemaNoEncoded, Brand = {}>(
106
+ identifier: string
107
+ ) => <Fields extends S.Struct.Fields>(
30
108
  fieldsOr: Fields | HasFields<Fields>,
31
- annotations?: ClassAnnotations<Self>
109
+ annotations?: ClassAnnotations<Self>,
110
+ options?: ClassOptions
32
111
  ) => [Self] extends [never] ? MissingSelfGeneric<"Class">
33
112
  : EnhancedClass<
34
113
  Self,
35
- S.Struct<Fields>,
36
- {}
37
- > = (identifier) => (fields, annotations) => {
38
- const cls = S.Class as any
39
- return class extends cls(identifier)(fields, annotations) {
40
- // static readonly include = include(fields)
41
- static readonly pick = (...selection: any[]) => pipe(this["fields"], Struct2.pick(selection))
42
- static readonly omit = (...selection: any[]) => pipe(this["fields"], Struct2.omit(selection))
114
+ ExtendedSchema<S.Struct<Fields>, Encoded>,
115
+ Brand
116
+ > = (identifier) => (fields, annotations, options) => {
117
+ const relaxed = options?.strict === false
118
+ // Build the original Schema.Class
119
+ const Base = (S.Class as any)(identifier)(fields, { ...concurrencyUnbounded, ...annotations })
120
+ // Get the original ast getter from the base class
121
+ const originalAstDescriptor = Object.getOwnPropertyDescriptor(Base, "ast")!
122
+
123
+ // Cache per-class to avoid recomputing
124
+ const astCache = new WeakMap<any, SchemaAST.Declaration>()
125
+ const copyCache = new WeakMap<any, ReturnType<typeof copyOrigin>>()
126
+
127
+ return class extends Base {
128
+ static get copy() {
129
+ let cached = copyCache.get(this)
130
+ if (cached === undefined) {
131
+ cached = copyOrigin(this)
132
+ copyCache.set(this, cached)
133
+ }
134
+ return cached
135
+ }
136
+ static get ast(): SchemaAST.Declaration {
137
+ let cached = astCache.get(this)
138
+ if (cached !== undefined) return cached
139
+ // Call the original getter with `this` bound to the actual user class,
140
+ // so getClassSchema(this) creates a schema that uses `new this(...)`.
141
+ const originalAst = originalAstDescriptor.get!.call(this) as SchemaAST.Declaration
142
+ cached = relaxed ? makeRelaxedDeclaration(originalAst, Base.fields, this) : originalAst
143
+ astCache.set(this, cached)
144
+ return cached
145
+ }
146
+ static mapFields(f: any, options?: any) {
147
+ return Base.mapFields(f, options).annotate(concurrencyUnbounded)
148
+ }
43
149
  } as any
44
150
  }
45
151
 
46
- export const TaggedClass: <Self = never>(identifier?: string) => <Tag extends string, Fields extends S.Struct.Fields>(
152
+ // ---------------------------------------------------------------------------
153
+ // TaggedClass — like Schema.TaggedClass but with relaxed encoding
154
+ // ---------------------------------------------------------------------------
155
+
156
+ /**
157
+ * Like `Schema.TaggedClass`, but the resulting class accepts plain objects
158
+ * matching the struct schema during encoding.
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * import * as Schema from "effect/Schema"
163
+ * import { TaggedClass } from "./Class.ts"
164
+ *
165
+ * class Circle extends TaggedClass<Circle>()("Circle", {
166
+ * radius: Schema.Number
167
+ * }) {}
168
+ *
169
+ * Schema.encodeUnknownSync(Circle)({ _tag: "Circle", radius: 5 })
170
+ * ```
171
+ */
172
+ export const TaggedClass: <Self = never, Encoded = ExtendedSchemaNoEncoded, Brand = {}>(
173
+ identifier?: string
174
+ ) => <Tag extends string, Fields extends S.Struct.Fields>(
47
175
  tag: Tag,
48
176
  fieldsOr: Fields | HasFields<Fields>,
49
- annotations?: ClassAnnotations<Self>
50
- ) => [Self] extends [never] ? MissingSelfGeneric<"Class">
177
+ annotations?: ClassAnnotations<Self>,
178
+ options?: ClassOptions
179
+ ) => [Self] extends [never] ? MissingSelfGeneric<"TaggedClass">
51
180
  : EnhancedClass<
52
181
  Self,
53
- S.Struct<{ readonly _tag: S.tag<Tag> } & Fields>,
54
- {}
55
- > = (identifier) => (tag, fields, annotations) => {
56
- const cls = S.TaggedClass as any
57
- return class extends cls(identifier)(tag, fields, annotations) {
58
- // static readonly include = include(fields)
59
- static readonly pick = (...selection: any[]) => pipe(this["fields"], Struct2.pick(selection))
60
- static readonly omit = (...selection: any[]) => pipe(this["fields"], Struct2.omit(selection))
182
+ ExtendedSchema<S.Struct<{ readonly _tag: S.tag<Tag> } & Fields>, Encoded>,
183
+ Brand
184
+ > = (identifier) => (tag, fields, annotations, options) => {
185
+ const relaxed = options?.strict === false
186
+ const Base = (S.TaggedClass as any)(identifier)(tag, fields, { ...concurrencyUnbounded, ...annotations })
187
+ const originalAstDescriptor = Object.getOwnPropertyDescriptor(Base, "ast")!
188
+ const astCache = new WeakMap<any, SchemaAST.Declaration>()
189
+ const copyCache = new WeakMap<any, ReturnType<typeof copyOrigin>>()
190
+
191
+ return class extends Base {
192
+ static get copy() {
193
+ let cached = copyCache.get(this)
194
+ if (cached === undefined) {
195
+ cached = copyOrigin(this)
196
+ copyCache.set(this, cached)
197
+ }
198
+ return cached
199
+ }
200
+ static get ast(): SchemaAST.Declaration {
201
+ let cached = astCache.get(this)
202
+ if (cached !== undefined) return cached
203
+ const originalAst = originalAstDescriptor.get!.call(this) as SchemaAST.Declaration
204
+ cached = relaxed ? makeRelaxedDeclaration(originalAst, Base.fields, this) : originalAst
205
+ astCache.set(this, cached)
206
+ return cached
207
+ }
208
+ static mapFields(f: any, options?: any) {
209
+ return Base.mapFields(f, options).annotate(concurrencyUnbounded)
210
+ }
61
211
  } as any
62
212
  }
63
213
 
64
- export const ExtendedClass: <Self, _SelfFrom>(identifier: string) => <Fields extends S.Struct.Fields>(
214
+ // ---------------------------------------------------------------------------
215
+ // ErrorClass — like Schema.ErrorClass but with relaxed encoding
216
+ // ---------------------------------------------------------------------------
217
+
218
+ export const ErrorClass: <Self = never, Encoded = ExtendedSchemaNoEncoded, Brand = {}>(
219
+ identifier: string
220
+ ) => <Fields extends S.Struct.Fields>(
65
221
  fieldsOr: Fields | HasFields<Fields>,
66
- annotations?: ClassAnnotations<Self>
67
- ) => EnhancedClass<
68
- Self,
69
- S.Struct<Fields>,
70
- {}
71
- > = Class as any
72
-
73
- export interface EnhancedTaggedClass<Self, Tag extends string, Fields extends Struct.Fields, SelfFrom>
74
- extends
75
- EnhancedClass<
76
- Self,
77
- S.Struct<Fields> & { readonly Encoded: SelfFrom },
78
- {}
79
- >
80
- {
81
- readonly _tag: Tag
82
- }
222
+ annotations?: ClassAnnotations<Self>,
223
+ options?: ClassOptions
224
+ ) => [Self] extends [never] ? MissingSelfGeneric<"ErrorClass">
225
+ : EnhancedClass<
226
+ Self,
227
+ ExtendedSchema<S.Struct<Fields>, Encoded>,
228
+ Cause.YieldableError & Brand
229
+ > = (identifier) => (fields, annotations, options) => {
230
+ const relaxed = options?.strict === false
231
+ const Base = (S.ErrorClass as any)(identifier)(fields, { ...concurrencyUnbounded, ...annotations })
232
+ const originalAstDescriptor = Object.getOwnPropertyDescriptor(Base, "ast")!
233
+ const astCache = new WeakMap<any, SchemaAST.Declaration>()
234
+ const copyCache = new WeakMap<any, ReturnType<typeof copyOrigin>>()
235
+
236
+ return class extends Base {
237
+ static get copy() {
238
+ let cached = copyCache.get(this)
239
+ if (cached === undefined) {
240
+ cached = copyOrigin(this)
241
+ copyCache.set(this, cached)
242
+ }
243
+ return cached
244
+ }
245
+ static get ast(): SchemaAST.Declaration {
246
+ let cached = astCache.get(this)
247
+ if (cached !== undefined) return cached
248
+ const originalAst = originalAstDescriptor.get!.call(this) as SchemaAST.Declaration
249
+ cached = relaxed ? makeRelaxedDeclaration(originalAst, Base.fields, this) : originalAst
250
+ astCache.set(this, cached)
251
+ return cached
252
+ }
253
+ static mapFields(f: any, options?: any) {
254
+ return Base.mapFields(f, options).annotate(concurrencyUnbounded)
255
+ }
256
+ } as any
257
+ }
83
258
 
84
- export const ExtendedTaggedClass: <Self, SelfFrom>(
259
+ // ---------------------------------------------------------------------------
260
+ // TaggedErrorClass — like Schema.TaggedErrorClass but with relaxed encoding
261
+ // ---------------------------------------------------------------------------
262
+
263
+ export const TaggedErrorClass: <Self = never, Encoded = ExtendedSchemaNoEncoded, Brand = {}>(
85
264
  identifier?: string
86
265
  ) => <Tag extends string, Fields extends S.Struct.Fields>(
87
266
  tag: Tag,
88
267
  fieldsOr: Fields | HasFields<Fields>,
89
- annotations?: ClassAnnotations<Self>
90
- ) => EnhancedTaggedClass<
268
+ annotations?: ClassAnnotations<Self>,
269
+ options?: ClassOptions
270
+ ) => [Self] extends [never] ? MissingSelfGeneric<"TaggedErrorClass">
271
+ : EnhancedClass<
272
+ Self,
273
+ ExtendedSchema<S.Struct<{ readonly _tag: S.tag<Tag> } & Fields>, Encoded>,
274
+ Cause.YieldableError & Brand
275
+ > = (identifier) => (tag, fields, annotations, options) => {
276
+ const relaxed = options?.strict === false
277
+ const Base = (S.TaggedErrorClass as any)(identifier)(tag, fields, { ...concurrencyUnbounded, ...annotations })
278
+ const originalAstDescriptor = Object.getOwnPropertyDescriptor(Base, "ast")!
279
+ const astCache = new WeakMap<any, SchemaAST.Declaration>()
280
+ const copyCache = new WeakMap<any, ReturnType<typeof copyOrigin>>()
281
+
282
+ return class extends Base {
283
+ static get copy() {
284
+ let cached = copyCache.get(this)
285
+ if (cached === undefined) {
286
+ cached = copyOrigin(this)
287
+ copyCache.set(this, cached)
288
+ }
289
+ return cached
290
+ }
291
+ static get ast(): SchemaAST.Declaration {
292
+ let cached = astCache.get(this)
293
+ if (cached !== undefined) return cached
294
+ const originalAst = originalAstDescriptor.get!.call(this) as SchemaAST.Declaration
295
+ cached = relaxed ? makeRelaxedDeclaration(originalAst, Base.fields, this) : originalAst
296
+ astCache.set(this, cached)
297
+ return cached
298
+ }
299
+ static mapFields(f: any, options?: any) {
300
+ return Base.mapFields(f, options).annotate(concurrencyUnbounded)
301
+ }
302
+ } as any
303
+ }
304
+
305
+ export interface Opaque<Self, Encoded, SchemaS extends S.Top, Brand>
306
+ extends S.Opaque<Self, ExtendedSchema<SchemaS, Encoded>, Brand>
307
+ {}
308
+
309
+ export const Opaque: <Self, Encoded = ExtendedSchemaNoEncoded, Brand = {}>() => <S extends S.Top>(
310
+ schema: S
311
+ ) => Opaque<Self, Encoded, S, Brand> & Omit<S, keyof S.Top> = S.Opaque as any
312
+
313
+ /**
314
+ * Like {@link Opaque}, but the class **instance type is exactly `Self`** (the supplied
315
+ * decoded `Type`) instead of the structurally-computed `struct["Type"] & Brand`.
316
+ *
317
+ * Stock `Opaque` types the instance as `struct["Type"] & Brand` and only overrides the
318
+ * schema's `Type`/`Encoded` *members* with `Self`/`Encoded`. So `make`/`copy`/consumers
319
+ * still resolve the struct's mapped `Type`. With a codegen-supplied pre-expanded literal
320
+ * `Type` interface, `OpaqueType` lets all of those resolve a single **named** interface
321
+ * (resolved once per checker) instead of re-deriving the mapped `Type` — cutting
322
+ * instantiation on `Type`-touching consumers.
323
+ *
324
+ * Use with `class X extends OpaqueType<X.Type, X.Encoded>()(struct) {}` where `X.Type`
325
+ * and `X.Encoded` are generated literal interfaces (see `@effect-app/eslint-codegen-model`,
326
+ * `static` + `type` mode).
327
+ *
328
+ * KNOWN GAP — **no branding**: the instance type is a plain structural `Self`, so opaque
329
+ * types of identical shape are mutually assignable. (Stock `Opaque` is also structural by
330
+ * default — `Brand` defaults to `{}` — so this only differs if you passed a non-default
331
+ * `Brand`.) Re-introducing a nominal brand on top of a supplied `Self` (e.g. branding the
332
+ * generated `Type` interface) is not yet implemented.
333
+ *
334
+ * NOTE: only `Type` (via `Self`) and `Encoded` are supplied statically here; `make`'s input
335
+ * (`~type.make.in`) and other derived members are still computed from the struct. See
336
+ * a future `OpaqueShape`-style helper if those also need to be supplied.
337
+ */
338
+ export interface OpaqueType<Self, Encoded, SchemaS extends S.Top, Brand>
339
+ extends S.Opaque<Self, ExtendedSchema<SchemaS, Encoded>, Brand>
340
+ {
341
+ new(_: never): Self
342
+ }
343
+
344
+ export const OpaqueType: <Self, Encoded = ExtendedSchemaNoEncoded, Brand = {}>() => <S extends S.Top>(
345
+ schema: S
346
+ ) => OpaqueType<Self, Encoded, S, Brand> & Omit<S, keyof S.Top> = S.Opaque as any
347
+
348
+ // Override both the `Encoded` and make-input (`~type.make.in`) members in one go,
349
+ // like `ExtendedSchema` does for `Encoded` alone.
350
+ type ExtendedShape<SchemaS extends S.Top, Encoded, MakeIn> =
351
+ & Omit<SchemaS, "Encoded" | "~type.make.in">
352
+ & { readonly Encoded: Encoded; readonly "~type.make.in": MakeIn }
353
+
354
+ type OpaqueFacadeConstructorArgs<MakeIn> = {} extends MakeIn ? [props?: MakeIn, options?: S.MakeOptions]
355
+ : [props: MakeIn, options?: S.MakeOptions]
356
+
357
+ // Only the codec channels are required. `copy`/`fields`/`mapFields` are NOT
358
+ // required here: transformed schemas (`.pipe(S.encodeKeys/annotate/filter/...)`)
359
+ // don't expose them at the static level, and requiring them would reject those
360
+ // models from facading. When present they still flow through via
361
+ // `OpaqueFacadeStatics`; when absent the facade simply doesn't offer them.
362
+ type OpaqueFacadeInput<DecodingServices, EncodingServices> = S.Top & {
363
+ readonly DecodingServices: DecodingServices
364
+ readonly EncodingServices: EncodingServices
365
+ }
366
+
367
+ // Carry the schema's own statics, dropping the generic `S.Top` machinery and
368
+ // `prototype`. EXCEPT `to`: models compose each other via `X.to.fields` /
369
+ // `X.to.copy` at definition time, so it must survive on the facade.
370
+ type OpaqueFacadeStatics<SchemaS extends S.Top> = Omit<SchemaS, Exclude<keyof S.Top, "to"> | "prototype">
371
+
372
+ /**
373
+ * Like {@link OpaqueType}, but ALSO supplies a static **make-input** shape, so
374
+ * `make`/`copy` resolve a named `MakeIn` interface instead of re-deriving the struct's
375
+ * mapped `~type.make.in`. Use with codegen-supplied `X.Type` / `X.Encoded` / `X.Make`:
376
+ *
377
+ * ```ts
378
+ * class X extends OpaqueShape<X.Type, X.Encoded, X.Make>()(struct) {}
379
+ * ```
380
+ *
381
+ * `decode`/`encode` already use the supplied `Type`/`Encoded` (they read the schema's
382
+ * `Type`/`Encoded` members, which are `Self`/`Encoded` here) — no separate override needed.
383
+ *
384
+ * NOTE — measured gain is modest (~5%): the struct passed to the wrapper is still
385
+ * constructed in full (definition cost dominates); the static shapes only cheapen
386
+ * consumer-side reads of `Type`/`Encoded`/`MakeIn`. Same `no-branding` gap as
387
+ * {@link OpaqueType}.
388
+ */
389
+ export interface OpaqueShape<Self, Encoded, MakeIn, SchemaS extends S.Top, Brand>
390
+ extends S.Opaque<Self, ExtendedShape<SchemaS, Encoded, MakeIn>, Brand>
391
+ {
392
+ new(_: never): Self
393
+ }
394
+
395
+ export const OpaqueShape: <Self, Encoded, MakeIn, Brand = {}>() => <S extends S.Top>(
396
+ schema: S
397
+ ) => OpaqueShape<Self, Encoded, MakeIn, S, Brand> & Omit<S, keyof S.Top> = S.Opaque as any
398
+
399
+ /**
400
+ * Shallow public view for generated model facades.
401
+ *
402
+ * The runtime value can still be the full private schema class, but emitted
403
+ * declarations expose only named `Type` / `Encoded` / `Make` interfaces and a
404
+ * small static surface. This keeps downstream project references from pulling
405
+ * the private struct field map back through `typeof Model`.
406
+ */
407
+ export interface OpaqueFacade<
408
+ Self,
409
+ Encoded,
410
+ MakeIn,
411
+ DecodingServices = never,
412
+ EncodingServices = DecodingServices,
413
+ Brand = {}
414
+ > extends
415
+ S.Bottom<
416
+ Self,
417
+ Encoded,
418
+ DecodingServices,
419
+ EncodingServices,
420
+ SchemaAST.AST,
421
+ S.Codec<Self, Encoded, DecodingServices, EncodingServices>,
422
+ MakeIn,
423
+ Self,
424
+ readonly [],
425
+ MakeIn
426
+ >
427
+ {
428
+ new(...args: OpaqueFacadeConstructorArgs<MakeIn>): Self & Brand
429
+ readonly copy: ReturnType<typeof copyOrigin<new(_: MakeIn) => Self>>
430
+ // NOTE: `fields` / `mapFields` are intentionally NOT redeclared here. They are
431
+ // carried (precise) from the underlying schema via `OpaqueFacadeStatics`. A wide
432
+ // `mapFields(f: (fields: S.Struct.Fields) => To)` override would win overload
433
+ // resolution and erase field precision in `Q.project(X.mapFields(...))`.
434
+ }
435
+
436
+ export function OpaqueFacade<
91
437
  Self,
92
- Tag,
93
- { readonly _tag: S.tag<Tag> } & Fields,
94
- SelfFrom
95
- > = TaggedClass as any
438
+ Encoded,
439
+ MakeIn,
440
+ DecodingServices = never,
441
+ EncodingServices = DecodingServices,
442
+ Brand = {}
443
+ >() {
444
+ return <SchemaS extends OpaqueFacadeInput<DecodingServices, EncodingServices>>(
445
+ schema: SchemaS
446
+ ): OpaqueFacade<Self, Encoded, MakeIn, DecodingServices, EncodingServices, Brand> & OpaqueFacadeStatics<SchemaS> =>
447
+ schema as SchemaS & OpaqueFacade<Self, Encoded, MakeIn, DecodingServices, EncodingServices, Brand>
448
+ }
449
+
450
+ export interface OpaqueFacadeClass<
451
+ Self,
452
+ Encoded,
453
+ MakeIn,
454
+ DecodingServices = never,
455
+ EncodingServices = DecodingServices,
456
+ Brand = {}
457
+ > extends
458
+ S.Bottom<
459
+ Self,
460
+ Encoded,
461
+ DecodingServices,
462
+ EncodingServices,
463
+ SchemaAST.AST,
464
+ S.Codec<Self, Encoded, DecodingServices, EncodingServices>,
465
+ MakeIn,
466
+ Self,
467
+ readonly [],
468
+ MakeIn
469
+ >
470
+ {
471
+ new(...args: OpaqueFacadeConstructorArgs<MakeIn>): Brand
472
+ readonly copy: ReturnType<typeof copyOrigin<new(_: MakeIn) => Self>>
473
+ // NOTE: `fields` / `mapFields` intentionally not redeclared — carried precise
474
+ // from the underlying schema via `OpaqueFacadeStatics` (see OpaqueFacade above).
475
+ }
476
+
477
+ export function OpaqueFacadeClass<
478
+ Self,
479
+ Encoded,
480
+ MakeIn,
481
+ DecodingServices = never,
482
+ EncodingServices = DecodingServices,
483
+ Brand = {}
484
+ >() {
485
+ return <SchemaS extends OpaqueFacadeInput<DecodingServices, EncodingServices>>(
486
+ schema: SchemaS
487
+ ):
488
+ & OpaqueFacadeClass<Self, Encoded, MakeIn, DecodingServices, EncodingServices, Brand>
489
+ & OpaqueFacadeStatics<SchemaS> =>
490
+ {
491
+ // Make the result constructable (like `S.Opaque`), so the private `_X` may be a
492
+ // plain `S.Struct`/`S.TaggedStruct` (lighter type) — not only an `S.Opaque` class —
493
+ // while `export class X extends ...(_X)` still works.
494
+ class Facade {}
495
+ return Object.setPrototypeOf(Facade, schema)
496
+ }
497
+ }
498
+
499
+ /**
500
+ * Like {@link OpaqueFacadeClass}, but for error models (`TaggedErrorClass` /
501
+ * `ErrorClass`). The decoded instance type carries `Cause.YieldableError`, so
502
+ * `yield* new MyError(...)`, `Effect.fail(myError)`, and `instanceof` all keep
503
+ * working through the facade — the runtime `_X` is the real error class (the
504
+ * facade `X extends ...(_X)` inherits its prototype), and the type reflects it.
505
+ * Nothing is lost vs the underlying error class.
506
+ */
507
+ export interface OpaqueErrorFacadeClass<
508
+ Self,
509
+ Encoded,
510
+ MakeIn,
511
+ DecodingServices = never,
512
+ EncodingServices = DecodingServices,
513
+ Brand = {}
514
+ > extends
515
+ S.Bottom<
516
+ Self,
517
+ Encoded,
518
+ DecodingServices,
519
+ EncodingServices,
520
+ SchemaAST.AST,
521
+ S.Codec<Self, Encoded, DecodingServices, EncodingServices>,
522
+ MakeIn,
523
+ Self,
524
+ readonly [],
525
+ MakeIn
526
+ >
527
+ {
528
+ // YieldableError (not Self) on the constructed instance — like OpaqueFacadeClass's
529
+ // `new(): Brand`, the data type comes from the declaration-merged `interface X`,
530
+ // so `Self` must NOT appear here (would recurse). Merging `X & YieldableError`
531
+ // makes `yield* new X()` / `Effect.fail` / `instanceof` work without losing data.
532
+ new(...args: OpaqueFacadeConstructorArgs<MakeIn>): Cause.YieldableError & Brand
533
+ readonly copy: ReturnType<typeof copyOrigin<new(_: MakeIn) => Self>>
534
+ }
535
+
536
+ export function OpaqueErrorFacadeClass<
537
+ Self,
538
+ Encoded,
539
+ MakeIn,
540
+ DecodingServices = never,
541
+ EncodingServices = DecodingServices,
542
+ Brand = {}
543
+ >() {
544
+ return <SchemaS extends OpaqueFacadeInput<DecodingServices, EncodingServices>>(
545
+ schema: SchemaS
546
+ ):
547
+ & OpaqueErrorFacadeClass<Self, Encoded, MakeIn, DecodingServices, EncodingServices, Brand>
548
+ & OpaqueFacadeStatics<SchemaS> =>
549
+ {
550
+ class Facade {}
551
+ return Object.setPrototypeOf(Facade, schema)
552
+ }
553
+ }
@@ -0,0 +1,12 @@
1
+ import * as SchemaParser from "effect/SchemaParser"
2
+ import { withDefaultParseOptions } from "./ext.ts"
3
+
4
+ export * from "effect/SchemaParser"
5
+
6
+ export const decodeEffectConcurrently: typeof SchemaParser.decodeEffect = withDefaultParseOptions(
7
+ SchemaParser.decodeEffect
8
+ )
9
+
10
+ export const decodeUnknownEffectConcurrently: typeof SchemaParser.decodeUnknownEffect = withDefaultParseOptions(
11
+ SchemaParser.decodeUnknownEffect
12
+ )