Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No schema for encoding #1157

Closed
jasonkuhrt opened this issue Oct 2, 2024 · 1 comment · Fixed by #1160
Closed

No schema for encoding #1157

jasonkuhrt opened this issue Oct 2, 2024 · 1 comment · Fixed by #1160

Comments

@jasonkuhrt
Copy link
Member

jasonkuhrt commented Oct 2, 2024

Perceived Problem

I am trying to remove the need for runtime schema (whole or optimized specialty indexes of e.g. just custom scalar input paths) until absolutely needed for a feature. Example of such a feature is custom scalars or result field schema errors.

Ideas / Proposed Solution(s)

In our encoder we use the schema to differentiate strings from enums. This is because we use strings to input both of them. If we remove this use-case we can infer encoding for all other standard scalar types reasonably based on their JS runtime input without the need for a runtime schema. In fact there is very little encoding to do: ID and String just get quoted and both can be seen as strings in JS, Float and Int can receive JS numbers as is, same for Boolean, List, Input Object (we just recurse into them).

So it seems worthwhile to remove the one basic use-case for enum.

Steps we need to take:

  1. Generate an enum proxy. Have it typed as if it were not a proxy. Near zero cost from a bundle size point of view, and surely a trivial performance cost?
    Note: Later we can easily offer a generation option that replaces proxy with real runtime (objects) if people ask
  2. To continue supporting custom scalars we need to offer a function that will be called whenever a scalar is encoded along with what the path to it is. Then, people can opt-in to using the schema to encode them. The path received by the callback can be compared to an index in the schema and if a customer scalar is declared to be there then we look up its encoder and apply it.

Applying enums to inputs will be a bit more annoying than just flowing with strings because now an import will be needed. But I think we can make it pretty painless.

pokemon.mutation.addPokemon({
  $: {
    name: 'foobar',
    type: Pokemon.PokemonType.grass
  }
})

Another solution might be to support a enum constructor that has a type variable that will allow us to autocomplete. I will test this:

pokemon.mutation.addPokemon({
  $: {
    name: 'foobar',
    type: Enum('grass')
  }
})

We could play with the function name:

pokemon.mutation.addPokemon({
  $: {
    name: 'foobar',
    type: $('grass')
  }
})
pokemon.mutation.addPokemon({
  $: {
    name: 'foobar',
    type: _('grass')
  }
})

Alternatively we could play with the key name using something that is not valid in GraphQL to allow our encoder to transform it into enum that way:

pokemon.mutation.addPokemon({
  $: {
    name: 'foobar',
    $type: 'grass'
  }
})
pokemon.mutation.addPokemon({
  $: {
    name: 'foobar',
    type$enum: 'grass'
  }
})
@jasonkuhrt jasonkuhrt changed the title Generate enum proxy No schema for encoding Oct 2, 2024
@jasonkuhrt
Copy link
Member Author

Decided to go with the $ prefix approach on keys for now. Maybe we can open up options/alternatives if people need it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant