@bigmistqke/view.gl 0.1.6 → 0.1.8

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.
@@ -1,13 +1,6 @@
1
- type Merge<A, B> = {
2
- [K in keyof A | keyof B]: K extends keyof A ? K extends keyof B ? A[K] | B[K] : A[K] : K extends keyof B ? B[K] : never;
3
- };
4
1
  type Prettify<T> = {
5
2
  [K in keyof T]: T[K];
6
3
  } & {};
7
- type RemoveSuffix<T, S extends string> = {
8
- [K in keyof T as K extends `${infer Prefix}${S}` ? Prefix : K]: T[K];
9
- };
10
- type GL = WebGLRenderingContext | WebGL2RenderingContext;
11
4
  type DeepMerge<A extends readonly [...any]> = A extends [infer L, ...infer R] ? DeepMergeTwo<L, DeepMerge<R>> : unknown;
12
5
  type DeepMergeTwo<TBase, TOverride> = {
13
6
  [K in keyof TBase | keyof TOverride]: K extends keyof TOverride ? K extends keyof TBase ? ShallowMerge<[TBase[K], TOverride[K]]> : TOverride[K] : K extends keyof TBase ? TBase[K] : never;
@@ -25,8 +18,8 @@ type Id<T> = T extends infer U ? {
25
18
  [K in keyof U]: U[K];
26
19
  } : never;
27
20
  type ShallowMergeTwo<L, R> = Id<Pick<L, Exclude<keyof L, keyof R>> & Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>> & Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>> & SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>>;
28
- /**********************************************************************************/
29
- /**********************************************************************************/
21
+
22
+ type GL = WebGLRenderingContext | WebGL2RenderingContext;
30
23
  type GLTarget = 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER';
31
24
  type GLUsage = 'STATIC_DRAW' | 'DYNAMIC_DRAW' | 'STREAM_DRAW';
32
25
  type GLTextureTarget = 'TEXTURE_2D' | 'TEXTURE_CUBE_MAP';
@@ -254,16 +247,16 @@ interface UniformKindMap {
254
247
  usamplerCube: [number];
255
248
  usampler2DArray: [number];
256
249
  }
257
- interface UniformOptions {
250
+ interface UniformDefinition {
258
251
  kind: UniformKind;
259
252
  size?: number;
260
253
  }
261
- type UniformSchema = Record<string | symbol, UniformOptions>;
262
- type UniformSchemaPartial = Record<string | symbol, Partial<UniformOptions>>;
263
- type UniformMethods<TOptions extends UniformOptions> = TOptions['size'] extends number ? {
254
+ type UniformSchema = Record<string | symbol, UniformDefinition>;
255
+ type UniformSchemaPartial = Record<string | symbol, Partial<UniformDefinition>>;
256
+ type UniformMethods<TDefinition extends UniformDefinition> = TDefinition['size'] extends number ? {
264
257
  set(arg: Float32Array): void;
265
258
  } : {
266
- set(...args: UniformKindMap[TOptions['kind']]): void;
259
+ set(...args: UniformKindMap[TDefinition['kind']]): void;
267
260
  };
268
261
  type UniformView<T extends UniformSchema> = {
269
262
  [K in keyof T]: UniformMethods<T[K]>;
@@ -272,12 +265,12 @@ type UniformView<T extends UniformSchema> = {
272
265
  /**********************************************************************************/
273
266
  type AttributeShortHand = '1f' | '2f' | '3f' | '4f' | '1i' | '2i' | '3i' | '4i' | '1ui' | '2ui' | '3ui' | '4ui';
274
267
  type AttributeKind = 'float' | 'vec2' | 'vec3' | 'vec4' | 'mat2' | 'mat3' | 'mat4' | 'mat2x3' | 'mat2x4' | 'mat3x2' | 'mat3x4' | 'mat4x2' | 'mat4x3' | 'int' | 'ivec2' | 'ivec3' | 'ivec4' | 'uint' | 'uvec2' | 'uvec3' | 'uvec4';
275
- interface AttributeOptions {
268
+ interface AttributeDefinition {
276
269
  kind: AttributeKind;
277
270
  instanced?: boolean;
278
271
  buffer?: WebGLBuffer;
279
272
  }
280
- type AttributeSchema = Record<string | symbol, AttributeOptions>;
273
+ type AttributeSchema = Record<string | symbol, AttributeDefinition>;
281
274
  interface AttributeMethods<T = AttributeKind> {
282
275
  buffer: WebGLBuffer;
283
276
  bind(): void;
@@ -295,11 +288,11 @@ interface InterleavedAttributeLayout {
295
288
  key: string | symbol;
296
289
  kind: AttributeKind;
297
290
  }
298
- interface InterleavedAttributeOptions {
291
+ interface InterleavedAttributeDefinition {
299
292
  layout: InterleavedAttributeLayout[];
300
293
  instanced?: boolean;
301
294
  }
302
- type InterleavedAttributeSchema = Record<string | symbol, InterleavedAttributeOptions>;
295
+ type InterleavedAttributeSchema = Record<string | symbol, InterleavedAttributeDefinition>;
303
296
  interface InterleavedAttributeMethods<T extends InterleavedAttributeLayout[] = InterleavedAttributeLayout[]> {
304
297
  bind(): void;
305
298
  unbind(): void;
@@ -311,11 +304,11 @@ type InterleavedAttributeView<T extends InterleavedAttributeSchema> = {
311
304
  };
312
305
  /**********************************************************************************/
313
306
  /**********************************************************************************/
314
- interface BufferOptions {
307
+ interface BufferDefinition {
315
308
  target?: GLTarget;
316
309
  usage?: GLUsage;
317
310
  }
318
- type BufferSchema = Record<string | symbol, BufferOptions>;
311
+ type BufferSchema = Record<string | symbol, BufferDefinition>;
319
312
  interface BufferMethods {
320
313
  set(data: Float32Array | Uint16Array | Uint32Array): void;
321
314
  bind(): void;
@@ -326,11 +319,11 @@ type BufferView<T extends BufferSchema> = {
326
319
  };
327
320
  /**********************************************************************************/
328
321
  /**********************************************************************************/
329
- interface FramebufferOptions extends Omit<TextureOptions, 'data'> {
322
+ interface FramebufferDefinition extends Omit<TextureDefinition, 'data'> {
330
323
  attachment: 'color' | 'depth' | 'stencil' | 'depthStencil';
331
324
  texture?: WebGLTexture;
332
325
  }
333
- interface TextureOptions {
326
+ interface TextureDefinition {
334
327
  target?: GLTextureTarget;
335
328
  width: number;
336
329
  height: number;
@@ -352,7 +345,7 @@ interface Framebuffer {
352
345
  /**********************************************************************************/
353
346
  /**********************************************************************************/
354
347
  type TextureTarget = 'TEXTURE_2D' | 'TEXTURE_CUBE_MAP' | 'TEXTURE_3D' | 'TEXTURE_2D_ARRAY';
355
- type TextureSchema = Record<string | symbol, TextureOptions>;
348
+ type TextureSchema = Record<string | symbol, TextureDefinition>;
356
349
  interface TextureMethods {
357
350
  texture: WebGLTexture;
358
351
  dispose(): void;
@@ -390,16 +383,16 @@ interface ViewSchema {
390
383
  buffers?: BufferSchema;
391
384
  }
392
385
  interface ViewSchemaPartial {
393
- uniforms?: Record<string | symbol, Partial<UniformOptions>>;
394
- attributes?: Record<string | symbol, Partial<AttributeOptions>>;
395
- interleavedAttributes?: Record<string | symbol, Partial<InterleavedAttributeOptions>>;
396
- buffers?: Record<string | symbol, Partial<BufferOptions>>;
386
+ uniforms?: Record<string | symbol, Partial<UniformDefinition>>;
387
+ attributes?: Record<string | symbol, Partial<AttributeDefinition>>;
388
+ interleavedAttributes?: Record<string | symbol, Partial<InterleavedAttributeDefinition>>;
389
+ buffers?: Record<string | symbol, Partial<BufferDefinition>>;
397
390
  }
398
391
  type View<T extends ViewSchema = ViewSchema> = {
399
- attributes: T['attributes'] extends AttributeSchema ? AttributeView<T['attributes']> : undefined;
400
- interleavedAttributes: T['interleavedAttributes'] extends InterleavedAttributeSchema ? InterleavedAttributeView<T['interleavedAttributes']> : undefined;
401
- buffers: T['buffers'] extends BufferSchema ? BufferView<T['buffers']> : undefined;
402
- uniforms: T['uniforms'] extends UniformSchema ? UniformView<T['uniforms']> : never;
392
+ attributes: T['attributes'] extends AttributeSchema ? Prettify<AttributeView<T['attributes']>> : never;
393
+ interleavedAttributes: T['interleavedAttributes'] extends InterleavedAttributeSchema ? Prettify<InterleavedAttributeView<T['interleavedAttributes']>> : never;
394
+ buffers: T['buffers'] extends BufferSchema ? Prettify<BufferView<T['buffers']>> : never;
395
+ uniforms: T['uniforms'] extends UniformSchema ? Prettify<UniformView<T['uniforms']>> : never;
403
396
  };
404
397
  /**********************************************************************************/
405
398
  /**********************************************************************************/
@@ -407,14 +400,14 @@ interface GLSLResult {
407
400
  program: WebGLProgram;
408
401
  schema: ViewSchema;
409
402
  }
410
- type GLSLSlotItem = GLSLTag | UniformTag | AttributeTag | InterleaveTag | string | number | symbol;
403
+ type GLSLSlotItem = GLSL | UniformToken | AttributeToken | InterleaveToken | string | number | symbol;
411
404
  type GLSLSlot = GLSLSlotItem | Array<GLSLSlotItem>;
412
- interface GLSLTag<TSlots extends GLSLSlot[] = GLSLSlot[]> {
405
+ interface GLSL<TSlots extends GLSLSlot[] = GLSLSlot[]> {
413
406
  type: 'glsl';
414
407
  template: TemplateStringsArray;
415
408
  slots: TSlots;
416
409
  }
417
- type UniformTag<TKey extends string | symbol = string | symbol, TKind extends UniformKind = UniformKind, TOptions extends Partial<UniformOptions> = UniformOptions> = TOptions extends {
410
+ type UniformToken<TKey extends string | symbol = string | symbol, TKind extends UniformKind = UniformKind, TDefinition extends Partial<UniformDefinition> = UniformDefinition> = TDefinition extends {
418
411
  size: infer TSize;
419
412
  } ? {
420
413
  type: 'uniform';
@@ -426,26 +419,62 @@ type UniformTag<TKey extends string | symbol = string | symbol, TKind extends Un
426
419
  kind: TKind;
427
420
  key: TKey;
428
421
  };
429
- interface UniformTagFn<TKind extends UniformKind> {
430
- <const TKey extends string | symbol, const TOptions extends Omit<UniformOptions, 'kind'>>(key: TKey, TOptions: TOptions): Prettify<UniformTag<TKey, TKind, TOptions>>;
431
- <const TName extends string | symbol>(key: TName): Prettify<UniformTag<TName, TKind>>;
422
+ interface UniformTokenFn<TKind extends UniformKind> {
423
+ <const TKey extends string | symbol, const TDefinition extends Omit<UniformDefinition, 'kind'>>(key: TKey, TDefinition: TDefinition): Prettify<UniformToken<TKey, TKind, TDefinition>>;
424
+ <const TName extends string | symbol>(key: TName): Prettify<UniformToken<TName, TKind>>;
432
425
  }
433
- interface AttributeTag<TKey extends string | symbol = string | symbol, TKind extends AttributeKind = AttributeKind, TInstanced extends boolean | undefined = boolean | undefined> {
426
+ interface AttributeToken<TKey extends string | symbol = string | symbol, TKind extends AttributeKind = AttributeKind, TInstanced extends boolean | undefined = boolean | undefined> {
434
427
  type: 'attribute';
435
428
  kind: TKind;
436
429
  instanced: TInstanced;
437
430
  key: TKey;
438
431
  }
439
- interface AttributeTagFn<TKey extends AttributeKind> {
440
- <TName extends string | symbol, TOptions extends Omit<AttributeOptions, 'kind'>>(key: TName, options: TOptions): Prettify<AttributeTag<TName, TKey, TOptions['instanced']>>;
441
- <TName extends string | symbol>(key: TName): Prettify<AttributeTag<TName, TKey, undefined>>;
432
+ interface AttributeTokenFn<TKey extends AttributeKind> {
433
+ <TName extends string | symbol, TDefinition extends Omit<AttributeDefinition, 'kind'>>(key: TName, options: TDefinition): Prettify<AttributeToken<TName, TKey, TDefinition['instanced']>>;
434
+ <TName extends string | symbol>(key: TName): Prettify<AttributeToken<TName, TKey, undefined>>;
442
435
  }
443
- type InterleaveTag<TKey extends string | symbol = string | symbol, TLayout extends Array<AttributeTag<string | symbol, AttributeKind, undefined>> = Array<AttributeTag<string | symbol, AttributeKind, undefined>>, TOptions extends Omit<AttributeOptions, 'kind'> = Omit<AttributeOptions, 'kind'>> = TOptions & {
436
+ type InterleaveToken<TKey extends string | symbol = string | symbol, TLayout extends Array<AttributeToken<string | symbol, AttributeKind, undefined>> = Array<AttributeToken<string | symbol, AttributeKind, undefined>>, TDefinition extends Omit<AttributeDefinition, 'kind'> = Omit<AttributeDefinition, 'kind'>> = TDefinition & {
444
437
  key: TKey;
445
438
  type: 'interleavedAttribute';
446
439
  layout: {
447
440
  [TKey in keyof TLayout]: Prettify<Pick<TLayout[TKey], 'kind' | 'key'>>;
448
441
  };
449
442
  };
443
+ type GLSLToSchema<T extends GLSL> = FlattenSlots<T> extends infer TSlots ? TSlots extends Array<any> ? GLSLSlotsToSchema<TSlots> : never : never;
444
+ type GLSLToView<T extends GLSL> = View<GLSLToSchema<T>>;
445
+ type GLSLSlotsToSchema<TSlots extends Array<GLSLSlot>> = {
446
+ uniforms: {
447
+ [K in Extract<TSlots[number], UniformToken> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>;
448
+ };
449
+ attributes: {
450
+ [K in Extract<TSlots[number], AttributeToken> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>;
451
+ };
452
+ interleavedAttributes: {
453
+ [K in Extract<TSlots[number], InterleaveToken> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>;
454
+ };
455
+ };
456
+ type FlattenSlots<T> = T extends GLSL<infer TSlots> ? _FlattenSlots<TSlots> : T extends Array<GLSLSlot> ? _FlattenSlots<T> : never;
457
+ type _FlattenSlots<T extends Array<GLSLSlot>> = T extends [infer First, ...infer Rest] ? First extends GLSL ? [...FlattenSlots<First>, ...FlattenSlots<Rest>] : First extends unknown[] ? [...FlattenSlots<First>, ...FlattenSlots<Rest>] : [First, ...FlattenSlots<Rest>] : [];
458
+ type MergeGLSLSchema<TVertex extends ViewSchema, TFragment extends ViewSchema, TOverrides extends ViewSchemaPartial = {}> = {
459
+ uniforms: DeepMerge<[
460
+ ShallowMerge<[TVertex['uniforms'], TFragment['uniforms']]>,
461
+ TOverrides['uniforms']
462
+ ]>;
463
+ attributes: DeepMerge<[
464
+ ShallowMerge<[TVertex['attributes'], TFragment['attributes']]>,
465
+ TOverrides['attributes']
466
+ ]>;
467
+ interleavedAttributes: DeepMerge<[
468
+ ShallowMerge<[TVertex['interleavedAttributes'], TFragment['interleavedAttributes']]>,
469
+ TOverrides['interleavedAttributes']
470
+ ]>;
471
+ };
472
+ type CompileResult<TVertex extends GLSL, TFragment extends GLSL, TOverrideSchema extends ViewSchemaPartial> = MergeGLSLSchema<GLSLToSchema<TVertex>, GLSLToSchema<TFragment>, TOverrideSchema> extends infer TSchema extends ViewSchema ? {
473
+ program: WebGLProgram;
474
+ schema: TSchema;
475
+ view: Prettify<View<TSchema>>;
476
+ vertex: string;
477
+ fragment: string;
478
+ } : never;
450
479
 
451
- export type { AttributeTag as $, AttributeSchema as A, BufferSchema as B, TextureParameterName as C, DeepMerge as D, TextureParameterValue as E, FramebufferOptions as F, GL as G, TextureParameters as H, InterleavedAttributeSchema as I, InternalFormat as J, KIND_TO_UNIFORM_FN_NAME_MAP as K, Format as L, Merge as M, PixelType as N, TexImage2DOptions as O, Prettify as P, ViewSchemaPartial as Q, RemoveSuffix as R, ShallowMerge as S, TextureOptions as T, UniformSchema as U, ViewSchema as V, GLSLResult as W, GLSLSlot as X, GLSLTag as Y, UniformTag as Z, UniformTagFn as _, ViewOptions as a, AttributeTagFn as a0, InterleaveTag as a1, View as b, UniformView as c, AttributeView as d, InterleavedAttributeView as e, BufferView as f, KIND_TO_SIZE_MAP as g, UniformFnName as h, UniformKind as i, UniformOptions as j, UniformSchemaPartial as k, UniformMethods as l, AttributeShortHand as m, AttributeKind as n, AttributeOptions as o, AttributeMethods as p, InterleavedAttributeLayout as q, InterleavedAttributeOptions as r, InterleavedAttributeMethods as s, BufferOptions as t, BufferMethods as u, Framebuffer as v, TextureTarget as w, TextureSchema as x, TextureMethods as y, TextureView as z };
480
+ export type { UniformToken as $, AttributeSchema as A, BufferSchema as B, BufferDefinition as C, BufferMethods as D, Framebuffer as E, FramebufferDefinition as F, GL as G, TextureTarget as H, InterleavedAttributeSchema as I, TextureSchema as J, KIND_TO_UNIFORM_FN_NAME_MAP as K, TextureMethods as L, TextureView as M, TextureParameterName as N, TextureParameterValue as O, TextureParameters as P, InternalFormat as Q, Format as R, PixelType as S, TextureDefinition as T, UniformSchema as U, ViewSchema as V, TexImage2DOptions as W, ViewSchemaPartial as X, GLSLResult as Y, GLSLSlot as Z, GLSL as _, ViewOptions as a, UniformTokenFn as a0, AttributeToken as a1, AttributeTokenFn as a2, InterleaveToken as a3, GLSLToSchema as a4, GLSLToView as a5, GLSLSlotsToSchema as a6, MergeGLSLSchema as a7, CompileResult as a8, Prettify as a9, View as b, UniformView as c, AttributeView as d, InterleavedAttributeView as e, BufferView as f, GLTarget as g, GLUsage as h, GLTextureTarget as i, GLTextureFormat as j, GLTextureType as k, GLTextureFilter as l, GLTextureWrap as m, KIND_TO_SIZE_MAP as n, UniformFnName as o, UniformKind as p, UniformDefinition as q, UniformSchemaPartial as r, UniformMethods as s, AttributeShortHand as t, AttributeKind as u, AttributeDefinition as v, AttributeMethods as w, InterleavedAttributeLayout as x, InterleavedAttributeDefinition as y, InterleavedAttributeMethods as z };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bigmistqke/view.gl",
3
- "version": "0.1.6",
4
- "description": "🪟 Utilities for managing WebGL resources.",
3
+ "version": "0.1.8",
4
+ "description": "👀 Utilities for managing WebGL resources.",
5
5
  "exports": {
6
6
  ".": {
7
7
  "import": "./dist/index.mjs",
package/src/features.ts CHANGED
@@ -1,4 +1,5 @@
1
- import type { GL, RemoveSuffix } from './types'
1
+ import { RemoveSuffix } from './type-utils'
2
+ import type { GL } from './types'
2
3
 
3
4
  const INSTANCED_ARRAYS_WRAPPER_MAP = new WeakMap<
4
5
  GL,
package/src/tag.ts CHANGED
@@ -1,20 +1,18 @@
1
1
  import { toID, view } from '.'
2
+ import type { Prettify } from './type-utils'
2
3
  import type {
4
+ AttributeDefinition,
3
5
  AttributeKind,
4
- AttributeOptions,
5
- AttributeTag,
6
- AttributeTagFn as AttributeTagMethod,
7
- DeepMerge,
6
+ AttributeTokenFn as AttributeTagMethod,
7
+ AttributeToken,
8
+ CompileResult,
9
+ GLSL,
8
10
  GLSLSlot,
9
- GLSLTag,
10
- InterleaveTag,
11
- Prettify,
12
- ShallowMerge,
11
+ GLSLToSchema,
12
+ InterleaveToken,
13
+ UniformDefinition,
13
14
  UniformKind,
14
- UniformOptions,
15
- UniformTag,
16
- UniformTagFn as UniformTagMethod,
17
- View,
15
+ UniformTokenFn as UniformTagMethod,
18
16
  ViewSchema,
19
17
  ViewSchemaPartial,
20
18
  } from './types'
@@ -23,7 +21,7 @@ import { createProgram } from './utils'
23
21
  export function glsl<TSlot extends GLSLSlot, TSlots extends TSlot[]>(
24
22
  template: TemplateStringsArray,
25
23
  ...slots: [...TSlots]
26
- ): GLSLTag<TSlots> {
24
+ ): GLSL<TSlots> {
27
25
  return { template, slots, type: 'glsl' }
28
26
  }
29
27
 
@@ -35,7 +33,7 @@ export const uniform = new Proxy(
35
33
  get(target, property) {
36
34
  // @ts-expect-error
37
35
  if (typeof property === 'symbol') return target[property]
38
- return (key: string, options?: Omit<UniformOptions, 'kind'>) => ({
36
+ return (key: string, options?: Omit<UniformDefinition, 'kind'>) => ({
39
37
  type: 'uniform',
40
38
  key,
41
39
  kind: property,
@@ -53,7 +51,7 @@ export const attribute = new Proxy(
53
51
  get(target, property) {
54
52
  // @ts-expect-error
55
53
  if (typeof property === 'symbol') return target[property]
56
- return (key: string, options?: Omit<AttributeOptions, 'kind'>) => ({
54
+ return (key: string, options?: Omit<AttributeDefinition, 'kind'>) => ({
57
55
  type: 'attribute',
58
56
  key,
59
57
  kind: property,
@@ -65,17 +63,17 @@ export const attribute = new Proxy(
65
63
 
66
64
  export function interleave<
67
65
  const TKey extends string | symbol,
68
- const TLayout extends Array<AttributeTag<string | symbol, AttributeKind, undefined>>,
69
- const TOptions extends Omit<AttributeOptions, 'kind'>,
70
- >(key: TKey, layout: TLayout, instanced: TOptions): InterleaveTag<TKey, TLayout, TOptions>
66
+ const TLayout extends Array<AttributeToken<string | symbol, AttributeKind, undefined>>,
67
+ const TOptions extends Omit<AttributeDefinition, 'kind'>,
68
+ >(key: TKey, layout: TLayout, instanced: TOptions): InterleaveToken<TKey, TLayout, TOptions>
71
69
  export function interleave<
72
70
  const TKey extends string | symbol,
73
- const TLayout extends Array<AttributeTag<string | symbol, AttributeKind, undefined>>,
74
- >(key: TKey, layout: TLayout): InterleaveTag<TKey, TLayout, { instanced: false }>
71
+ const TLayout extends Array<AttributeToken<string | symbol, AttributeKind, undefined>>,
72
+ >(key: TKey, layout: TLayout): InterleaveToken<TKey, TLayout, { instanced: false }>
75
73
  export function interleave<
76
74
  const TKey extends string | symbol,
77
- const TLayout extends Array<AttributeTag<string | symbol, AttributeKind, undefined>>,
78
- const TOptions extends Omit<AttributeOptions, 'kind'>,
75
+ const TLayout extends Array<AttributeToken<string | symbol, AttributeKind, undefined>>,
76
+ const TOptions extends Omit<AttributeDefinition, 'kind'>,
79
77
  >(key: TKey, layout: TLayout, { instanced, buffer }: Partial<TOptions> = {}) {
80
78
  return {
81
79
  type: 'interleavedAttribute',
@@ -87,7 +85,7 @@ export function interleave<
87
85
  })),
88
86
  instanced: !!instanced,
89
87
  buffer,
90
- } as unknown as InterleaveTag<TKey, TLayout, TOptions>
88
+ } as unknown as InterleaveToken<TKey, TLayout, TOptions>
91
89
  }
92
90
 
93
91
  /**********************************************************************************/
@@ -96,83 +94,13 @@ export function interleave<
96
94
  /* */
97
95
  /**********************************************************************************/
98
96
 
99
- type glslTagToSchema<TTag extends GLSLTag> =
100
- FlattenSlots<TTag> extends infer TSlots
101
- ? TSlots extends Array<any>
102
- ? GLSLSlotsToSchema<TSlots>
103
- : never
104
- : never
105
-
106
- type GLSLSlotsToSchema<TSlots extends Array<GLSLSlot>> = {
107
- uniforms: {
108
- [K in Extract<TSlots[number], UniformTag> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
109
- }
110
- attributes: {
111
- [K in Extract<TSlots[number], AttributeTag> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
112
- }
113
- interleavedAttributes: {
114
- [K in Extract<TSlots[number], InterleaveTag> as K['key']]: Prettify<Omit<K, 'name' | 'type'>>
115
- }
116
- }
117
-
118
- type FlattenSlots<T> =
119
- T extends GLSLTag<infer TSlots>
120
- ? _FlattenSlots<TSlots>
121
- : T extends Array<GLSLSlot>
122
- ? _FlattenSlots<T>
123
- : never
124
-
125
- type _FlattenSlots<T extends Array<GLSLSlot>> = T extends [infer First, ...infer Rest]
126
- ? First extends GLSLTag
127
- ? [...FlattenSlots<First>, ...FlattenSlots<Rest>]
128
- : First extends unknown[]
129
- ? [...FlattenSlots<First>, ...FlattenSlots<Rest>]
130
- : [First, ...FlattenSlots<Rest>]
131
- : []
132
-
133
- type MergeGLSLSchema<
134
- TVertex extends ViewSchema,
135
- TFragment extends ViewSchema,
136
- TOverrides extends ViewSchemaPartial,
137
- > = {
138
- uniforms: DeepMerge<
139
- [ShallowMerge<[TVertex['uniforms'], TFragment['uniforms']]>, TOverrides['uniforms']]
140
- >
141
- attributes: DeepMerge<
142
- [ShallowMerge<[TVertex['attributes'], TFragment['attributes']]>, TOverrides['attributes']]
143
- >
144
- interleavedAttributes: DeepMerge<
145
- [
146
- ShallowMerge<[TVertex['interleavedAttributes'], TFragment['interleavedAttributes']]>,
147
- TOverrides['interleavedAttributes'],
148
- ]
149
- >
150
- }
151
-
152
- type CompileResult<
153
- TVertex extends GLSLTag,
154
- TFragment extends GLSLTag,
155
- TOverrides extends ViewSchemaPartial,
156
- > =
157
- MergeGLSLSchema<
158
- glslTagToSchema<TVertex>,
159
- glslTagToSchema<TFragment>,
160
- TOverrides
161
- > extends infer TSchema extends ViewSchema
162
- ? {
163
- program: WebGLProgram
164
- schema: TSchema
165
- view: View<TSchema>
166
- }
167
- : never
168
-
169
97
  export function compile<
170
- TVertex extends GLSLTag,
171
- TFragment extends GLSLTag,
98
+ TVertex extends GLSL,
99
+ TFragment extends GLSL,
172
100
  TOverride extends ViewSchemaPartial,
173
101
  >(gl: WebGLRenderingContext, vertex: TVertex, fragment: TFragment, overrideSchema?: TOverride) {
174
- const _vertex = resolveGLSLTag(vertex)
175
- const _fragment = resolveGLSLTag(fragment)
102
+ const _vertex = resolveGLSLTag(vertex) as { template: string; schema: ViewSchema }
103
+ const _fragment = resolveGLSLTag(fragment) as { template: string; schema: ViewSchema }
176
104
 
177
105
  const schema = {
178
106
  uniforms: {
@@ -194,9 +122,7 @@ export function compile<
194
122
  const overrideSchemaKind = overrideSchema[kind]
195
123
 
196
124
  for (const key in overrideSchemaKind) {
197
- // @ts-expect-error
198
125
  schemaKind[key] = {
199
- // @ts-expect-error
200
126
  ...schemaKind[key],
201
127
  ...overrideSchemaKind[key],
202
128
  }
@@ -209,17 +135,19 @@ export function compile<
209
135
  program,
210
136
  schema,
211
137
  view: view(gl, program, schema),
212
- } as CompileResult<TVertex, TFragment, TOverride>
138
+ vertex: _vertex.template,
139
+ fragment: _fragment.template,
140
+ } as unknown as Prettify<CompileResult<TVertex, TFragment, TOverride>>
213
141
  }
214
142
 
215
- function resolveGLSLTag<TTag extends GLSLTag>(tag: TTag) {
143
+ function resolveGLSLTag<TTag extends GLSL>(tag: TTag) {
216
144
  return {
217
- template: glslTagToString(tag),
218
- schema: glslTagToSchema(tag),
145
+ template: compile.toString(tag),
146
+ schema: compile.toSchema(tag),
219
147
  }
220
148
  }
221
149
 
222
- function glslTagToSchema<TTag extends GLSLTag>(tag: TTag) {
150
+ compile.toSchema = function <TTag extends GLSL>(tag: TTag) {
223
151
  const result = {
224
152
  uniforms: {},
225
153
  attributes: {},
@@ -237,7 +165,7 @@ function glslTagToSchema<TTag extends GLSLTag>(tag: TTag) {
237
165
  }
238
166
 
239
167
  if (slot.type === 'glsl') {
240
- const { uniforms, attributes, interleavedAttributes } = glslTagToSchema(slot)
168
+ const { uniforms, attributes, interleavedAttributes } = compile.toSchema(slot)
241
169
 
242
170
  result.uniforms = {
243
171
  ...result.uniforms,
@@ -263,45 +191,10 @@ function glslTagToSchema<TTag extends GLSLTag>(tag: TTag) {
263
191
 
264
192
  tag.slots.forEach(handleSlot)
265
193
 
266
- return result
194
+ return result as unknown as Prettify<GLSLToSchema<TTag>>
267
195
  }
268
196
 
269
- // function glslSlotToSchema(slot: GLSLSlot){
270
- // if(Array.isArray(slot)){
271
-
272
- // return
273
- // }
274
-
275
- // if (typeof slot !== 'object') {
276
- // return
277
- // }
278
-
279
- // if (slot.type === 'glsl') {
280
- // return glslTagToSchema(slot)
281
-
282
- // // result.uniforms = {
283
- // // ...result.uniforms,
284
- // // ...uniforms,
285
- // // }
286
- // // result.attributes = {
287
- // // ...result.attributes,
288
- // // ...attributes,
289
- // // }
290
- // // result.interleavedAttributes = {
291
- // // ...result.interleavedAttributes,
292
- // // ...interleavedAttributes,
293
- // // }
294
-
295
- // // continue
296
- // }
297
-
298
- // const { key: name, type, ...rest } = slot
299
-
300
- // // @ts-expect-error
301
- // result[`${type}s`][name] = rest
302
- // }
303
-
304
- function glslTagToString<TTag extends GLSLTag>({ template: [initial, ...rest], slots }: TTag) {
197
+ compile.toString = function <TTag extends GLSL>({ template: [initial, ...rest], slots }: TTag) {
305
198
  const v300 = !!initial?.startsWith('#version 300 es')
306
199
 
307
200
  let template = initial ?? ''
@@ -323,7 +216,7 @@ function glslSlotToString(slot: GLSLSlot, v300: boolean): string {
323
216
  }
324
217
 
325
218
  if (slot.type === 'glsl') {
326
- return glslTagToString(slot)
219
+ return compile.toString(slot)
327
220
  }
328
221
 
329
222
  if (slot.type === 'interleavedAttribute') {
@@ -0,0 +1,43 @@
1
+ export type Prettify<T> = {
2
+ [K in keyof T]: T[K]
3
+ } & {}
4
+
5
+ export type RemoveSuffix<T, S extends string> = {
6
+ [K in keyof T as K extends `${infer Prefix}${S}` ? Prefix : K]: T[K]
7
+ }
8
+
9
+ export type DeepMerge<A extends readonly [...any]> = A extends [infer L, ...infer R]
10
+ ? DeepMergeTwo<L, DeepMerge<R>>
11
+ : unknown
12
+
13
+ type DeepMergeTwo<TBase, TOverride> = {
14
+ [K in keyof TBase | keyof TOverride]: K extends keyof TOverride
15
+ ? K extends keyof TBase
16
+ ? ShallowMerge<[TBase[K], TOverride[K]]>
17
+ : TOverride[K]
18
+ : K extends keyof TBase
19
+ ? TBase[K]
20
+ : never
21
+ }
22
+
23
+ // see https://stackoverflow.com/a/49683575
24
+ export type ShallowMerge<A extends readonly [...any]> = A extends [infer L, ...infer R]
25
+ ? ShallowMergeTwo<L, ShallowMerge<R>>
26
+ : unknown
27
+
28
+ type OptionalPropertyNames<T> = {
29
+ [K in keyof T]-?: {} extends { [P in K]: T[K] } ? K : never
30
+ }[keyof T]
31
+
32
+ type SpreadProperties<L, R, K extends keyof L & keyof R> = {
33
+ [P in K]: L[P] | Exclude<R[P], undefined>
34
+ }
35
+
36
+ type Id<T> = T extends infer U ? { [K in keyof U]: U[K] } : never
37
+
38
+ type ShallowMergeTwo<L, R> = Id<
39
+ Pick<L, Exclude<keyof L, keyof R>> &
40
+ Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>> &
41
+ Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>> &
42
+ SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>
43
+ >