Skip to content

reflecting to types, e.g. for TypeGPU #167

@mighdoll

Description

@mighdoll

In #159 (comment), we started a discussion about how to handle runtime conditions for reflecting into TypeScript.

from @iwoplaza:


Hmm, let's explore this a bit. Currently we're able to import structs as named exports from a shader file, like so:

// shader.wgsl
struct Boid {
  position: vec3f,
  velocity: vec3f,
}
// main.ts
import { Boid } from './shader.wgsl?typegpu';

However, if the definitions were dependent on runtime constants, we would have to provide them before getting reified references back:

// shader.wgsl
import constants::boids;

@if(boids)
struct Boid {
  position: vec3f,
  velocity: vec3f,
}
// main.ts
import shaderReflection from './shader.wgsl?typegpu';

const { Boid } = shaderReflection({
  boids: true,
});

The dynamically generated code of ./shader.wgsl?typegpu could be:

import * as d from 'typegpu';

const Boid = d.struct({
  position: d.vec3f,
  velocity: d.vec3f,
});

interface Constants {
  boids: boolean;
};

function reflection<T extends Constants>(constants: T):
  T['boids'] extends true
    ? { boids: typeof Boid }
    : { boids: undefined } {
  return {
    Boid: constants.boids ? Boid : undefined,
  };
}

export default reflection;

We can also handle more complex cases, like using constants inside of struct definitions, but lets omit that for now.

Solutions

I see a couple possible solutions we could try out:

  1. Export static definitions (those independent of runtime-constants) as named exports, as those are going to be a majority, and house the rest in the default "reflection" export.
  2. Export everything always as the default export.

The latter is simpler to implement and maintain, but also sours the DX for most common use-cases. What do we think? 🤔

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Unprioritized

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions