effect-app 4.0.0-beta.99 → 4.0.1

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 (391) hide show
  1. package/CHANGELOG.md +2042 -0
  2. package/dist/Array.d.ts +1 -17
  3. package/dist/Array.d.ts.map +1 -1
  4. package/dist/Array.js +3 -27
  5. package/dist/Chunk.d.ts +3 -27
  6. package/dist/Chunk.d.ts.map +1 -1
  7. package/dist/Chunk.js +4 -39
  8. package/dist/Config/SecretURL.d.ts +3 -1
  9. package/dist/Config/SecretURL.d.ts.map +1 -1
  10. package/dist/Config/SecretURL.js +3 -6
  11. package/dist/Config/internal/configSecretURL.d.ts.map +1 -1
  12. package/dist/Config/internal/configSecretURL.js +2 -2
  13. package/dist/Config.d.ts +0 -5
  14. package/dist/Config.d.ts.map +1 -1
  15. package/dist/Config.js +7 -5
  16. package/dist/ConfigProvider.d.ts +0 -37
  17. package/dist/ConfigProvider.d.ts.map +1 -1
  18. package/dist/ConfigProvider.js +5 -41
  19. package/dist/Context.d.ts +6 -4
  20. package/dist/Context.d.ts.map +1 -1
  21. package/dist/Context.js +4 -3
  22. package/dist/DataDependencies.d.ts +136 -0
  23. package/dist/DataDependencies.d.ts.map +1 -0
  24. package/dist/DataDependencies.js +112 -0
  25. package/dist/DateTime.d.ts +33 -0
  26. package/dist/DateTime.d.ts.map +1 -0
  27. package/dist/DateTime.js +18 -0
  28. package/dist/Effect.d.ts +3 -14
  29. package/dist/Effect.d.ts.map +1 -1
  30. package/dist/Effect.js +8 -26
  31. package/dist/Emailer.d.ts +51 -0
  32. package/dist/Emailer.d.ts.map +1 -0
  33. package/dist/Emailer.js +7 -0
  34. package/dist/Function.d.ts +0 -4
  35. package/dist/Function.d.ts.map +1 -1
  36. package/dist/Function.js +1 -7
  37. package/dist/Layer.d.ts +6 -3
  38. package/dist/Layer.d.ts.map +1 -1
  39. package/dist/Layer.js +3 -2
  40. package/dist/Model/Repository/Registry.d.ts +22 -0
  41. package/dist/Model/Repository/Registry.d.ts.map +1 -0
  42. package/dist/Model/Repository/Registry.js +18 -0
  43. package/dist/Model/Repository/dependency.d.ts +6 -0
  44. package/dist/Model/Repository/dependency.d.ts.map +1 -0
  45. package/dist/Model/Repository/dependency.js +29 -0
  46. package/dist/Model/Repository/ext.d.ts +60 -0
  47. package/dist/Model/Repository/ext.d.ts.map +1 -0
  48. package/dist/Model/Repository/ext.js +124 -0
  49. package/dist/Model/Repository/internal/internal.d.ts +68 -0
  50. package/dist/Model/Repository/internal/internal.d.ts.map +1 -0
  51. package/dist/Model/Repository/internal/internal.js +610 -0
  52. package/dist/Model/Repository/legacy.d.ts +21 -0
  53. package/dist/Model/Repository/legacy.d.ts.map +1 -0
  54. package/dist/Model/Repository/legacy.js +2 -0
  55. package/dist/Model/Repository/makeRepo.d.ts +71 -0
  56. package/dist/Model/Repository/makeRepo.d.ts.map +1 -0
  57. package/dist/Model/Repository/makeRepo.js +30 -0
  58. package/dist/Model/Repository/service.d.ts +121 -0
  59. package/dist/Model/Repository/service.d.ts.map +1 -0
  60. package/dist/Model/Repository/service.js +2 -0
  61. package/dist/Model/Repository/validation.d.ts +72 -0
  62. package/dist/Model/Repository/validation.d.ts.map +1 -0
  63. package/dist/Model/Repository/validation.js +39 -0
  64. package/dist/Model/Repository.d.ts +8 -0
  65. package/dist/Model/Repository.d.ts.map +1 -0
  66. package/dist/Model/Repository.js +8 -0
  67. package/dist/Model/dsl.d.ts +34 -0
  68. package/dist/Model/dsl.d.ts.map +1 -0
  69. package/dist/Model/dsl.js +45 -0
  70. package/dist/Model/filter/filterApi.d.ts +30 -0
  71. package/dist/Model/filter/filterApi.d.ts.map +1 -0
  72. package/dist/Model/filter/filterApi.js +2 -0
  73. package/dist/Model/filter/types/errors.d.ts +29 -0
  74. package/dist/Model/filter/types/errors.d.ts.map +1 -0
  75. package/dist/Model/filter/types/errors.js +2 -0
  76. package/dist/Model/filter/types/fields.d.ts +15 -0
  77. package/dist/Model/filter/types/fields.d.ts.map +1 -0
  78. package/dist/Model/filter/types/fields.js +2 -0
  79. package/dist/Model/filter/types/path/common.d.ts +316 -0
  80. package/dist/Model/filter/types/path/common.d.ts.map +1 -0
  81. package/dist/Model/filter/types/path/common.js +2 -0
  82. package/dist/Model/filter/types/path/eager.d.ts +94 -0
  83. package/dist/Model/filter/types/path/eager.d.ts.map +1 -0
  84. package/dist/Model/filter/types/path/eager.js +36 -0
  85. package/dist/Model/filter/types/path/index.d.ts +4 -0
  86. package/dist/Model/filter/types/path/index.d.ts.map +1 -0
  87. package/dist/Model/filter/types/path/index.js +3 -0
  88. package/dist/Model/filter/types/utils.d.ts +79 -0
  89. package/dist/Model/filter/types/utils.d.ts.map +1 -0
  90. package/dist/Model/filter/types/utils.js +2 -0
  91. package/dist/Model/filter/types/validator.d.ts +30 -0
  92. package/dist/Model/filter/types/validator.d.ts.map +1 -0
  93. package/dist/Model/filter/types/validator.js +2 -0
  94. package/dist/Model/filter/types.d.ts +5 -0
  95. package/dist/Model/filter/types.d.ts.map +1 -0
  96. package/dist/Model/filter/types.js +7 -0
  97. package/dist/Model/query/dsl.d.ts +630 -0
  98. package/dist/Model/query/dsl.d.ts.map +1 -0
  99. package/dist/Model/query/dsl.js +376 -0
  100. package/dist/Model/query/new-kid-interpreter.d.ts +132 -0
  101. package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -0
  102. package/dist/Model/query/new-kid-interpreter.js +369 -0
  103. package/dist/Model/query.d.ts +15 -0
  104. package/dist/Model/query.d.ts.map +1 -0
  105. package/dist/Model/query.js +3 -0
  106. package/dist/Model.d.ts +6 -0
  107. package/dist/Model.d.ts.map +1 -0
  108. package/dist/Model.js +6 -0
  109. package/dist/NonEmptySet.d.ts +3 -1
  110. package/dist/NonEmptySet.d.ts.map +1 -1
  111. package/dist/NonEmptySet.js +2 -2
  112. package/dist/Option.d.ts +1 -2
  113. package/dist/Option.d.ts.map +1 -1
  114. package/dist/Option.js +3 -7
  115. package/dist/Pure.d.ts +9 -7
  116. package/dist/Pure.d.ts.map +1 -1
  117. package/dist/Pure.js +20 -17
  118. package/dist/QueueMaker.d.ts +11 -0
  119. package/dist/QueueMaker.d.ts.map +1 -0
  120. package/dist/QueueMaker.js +11 -0
  121. package/dist/RequestContext.d.ts +87 -0
  122. package/dist/RequestContext.d.ts.map +1 -0
  123. package/dist/RequestContext.js +45 -0
  124. package/dist/RequestScopedDependencies.d.ts +21 -0
  125. package/dist/RequestScopedDependencies.d.ts.map +1 -0
  126. package/dist/RequestScopedDependencies.js +16 -0
  127. package/dist/Schema/Class.d.ts +163 -16
  128. package/dist/Schema/Class.d.ts.map +1 -1
  129. package/dist/Schema/Class.js +193 -21
  130. package/dist/Schema/FastCheck.d.ts.map +1 -1
  131. package/dist/Schema/SchemaParser.d.ts +5 -0
  132. package/dist/Schema/SchemaParser.d.ts.map +1 -0
  133. package/dist/Schema/SchemaParser.js +6 -0
  134. package/dist/Schema/SpecialJsonSchema.d.ts +15 -2
  135. package/dist/Schema/SpecialJsonSchema.d.ts.map +1 -1
  136. package/dist/Schema/SpecialJsonSchema.js +70 -12
  137. package/dist/Schema/SpecialOpenApi.d.ts +1 -1
  138. package/dist/Schema/SpecialOpenApi.js +3 -3
  139. package/dist/Schema/brand.d.ts +5 -5
  140. package/dist/Schema/brand.d.ts.map +1 -1
  141. package/dist/Schema/brand.js +6 -4
  142. package/dist/Schema/email.d.ts.map +1 -1
  143. package/dist/Schema/email.js +8 -5
  144. package/dist/Schema/ext.d.ts +279 -75
  145. package/dist/Schema/ext.d.ts.map +1 -1
  146. package/dist/Schema/ext.js +330 -72
  147. package/dist/Schema/moreStrings.d.ts +82 -48
  148. package/dist/Schema/moreStrings.d.ts.map +1 -1
  149. package/dist/Schema/moreStrings.js +85 -51
  150. package/dist/Schema/numbers.d.ts +33 -21
  151. package/dist/Schema/numbers.d.ts.map +1 -1
  152. package/dist/Schema/numbers.js +64 -12
  153. package/dist/Schema/phoneNumber.d.ts.map +1 -1
  154. package/dist/Schema/phoneNumber.js +6 -6
  155. package/dist/Schema/schema.d.ts +1 -1
  156. package/dist/Schema/schema.d.ts.map +1 -1
  157. package/dist/Schema/schema.js +2 -2
  158. package/dist/Schema/strings.d.ts +18 -4
  159. package/dist/Schema/strings.d.ts.map +1 -1
  160. package/dist/Schema/strings.js +1 -5
  161. package/dist/Schema.d.ts +224 -7
  162. package/dist/Schema.d.ts.map +1 -1
  163. package/dist/Schema.js +190 -24
  164. package/dist/SchemaAST.d.ts +2 -0
  165. package/dist/SchemaAST.d.ts.map +1 -0
  166. package/dist/SchemaAST.js +2 -0
  167. package/dist/Set.d.ts +4 -1
  168. package/dist/Set.d.ts.map +1 -1
  169. package/dist/Set.js +8 -6
  170. package/dist/Store.d.ts +215 -0
  171. package/dist/Store.d.ts.map +1 -0
  172. package/dist/Store.js +113 -0
  173. package/dist/_ext/Array.d.ts +1 -1
  174. package/dist/_ext/Array.d.ts.map +1 -1
  175. package/dist/_ext/Array.js +4 -2
  176. package/dist/_ext/ord.ext.d.ts +2 -1
  177. package/dist/_ext/ord.ext.d.ts.map +1 -1
  178. package/dist/_ext/ord.ext.js +2 -2
  179. package/dist/builtin.d.ts +2 -14
  180. package/dist/builtin.d.ts.map +1 -1
  181. package/dist/builtin.js +1 -1
  182. package/dist/client/InvalidationKeys.d.ts +30 -0
  183. package/dist/client/InvalidationKeys.d.ts.map +1 -0
  184. package/dist/client/InvalidationKeys.js +37 -0
  185. package/dist/client/apiClientFactory.d.ts +13 -8
  186. package/dist/client/apiClientFactory.d.ts.map +1 -1
  187. package/dist/client/apiClientFactory.js +154 -34
  188. package/dist/client/clientFor.d.ts +48 -13
  189. package/dist/client/clientFor.d.ts.map +1 -1
  190. package/dist/client/clientFor.js +9 -1
  191. package/dist/client/errors.d.ts +74 -28
  192. package/dist/client/errors.d.ts.map +1 -1
  193. package/dist/client/errors.js +41 -10
  194. package/dist/client/makeClient.d.ts +487 -32
  195. package/dist/client/makeClient.d.ts.map +1 -1
  196. package/dist/client/makeClient.js +47 -21
  197. package/dist/client.d.ts +2 -0
  198. package/dist/client.d.ts.map +1 -1
  199. package/dist/client.js +3 -1
  200. package/dist/faker.d.ts.map +1 -1
  201. package/dist/http/Request.d.ts +2 -2
  202. package/dist/http/Request.d.ts.map +1 -1
  203. package/dist/http/Request.js +2 -2
  204. package/dist/http/internal/lib.d.ts +12 -12
  205. package/dist/http/internal/lib.d.ts.map +1 -1
  206. package/dist/http/internal/lib.js +13 -13
  207. package/dist/ids.d.ts +32 -14
  208. package/dist/ids.d.ts.map +1 -1
  209. package/dist/ids.js +38 -7
  210. package/dist/index.d.ts +3 -0
  211. package/dist/index.d.ts.map +1 -1
  212. package/dist/index.js +5 -1
  213. package/dist/middleware.d.ts +12 -6
  214. package/dist/middleware.d.ts.map +1 -1
  215. package/dist/middleware.js +13 -7
  216. package/dist/migration/nativeEffect.d.ts +21 -0
  217. package/dist/migration/nativeEffect.d.ts.map +1 -0
  218. package/dist/migration/nativeEffect.js +598 -0
  219. package/dist/rpc/Invalidation.d.ts +1124 -0
  220. package/dist/rpc/Invalidation.d.ts.map +1 -0
  221. package/dist/rpc/Invalidation.js +178 -0
  222. package/dist/rpc/MiddlewareMaker.d.ts +10 -7
  223. package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
  224. package/dist/rpc/MiddlewareMaker.js +57 -37
  225. package/dist/rpc/RpcContextMap.d.ts +2 -2
  226. package/dist/rpc/RpcContextMap.d.ts.map +1 -1
  227. package/dist/rpc/RpcMiddleware.d.ts +13 -10
  228. package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
  229. package/dist/rpc/RpcMiddleware.js +2 -2
  230. package/dist/rpc.d.ts +1 -1
  231. package/dist/rpc.d.ts.map +1 -1
  232. package/dist/rpc.js +2 -2
  233. package/dist/runtime.d.ts +19 -0
  234. package/dist/runtime.d.ts.map +1 -0
  235. package/dist/runtime.js +40 -0
  236. package/dist/setupRequest.d.ts +20 -0
  237. package/dist/setupRequest.d.ts.map +1 -0
  238. package/dist/setupRequest.js +72 -0
  239. package/dist/toast.d.ts +51 -0
  240. package/dist/toast.d.ts.map +1 -0
  241. package/dist/toast.js +34 -0
  242. package/dist/transform.d.ts +1 -1
  243. package/dist/transform.d.ts.map +1 -1
  244. package/dist/transform.js +4 -5
  245. package/dist/utils/effectify.d.ts +1 -1
  246. package/dist/utils/effectify.d.ts.map +1 -1
  247. package/dist/utils/effectify.js +2 -2
  248. package/dist/utils/extend.d.ts +6 -1
  249. package/dist/utils/extend.d.ts.map +1 -1
  250. package/dist/utils/extend.js +24 -6
  251. package/dist/utils/gen.d.ts +4 -4
  252. package/dist/utils/gen.d.ts.map +1 -1
  253. package/dist/utils/logLevel.d.ts +2 -2
  254. package/dist/utils/logLevel.d.ts.map +1 -1
  255. package/dist/utils/logger.d.ts +2 -1
  256. package/dist/utils/logger.d.ts.map +1 -1
  257. package/dist/utils/logger.js +2 -2
  258. package/dist/utils.d.ts +34 -45
  259. package/dist/utils.d.ts.map +1 -1
  260. package/dist/utils.js +33 -49
  261. package/dist/validation/validators.d.ts.map +1 -1
  262. package/dist/validation.d.ts.map +1 -1
  263. package/dist/withToast.d.ts +30 -0
  264. package/dist/withToast.d.ts.map +1 -0
  265. package/dist/withToast.js +64 -0
  266. package/package.json +25 -266
  267. package/src/Array.ts +7 -39
  268. package/src/Chunk.ts +6 -55
  269. package/src/Config/SecretURL.ts +6 -3
  270. package/src/Config/internal/configSecretURL.ts +2 -2
  271. package/src/Config.ts +6 -13
  272. package/src/ConfigProvider.ts +4 -47
  273. package/src/Context.ts +9 -8
  274. package/src/DataDependencies.ts +171 -0
  275. package/src/DateTime.ts +473 -0
  276. package/src/Effect.ts +10 -32
  277. package/src/Emailer.ts +51 -0
  278. package/src/Function.ts +0 -7
  279. package/src/Inputify.type.ts +1 -1
  280. package/src/Layer.ts +8 -5
  281. package/src/Model/Repository/Registry.ts +35 -0
  282. package/src/Model/Repository/dependency.ts +32 -0
  283. package/src/Model/Repository/ext.ts +374 -0
  284. package/src/Model/Repository/internal/internal.ts +987 -0
  285. package/src/Model/Repository/legacy.ts +29 -0
  286. package/src/Model/Repository/makeRepo.ts +168 -0
  287. package/src/Model/Repository/service.ts +676 -0
  288. package/src/Model/Repository/validation.ts +38 -0
  289. package/src/Model/Repository.ts +7 -0
  290. package/src/Model/dsl.ts +130 -0
  291. package/src/Model/filter/filterApi.ts +78 -0
  292. package/src/Model/filter/types/errors.ts +47 -0
  293. package/src/Model/filter/types/fields.ts +50 -0
  294. package/src/Model/filter/types/path/common.ts +404 -0
  295. package/src/Model/filter/types/path/eager.ts +329 -0
  296. package/src/Model/filter/types/path/index.ts +4 -0
  297. package/src/Model/filter/types/utils.ts +128 -0
  298. package/src/Model/filter/types/validator.ts +46 -0
  299. package/src/Model/filter/types.ts +6 -0
  300. package/src/Model/query/dsl.ts +3092 -0
  301. package/src/Model/query/new-kid-interpreter.ts +531 -0
  302. package/src/Model/query.ts +13 -0
  303. package/src/Model.ts +5 -0
  304. package/src/NonEmptySet.ts +6 -4
  305. package/src/Option.ts +3 -8
  306. package/src/Pure.ts +20 -17
  307. package/src/QueueMaker.ts +11 -0
  308. package/src/RequestContext.ts +48 -0
  309. package/src/RequestScopedDependencies.ts +45 -0
  310. package/src/Schema/Class.ts +550 -56
  311. package/src/Schema/SchemaParser.ts +12 -0
  312. package/src/Schema/SpecialJsonSchema.ts +75 -7
  313. package/src/Schema/SpecialOpenApi.ts +5 -5
  314. package/src/Schema/brand.ts +27 -12
  315. package/src/Schema/email.ts +9 -7
  316. package/src/Schema/ext.ts +405 -95
  317. package/src/Schema/moreStrings.ts +213 -88
  318. package/src/Schema/numbers.ts +107 -29
  319. package/src/Schema/phoneNumber.ts +8 -9
  320. package/src/Schema/schema.ts +1 -1
  321. package/src/Schema/strings.ts +23 -14
  322. package/src/Schema.ts +403 -46
  323. package/src/SchemaAST.ts +1 -0
  324. package/src/Set.ts +10 -5
  325. package/src/Store.ts +325 -0
  326. package/src/_ext/Array.ts +4 -2
  327. package/src/_ext/ord.ext.ts +2 -1
  328. package/src/builtin-json.d.ts +24 -0
  329. package/src/builtin.ts +16 -21
  330. package/src/client/InvalidationKeys.ts +55 -0
  331. package/src/client/apiClientFactory.ts +295 -129
  332. package/src/client/clientFor.ts +101 -33
  333. package/src/client/errors.ts +66 -20
  334. package/src/client/makeClient.ts +519 -60
  335. package/src/client.ts +6 -4
  336. package/src/http/Request.ts +4 -4
  337. package/src/http/internal/lib.ts +12 -12
  338. package/src/http.ts +1 -1
  339. package/src/ids.ts +45 -8
  340. package/src/index.ts +20 -16
  341. package/src/middleware.ts +12 -8
  342. package/src/migration/nativeEffect.ts +645 -0
  343. package/src/rpc/Invalidation.ts +278 -0
  344. package/src/rpc/MiddlewareMaker.ts +86 -79
  345. package/src/rpc/README.md +2 -2
  346. package/src/rpc/RpcContextMap.ts +4 -4
  347. package/src/rpc/RpcMiddleware.ts +18 -13
  348. package/src/rpc.ts +4 -4
  349. package/src/runtime.ts +57 -0
  350. package/src/setupRequest.ts +138 -0
  351. package/src/toast.ts +54 -0
  352. package/src/transform.ts +4 -4
  353. package/src/utils/effectify.ts +1 -1
  354. package/src/utils/extend.ts +24 -5
  355. package/src/utils/gen.ts +7 -7
  356. package/src/utils/logLevel.ts +1 -1
  357. package/src/utils/logger.ts +3 -2
  358. package/src/utils.ts +85 -175
  359. package/src/validation.ts +2 -2
  360. package/src/withToast.ts +133 -0
  361. package/test/dateTimeLocal.test.ts +55 -0
  362. package/test/dist/dateTimeLocal.test.d.ts.map +1 -0
  363. package/test/dist/nativeEffectMigration.test.d.ts.map +1 -0
  364. package/test/dist/rpc.test.d.ts.map +1 -1
  365. package/test/dist/rpcMiddlewareContext.test.d.ts.map +1 -0
  366. package/test/moreStrings.test.ts +55 -10
  367. package/test/nativeEffectMigration.test.ts +77 -0
  368. package/test/rpc.test.ts +28 -11
  369. package/test/rpcMiddlewareContext.test.ts +63 -0
  370. package/test/schema.test.ts +318 -55
  371. package/test/secretURL.test.ts +4 -1
  372. package/test/special.test.ts +663 -131
  373. package/test/utils.test.ts +5 -5
  374. package/tsconfig.base.json +6 -4
  375. package/tsconfig.json +9 -1
  376. package/tsconfig.src.json +29 -29
  377. package/tsconfig.test.json +2 -2
  378. package/dist/Operations.d.ts +0 -124
  379. package/dist/Operations.d.ts.map +0 -1
  380. package/dist/Operations.js +0 -29
  381. package/dist/_ext/date.d.ts +0 -15
  382. package/dist/_ext/date.d.ts.map +0 -1
  383. package/dist/_ext/date.js +0 -16
  384. package/dist/_ext/misc.d.ts +0 -14
  385. package/dist/_ext/misc.d.ts.map +0 -1
  386. package/dist/_ext/misc.js +0 -17
  387. package/eslint.config.mjs +0 -26
  388. package/src/Operations.ts +0 -55
  389. package/src/_ext/date.ts +0 -27
  390. package/src/_ext/misc.ts +0 -46
  391. package/tsconfig.json.bak +0 -12
@@ -1,12 +1,27 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { Effect, Option, Schema, SchemaAST, SchemaIssue } from "effect"
2
+ import type * as Cause from "effect/Cause"
3
+ import * as Effect from "effect/Effect"
3
4
  import * as S from "effect/Schema"
5
+ import * as SchemaGetter from "effect/SchemaGetter"
6
+ import * as SchemaIssue from "effect/SchemaIssue"
7
+ import * as SchemaTransformation from "effect/SchemaTransformation"
8
+ import type { Struct as EffectAppStruct } from "../Schema.ts"
9
+ import * as SchemaAST from "../SchemaAST.ts"
10
+ import { copyOrigin } from "../utils.ts"
11
+ import { concurrencyUnbounded } from "./ext.ts"
12
+ import * as SchemaParser from "./SchemaParser.ts"
4
13
 
5
14
  type ClassAnnotations<Self> = S.Annotations.Declaration<Self, readonly [any]>
6
15
 
7
- export interface EnhancedClass<Self, SchemaS extends S.Top & { readonly fields: S.Struct.Fields }, Inherited>
8
- extends S.Class<Self, SchemaS, Inherited>
9
- {
16
+ export interface EnhancedClass<
17
+ Self,
18
+ SchemaS extends S.Constraint & { readonly fields: S.Struct.Fields },
19
+ Inherited
20
+ > extends S.Class<Self, SchemaS, Inherited> {
21
+ /**
22
+ * See `copyOrigin` docs in `utils.ts` for return-type design details.
23
+ */
24
+ readonly copy: ReturnType<typeof copyOrigin<new(_: any) => Self>>
10
25
  }
11
26
  type MissingSelfGeneric<Usage extends string, Params extends string = ""> =
12
27
  `Missing \`Self\` generic - use \`class Self extends ${Usage}<Self>()(${Params}{ ... })\``
@@ -17,7 +32,34 @@ type HasFields<Fields extends S.Struct.Fields> = {
17
32
  readonly from: HasFields<Fields>
18
33
  }
19
34
 
20
- export type Class<Self, S extends S.Top & { readonly fields: S.Struct.Fields }, Inherited> = S.Class<Self, S, Inherited>
35
+ type ClassOptions = {
36
+ readonly strict?: boolean
37
+ }
38
+
39
+ export declare const ExtendedSchemaNoEncoded: unique symbol
40
+
41
+ export type ExtendedSchemaNoEncoded = typeof ExtendedSchemaNoEncoded
42
+
43
+ /**
44
+ * Override schema `Encoded` while keeping `Constraint` (intersection, not `Omit`).
45
+ * Free type-params for `Encoded` keep the conditional unresolved — callers that
46
+ * need Encoded overrides use the intersection form of the class factory return type.
47
+ */
48
+ type WithEncoded<SchemaS extends S.Constraint, Encoded> = SchemaS & { readonly Encoded: Encoded }
49
+
50
+ type ExtendedSchema<SchemaS extends S.Constraint & { readonly fields: S.Struct.Fields }, Encoded> = [
51
+ Encoded
52
+ ] extends [ExtendedSchemaNoEncoded] ? SchemaS
53
+ : WithEncoded<SchemaS, Encoded>
54
+
55
+ /** Struct fields schema, optionally with a caller-supplied Encoded override. */
56
+ type ClassFieldsSchema<Fields extends S.Struct.Fields, Encoded> = ExtendedSchema<S.Struct<Fields>, Encoded>
57
+
58
+ export type Class<Self, S extends S.Constraint & { readonly fields: S.Struct.Fields }, Inherited> = EnhancedClass<
59
+ Self,
60
+ S,
61
+ Inherited
62
+ >
21
63
 
22
64
  /**
23
65
  * Build a modified Declaration that accepts struct-matching values during
@@ -25,18 +67,24 @@ export type Class<Self, S extends S.Top & { readonly fields: S.Struct.Fields },
25
67
  */
26
68
  function makeRelaxedDeclaration(
27
69
  ast: SchemaAST.Declaration,
28
- fields: Schema.Struct.Fields,
70
+ fields: S.Struct.Fields,
29
71
  cls: any
30
72
  ): SchemaAST.Declaration {
31
- const structSchema = Schema.Struct(fields)
32
- const isStructValue = Schema.is(structSchema)
73
+ const parseOptions = ast.annotations?.["parseOptions"] as SchemaAST.ParseOptions | undefined
74
+ const structSchema = S.Struct(fields)
75
+ const annotatedStruct = parseOptions ? S.toType(structSchema).annotate({ parseOptions }) : S.toType(structSchema)
76
+ const decodeStruct = SchemaParser.decodeUnknownEffect(annotatedStruct)
77
+
33
78
  return new SchemaAST.Declaration(
34
79
  ast.typeParameters,
35
- () => (input: unknown, self: SchemaAST.Declaration) => {
36
- if (input instanceof cls || isStructValue(input)) {
80
+ () => (input: unknown, self: SchemaAST.Declaration, options: SchemaAST.ParseOptions) => {
81
+ if (input instanceof cls) {
37
82
  return Effect.succeed(input)
38
83
  }
39
- return Effect.fail(new SchemaIssue.InvalidType(self, Option.some(input)))
84
+ if (input !== null && typeof input === "object") {
85
+ return decodeStruct(input, options)
86
+ }
87
+ return Effect.fail(new SchemaIssue.InvalidType(self, input))
40
88
  },
41
89
  ast.annotations,
42
90
  ast.checks,
@@ -56,8 +104,8 @@ function makeRelaxedDeclaration(
56
104
  *
57
105
  * @example
58
106
  * ```ts
59
- * import { Schema } from "effect"
60
- * import { Class } from "./Class.js"
107
+ * import * as Schema from "effect/Schema"
108
+ * import { Class } from "./Class.ts"
61
109
  *
62
110
  * class A extends Class<A>("A")({ a: Schema.String }) {}
63
111
  *
@@ -68,34 +116,50 @@ function makeRelaxedDeclaration(
68
116
  * Schema.encodeUnknownSync(A)({ a: "hello" }) // { a: "hello" }
69
117
  * ```
70
118
  */
71
- export const Class: <Self = never>(identifier: string) => <Fields extends S.Struct.Fields>(
119
+ export const Class: <Self = never, Encoded = ExtendedSchemaNoEncoded, Brand = {}>(
120
+ identifier: string
121
+ ) => <Fields extends S.Struct.Fields>(
72
122
  fieldsOr: Fields | HasFields<Fields>,
73
- annotations?: ClassAnnotations<Self>
123
+ annotations?: ClassAnnotations<Self>,
124
+ options?: ClassOptions
74
125
  ) => [Self] extends [never] ? MissingSelfGeneric<"Class">
75
126
  : EnhancedClass<
76
127
  Self,
77
- S.Struct<Fields>,
78
- {}
79
- > = (identifier) => (fields, annotations) => {
128
+ ClassFieldsSchema<Fields, Encoded>,
129
+ Brand
130
+ > = (identifier) => (fields, annotations, options) => {
131
+ const relaxed = options?.strict === false
80
132
  // Build the original Schema.Class
81
- const Base = (S.Class as any)(identifier)(fields, annotations)
133
+ const Base = (S.Class as any)(identifier)(fields, { ...concurrencyUnbounded, ...annotations })
82
134
  // Get the original ast getter from the base class
83
135
  const originalAstDescriptor = Object.getOwnPropertyDescriptor(Base, "ast")!
84
136
 
85
137
  // Cache per-class to avoid recomputing
86
138
  const astCache = new WeakMap<any, SchemaAST.Declaration>()
139
+ const copyCache = new WeakMap<any, ReturnType<typeof copyOrigin>>()
87
140
 
88
141
  return class extends Base {
142
+ static get copy() {
143
+ let cached = copyCache.get(this)
144
+ if (cached === undefined) {
145
+ cached = copyOrigin(this)
146
+ copyCache.set(this, cached)
147
+ }
148
+ return cached
149
+ }
89
150
  static get ast(): SchemaAST.Declaration {
90
151
  let cached = astCache.get(this)
91
152
  if (cached !== undefined) return cached
92
153
  // Call the original getter with `this` bound to the actual user class,
93
154
  // so getClassSchema(this) creates a schema that uses `new this(...)`.
94
155
  const originalAst = originalAstDescriptor.get!.call(this) as SchemaAST.Declaration
95
- cached = makeRelaxedDeclaration(originalAst, Base.fields, this)
156
+ cached = relaxed ? makeRelaxedDeclaration(originalAst, Base.fields, this) : originalAst
96
157
  astCache.set(this, cached)
97
158
  return cached
98
159
  }
160
+ static mapFields(f: any, options?: any) {
161
+ return Base.mapFields(f, options).annotate(concurrencyUnbounded)
162
+ }
99
163
  } as any
100
164
  }
101
165
 
@@ -109,8 +173,8 @@ export const Class: <Self = never>(identifier: string) => <Fields extends S.Stru
109
173
  *
110
174
  * @example
111
175
  * ```ts
112
- * import { Schema } from "effect"
113
- * import { TaggedClass } from "./Class.js"
176
+ * import * as Schema from "effect/Schema"
177
+ * import { TaggedClass } from "./Class.ts"
114
178
  *
115
179
  * class Circle extends TaggedClass<Circle>()("Circle", {
116
180
  * radius: Schema.Number
@@ -119,71 +183,501 @@ export const Class: <Self = never>(identifier: string) => <Fields extends S.Stru
119
183
  * Schema.encodeUnknownSync(Circle)({ _tag: "Circle", radius: 5 })
120
184
  * ```
121
185
  */
122
- export const TaggedClass: <Self = never>(
186
+ export const TaggedClass: <Self = never, Encoded = ExtendedSchemaNoEncoded, Brand = {}>(
123
187
  identifier?: string
124
188
  ) => <Tag extends string, Fields extends S.Struct.Fields>(
125
189
  tag: Tag,
126
190
  fieldsOr: Fields | HasFields<Fields>,
127
- annotations?: ClassAnnotations<Self>
191
+ annotations?: ClassAnnotations<Self>,
192
+ options?: ClassOptions
128
193
  ) => [Self] extends [never] ? MissingSelfGeneric<"TaggedClass">
129
194
  : EnhancedClass<
130
195
  Self,
131
- S.Struct<{ readonly _tag: S.tag<Tag> } & Fields>,
132
- {}
133
- > = (identifier) => (tag, fields, annotations) => {
134
- const Base = (S.TaggedClass as any)(identifier)(tag, fields, annotations)
196
+ ClassFieldsSchema<{ readonly _tag: S.tag<Tag> } & Fields, Encoded>,
197
+ Brand
198
+ > = (identifier) => (tag, fields, annotations, options) => {
199
+ const relaxed = options?.strict === false
200
+ const Base = (S.TaggedClass as any)(identifier)(tag, fields, { ...concurrencyUnbounded, ...annotations })
135
201
  const originalAstDescriptor = Object.getOwnPropertyDescriptor(Base, "ast")!
136
202
  const astCache = new WeakMap<any, SchemaAST.Declaration>()
203
+ const copyCache = new WeakMap<any, ReturnType<typeof copyOrigin>>()
137
204
 
138
205
  return class extends Base {
206
+ static get copy() {
207
+ let cached = copyCache.get(this)
208
+ if (cached === undefined) {
209
+ cached = copyOrigin(this)
210
+ copyCache.set(this, cached)
211
+ }
212
+ return cached
213
+ }
139
214
  static get ast(): SchemaAST.Declaration {
140
215
  let cached = astCache.get(this)
141
216
  if (cached !== undefined) return cached
142
217
  const originalAst = originalAstDescriptor.get!.call(this) as SchemaAST.Declaration
143
- cached = makeRelaxedDeclaration(originalAst, Base.fields, this)
218
+ cached = relaxed ? makeRelaxedDeclaration(originalAst, Base.fields, this) : originalAst
144
219
  astCache.set(this, cached)
145
220
  return cached
146
221
  }
222
+ static mapFields(f: any, options?: any) {
223
+ return Base.mapFields(f, options).annotate(concurrencyUnbounded)
224
+ }
147
225
  } as any
148
226
  }
149
227
 
150
228
  // ---------------------------------------------------------------------------
151
- // ExtendedClass — like Class but with extra type parameter for hierarchies
229
+ // ErrorClass — like Schema.ErrorClass but with relaxed encoding
152
230
  // ---------------------------------------------------------------------------
153
231
 
154
- export const ExtendedClass: <Self, _SelfFrom>(identifier: string) => <Fields extends S.Struct.Fields>(
232
+ export const ErrorClass: <Self = never, Encoded = ExtendedSchemaNoEncoded, Brand = {}>(
233
+ identifier: string
234
+ ) => <Fields extends S.Struct.Fields>(
155
235
  fieldsOr: Fields | HasFields<Fields>,
156
- annotations?: ClassAnnotations<Self>
157
- ) => EnhancedClass<
158
- Self,
159
- S.Struct<Fields>,
160
- {}
161
- > = Class as any
236
+ annotations?: ClassAnnotations<Self>,
237
+ options?: ClassOptions
238
+ ) => [Self] extends [never] ? MissingSelfGeneric<"ErrorClass">
239
+ : EnhancedClass<
240
+ Self,
241
+ ClassFieldsSchema<Fields, Encoded>,
242
+ Cause.YieldableError & Brand
243
+ > = (identifier) => (fields, annotations, options) => {
244
+ const relaxed = options?.strict === false
245
+ const Base = (S.Error as any)(identifier)(fields, { ...concurrencyUnbounded, ...annotations })
246
+ const originalAstDescriptor = Object.getOwnPropertyDescriptor(Base, "ast")!
247
+ const astCache = new WeakMap<any, SchemaAST.Declaration>()
248
+ const copyCache = new WeakMap<any, ReturnType<typeof copyOrigin>>()
249
+
250
+ return class extends Base {
251
+ static get copy() {
252
+ let cached = copyCache.get(this)
253
+ if (cached === undefined) {
254
+ cached = copyOrigin(this)
255
+ copyCache.set(this, cached)
256
+ }
257
+ return cached
258
+ }
259
+ static get ast(): SchemaAST.Declaration {
260
+ let cached = astCache.get(this)
261
+ if (cached !== undefined) return cached
262
+ const originalAst = originalAstDescriptor.get!.call(this) as SchemaAST.Declaration
263
+ cached = relaxed ? makeRelaxedDeclaration(originalAst, Base.fields, this) : originalAst
264
+ astCache.set(this, cached)
265
+ return cached
266
+ }
267
+ static mapFields(f: any, options?: any) {
268
+ return Base.mapFields(f, options).annotate(concurrencyUnbounded)
269
+ }
270
+ } as any
271
+ }
162
272
 
163
273
  // ---------------------------------------------------------------------------
164
- // ExtendedTaggedClass — like TaggedClass but with extra type parameter for hierarchies
274
+ // TaggedErrorClass — like Schema.TaggedErrorClass but with relaxed encoding
165
275
  // ---------------------------------------------------------------------------
166
276
 
167
- export interface EnhancedTaggedClass<Self, Tag extends string, Fields extends S.Struct.Fields, SelfFrom>
168
- extends
169
- EnhancedClass<
170
- Self,
171
- S.Struct<Fields> & { readonly Encoded: SelfFrom },
172
- {}
173
- >
174
- {
175
- readonly _tag: Tag
176
- }
177
-
178
- export const ExtendedTaggedClass: <Self, SelfFrom>(
277
+ export const TaggedErrorClass: <Self = never, Encoded = ExtendedSchemaNoEncoded, Brand = {}>(
179
278
  identifier?: string
180
279
  ) => <Tag extends string, Fields extends S.Struct.Fields>(
181
280
  tag: Tag,
182
281
  fieldsOr: Fields | HasFields<Fields>,
183
- annotations?: ClassAnnotations<Self>
184
- ) => EnhancedTaggedClass<
282
+ annotations?: ClassAnnotations<Self>,
283
+ options?: ClassOptions
284
+ ) => [Self] extends [never] ? MissingSelfGeneric<"TaggedErrorClass">
285
+ : EnhancedClass<
286
+ Self,
287
+ ClassFieldsSchema<{ readonly _tag: S.tag<Tag> } & Fields, Encoded>,
288
+ Cause.YieldableError & Brand
289
+ > = (identifier) => (tag, fields, annotations, options) => {
290
+ const relaxed = options?.strict === false
291
+ const Base = (S.TaggedError as any)(identifier)(tag, fields, { ...concurrencyUnbounded, ...annotations })
292
+ const originalAstDescriptor = Object.getOwnPropertyDescriptor(Base, "ast")!
293
+ const astCache = new WeakMap<any, SchemaAST.Declaration>()
294
+ const copyCache = new WeakMap<any, ReturnType<typeof copyOrigin>>()
295
+
296
+ return class extends Base {
297
+ static get copy() {
298
+ let cached = copyCache.get(this)
299
+ if (cached === undefined) {
300
+ cached = copyOrigin(this)
301
+ copyCache.set(this, cached)
302
+ }
303
+ return cached
304
+ }
305
+ static get ast(): SchemaAST.Declaration {
306
+ let cached = astCache.get(this)
307
+ if (cached !== undefined) return cached
308
+ const originalAst = originalAstDescriptor.get!.call(this) as SchemaAST.Declaration
309
+ cached = relaxed ? makeRelaxedDeclaration(originalAst, Base.fields, this) : originalAst
310
+ astCache.set(this, cached)
311
+ return cached
312
+ }
313
+ static mapFields(f: any, options?: any) {
314
+ return Base.mapFields(f, options).annotate(concurrencyUnbounded)
315
+ }
316
+ } as any
317
+ }
318
+
319
+ export interface Opaque<Self, Encoded, SchemaS extends S.Top, Brand> extends S.Opaque<Self, SchemaS, Brand> {
320
+ readonly "Encoded": Encoded extends ExtendedSchemaNoEncoded ? SchemaS["Encoded"] : Encoded
321
+ }
322
+
323
+ export const Opaque: <Self, Encoded = ExtendedSchemaNoEncoded, Brand = {}>() => <S extends S.Top>(
324
+ schema: S
325
+ ) => Opaque<Self, Encoded, S, Brand> & Omit<S, keyof S.Top> = S.Opaque as any
326
+
327
+ /**
328
+ * Like {@link Opaque}, but the class **instance type is exactly `Self`** (the supplied
329
+ * decoded `Type`) instead of the structurally-computed `struct["Type"] & Brand`.
330
+ *
331
+ * Stock `Opaque` types the instance as `struct["Type"] & Brand` and only overrides the
332
+ * schema's `Type`/`Encoded` *members* with `Self`/`Encoded`. So `make`/`copy`/consumers
333
+ * still resolve the struct's mapped `Type`. With a codegen-supplied pre-expanded literal
334
+ * `Type` interface, `OpaqueType` lets all of those resolve a single **named** interface
335
+ * (resolved once per checker) instead of re-deriving the mapped `Type` — cutting
336
+ * instantiation on `Type`-touching consumers.
337
+ *
338
+ * Use with `class X extends OpaqueType<X.Type, X.Encoded>()(struct) {}` where `X.Type`
339
+ * and `X.Encoded` are generated literal interfaces (see `@effect-app/eslint-codegen-model`,
340
+ * `static` + `type` mode).
341
+ *
342
+ * KNOWN GAP — **no branding**: the instance type is a plain structural `Self`, so opaque
343
+ * types of identical shape are mutually assignable. (Stock `Opaque` is also structural by
344
+ * default — `Brand` defaults to `{}` — so this only differs if you passed a non-default
345
+ * `Brand`.) Re-introducing a nominal brand on top of a supplied `Self` (e.g. branding the
346
+ * generated `Type` interface) is not yet implemented.
347
+ *
348
+ * NOTE: only `Type` (via `Self`) and `Encoded` are supplied statically here; `make`'s input
349
+ * (`~type.make.in`) and other derived members are still computed from the struct. See
350
+ * a future `OpaqueShape`-style helper if those also need to be supplied.
351
+ */
352
+ export interface OpaqueType<Self, Encoded, SchemaS extends S.Top, Brand> extends S.Opaque<Self, SchemaS, Brand> {
353
+ readonly "Encoded": Encoded extends ExtendedSchemaNoEncoded ? SchemaS["Encoded"] : Encoded
354
+ new(_: never): Self
355
+ }
356
+
357
+ export const OpaqueType: <Self, Encoded = ExtendedSchemaNoEncoded, Brand = {}>() => <S extends S.Top>(
358
+ schema: S
359
+ ) => OpaqueType<Self, Encoded, S, Brand> & Omit<S, keyof S.Top> = S.Opaque as any
360
+
361
+ type OpaqueFacadeConstructorArgs<MakeIn> = {} extends MakeIn ? [props?: MakeIn, options?: S.MakeOptions]
362
+ : [props: MakeIn, options?: S.MakeOptions]
363
+
364
+ // Only the codec channels are required. `copy`/`fields`/`mapFields` are NOT
365
+ // required here: transformed schemas (`.pipe(S.encodeKeys/annotate/filter/...)`)
366
+ // don't expose them at the static level, and requiring them would reject those
367
+ // models from facading. When present they still flow through via
368
+ // `OpaqueFacadeStatics`; when absent the facade simply doesn't offer them.
369
+ type OpaqueFacadeInput<DecodingServices, EncodingServices> = S.Top & {
370
+ readonly DecodingServices: DecodingServices
371
+ readonly EncodingServices: EncodingServices
372
+ }
373
+
374
+ type OpaqueClassFacadeInput<DecodingServices, EncodingServices> =
375
+ & OpaqueFacadeInput<
376
+ DecodingServices,
377
+ EncodingServices
378
+ >
379
+ & (abstract new(...args: Array<never>) => unknown)
380
+
381
+ type PrototypeFunction = Function & { prototype: object }
382
+
383
+ // Class schemas expose a constructor descriptor under this key (was previously
384
+ // identified via a `~effect/Schema/Class` annotation id).
385
+ const ConstructorAnnotationKey = "~constructor"
386
+
387
+ const getOwnOrInheritedPropertyDescriptor = (value: object, property: PropertyKey): PropertyDescriptor | undefined => {
388
+ let current: object | null = value
389
+ while (current !== null) {
390
+ const descriptor = Object.getOwnPropertyDescriptor(current, property)
391
+ if (descriptor !== undefined) return descriptor
392
+ current = Object.getPrototypeOf(current)
393
+ }
394
+ }
395
+
396
+ const isClassSchemaConstructor = (value: unknown): value is PrototypeFunction => {
397
+ if (typeof value !== "function") return false
398
+ // Transformed schemas (e.g. `Class.pipe(S.encodeKeys(...))`) are also functions with a
399
+ // Declaration AST that still carries `~constructor`, but they are not constructable classes.
400
+ // Real Schema.Class constructors expose a static `identifier`.
401
+ if (typeof (value as { readonly identifier?: unknown }).identifier !== "string") return false
402
+ const ast = (value as { readonly ast?: unknown }).ast
403
+ return SchemaAST.isAST(ast)
404
+ && SchemaAST.isDeclaration(ast)
405
+ && ast.annotations?.[ConstructorAnnotationKey] !== undefined
406
+ }
407
+
408
+ const getFacadeClassSchema = (schema: OpaqueFacadeInput<any, any>): PrototypeFunction | undefined => {
409
+ if (isClassSchemaConstructor(schema)) return schema
410
+ const target = "to" in schema ? (schema as { readonly to?: unknown }).to : undefined
411
+ return isClassSchemaConstructor(target) ? target : undefined
412
+ }
413
+
414
+ const makePublicClassTransformation = (Public: PrototypeFunction) =>
415
+ new SchemaTransformation.Transformation<any, any, never, never>(
416
+ SchemaGetter.transform((input) => Reflect.construct(Public, [input], Public)),
417
+ SchemaGetter.passthrough()
418
+ )
419
+
420
+ const makeFacadeClassAst = (
421
+ schema: OpaqueFacadeInput<any, any>,
422
+ originalAst: SchemaAST.AST,
423
+ Public: PrototypeFunction
424
+ ): SchemaAST.AST => {
425
+ if (SchemaAST.isDeclaration(schema.ast)) {
426
+ const schemaEncoding = schema.ast.encoding ?? []
427
+ if (schemaEncoding.length > 0) {
428
+ return new SchemaAST.Declaration(
429
+ schema.ast.typeParameters,
430
+ schema.ast.run,
431
+ schema.ast.annotations,
432
+ schema.ast.checks,
433
+ [new SchemaAST.Link(schemaEncoding[0]!.to, makePublicClassTransformation(Public)), ...schemaEncoding.slice(1)],
434
+ schema.ast.context,
435
+ schema.ast.encodingChecks
436
+ )
437
+ }
438
+ }
439
+
440
+ return schema.rebuild(originalAst).ast
441
+ }
442
+
443
+ // Carry the schema's own statics, dropping the generic `S.Top` machinery and
444
+ // `prototype`. EXCEPT `to`: models compose each other via `X.to.fields` /
445
+ // `X.to.copy` at definition time, so it must survive on the facade.
446
+ type OpaqueFacadeStatics<SchemaS extends S.Top> = Omit<SchemaS, Exclude<keyof S.Top, "to"> | "prototype">
447
+
448
+ /**
449
+ * Like {@link OpaqueType}, but ALSO supplies a static **make-input** shape, so
450
+ * `make`/`copy` resolve a named `MakeIn` interface instead of re-deriving the struct's
451
+ * mapped `~type.make.in`. Use with codegen-supplied `X.Type` / `X.Encoded` / `X.Make`:
452
+ *
453
+ * ```ts
454
+ * class X extends OpaqueShape<X.Type, X.Encoded, X.Make>()(struct) {}
455
+ * ```
456
+ *
457
+ * `decode`/`encode` already use the supplied `Type`/`Encoded` (they read the schema's
458
+ * `Type`/`Encoded` members, which are `Self`/`Encoded` here) — no separate override needed.
459
+ *
460
+ * NOTE — measured gain is modest (~5%): the struct passed to the wrapper is still
461
+ * constructed in full (definition cost dominates); the static shapes only cheapen
462
+ * consumer-side reads of `Type`/`Encoded`/`MakeIn`. Same `no-branding` gap as
463
+ * {@link OpaqueType}.
464
+ */
465
+ export interface OpaqueShape<Self, Encoded, MakeIn, SchemaS extends S.Top, Brand>
466
+ extends S.Opaque<Self, SchemaS, Brand>
467
+ {
468
+ readonly "Encoded": Encoded
469
+ readonly "~type.make.in": MakeIn
470
+ new(_: never): Self
471
+ }
472
+
473
+ export const OpaqueShape: <Self, Encoded, MakeIn, Brand = {}>() => <S extends S.Top>(
474
+ schema: S
475
+ ) => OpaqueShape<Self, Encoded, MakeIn, S, Brand> & Omit<S, keyof S.Top> = S.Opaque as any
476
+
477
+ /**
478
+ * Shallow public view for generated model facades.
479
+ *
480
+ * The runtime value can still be the full private schema class, but emitted
481
+ * declarations expose only named `Type` / `Encoded` / `Make` interfaces and a
482
+ * small static surface. This keeps downstream project references from pulling
483
+ * the private struct field map back through `typeof Model`.
484
+ */
485
+ export interface OpaqueFacade<
185
486
  Self,
186
- Tag,
187
- { readonly _tag: S.tag<Tag> } & Fields,
188
- SelfFrom
189
- > = TaggedClass as any
487
+ Encoded,
488
+ MakeIn,
489
+ DecodingServices = never,
490
+ EncodingServices = DecodingServices,
491
+ Brand = {}
492
+ > extends
493
+ S.Bottom<
494
+ Self,
495
+ Encoded,
496
+ DecodingServices,
497
+ EncodingServices,
498
+ SchemaAST.AST,
499
+ S.Codec<Self, Encoded, DecodingServices, EncodingServices>,
500
+ MakeIn,
501
+ Self,
502
+ readonly [],
503
+ MakeIn
504
+ >
505
+ {
506
+ new(_: never): Brand
507
+ readonly copy: ReturnType<typeof copyOrigin<new(_: MakeIn) => Self>>
508
+ // NOTE: no `identifier` here — `S.Opaque` (and requests) build on `S.Bottom`, not `S.Class`,
509
+ // so they have no `identifier`. It lives only on the class facades below.
510
+ // NOTE: `fields` / `mapFields` are intentionally NOT redeclared here. They are
511
+ // carried (precise) from the underlying schema via `OpaqueFacadeStatics`. A wide
512
+ // `mapFields(f: (fields: S.Struct.Fields) => To)` override would win overload
513
+ // resolution and erase field precision in `Q.project(X.mapFields(...))`.
514
+ }
515
+
516
+ export interface OpaqueClassFacade<
517
+ Self,
518
+ Encoded,
519
+ MakeIn,
520
+ DecodingServices = never,
521
+ EncodingServices = DecodingServices,
522
+ Brand = {}
523
+ > extends
524
+ S.Bottom<
525
+ Self,
526
+ Encoded,
527
+ DecodingServices,
528
+ EncodingServices,
529
+ SchemaAST.AST,
530
+ S.Codec<Self, Encoded, DecodingServices, EncodingServices>,
531
+ MakeIn,
532
+ Self,
533
+ readonly [],
534
+ MakeIn
535
+ >
536
+ {
537
+ new(...args: OpaqueFacadeConstructorArgs<MakeIn>): Brand
538
+ readonly copy: ReturnType<typeof copyOrigin<new(_: MakeIn) => Self>>
539
+ readonly identifier: string
540
+ }
541
+
542
+ export function OpaqueFacade<
543
+ Self,
544
+ Encoded,
545
+ MakeIn,
546
+ DecodingServices = never,
547
+ EncodingServices = DecodingServices,
548
+ Brand = {}
549
+ >() {
550
+ function facade<SchemaS extends OpaqueClassFacadeInput<DecodingServices, EncodingServices>>(
551
+ schema: SchemaS
552
+ ):
553
+ & OpaqueClassFacade<Self, Encoded, MakeIn, DecodingServices, EncodingServices, Brand>
554
+ & OpaqueFacadeStatics<SchemaS>
555
+ function facade<SchemaS extends OpaqueFacadeInput<DecodingServices, EncodingServices>>(
556
+ schema: SchemaS
557
+ ):
558
+ & OpaqueFacade<Self, Encoded, MakeIn, DecodingServices, EncodingServices, Brand>
559
+ & OpaqueFacadeStatics<SchemaS>
560
+ function facade(schema: OpaqueFacadeInput<DecodingServices, EncodingServices>) {
561
+ const Base = getFacadeClassSchema(schema)
562
+ if (Base !== undefined) {
563
+ const astCache = new WeakMap<object, SchemaAST.AST>()
564
+ const originalAstDescriptor = getOwnOrInheritedPropertyDescriptor(Base, "ast")
565
+
566
+ return class extends (Base as any) {
567
+ static get ast(): SchemaAST.AST {
568
+ let cached = astCache.get(this)
569
+ if (cached !== undefined) return cached
570
+
571
+ const originalAst = originalAstDescriptor?.get?.call(this) as SchemaAST.AST
572
+ cached = makeFacadeClassAst(schema, originalAst, this)
573
+ astCache.set(this, cached)
574
+ return cached
575
+ }
576
+ }
577
+ }
578
+
579
+ class Facade {}
580
+ return Object.setPrototypeOf(Facade, schema)
581
+ }
582
+
583
+ return facade
584
+ }
585
+
586
+ /**
587
+ * Like class-schema {@link OpaqueFacade}, but for error models (`TaggedErrorClass` /
588
+ * `ErrorClass`). The decoded instance type carries `Cause.YieldableError`, so
589
+ * `yield* new MyError(...)`, `Effect.fail(myError)`, and `instanceof` all keep
590
+ * working through the facade — the runtime `_X` is the real error class (the
591
+ * facade `X extends ...(_X)` inherits its prototype), and the type reflects it.
592
+ * Nothing is lost vs the underlying error class.
593
+ */
594
+ export interface OpaqueErrorFacadeClass<
595
+ Self,
596
+ Encoded,
597
+ MakeIn,
598
+ DecodingServices = never,
599
+ EncodingServices = DecodingServices,
600
+ Brand = {}
601
+ > extends
602
+ S.Bottom<
603
+ Self,
604
+ Encoded,
605
+ DecodingServices,
606
+ EncodingServices,
607
+ SchemaAST.AST,
608
+ S.Codec<Self, Encoded, DecodingServices, EncodingServices>,
609
+ MakeIn,
610
+ Self,
611
+ readonly [],
612
+ MakeIn
613
+ >
614
+ {
615
+ // YieldableError (not Self) on the constructed instance — like class-schema OpaqueFacade's
616
+ // `new(): Brand`, the data type comes from the declaration-merged `interface X`,
617
+ // so `Self` must NOT appear here (would recurse). Merging `X & YieldableError`
618
+ // makes `yield* new X()` / `Effect.fail` / `instanceof` work without losing data.
619
+ new(...args: OpaqueFacadeConstructorArgs<MakeIn>): Cause.YieldableError & Brand
620
+ readonly copy: ReturnType<typeof copyOrigin<new(_: MakeIn) => Self>>
621
+ readonly identifier: string
622
+ }
623
+
624
+ export function OpaqueErrorFacadeClass<
625
+ Self,
626
+ Encoded,
627
+ MakeIn,
628
+ DecodingServices = never,
629
+ EncodingServices = DecodingServices,
630
+ Brand = {}
631
+ >() {
632
+ return <SchemaS extends OpaqueClassFacadeInput<DecodingServices, EncodingServices>>(
633
+ schema: SchemaS
634
+ ):
635
+ & OpaqueErrorFacadeClass<Self, Encoded, MakeIn, DecodingServices, EncodingServices, Brand>
636
+ & OpaqueFacadeStatics<SchemaS> =>
637
+ {
638
+ type FacadeSchema =
639
+ & OpaqueErrorFacadeClass<Self, Encoded, MakeIn, DecodingServices, EncodingServices, Brand>
640
+ & OpaqueFacadeStatics<SchemaS>
641
+
642
+ if (isClassSchemaConstructor(schema)) {
643
+ return schema as SchemaS & FacadeSchema
644
+ }
645
+
646
+ throw new TypeError("OpaqueErrorFacadeClass requires a class schema")
647
+ }
648
+ }
649
+
650
+ /**
651
+ * Workflow-compatible struct facade.
652
+ *
653
+ * A top-level `const X = S.Struct(...)` / `S.TaggedStruct(...)` schema model whose `.d.ts`
654
+ * is produced by the schema-aware declaration emitter is retyped from the giant inline
655
+ * `S.Struct<{ ...fields... }>` to this facade.
656
+ *
657
+ * Unlike {@link OpaqueFacade}, `StructFacade` **extends effect-app's `Struct<Fields>`**, so the
658
+ * value is still a real (effect-app) struct schema: it satisfies `Workflow.AnyStructSchema` and
659
+ * the `Struct<Fields & Context>` reconstruction the workflow machinery performs, and `Union` /
660
+ * `.fields.x` keep working. It MUST be effect-app's `Struct` (not effect core's) — scanner
661
+ * models are effect-app `S.Struct`, so a facade built on `effect/Schema`'s `Struct` is not
662
+ * assignable where an effect-app struct is expected. At the same time the type-level members
663
+ * (`Type` / `Encoded` / make-input / services) are pinned to the named interfaces the emitter
664
+ * generates in `namespace X`, so consumers reference those by name instead of re-deriving them
665
+ * from `Fields` on every use. `Fields` is the model's own generated `X.Fields` interface — a
666
+ * single materialization of the (expensive) field shape that every reference site points at.
667
+ */
668
+ export type StructFacade<
669
+ Self,
670
+ Encoded,
671
+ MakeIn,
672
+ DecodingServices,
673
+ EncodingServices,
674
+ Fields extends S.Struct.Fields
675
+ > =
676
+ & Omit<EffectAppStruct<Fields>, "Type" | "Encoded" | "~type.make.in" | "DecodingServices" | "EncodingServices">
677
+ & {
678
+ readonly "Type": Self
679
+ readonly "Encoded": Encoded
680
+ readonly "~type.make.in": MakeIn
681
+ readonly "DecodingServices": DecodingServices
682
+ readonly "EncodingServices": EncodingServices
683
+ }