Emit effect-app schema facades at .d.ts (Class/Error/Struct/Opaque)#3
Open
patroza wants to merge 24 commits into
Open
Emit effect-app schema facades at .d.ts (Class/Error/Struct/Opaque)#3patroza wants to merge 24 commits into
patroza wants to merge 24 commits into
Conversation
…to release-6.0 (microsoft#63208) Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com>
…to release-6.0 (microsoft#63246) Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com>
…to release-6.0 (microsoft#63327) Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
…lease-6.0 (microsoft#63372) Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com>
…to release-6.0 (microsoft#63407) Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com>
This was referenced Jun 21, 2026
…Class models
Extend the schema-model facade rewrite beyond the Opaque family to the
class and error families. Detection is now family-aware on the source heritage
constructor:
- S.Opaque / S.OpaqueFacade -> S.OpaqueFacade
- S.Class / S.TaggedClass -> S.OpaqueClassFacade
- S.ErrorClass / S.TaggedErrorClass -> S.OpaqueErrorFacadeClass
These class/error models emit an `S.EnhancedClass<Self, Schema, Inherited>`
base; the 3rd type arg (the brand, e.g. `Cause.YieldableError` for errors) is
extracted and preserved as the facade's Brand. The Opaque family keeps `{}`.
Validated on macs/scanner (static-OFF, 0 errors): 46 OpaqueErrorFacadeClass +
10 OpaqueClassFacade bases now faceted (were emitted as the full
`S.EnhancedClass<Self, S.Struct<...full...>>` before).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A `const X = S.Struct(...)` / `S.TaggedStruct(...)` model has no backing class,
so it is faceted on the const itself: the giant inline `S.Struct<{...}>`
annotation is replaced by a compact facade and the named member types are
attached via a sibling `interface X` (decoded Self) plus a TYPE-ONLY
`declare namespace X` (Fields/Encoded/Make/services). Both are type-space, so
they merge with the `const X` value without a value-space collision. The
source's `export type X = typeof X.Type` companion is dropped (the interface
replaces it).
Workflow compatibility: struct models are frequently workflow payloads, and the
Workflow types demand a concrete `S.Struct<Fields>` (AnyStructSchema +
`Struct<Fields & Context>` reconstruction). An `OpaqueFacade` is not a Struct
and breaks them, so the const is retyped to a scanner-local
`StructFacade<Self, Encoded, Make, DecodingServices, EncodingServices, Fields>`
(emitted as a self-contained `import("#lib/StructFacade").StructFacade<...>`
type) which is `Omit<S.Struct<Fields>, ...> & { pinned type-level members }` —
still a real struct schema, but with Type/Encoded/make/services resolved to the
named interfaces so consumers stop re-deriving them.
Member materialization uses a new EmitResolver method
`createTypeOfStructSchemaProperty`: it reads a property (Encoded / Type /
~type.make.in / DecodingServices / EncodingServices / fields) off the type of
the const's initializer and serializes the resolved type. Serializing the
resolved type keeps `never` services as `never` and never synthesizes
`S.Struct.*` references that could fail to resolve in a source file's scope.
Scanner src tree: 56 structs faceted, 0 errors (workflows/controllers/services
included). Function-returned structs (e.g. `addressWithMaxLength(...)`) are left
unfaceted, since their initializer is not a direct `S.Struct(...)` call.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The facade base is S.Bottom-based (not S.Class), so 'identifier: string' — an
S.Class/EnhancedClass static — was dropped from faceted class/error models.
Stock carries it via the EnhancedClass reference; add it to the facade static
members so the faceted type stays equal to stock. fields + the YieldableError/{}
prototype brand were already preserved.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…erface identifier (generic string) now sits on OpaqueFacade/OpaqueClassFacade/ OpaqueErrorFacadeClass in effect-app (effect-app/libs), so the compiler must not hand-emit it per model. Only per-model precise statics (fields/mapFields/to/from/ copy) stay compiler-emitted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…type) + docs
Struct models now emit `S.StructFacade<X, X.Encoded, X.Make, X.DecodingServices,
X.EncodingServices, X.Fields>` via the file's own `S` import (StructFacade is
exported from effect-app >= 4.0.0-beta.279) instead of
`import("#lib/StructFacade").StructFacade<...>`. No scanner-local module needed.
Add docs/effect-schema-facade-emit.md (what/why/how/results + facade links).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
af09341 to
0f1017f
Compare
…ss+Encoded/Struct) Real stock-vs-patched output for each schema-model kind. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ache) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tions Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Emit compact effect-app schema facade declarations from the TypeScript declaration transformer.
What changes:
Class/Opaque/TaggedErrorClassschema declarations into facade-shaped.d.tsoutput.Encoded,Make,DecodingServices, andEncodingServiceswhere the checker can serialize them.Encoded extends S.StructNestedEncoded<typeof SameModel>placeholders with the static generatedEncodedinterface.import("...")type references.Validation against scanner:
effect-app/TypeScript@v6.0.3-effect-app.3from this PR head (d26f6896f)..3tarball and ran/node_modules/.bin/tsc --version:Version 6.0.3.MACS_TS_COMPILER=tsc node scripts/tsgo-or-tsc.mjs --build api/tsconfig.src.json --force --stopBuildOnErrors.api/disthas0remainingStructNestedEncodedplaceholders.Base:
6.0.3source.