Fionabronwen/graphql alloy foundation#75
Draft
FionaBronwen wants to merge 3 commits intofeature/graphqlfrom
Draft
Fionabronwen/graphql alloy foundation#75FionaBronwen wants to merge 3 commits intofeature/graphqlfrom
FionaBronwen wants to merge 3 commits intofeature/graphqlfrom
Conversation
Foundation for the component-based GraphQL emitter: Build infrastructure: - Add @alloy-js/graphql dependency, switch to alloy build - Configure JSX in tsconfig for Alloy components - Add Alloy Rollup plugin for vitest Context system: - GraphQLSchemaContext: schema-wide state (classified types, model variants, scalar specifications) - TypeResolutionContext: input/output mode tracking for type resolution Field components: - GraphQLTypeExpression: resolves TypeSpec types to GraphQL type info using Typekit predicates and context hooks. Handles nullability from two sources (property-level and type-level state maps), inline union unwrapping, array element recursion, scalar mapping, and model Input suffix determination. - Field: renders a model property as gql.Field or gql.InputField - OperationField: renders an operation as a field with input arguments Nullable tracking fix: - Track nullability on ModelProperty (unique per use-site) instead of the type (shared scalar singletons get poisoned) - Add nullableElements state for Array<T | null> element tracking - Add getGraphQLBuiltinName() identity-based scalar check
Replace raw indexer checks and `as Union`/`as Model` casts with proper type guards (isArray(), $.union.is() narrowing). Add comprehensive module-level documentation to nullable.ts explaining why state maps are needed and how property-level vs type-level tracking works. Fix missing nullable propagation for operation parameters in OperationField.
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.
Summary
compiler config)
for sharing classified types and input/output mode across the component tree
resolution component that handles scalars, models, enums, unions, arrays, nullability, and
input/output type splitting
of the shared type singleton to prevent poisoning all uses of a scalar. Add comprehensive
module documentation in nullable.ts explaining the architecture.
Details
This is the foundation layer for the Alloy-based GraphQL emitter rewrite. It provides:
Build infrastructure: Alloy CLI for builds, rollup plugin for vitest JSX transform, TSX-aware
TypeScript config.
Context system: Two React-style contexts — GraphQLSchemaContext provides classified types
(models, enums, scalars, unions, operations) and model variant lookups for input/output name
resolution. GraphQLTypeResolutionContext tracks whether we're resolving types in input or
output mode, which determines naming (e.g., Foo vs FooInput) and non-null semantics.
Nullable tracking: The mutation engine strips null variants from unions before components
render. Since the structural evidence of nullability is gone by render time, state maps bridge
the gap. Three tracking sites:
See nullable.ts module doc for the full architectural explanation.
Field components: Field renders model properties as gql.Field/gql.InputField. OperationField
renders operations as fields with arguments. Both delegate type resolution to
GraphQLTypeExpression, which uses typekit predicates for type narrowing and render-prop
children for structured output.