@frapx/core 0.5.0 → 0.6.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.0 - 2026-10-23
4
+
5
+ ### Added
6
+
7
+ - `timeSource` host option and `setTimeSource(source | null)`: the realtime loop takes each frame's time from an external transport (`() => seconds`), such as an audio player, while the offscreen, hidden and reduced-motion gates and the pointer keep working. `time` is the source's value, never clamped; `delta` is the step from the previous frame, clamped to `[0, 0.1]`, and 0 when the source goes back or on the first frame after a pause. The reduced-motion still frame reads the source; `render()` and `captureFrame()` redraw at the last frame's time. A manual clock ignores the source but keeps it, and `renderMode: "demand"` (no frame loop) never reads it, with a `debug` warning. New `TimeSource` type.
8
+
9
+ ### Fixed
10
+
11
+ - An unawaited `ready` no longer produces an unhandled rejection when `destroy()` rejects it with `DestroyedError` (for example a React StrictMode effect cleanup) or when the environment is unsupported (`UnsupportedError`, including the no-op instance created without a browser). Awaiting `ready` or `.then(…, onError)` still observes the rejection. Setup failures and `TargetNotFoundError` still surface.
12
+
13
+ ## 0.5.1 - 2026-10-20
14
+
15
+ ### Fixed
16
+
17
+ - The host's `onResize` now also fires when a frame is the first to see a new size. Browsers run animation frames before resize observations, so in a running realtime loop the frame took the new size and the resize observer then found nothing changed: `onResize` almost never fired while playing. It runs before that frame's draw.
18
+
3
19
  ## 0.5.0 - 2026-10-15
4
20
 
5
21
  ### Added
package/README.md CHANGED
@@ -2,9 +2,20 @@
2
2
 
3
3
  Shared WebGL runtime host for `@frapx` packages.
4
4
 
5
- This package provides the core WebGL lifecycle engine (canvas setup, context management, animation loop, a11y gates) shared between `@frapx/fx-canvas` and future frapx packages. It is a low-level building block and its API may change between minor versions while `@frapx/core` remains at `0.x`.
5
+ This package is the lifecycle engine (canvas setup, context management and restore, animation loop and clocks, a11y gates, frame capture) shared by `@frapx/fx-canvas`, `@frapx/fx-passes` and `@frapx/fx-particles`. It is a low-level building block and its API may change between minor versions while `@frapx/core` remains at `0.x`.
6
6
 
7
- If you are building a WebGL experience, you most likely want [`@frapx/fx-canvas`](https://www.npmjs.com/package/@frapx/fx-canvas) instead.
7
+ If you are building a WebGL experience, you most likely want [`@frapx/fx-canvas`](https://www.npmjs.com/package/@frapx/fx-canvas) (or another `fx-*` package) instead.
8
+
9
+ ## Exports
10
+
11
+ For building a new `fx-*` runtime on the same host:
12
+
13
+ - `createRuntimeHost(options)` — the host: canvas setup, `realtime` / `manual` clocks, fixed `resolution`, offscreen / hidden / reduced-motion gates, context loss and restore, and `captureFrame()`. A runtime plugs in through `createContext`, `onInit`, `onDraw`, `onCaptureDraw`, `captureSource`, `onResize` and the context hooks.
14
+ - Programs and uniforms — `createProgram`, `createFullscreenProgram`, `createFullscreenBuffer`, `collectUniformLocations`, `applyUniform(s)`, `normalizeUniform`, `createUniformCache`, `toUniformName` / `fromUniformName`.
15
+ - Textures and targets — `loadTexture`, `createTextureSet`, `createRenderTarget`, `createPingPong`, `supportsRenderTargetFormat`, `resolveRenderTargetFormat`, `createBlitter`.
16
+ - Timelines — `createUniformBindings`, `keyframes`.
17
+ - Helpers — `waitForGpu`, `glsl`, `glslUtils`, `hexToRgb` / `hexToRgba`, `parseShaderLog`, `isWebGL2Context`, `isGLSL300`, `setupCanvas`, `resolveDpr`.
18
+ - Errors — `ShaderError`, `ShaderCompileError`, `UnsupportedError`, `TargetNotFoundError`, `TextureLoadError`, `DestroyedError`.
8
19
 
9
20
  ## License
10
21
 
package/dist/index.d.ts CHANGED
@@ -10,6 +10,12 @@ type RenderMode = "always" | "demand";
10
10
  * drawn only by explicit `render()` calls, so output is deterministic.
11
11
  */
12
12
  type ClockMode = "realtime" | "manual";
13
+ /**
14
+ * Returns the current time in seconds from an external transport, such as an
15
+ * audio player's position. Under the realtime clock it replaces
16
+ * requestAnimationFrame time while the gates keep working.
17
+ */
18
+ type TimeSource = () => number;
13
19
  /** Fixed internal render size in pixels: `[width, height]`. */
14
20
  type Resolution = readonly [number, number];
15
21
  type DprOption = "auto" | number | (() => number);
@@ -144,6 +150,8 @@ type RuntimeHostOptions = {
144
150
  renderMode?: RenderMode;
145
151
  /** Defaults to `"realtime"`. See {@link ClockMode}. */
146
152
  clock?: ClockMode;
153
+ /** Takes realtime loop frames' time from this source; unread in demand mode. See {@link TimeSource}. */
154
+ timeSource?: TimeSource;
147
155
  /**
148
156
  * Fixes the internal render size instead of following the target's size.
149
157
  * Required when neither `target` nor `canvas` is given.
@@ -180,6 +188,7 @@ type RuntimeHostInstance = {
180
188
  readonly supported: boolean;
181
189
  readonly ready: Promise<void>;
182
190
  readonly clock: ClockMode;
191
+ readonly timeSource: TimeSource | null;
183
192
  start(): void;
184
193
  stop(): void;
185
194
  render(): void;
@@ -193,6 +202,12 @@ type RuntimeHostInstance = {
193
202
  setTime(seconds: number): void;
194
203
  /** Switches between realtime and manual clocks after creation. */
195
204
  setClock(clock: ClockMode): void;
205
+ /**
206
+ * Sets or removes the realtime clock's external time source. Each realtime
207
+ * frame then takes `time = source()` and `delta` from the previous frame's
208
+ * value, clamped to `[0, 0.1]`. A manual clock ignores the source but keeps it.
209
+ */
210
+ setTimeSource(source: TimeSource | null): void;
196
211
  /**
197
212
  * Fixes the internal render size, or follows the target's size again when
198
213
  * `null`. Throws `UnsupportedError` when the size exceeds the GPU limits.
@@ -462,4 +477,4 @@ declare const createRenderTarget: (gl: GLContext, width: number, height: number,
462
477
  */
463
478
  declare const createPingPong: (gl: GLContext, width: number, height: number, options?: RenderTargetOptions) => PingPong;
464
479
 
465
- export { type Blitter, type CaptureFormat, type CaptureOptions, type CaptureResult, type ClockMode, DestroyedError, type DomSetup, type DprOption, type Ease, type ExplicitUniformInput, type FullscreenProgram, type GLContext, type HostFrameState, type HostPointer, type Keyframe, type KeyframeOptions, type KeyframeTrack, type KeyframeValue, type LoadedTexture, type NormalizedUniform, type PingPong, type RenderMode, type RenderTarget, type RenderTargetFormat, type RenderTargetOptions, type Resolution, type RuntimeHostInstance, type RuntimeHostOptions, type SetupCanvasOptions, ShaderCompileError, ShaderError, type ShaderErrorLine, type ShaderLayer, type ShaderStage, type ShaderStatus, TargetNotFoundError, type TextureInput, TextureLoadError, type TextureMap, type TextureOptions, type TextureSet, type TextureSource, type UniformBindings, type UniformInput, type UniformInputMap, type UniformRuntimeValue, type UniformScalar, type UniformSource, type UniformType, type UniformVec2, type UniformVec3, type UniformVec4, UnsupportedError, applyProgramUniform, applyUniform, applyUniforms, collectUniformLocations, createBlitter, createFullscreenBuffer, createFullscreenProgram, createPingPong, createProgram, createRenderTarget, createRuntimeHost, createTextureSet, createUniformBindings, createUniformCache, defaultVertexShader, defaultVertexShader300, fromUniformName, isGLSL300, isWebGL2Context, keyframes, loadTexture, normalizeUniform, parseShaderLog, resizeCanvasToTarget, resolveDpr, resolveElement, resolveRenderTargetFormat, setupCanvas, supportsRenderTargetFormat, toUniformName, waitForGpu };
480
+ export { type Blitter, type CaptureFormat, type CaptureOptions, type CaptureResult, type ClockMode, DestroyedError, type DomSetup, type DprOption, type Ease, type ExplicitUniformInput, type FullscreenProgram, type GLContext, type HostFrameState, type HostPointer, type Keyframe, type KeyframeOptions, type KeyframeTrack, type KeyframeValue, type LoadedTexture, type NormalizedUniform, type PingPong, type RenderMode, type RenderTarget, type RenderTargetFormat, type RenderTargetOptions, type Resolution, type RuntimeHostInstance, type RuntimeHostOptions, type SetupCanvasOptions, ShaderCompileError, ShaderError, type ShaderErrorLine, type ShaderLayer, type ShaderStage, type ShaderStatus, TargetNotFoundError, type TextureInput, TextureLoadError, type TextureMap, type TextureOptions, type TextureSet, type TextureSource, type TimeSource, type UniformBindings, type UniformInput, type UniformInputMap, type UniformRuntimeValue, type UniformScalar, type UniformSource, type UniformType, type UniformVec2, type UniformVec3, type UniformVec4, UnsupportedError, applyProgramUniform, applyUniform, applyUniforms, collectUniformLocations, createBlitter, createFullscreenBuffer, createFullscreenProgram, createPingPong, createProgram, createRenderTarget, createRuntimeHost, createTextureSet, createUniformBindings, createUniformCache, defaultVertexShader, defaultVertexShader300, fromUniformName, isGLSL300, isWebGL2Context, keyframes, loadTexture, normalizeUniform, parseShaderLog, resizeCanvasToTarget, resolveDpr, resolveElement, resolveRenderTargetFormat, setupCanvas, supportsRenderTargetFormat, toUniformName, waitForGpu };
package/dist/index.js CHANGED
@@ -289,6 +289,7 @@ var applyCanvasStyle = (canvas, options, shouldPosition) => {
289
289
  // src/host.ts
290
290
  var MAX_DELTA_SECONDS = 0.1;
291
291
  var IDLE_POINTER = { x: 0, y: 0, uvX: 0, uvY: 0, active: 0 };
292
+ var clampDelta = (delta) => Math.min(Math.max(delta, 0), MAX_DELTA_SECONDS);
292
293
  var createRuntimeHost = (options) => {
293
294
  return new RuntimeHost(options);
294
295
  };
@@ -323,12 +324,16 @@ var RuntimeHost = class {
323
324
  this.statusBeforeLoss = "idle";
324
325
  this.manualDelta = 0;
325
326
  this.lastManualTime = null;
327
+ // The source's value at the previous loop frame; null restarts u_delta at 0.
328
+ this.lastSourceTime = null;
326
329
  this.objectFitRestore = null;
327
330
  // Letterbox offset (CSS px) of the contained canvas content inside the target.
328
331
  this.contentOffsetX = 0;
329
332
  this.contentOffsetY = 0;
330
333
  this.options = options;
331
334
  this.clockMode = options.clock ?? "realtime";
335
+ this.source = options.timeSource ?? null;
336
+ this.warnIfSourceUnread();
332
337
  this.fixedResolution = options.resolution ? normalizeResolution(options.resolution) : null;
333
338
  this.ready = new Promise((resolve, reject) => {
334
339
  this.readyResolve = resolve;
@@ -353,6 +358,9 @@ var RuntimeHost = class {
353
358
  get clock() {
354
359
  return this.clockMode;
355
360
  }
361
+ get timeSource() {
362
+ return this.source;
363
+ }
356
364
  start() {
357
365
  if (this.destroyed || this.currentStatus === "unsupported") return;
358
366
  this.running = true;
@@ -393,6 +401,18 @@ var RuntimeHost = class {
393
401
  this.lastManualTime = null;
394
402
  this.reconcile();
395
403
  }
404
+ setTimeSource(source) {
405
+ if (this.destroyed) return;
406
+ this.source = source;
407
+ this.lastSourceTime = null;
408
+ this.warnIfSourceUnread();
409
+ }
410
+ // Only the realtime loop reads the source, and demand mode runs no loop.
411
+ warnIfSourceUnread() {
412
+ if (this.source && this.options.renderMode === "demand") {
413
+ this.debugWarn('`timeSource` is not read with renderMode "demand", which runs no frame loop. Call setTime() instead.');
414
+ }
415
+ }
396
416
  setResolution(resolution) {
397
417
  if (this.destroyed) return;
398
418
  if (resolution === null) {
@@ -454,15 +474,7 @@ var RuntimeHost = class {
454
474
  this.resizePending = true;
455
475
  return;
456
476
  }
457
- const prevWidth = this.width;
458
- const prevHeight = this.height;
459
- const prevViewportWidth = this.viewportWidth;
460
- const prevViewportHeight = this.viewportHeight;
461
- this.measureSize();
462
- const sizeChanged = this.width !== prevWidth || this.height !== prevHeight || this.viewportWidth !== prevViewportWidth || this.viewportHeight !== prevViewportHeight;
463
- if (sizeChanged && this.context) {
464
- this.options.onResize?.(this.createFrameState(this.elapsed, 0));
465
- }
477
+ this.syncSize();
466
478
  if (this.shouldRenderOnDemand && !this.inRender) {
467
479
  this.render();
468
480
  }
@@ -487,11 +499,36 @@ var RuntimeHost = class {
487
499
  dom.target.style.position = dom.restoredPosition;
488
500
  }
489
501
  this.currentStatus = "destroyed";
502
+ this.markReadyHandled();
490
503
  this.readyReject?.(new DestroyedError("Runtime host was destroyed."));
491
504
  }
492
505
  get isManual() {
493
506
  return this.clockMode === "manual";
494
507
  }
508
+ get followsSource() {
509
+ return this.source !== null && !this.isManual;
510
+ }
511
+ // A non-finite reading holds the previous time instead of throwing in a frame.
512
+ readSource() {
513
+ if (!this.followsSource) return null;
514
+ const now = this.source();
515
+ return Number.isFinite(now) ? now : null;
516
+ }
517
+ // The static frame takes the source's current time without a delta.
518
+ syncSourceTime() {
519
+ const now = this.readSource();
520
+ if (now !== null) this.elapsed = now;
521
+ }
522
+ // A loop frame under a source: time is the source's value, never clamped;
523
+ // delta is the step from the previous frame, 0 when it went back.
524
+ advanceFromSource() {
525
+ const now = this.readSource();
526
+ if (now === null) return 0;
527
+ const previous = this.lastSourceTime;
528
+ this.lastSourceTime = now;
529
+ this.elapsed = now;
530
+ return previous === null ? 0 : clampDelta(now - previous);
531
+ }
495
532
  get isDetached() {
496
533
  if (this.dom) return this.dom.detached === true;
497
534
  return this.options.target === void 0 && this.options.canvas === void 0;
@@ -543,6 +580,7 @@ var RuntimeHost = class {
543
580
  }
544
581
  renderStaticFrame() {
545
582
  if (this.hasVisibilityBlock) return;
583
+ this.syncSourceTime();
546
584
  this.renderInternal(this.elapsed, 0);
547
585
  }
548
586
  renderInternal(time, delta) {
@@ -550,7 +588,7 @@ var RuntimeHost = class {
550
588
  const gl = this.context;
551
589
  this.inRender = true;
552
590
  try {
553
- this.measureSize();
591
+ this.syncSize();
554
592
  this.options.onDraw(this.createFrameState(time, delta, gl));
555
593
  this.frame++;
556
594
  } finally {
@@ -564,7 +602,7 @@ var RuntimeHost = class {
564
602
  this.inRender = true;
565
603
  this.captureDrawing = true;
566
604
  try {
567
- this.measureSize();
605
+ this.syncSize();
568
606
  await draw(this.createFrameState(this.elapsed, delta, this.context), signal);
569
607
  this.frame++;
570
608
  } finally {
@@ -614,6 +652,22 @@ var RuntimeHost = class {
614
652
  pointer: this.isManual ? { ...IDLE_POINTER } : { ...this.pointer }
615
653
  };
616
654
  }
655
+ /**
656
+ * Measures the size and calls onResize if it changed. Frames measure too:
657
+ * browsers run animation frames before resize observations, so in a running
658
+ * loop a frame is usually the first to see a new size.
659
+ */
660
+ syncSize() {
661
+ const prevWidth = this.width;
662
+ const prevHeight = this.height;
663
+ const prevViewportWidth = this.viewportWidth;
664
+ const prevViewportHeight = this.viewportHeight;
665
+ this.measureSize();
666
+ const sizeChanged = this.width !== prevWidth || this.height !== prevHeight || this.viewportWidth !== prevViewportWidth || this.viewportHeight !== prevViewportHeight;
667
+ if (sizeChanged && this.context) {
668
+ this.options.onResize?.(this.createFrameState(this.elapsed, 0));
669
+ }
670
+ }
617
671
  measureSize() {
618
672
  if (!this.dom) return;
619
673
  if (this.fixedResolution) {
@@ -666,10 +720,14 @@ var RuntimeHost = class {
666
720
  this.rafId = 0;
667
721
  if (!this.running || this.destroyed) return;
668
722
  const seconds = timestamp / 1e3;
669
- const rawDelta = this.lastTimestamp ? seconds - this.lastTimestamp : 0;
670
- const delta = Math.min(Math.max(rawDelta, 0), MAX_DELTA_SECONDS);
723
+ let delta;
724
+ if (this.followsSource) {
725
+ delta = this.advanceFromSource();
726
+ } else {
727
+ delta = this.lastTimestamp ? clampDelta(seconds - this.lastTimestamp) : 0;
728
+ this.elapsed += delta;
729
+ }
671
730
  this.lastTimestamp = seconds;
672
- this.elapsed += delta;
673
731
  this.renderInternal(this.elapsed, delta);
674
732
  this.scheduleFrame();
675
733
  });
@@ -680,6 +738,7 @@ var RuntimeHost = class {
680
738
  this.rafId = 0;
681
739
  }
682
740
  this.lastTimestamp = 0;
741
+ this.lastSourceTime = null;
683
742
  }
684
743
  async init() {
685
744
  if (typeof window === "undefined" || typeof document === "undefined") {
@@ -868,6 +927,7 @@ var RuntimeHost = class {
868
927
  this.currentStatus = "unsupported";
869
928
  this.debugWarn(error.message);
870
929
  this.options.onError?.(error);
930
+ if (error instanceof UnsupportedError) this.markReadyHandled();
871
931
  this.readyReject?.(error);
872
932
  }
873
933
  fail(error) {
@@ -876,6 +936,12 @@ var RuntimeHost = class {
876
936
  this.options.onError?.(error);
877
937
  this.readyReject?.(error);
878
938
  }
939
+ // Keeps an unawaited `ready` from surfacing as an unhandled rejection, e.g.
940
+ // after a StrictMode cleanup or during SSR. Callers still see the rejection.
941
+ markReadyHandled() {
942
+ this.ready.catch(() => {
943
+ });
944
+ }
879
945
  debugWarn(message) {
880
946
  if (this.options.debug) {
881
947
  console.warn(`[frapx/runtime] ${message}`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/errors.ts","../src/internal/shaderLog.ts","../src/internal/webgl.ts","../src/internal/capture.ts","../src/internal/dom.ts","../src/host.ts","../src/internal/names.ts","../src/internal/uniforms.ts","../src/internal/bindings.ts","../src/internal/textures.ts","../src/internal/textureSet.ts","../src/internal/fullscreenProgram.ts","../src/internal/blit.ts","../src/internal/renderTarget.ts"],"sourcesContent":["export class ShaderError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\n/** One line of a shader compile error, located in the source that was compiled. */\nexport type ShaderErrorLine = {\n /** 1-based line in the compiled source (after `glsl` template interpolation). */\n line: number;\n message: string;\n /** That line of the source, or \"\" when the log points past the end. */\n source: string;\n /** Up to two lines either side, with their numbers, the error line included. */\n context: ReadonlyArray<{ line: number; source: string }>;\n};\n\n/** `\"link\"` for program link errors, which carry no line numbers. */\nexport type ShaderStage = \"vertex\" | \"fragment\" | \"link\";\n\nexport class UnsupportedError extends ShaderError {}\nexport class TargetNotFoundError extends ShaderError {}\nexport class ShaderCompileError extends ShaderError {\n /** The stage that failed, or `null` for errors not tied to compiling a shader. */\n readonly stage: ShaderStage | null;\n /** Errors located in the source, parsed from the driver's info log. Empty when it had none. */\n readonly lines: readonly ShaderErrorLine[];\n\n constructor(\n message: string,\n details: { stage?: ShaderStage; lines?: readonly ShaderErrorLine[] } = {}\n ) {\n super(message);\n this.stage = details.stage ?? null;\n this.lines = details.lines ?? [];\n }\n}\nexport class TextureLoadError extends ShaderError {}\nexport class DestroyedError extends ShaderError {}\n","import type { ShaderErrorLine } from \"./errors\";\n\n// Browsers translate shaders through ANGLE: \"ERROR: 0:12: 'x' : undeclared identifier\".\nconst ANGLE_STYLE = /^\\s*ERROR:\\s*\\d+:(\\d+):\\s*(.*)$/;\n// Native NVIDIA-style drivers: \"0(12) : error C1008: undefined variable\".\nconst NVIDIA_STYLE = /^\\s*\\d+\\((\\d+)\\)\\s*:\\s*error\\s*\\w*\\s*:\\s*(.*)$/i;\n// Follow-up noise after the real error.\nconst NOISE = /compilation terminated|^\\s*''\\s*:\\s*$/i;\n\nconst CONTEXT_LINES = 2;\n\n/**\n * Finds the errors in a shader info log and attaches the source lines they\n * point at. Lines the log does not locate are left out; the log itself stays\n * the error message.\n */\nexport const parseShaderLog = (log: string, source: string): ShaderErrorLine[] => {\n const sourceLines = source.split(/\\r?\\n/);\n const lineAt = (line: number) => sourceLines[line - 1] ?? \"\";\n const results: ShaderErrorLine[] = [];\n const seen = new Set<string>();\n\n for (const entry of log.split(/\\r?\\n/)) {\n const match = ANGLE_STYLE.exec(entry) ?? NVIDIA_STYLE.exec(entry);\n if (!match) continue;\n const line = Number(match[1]);\n const message = match[2]!.trim();\n if (!message || NOISE.test(message)) continue;\n const key = `${line}:${message}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const context: Array<{ line: number; source: string }> = [];\n const first = Math.max(1, line - CONTEXT_LINES);\n const last = Math.min(sourceLines.length, line + CONTEXT_LINES);\n for (let current = first; current <= last; current++) {\n context.push({ line: current, source: lineAt(current) });\n }\n results.push({ line, message, source: lineAt(line), context });\n }\n return results;\n};\n","import type { GLContext } from \"../types\";\nimport { ShaderCompileError } from \"./errors\";\nimport { parseShaderLog } from \"./shaderLog\";\n\nexport const defaultVertexShader = `\nattribute vec2 a_position;\nvarying vec2 v_uv;\n\nvoid main() {\n v_uv = a_position * 0.5 + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n`;\n\nexport const defaultVertexShader300 = `#version 300 es\nin vec2 a_position;\nout vec2 v_uv;\n\nvoid main() {\n v_uv = a_position * 0.5 + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n`;\n\nexport const isGLSL300 = (src: string): boolean =>\n /^\\s*#version\\s+300\\s+es\\b/.test(src);\n\n// Duck-typed instead of `instanceof WebGL2RenderingContext` so this also works\n// against test mocks and other environments where the global constructor may\n// be unavailable.\nexport const isWebGL2Context = (gl: GLContext): gl is WebGL2RenderingContext =>\n typeof (gl as WebGL2RenderingContext).createVertexArray === \"function\";\n\nexport const createProgram = (\n gl: GLContext,\n vertexSource: string,\n fragmentSource: string\n): WebGLProgram => {\n const vertex = compileShader(gl, gl.VERTEX_SHADER, vertexSource);\n let fragment: WebGLShader;\n try {\n fragment = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);\n } catch (error) {\n gl.deleteShader(vertex);\n throw error;\n }\n const program = gl.createProgram();\n\n if (!program) {\n throw new ShaderCompileError(\"Failed to create WebGL program.\");\n }\n\n gl.attachShader(program, vertex);\n gl.attachShader(program, fragment);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const log = gl.getProgramInfoLog(program) ?? \"Unknown program link error.\";\n gl.deleteProgram(program);\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n throw new ShaderCompileError(log, { stage: \"link\" });\n }\n\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n return program;\n};\n\nexport const createFullscreenBuffer = (\n gl: GLContext,\n program: WebGLProgram\n): WebGLBuffer => {\n const buffer = gl.createBuffer();\n if (!buffer) {\n throw new ShaderCompileError(\"Failed to create fullscreen buffer.\");\n }\n\n const location = gl.getAttribLocation(program, \"a_position\");\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),\n gl.STATIC_DRAW\n );\n\n if (location >= 0) {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n};\n\nconst compileShader = (\n gl: GLContext,\n type: number,\n source: string\n): WebGLShader => {\n const shader = gl.createShader(type);\n if (!shader) {\n throw new ShaderCompileError(\"Failed to create WebGL shader.\");\n }\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const log = gl.getShaderInfoLog(shader) ?? \"Unknown shader compile error.\";\n gl.deleteShader(shader);\n throw new ShaderCompileError(log, {\n stage: type === gl.VERTEX_SHADER ? \"vertex\" : \"fragment\",\n lines: parseShaderLog(log, source)\n });\n }\n\n return shader;\n};\n","import type { GLContext } from \"../types\";\nimport { isWebGL2Context } from \"./webgl\";\n\n/**\n * Resolves once the GPU has finished every command submitted so far, polling\n * a fence between tasks. Waiting between heavy draws keeps each submission\n * short, so a long render never trips the browser's GPU watchdog and loses\n * the context. Resolves immediately on WebGL1.\n */\nexport const waitForGpu = (gl: GLContext): Promise<void> => {\n if (!isWebGL2Context(gl)) return Promise.resolve();\n const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);\n if (!sync) return Promise.resolve();\n gl.flush();\n return new Promise((resolve) => {\n const poll = () => {\n const status = gl.clientWaitSync(sync, 0, 0);\n if (status === gl.TIMEOUT_EXPIRED) {\n setTimeout(poll, 4);\n return;\n }\n gl.deleteSync(sync);\n resolve();\n };\n poll();\n });\n};\n\n/**\n * Reads RGBA pixels from `framebuffer` (or the drawing buffer when `null`) and\n * returns them top row first. Must run in the same task as the draw when\n * reading the drawing buffer, since it is not preserved.\n */\nexport const readPixels = <T extends \"rgba8\" | \"rgba16f\">(\n gl: GLContext,\n framebuffer: WebGLFramebuffer | null,\n width: number,\n height: number,\n format: T\n): T extends \"rgba16f\" ? Float32Array : Uint8Array => {\n const length = width * height * 4;\n const data =\n format === \"rgba16f\" ? new Float32Array(length) : new Uint8Array(length);\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n // RGBA/FLOAT is the read combination EXT_color_buffer_float guarantees.\n gl.readPixels(\n 0,\n 0,\n width,\n height,\n gl.RGBA,\n format === \"rgba16f\" ? gl.FLOAT : gl.UNSIGNED_BYTE,\n data\n );\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n flipRows(data, width * 4, height);\n return data as T extends \"rgba16f\" ? Float32Array : Uint8Array;\n};\n\n/** Encodes the canvas as PNG. The snapshot is taken synchronously. */\nexport const canvasToPng = (canvas: HTMLCanvasElement): Promise<Blob> =>\n new Promise((resolve, reject) => {\n canvas.toBlob((blob) => {\n if (blob) resolve(blob);\n else reject(new Error(\"Failed to encode the canvas as PNG.\"));\n }, \"image/png\");\n });\n\n// WebGL reads bottom-up; captures are top row first like images.\nconst flipRows = (\n data: Uint8Array | Float32Array,\n rowLength: number,\n rows: number\n): void => {\n const temp = data.slice(0, rowLength);\n for (let top = 0, bottom = rows - 1; top < bottom; top++, bottom--) {\n const topStart = top * rowLength;\n const bottomStart = bottom * rowLength;\n temp.set(data.subarray(topStart, topStart + rowLength));\n data.copyWithin(topStart, bottomStart, bottomStart + rowLength);\n data.set(temp, bottomStart);\n }\n};\n","import type { DprOption, Resolution, SetupCanvasOptions } from \"../types\";\n\nexport type DomSetup = {\n target: Element;\n canvas: HTMLCanvasElement;\n createdCanvas: boolean;\n restoredPosition: string | null;\n /** True when the canvas was created without being attached to the document. */\n detached?: boolean;\n};\n\nexport type CanvasSize = {\n width: number;\n height: number;\n viewportWidth: number;\n viewportHeight: number;\n};\n\nexport const resolveElement = (\n target: string | Element | undefined\n): Element | null => {\n if (!target) return null;\n if (typeof target === \"string\") return document.querySelector(target);\n return target;\n};\n\nexport const setupCanvas = (options: SetupCanvasOptions): DomSetup | null => {\n const target = resolveElement(options.target);\n const canvas = options.canvas ?? document.createElement(\"canvas\");\n const measurementTarget = target ?? options.canvas;\n\n if (!measurementTarget) {\n if (!options.detached) return null;\n canvas.dataset.frapxCanvas = \"\";\n return {\n target: canvas,\n canvas,\n createdCanvas: true,\n restoredPosition: null,\n detached: true\n };\n }\n\n const createdCanvas = !options.canvas;\n const restoredPosition =\n target && getComputedStyle(target).position === \"static\"\n ? (target as HTMLElement).style.position\n : null;\n\n if (target && restoredPosition !== null) {\n (target as HTMLElement).style.position = \"relative\";\n }\n\n applyCanvasStyle(canvas, options, createdCanvas);\n\n if (options.canvasClass) {\n canvas.classList.add(options.canvasClass);\n }\n\n if (options.canvasStyle) {\n Object.assign(canvas.style, options.canvasStyle);\n }\n\n if (createdCanvas && target) {\n if ((options.layer ?? \"background\") === \"overlay\") {\n target.append(canvas);\n } else {\n target.prepend(canvas);\n }\n }\n\n return {\n target: measurementTarget,\n canvas,\n createdCanvas,\n restoredPosition\n };\n};\n\nexport const resolveDpr = (\n dpr: DprOption | undefined,\n maxDpr: number | undefined\n): number => {\n const raw =\n typeof dpr === \"function\"\n ? dpr()\n : typeof dpr === \"number\"\n ? dpr\n : typeof window === \"undefined\"\n ? 1\n : window.devicePixelRatio || 1;\n\n return Math.max(1, Math.min(raw, maxDpr ?? 2));\n};\n\nexport const resizeCanvasToTarget = (\n canvas: HTMLCanvasElement,\n target: Element,\n dpr: number\n): CanvasSize => {\n const rect = target.getBoundingClientRect();\n const viewportWidth = Math.max(1, rect.width || canvas.clientWidth || 1);\n const viewportHeight = Math.max(1, rect.height || canvas.clientHeight || 1);\n const width = Math.max(1, Math.round(viewportWidth * dpr));\n const height = Math.max(1, Math.round(viewportHeight * dpr));\n\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n\n return { width, height, viewportWidth, viewportHeight };\n};\n\n/**\n * Sizes the canvas to a fixed internal resolution. The viewport size still\n * comes from the target so `u_viewportSize` reflects the displayed size; a\n * detached canvas has no layout, so its viewport equals the resolution.\n */\nexport const resizeCanvasToResolution = (\n canvas: HTMLCanvasElement,\n target: Element | null,\n resolution: Resolution\n): CanvasSize => {\n const [width, height] = resolution;\n let viewportWidth = width;\n let viewportHeight = height;\n\n if (target) {\n const rect = target.getBoundingClientRect();\n viewportWidth = Math.max(1, rect.width || canvas.clientWidth || 1);\n viewportHeight = Math.max(1, rect.height || canvas.clientHeight || 1);\n }\n\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n\n return { width, height, viewportWidth, viewportHeight };\n};\n\nconst applyCanvasStyle = (\n canvas: HTMLCanvasElement,\n options: SetupCanvasOptions,\n shouldPosition: boolean\n): void => {\n canvas.dataset.frapxCanvas = \"\";\n\n if (!shouldPosition) return;\n\n const layer = options.layer ?? \"background\";\n Object.assign(canvas.style, {\n position: \"absolute\",\n inset: \"0\",\n width: \"100%\",\n height: \"100%\",\n display: \"block\",\n pointerEvents: \"none\",\n zIndex: layer === \"overlay\" ? \"1\" : \"0\"\n });\n};\n","import type {\n CaptureFormat,\n CaptureOptions,\n CaptureResult,\n ClockMode,\n GLContext,\n HostFrameState,\n HostPointer,\n Resolution,\n RuntimeHostInstance,\n RuntimeHostOptions,\n ShaderStatus\n} from \"./types\";\nimport { DestroyedError, TargetNotFoundError, UnsupportedError } from \"./internal/errors\";\nimport { canvasToPng, readPixels } from \"./internal/capture\";\nimport {\n resolveDpr,\n resizeCanvasToResolution,\n resizeCanvasToTarget,\n setupCanvas,\n type DomSetup\n} from \"./internal/dom\";\n\nconst MAX_DELTA_SECONDS = 0.1;\n\n// Manual clocks report a neutral pointer so output never depends on input.\nconst IDLE_POINTER: HostPointer = { x: 0, y: 0, uvX: 0, uvY: 0, active: 0 };\n\ntype Gate = \"offscreen\" | \"hidden\" | \"reducedMotion\";\n\nexport const createRuntimeHost = (\n options: RuntimeHostOptions\n): RuntimeHostInstance => {\n return new RuntimeHost(options);\n};\n\nclass RuntimeHost implements RuntimeHostInstance {\n readonly ready: Promise<void>;\n\n private readonly options: RuntimeHostOptions;\n private readyResolve: (() => void) | null = null;\n private readyReject: ((error: Error) => void) | null = null;\n private dom: DomSetup | null = null;\n private context: GLContext | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private intersectionObserver: IntersectionObserver | null = null;\n private rafId = 0;\n private running = false;\n private inRender = false;\n private captureDrawing = false;\n private resizePending = false;\n private destroyed = false;\n private gates = new Set<Gate>();\n private reducedMotionActive = false;\n private frame = 0;\n private elapsed = 0;\n private lastTimestamp = 0;\n private pixelRatio = 1;\n private width = 1;\n private height = 1;\n private viewportWidth = 1;\n private viewportHeight = 1;\n private pointer = { x: 0, y: 0, uvX: 0, uvY: 0, active: 0 };\n private removeListeners: Array<() => void> = [];\n private currentStatus: ShaderStatus = \"idle\";\n private contextRestoredShouldRun = false;\n private statusBeforeLoss: ShaderStatus = \"idle\";\n private clockMode: ClockMode;\n private manualDelta = 0;\n private lastManualTime: number | null = null;\n private fixedResolution: Resolution | null;\n private objectFitRestore: string | null = null;\n // Letterbox offset (CSS px) of the contained canvas content inside the target.\n private contentOffsetX = 0;\n private contentOffsetY = 0;\n\n constructor(options: RuntimeHostOptions) {\n this.options = options;\n this.clockMode = options.clock ?? \"realtime\";\n this.fixedResolution = options.resolution\n ? normalizeResolution(options.resolution)\n : null;\n this.ready = new Promise<void>((resolve, reject) => {\n this.readyResolve = resolve;\n this.readyReject = reject;\n });\n queueMicrotask(() => {\n void this.init();\n });\n }\n\n get canvas(): HTMLCanvasElement | null {\n return this.dom?.canvas ?? null;\n }\n\n get gl(): GLContext | null {\n return this.context;\n }\n\n get status(): ShaderStatus {\n return this.currentStatus;\n }\n\n get supported(): boolean {\n return ![\"unsupported\", \"destroyed\"].includes(this.currentStatus);\n }\n\n get clock(): ClockMode {\n return this.clockMode;\n }\n\n start(): void {\n if (this.destroyed || this.currentStatus === \"unsupported\") return;\n this.running = true;\n this.reconcile();\n }\n\n stop(): void {\n this.running = false;\n this.cancelFrame();\n if (!this.destroyed && this.currentStatus !== \"unsupported\") {\n this.currentStatus = \"paused\";\n }\n }\n\n render(): void {\n if (\n this.destroyed ||\n !this.dom ||\n !this.context ||\n this.currentStatus === \"unsupported\" ||\n this.inRender\n )\n return;\n\n if (this.isManual) {\n // The caller decides when to draw; visibility gates do not apply.\n this.renderInternal(this.elapsed, this.manualDelta);\n return;\n }\n\n if (this.hasVisibilityBlock) return;\n this.renderInternal(this.elapsed, 0);\n }\n\n setTime(seconds: number): void {\n if (!Number.isFinite(seconds)) {\n throw new RangeError(`setTime() expects a finite number, got ${seconds}`);\n }\n if (this.destroyed) return;\n\n if (this.isManual) {\n this.manualDelta =\n this.lastManualTime === null ? 0 : seconds - this.lastManualTime;\n this.lastManualTime = seconds;\n }\n this.elapsed = seconds;\n }\n\n setClock(clock: ClockMode): void {\n if (this.destroyed || clock === this.clockMode) return;\n this.clockMode = clock;\n this.manualDelta = 0;\n this.lastManualTime = null;\n // Gates kept tracking while manual, so this resumes against current state.\n this.reconcile();\n }\n\n setResolution(resolution: Resolution | null): void {\n if (this.destroyed) return;\n\n if (resolution === null) {\n if (this.isDetached) {\n throw new TypeError(\n \"A canvas without a target needs a fixed resolution.\"\n );\n }\n this.fixedResolution = null;\n } else {\n const next = normalizeResolution(resolution);\n if (this.context) assertWithinLimits(this.context, next);\n this.fixedResolution = next;\n }\n\n this.applyObjectFit();\n this.resize();\n }\n\n async captureFrame<F extends CaptureFormat = \"png\">(\n options: CaptureOptions<F> = {}\n ): Promise<CaptureResult<F>> {\n const format: CaptureFormat = options.format ?? \"png\";\n if (format !== \"png\" && format !== \"rgba8\" && format !== \"rgba16f\") {\n throw new RangeError(`Unknown capture format: ${String(format)}`);\n }\n\n await this.ready;\n if (this.destroyed) {\n throw new DestroyedError(\"Runtime host was destroyed.\");\n }\n if (!this.dom || !this.context) {\n throw new UnsupportedError(\"Cannot capture without a WebGL context.\");\n }\n if (this.inRender) {\n throw new Error(\"captureFrame() cannot be called while a frame is drawing.\");\n }\n\n // Check before drawing so a rejected capture has no side effects.\n const sourceFormat = this.options.captureSource?.()?.format;\n if (format === \"rgba16f\" && sourceFormat !== \"rgba16f\" && sourceFormat !== \"rgba32f\") {\n throw new UnsupportedError(\n \"rgba16f capture needs a float render target, such as feedback with format rgba16f.\"\n );\n }\n options.signal?.throwIfAborted();\n\n const delta = this.isManual ? this.manualDelta : 0;\n const drawContext = this.context;\n if (!this.options.onCaptureDraw) {\n this.renderInternal(this.elapsed, delta);\n return this.readCapture(format, drawContext);\n }\n\n try {\n await this.renderForCapture(this.options.onCaptureDraw, delta, options.signal);\n return this.readCapture(format, drawContext);\n } finally {\n // Resizes requested while drawing apply once the frame is read.\n if (this.resizePending) {\n this.resizePending = false;\n this.resize();\n }\n }\n }\n\n resize(): void {\n if (this.destroyed || !this.dom) return;\n // Keep the size an asynchronous capture draw started with until it is read.\n if (this.captureDrawing) {\n this.resizePending = true;\n return;\n }\n\n const prevWidth = this.width;\n const prevHeight = this.height;\n const prevViewportWidth = this.viewportWidth;\n const prevViewportHeight = this.viewportHeight;\n\n this.measureSize();\n\n const sizeChanged =\n this.width !== prevWidth ||\n this.height !== prevHeight ||\n this.viewportWidth !== prevViewportWidth ||\n this.viewportHeight !== prevViewportHeight;\n\n if (sizeChanged && this.context) {\n this.options.onResize?.(this.createFrameState(this.elapsed, 0));\n }\n\n if (this.shouldRenderOnDemand && !this.inRender) {\n this.render();\n }\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.running = false;\n this.cancelFrame();\n this.resizeObserver?.disconnect();\n this.intersectionObserver?.disconnect();\n\n for (const remove of this.removeListeners) remove();\n this.removeListeners = [];\n\n this.context = null;\n\n if (this.dom?.createdCanvas) {\n this.dom.canvas.remove();\n } else if (this.dom && this.objectFitRestore !== null) {\n this.dom.canvas.style.objectFit = this.objectFitRestore;\n }\n\n const dom = this.dom;\n if (dom?.restoredPosition !== null && dom && this.options.target) {\n (dom.target as HTMLElement).style.position = dom.restoredPosition!;\n }\n\n this.currentStatus = \"destroyed\";\n this.readyReject?.(new DestroyedError(\"Runtime host was destroyed.\"));\n }\n\n private get isManual(): boolean {\n return this.clockMode === \"manual\";\n }\n\n private get isDetached(): boolean {\n if (this.dom) return this.dom.detached === true;\n return this.options.target === undefined && this.options.canvas === undefined;\n }\n\n // Demand mode re-renders on input changes, except under a manual clock where\n // only explicit render() calls draw.\n private get shouldRenderOnDemand(): boolean {\n return this.options.renderMode === \"demand\" && !this.isManual;\n }\n\n private get hasVisibilityBlock(): boolean {\n return this.gates.has(\"offscreen\") || this.gates.has(\"hidden\");\n }\n\n private get hasMotionBlock(): boolean {\n return (\n this.gates.has(\"reducedMotion\") && this.options.renderMode !== \"demand\"\n );\n }\n\n private setGate(gate: Gate, closed: boolean): void {\n if (closed === this.gates.has(gate)) return;\n if (closed) this.gates.add(gate);\n else this.gates.delete(gate);\n this.reconcile();\n }\n\n private reconcile(): void {\n if (\n this.destroyed ||\n this.currentStatus === \"unsupported\" ||\n this.currentStatus === \"error\" ||\n this.currentStatus === \"context-lost\"\n ) {\n return;\n }\n\n if (this.isManual) {\n this.cancelFrame();\n this.currentStatus = \"paused\";\n return;\n }\n\n if (this.running) {\n if (this.hasVisibilityBlock) {\n this.cancelFrame();\n this.currentStatus = \"paused\";\n return;\n }\n\n if (this.hasMotionBlock) {\n this.cancelFrame();\n this.currentStatus = \"paused\";\n this.renderStaticFrame();\n return;\n }\n\n this.currentStatus = \"running\";\n if (this.options.renderMode === \"demand\") this.render();\n else this.scheduleFrame();\n return;\n }\n\n if (this.options.renderMode === \"demand\") this.render();\n }\n\n private renderStaticFrame(): void {\n if (this.hasVisibilityBlock) return;\n this.renderInternal(this.elapsed, 0);\n }\n\n private renderInternal(time: number, delta: number): void {\n // An asynchronous capture draw holds the lock across tasks.\n if (!this.dom || !this.context || this.inRender) return;\n const gl = this.context;\n\n this.inRender = true;\n try {\n this.measureSize();\n this.options.onDraw(this.createFrameState(time, delta, gl));\n this.frame++;\n } finally {\n this.inRender = false;\n }\n }\n\n // Holds the render lock across an asynchronous capture draw so no other\n // frame interleaves with it.\n private async renderForCapture(\n draw: NonNullable<RuntimeHostOptions[\"onCaptureDraw\"]>,\n delta: number,\n signal: AbortSignal | undefined\n ): Promise<void> {\n if (!this.dom || !this.context) return;\n this.inRender = true;\n this.captureDrawing = true;\n try {\n this.measureSize();\n await draw(this.createFrameState(this.elapsed, delta, this.context), signal);\n this.frame++;\n } finally {\n this.inRender = false;\n this.captureDrawing = false;\n }\n }\n\n // Reads the frame just drawn, in the task that drew it: the drawing buffer\n // is not preserved. Fails if the context drawn into is gone, including when\n // it was lost and restored while an asynchronous draw was pending.\n private readCapture<F extends CaptureFormat>(\n format: CaptureFormat,\n drawContext: GLContext | null\n ): Promise<CaptureResult<F>> | CaptureResult<F> {\n if (this.destroyed) {\n throw new DestroyedError(\"Runtime host was destroyed.\");\n }\n const gl = this.context;\n if (!gl || gl !== drawContext || !this.dom) {\n throw new UnsupportedError(\"The WebGL context was lost while capturing.\");\n }\n\n if (format === \"png\") {\n return canvasToPng(this.dom.canvas) as Promise<CaptureResult<F>>;\n }\n if (format === \"rgba8\") {\n return readPixels(gl, null, this.width, this.height, \"rgba8\") as CaptureResult<F>;\n }\n const source = this.options.captureSource!()!;\n return readPixels(\n gl,\n source.framebuffer,\n source.width,\n source.height,\n \"rgba16f\"\n ) as CaptureResult<F>;\n }\n\n private createFrameState(\n time: number,\n delta: number,\n gl: GLContext = this.context!\n ): HostFrameState {\n return {\n gl,\n canvas: this.dom!.canvas,\n time,\n delta,\n frame: this.frame,\n width: this.width,\n height: this.height,\n viewportWidth: this.viewportWidth,\n viewportHeight: this.viewportHeight,\n pixelRatio: this.pixelRatio,\n reducedMotion: this.isManual ? false : this.reducedMotionActive,\n pointer: this.isManual ? { ...IDLE_POINTER } : { ...this.pointer }\n };\n }\n\n private measureSize(): void {\n if (!this.dom) return;\n\n if (this.fixedResolution) {\n const size = resizeCanvasToResolution(\n this.dom.canvas,\n this.dom.detached ? null : this.dom.target,\n this.fixedResolution\n );\n this.width = size.width;\n this.height = size.height;\n this.viewportWidth = size.viewportWidth;\n this.viewportHeight = size.viewportHeight;\n // Internal pixels per displayed CSS pixel under object-fit: contain.\n this.pixelRatio = Math.max(\n size.width / size.viewportWidth,\n size.height / size.viewportHeight\n );\n this.contentOffsetX =\n (size.viewportWidth - size.width / this.pixelRatio) / 2;\n this.contentOffsetY =\n (size.viewportHeight - size.height / this.pixelRatio) / 2;\n return;\n }\n\n this.contentOffsetX = 0;\n this.contentOffsetY = 0;\n this.pixelRatio = resolveDpr(this.options.dpr, this.options.maxDpr);\n const size = resizeCanvasToTarget(\n this.dom.canvas,\n this.dom.target,\n this.pixelRatio\n );\n this.width = size.width;\n this.height = size.height;\n this.viewportWidth = size.viewportWidth;\n this.viewportHeight = size.viewportHeight;\n }\n\n // Letterbox the fixed-resolution canvas instead of stretching it.\n private applyObjectFit(): void {\n if (!this.dom) return;\n const style = this.dom.canvas.style;\n if (this.fixedResolution && this.objectFitRestore === null) {\n this.objectFitRestore = style.objectFit ?? \"\";\n style.objectFit = \"contain\";\n } else if (!this.fixedResolution && this.objectFitRestore !== null) {\n style.objectFit = this.objectFitRestore;\n this.objectFitRestore = null;\n }\n }\n\n private scheduleFrame(): void {\n if (this.rafId || this.options.renderMode === \"demand\" || this.isManual)\n return;\n\n this.rafId = requestAnimationFrame((timestamp) => {\n this.rafId = 0;\n if (!this.running || this.destroyed) return;\n\n const seconds = timestamp / 1000;\n const rawDelta = this.lastTimestamp ? seconds - this.lastTimestamp : 0;\n const delta = Math.min(Math.max(rawDelta, 0), MAX_DELTA_SECONDS);\n this.lastTimestamp = seconds;\n this.elapsed += delta;\n this.renderInternal(this.elapsed, delta);\n this.scheduleFrame();\n });\n }\n\n private cancelFrame(): void {\n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = 0;\n }\n this.lastTimestamp = 0;\n }\n\n private async init(): Promise<void> {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n this.failUnsupported(new UnsupportedError(\"WebGL requires a browser.\"));\n return;\n }\n\n this.dom = setupCanvas({\n ...(this.options.target !== undefined && { target: this.options.target }),\n ...(this.options.canvas !== undefined && { canvas: this.options.canvas }),\n ...(this.options.layer !== undefined && { layer: this.options.layer }),\n ...(this.options.canvasClass !== undefined && { canvasClass: this.options.canvasClass }),\n ...(this.options.canvasStyle !== undefined && { canvasStyle: this.options.canvasStyle }),\n // Only a missing target/canvas may fall back to a detached canvas; a\n // target that fails to resolve must still report TargetNotFoundError.\n detached:\n this.fixedResolution !== null &&\n this.options.target === undefined &&\n this.options.canvas === undefined\n });\n\n if (!this.dom) {\n this.failUnsupported(\n new TargetNotFoundError(\n \"Target or canvas not found. Pass `resolution` to render without a target.\"\n )\n );\n return;\n }\n\n let gl: GLContext | null;\n try {\n gl = this.options.createContext(this.dom.canvas);\n } catch (error) {\n this.failUnsupported(\n error instanceof UnsupportedError\n ? error\n : new UnsupportedError(String(error))\n );\n return;\n }\n if (!gl) {\n this.failUnsupported(new UnsupportedError(\"WebGL is not supported.\"));\n return;\n }\n\n if (this.fixedResolution) {\n try {\n assertWithinLimits(gl, this.fixedResolution);\n } catch (error) {\n this.failUnsupported(\n error instanceof Error ? error : new UnsupportedError(String(error))\n );\n return;\n }\n if (this.options.dpr !== undefined || this.options.maxDpr !== undefined) {\n this.debugWarn(\"`dpr` and `maxDpr` are ignored while `resolution` is set.\");\n }\n }\n\n this.context = gl;\n this.currentStatus = \"loading\";\n\n try {\n this.applyObjectFit();\n this.setupDomObservers();\n this.setupContextEvents();\n this.measureSize();\n await this.options.onInit(gl, this.width, this.height);\n if (this.destroyed) return;\n this.currentStatus = \"ready\";\n this.readyResolve?.();\n this.options.onReady?.();\n\n if (this.running || (this.options.autoStart ?? true)) {\n this.start();\n } else if (this.shouldRenderOnDemand) {\n this.render();\n }\n } catch (error) {\n if (error instanceof UnsupportedError) this.failUnsupported(error);\n else this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n private setupDomObservers(): void {\n if (!this.dom) return;\n const detached = this.dom.detached === true;\n\n // A detached canvas has no layout: it can never be measured, scrolled into\n // view or pointed at, so only document-level observers apply.\n if (!detached && (this.options.autoResize ?? true)) {\n this.resizeObserver = new ResizeObserver(() => {\n this.resize();\n });\n this.resizeObserver.observe(this.dom.target);\n }\n\n if (!detached && (this.options.pauseWhenOffscreen ?? true)) {\n this.intersectionObserver = new IntersectionObserver((entries) => {\n const entry = entries[0];\n this.setGate(\"offscreen\", !entry?.isIntersecting);\n });\n this.intersectionObserver.observe(this.dom.target);\n }\n\n if (this.options.pauseWhenHidden ?? true) {\n if (document.hidden) this.gates.add(\"hidden\");\n const onVisibility = () => {\n this.setGate(\"hidden\", document.hidden);\n };\n document.addEventListener(\"visibilitychange\", onVisibility);\n this.removeListeners.push(() => {\n document.removeEventListener(\"visibilitychange\", onVisibility);\n });\n }\n\n this.setupMotionObserver();\n\n if (detached) return;\n\n const onPointerMove = (event: Event) => {\n if (!this.dom) return;\n const pointerEvent = event as PointerEvent;\n const rect = this.dom.target.getBoundingClientRect();\n const x = pointerEvent.clientX - rect.left - this.contentOffsetX;\n const y = pointerEvent.clientY - rect.top - this.contentOffsetY;\n // Displayed content size in CSS px (smaller than rect when letterboxed).\n const contentWidth = this.fixedResolution\n ? this.width / this.pixelRatio\n : rect.width;\n const contentHeight = this.fixedResolution\n ? this.height / this.pixelRatio\n : rect.height;\n this.pointer.x = x * this.pixelRatio;\n this.pointer.y = (contentHeight - y) * this.pixelRatio;\n this.pointer.uvX = contentWidth > 0 ? x / contentWidth : 0;\n this.pointer.uvY = contentHeight > 0 ? 1 - y / contentHeight : 0;\n this.pointer.active = 1;\n\n if (this.shouldRenderOnDemand) this.render();\n };\n const onPointerLeave = () => {\n this.pointer.active = 0;\n if (this.shouldRenderOnDemand) this.render();\n };\n\n this.dom.target.addEventListener(\"pointermove\", onPointerMove);\n this.dom.target.addEventListener(\"pointerenter\", onPointerMove);\n this.dom.target.addEventListener(\"pointerleave\", onPointerLeave);\n this.removeListeners.push(() => {\n this.dom?.target.removeEventListener(\"pointermove\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerenter\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerleave\", onPointerLeave);\n });\n }\n\n private setupMotionObserver(): void {\n if (typeof window.matchMedia !== \"function\") return;\n\n const query = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n this.reducedMotionActive = query.matches;\n if (this.options.respectReducedMotion && query.matches) {\n this.gates.add(\"reducedMotion\");\n }\n\n const onChange = (event: MediaQueryListEvent) => {\n this.reducedMotionActive = event.matches;\n if (this.options.respectReducedMotion) {\n this.setGate(\"reducedMotion\", event.matches);\n } else if (this.shouldRenderOnDemand) {\n this.render();\n }\n };\n\n query.addEventListener(\"change\", onChange);\n this.removeListeners.push(() => {\n query.removeEventListener(\"change\", onChange);\n });\n }\n\n private setupContextEvents(): void {\n if (!this.dom) return;\n\n const onLost = (event: Event) => {\n event.preventDefault();\n this.contextRestoredShouldRun = this.running;\n this.statusBeforeLoss = this.currentStatus;\n this.cancelFrame();\n this.context = null;\n this.currentStatus = \"context-lost\";\n this.options.onContextLost?.();\n this.options.onError?.(new UnsupportedError(\"WebGL context lost.\"));\n };\n\n const onRestored = () => {\n if (!this.dom || this.destroyed) return;\n const gl = this.options.createContext(this.dom.canvas);\n if (!gl) return;\n this.context = gl;\n\n const afterRestore = async () => {\n try {\n await this.options.onContextRestored?.(gl, this.width, this.height);\n // A stopped or manual-clock instance would otherwise stay\n // \"context-lost\", and render() would refuse to draw.\n if (this.currentStatus === \"context-lost\") this.currentStatus = this.statusBeforeLoss;\n if (this.contextRestoredShouldRun) this.start();\n else if (!this.isManual) this.render();\n } catch (error) {\n this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n };\n void afterRestore();\n };\n\n this.dom.canvas.addEventListener(\"webglcontextlost\", onLost);\n this.dom.canvas.addEventListener(\"webglcontextrestored\", onRestored);\n this.removeListeners.push(() => {\n this.dom?.canvas.removeEventListener(\"webglcontextlost\", onLost);\n this.dom?.canvas.removeEventListener(\"webglcontextrestored\", onRestored);\n });\n }\n\n private failUnsupported(error: Error): void {\n this.currentStatus = \"unsupported\";\n this.debugWarn(error.message);\n this.options.onError?.(error);\n this.readyReject?.(error);\n }\n\n private fail(error: Error): void {\n this.currentStatus = \"error\";\n this.debugWarn(error.message);\n this.options.onError?.(error);\n this.readyReject?.(error);\n }\n\n private debugWarn(message: string): void {\n if (this.options.debug) {\n console.warn(`[frapx/runtime] ${message}`);\n }\n }\n}\n\nconst normalizeResolution = (resolution: Resolution): Resolution => {\n const [width, height] = resolution;\n if (\n !Number.isFinite(width) ||\n !Number.isFinite(height) ||\n width < 1 ||\n height < 1\n ) {\n throw new RangeError(`Invalid resolution: ${width}x${height}`);\n }\n return [Math.round(width), Math.round(height)];\n};\n\nconst assertWithinLimits = (gl: GLContext, resolution: Resolution): void => {\n const [width, height] = resolution;\n const viewportDims = gl.getParameter(gl.MAX_VIEWPORT_DIMS) as\n | ArrayLike<number>\n | null;\n const renderbufferSize = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE) as\n | number\n | null;\n const limit = (axis: 0 | 1): number =>\n Math.min(\n viewportDims?.[axis] ?? Number.POSITIVE_INFINITY,\n typeof renderbufferSize === \"number\"\n ? renderbufferSize\n : Number.POSITIVE_INFINITY\n );\n\n if (width > limit(0) || height > limit(1)) {\n throw new UnsupportedError(\n `Resolution ${width}x${height} exceeds this GPU's limit of ${limit(0)}x${limit(1)}.`\n );\n }\n};\n","export const toUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name : `u_${name}`;\n\nexport const fromUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name.slice(2) : name;\n","import type { ExplicitUniformInput, GLContext, UniformInput, UniformType } from \"../types\";\nimport { toUniformName } from \"./names\";\n\nexport type NormalizedUniform = {\n type: UniformType;\n value: number[] | Float32Array;\n};\n\nexport const normalizeUniform = (input: UniformInput): NormalizedUniform => {\n if (typeof input === \"number\") {\n return { type: \"float\", value: [input] };\n }\n\n if (input instanceof Float32Array) {\n if (input.length === 9) return { type: \"mat3\", value: input };\n if (input.length === 16) return { type: \"mat4\", value: input };\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n if (isExplicitUniform(input)) {\n return { type: input.type, value: input.value };\n }\n\n if (Array.isArray(input)) {\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n return { type: \"float\", value: [0] };\n};\n\nexport const applyUniform = (\n gl: GLContext,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n const value = uniform.value;\n\n switch (uniform.type) {\n case \"float\":\n gl.uniform1f(location, value[0] ?? 0);\n break;\n case \"vec2\":\n gl.uniform2f(location, value[0] ?? 0, value[1] ?? 0);\n break;\n case \"vec3\":\n gl.uniform3f(location, value[0] ?? 0, value[1] ?? 0, value[2] ?? 0);\n break;\n case \"vec4\":\n gl.uniform4f(\n location,\n value[0] ?? 0,\n value[1] ?? 0,\n value[2] ?? 0,\n value[3] ?? 0\n );\n break;\n case \"mat3\":\n gl.uniformMatrix3fv(location, false, value);\n break;\n case \"mat4\":\n gl.uniformMatrix4fv(location, false, value);\n break;\n }\n};\n\nexport const applyProgramUniform = (\n gl: GLContext,\n program: WebGLProgram,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n gl.useProgram(program);\n applyUniform(gl, location, uniform);\n};\n\n/**\n * Uploads every cached uniform to the bound program. Calls `onMissing` with\n * the name of each uniform the program lacks or optimized out.\n */\nexport const applyUniforms = (\n gl: GLContext,\n locations: ReadonlyMap<string, WebGLUniformLocation>,\n cache: ReadonlyMap<string, NormalizedUniform>,\n onMissing?: (name: string) => void\n): void => {\n for (const [name, uniform] of cache) {\n const location = locations.get(name);\n if (!location) {\n onMissing?.(name);\n continue;\n }\n applyUniform(gl, location, uniform);\n }\n};\n\nexport const collectUniformLocations = (\n gl: GLContext,\n program: WebGLProgram\n): Map<string, WebGLUniformLocation> => {\n const locations = new Map<string, WebGLUniformLocation>();\n const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS) as number;\n\n for (let index = 0; index < count; index += 1) {\n const active = gl.getActiveUniform(program, index);\n if (!active) continue;\n\n const name = active.name.replace(/\\[0\\]$/, \"\");\n const location = gl.getUniformLocation(program, name);\n if (location) {\n locations.set(name, location);\n }\n }\n\n return locations;\n};\n\nexport const createUniformCache = (\n uniforms: Record<string, UniformInput> | undefined\n): Map<string, NormalizedUniform> => {\n const cache = new Map<string, NormalizedUniform>();\n\n for (const [name, value] of Object.entries(uniforms ?? {})) {\n cache.set(toUniformName(name), normalizeUniform(value));\n }\n\n return cache;\n};\n\nconst isExplicitUniform = (input: unknown): input is ExplicitUniformInput => {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) return false;\n return \"type\" in input && \"value\" in input;\n};\n","import type { UniformInput } from \"../types\";\nimport { toUniformName } from \"./names\";\nimport { normalizeUniform, type NormalizedUniform } from \"./uniforms\";\n\n/**\n * Supplies uniform values for a time, such as a keyframe timeline. Runtimes\n * call `get()` with the same time as `u_time` before drawing.\n */\nexport type UniformSource = {\n get(time: number): Readonly<Record<string, UniformInput>>;\n};\n\n/** Ordered sources whose values override the runtime's own uniforms. */\nexport type UniformBindings = {\n /** Adds `source`; a later source wins for the same name. Returns its removal. */\n add(source: UniformSource): () => void;\n readonly size: number;\n /** Merged, normalized values at `time`, keyed by uniform name (`u_` prefixed). */\n evaluate(time: number): Map<string, NormalizedUniform>;\n /** A stable string of the values at `time`, to notice when they change. */\n signature(time: number): string;\n};\n\nexport const createUniformBindings = (): UniformBindings => {\n const sources: UniformSource[] = [];\n\n const evaluate = (time: number): Map<string, NormalizedUniform> => {\n const merged = new Map<string, NormalizedUniform>();\n for (const source of sources) {\n for (const [name, value] of Object.entries(source.get(time))) {\n merged.set(toUniformName(name), normalizeUniform(value));\n }\n }\n return merged;\n };\n\n return {\n add(source) {\n sources.push(source);\n let removed = false;\n return () => {\n if (removed) return;\n removed = true;\n const index = sources.indexOf(source);\n if (index >= 0) sources.splice(index, 1);\n };\n },\n get size() {\n return sources.length;\n },\n evaluate,\n signature(time) {\n if (sources.length === 0) return \"\";\n let text = \"\";\n for (const [name, uniform] of evaluate(time)) {\n text += `${name}:${uniform.type}:${Array.from(uniform.value).join(\",\")};`;\n }\n return text;\n }\n };\n};\n\n// --- Keyframes -------------------------------------------------------------------\n\nexport type KeyframeValue =\n | number\n | readonly [number, number]\n | readonly [number, number, number]\n | readonly [number, number, number, number];\n\n/** `[time in seconds, value]`. */\nexport type Keyframe = readonly [number, KeyframeValue];\n\n/**\n * How a segment eases from one key to the next: `\"linear\"`, `\"smooth\"`\n * (smoothstep), `\"step\"` (hold the earlier key), or a function of the\n * segment's 0–1 progress.\n */\nexport type Ease = \"linear\" | \"smooth\" | \"step\" | ((t: number) => number);\n\nexport type KeyframeTrack = readonly Keyframe[] | { keys: readonly Keyframe[]; ease?: Ease };\n\nexport type KeyframeOptions = {\n /** Default ease for tracks that do not set their own. Defaults to `\"linear\"`. */\n ease?: Ease;\n};\n\nconst EASES: Record<Exclude<Ease, (t: number) => number>, (t: number) => number> = {\n linear: (t) => t,\n smooth: (t) => t * t * (3 - 2 * t),\n step: () => 0\n};\n\nconst toEaseFunction = (ease: Ease): ((t: number) => number) => {\n if (typeof ease === \"function\") return ease;\n const fn = EASES[ease];\n if (!fn) throw new RangeError(`Unknown ease: ${String(ease)}`);\n return fn;\n};\n\nconst componentsOf = (value: KeyframeValue): readonly number[] =>\n typeof value === \"number\" ? [value] : value;\n\ntype CompiledTrack = {\n times: number[];\n values: Array<readonly number[]>;\n scalar: boolean;\n ease: (t: number) => number;\n};\n\nconst isKeyList = (track: KeyframeTrack): track is readonly Keyframe[] => Array.isArray(track);\n\nconst compileTrack = (name: string, track: KeyframeTrack, fallback: Ease): CompiledTrack => {\n // Not `\"keys\" in track`: arrays have a keys() method.\n const list = isKeyList(track);\n const keys = list ? track : track.keys;\n const ease = toEaseFunction((list ? undefined : track.ease) ?? fallback);\n if (keys.length === 0) throw new TypeError(`Keyframe track ${name} has no keys.`);\n\n const sorted = [...keys].sort((a, b) => a[0] - b[0]);\n const scalar = typeof sorted[0]![1] === \"number\";\n const size = componentsOf(sorted[0]![1]).length;\n for (const [time, value] of sorted) {\n if (!Number.isFinite(time)) throw new TypeError(`Keyframe track ${name} has a non-finite time.`);\n const components = componentsOf(value);\n if ((typeof value === \"number\") !== scalar || components.length !== size) {\n throw new TypeError(`Keyframe track ${name} mixes values of different sizes.`);\n }\n if (!components.every(Number.isFinite)) {\n throw new TypeError(`Keyframe track ${name} has a non-finite value.`);\n }\n }\n return {\n times: sorted.map(([time]) => time),\n values: sorted.map(([, value]) => componentsOf(value)),\n scalar,\n ease\n };\n};\n\nconst sampleTrack = (track: CompiledTrack, time: number): UniformInput => {\n const { times, values } = track;\n const last = times.length - 1;\n let components: readonly number[];\n if (time <= times[0]!) {\n components = values[0]!;\n } else if (time >= times[last]!) {\n components = values[last]!;\n } else {\n // The last key at or before `time`.\n let low = 0;\n let high = last;\n while (high - low > 1) {\n const middle = (low + high) >> 1;\n if (times[middle]! <= time) low = middle;\n else high = middle;\n }\n const span = times[high]! - times[low]!;\n const t = span > 0 ? track.ease((time - times[low]!) / span) : 0;\n const from = values[low]!;\n const to = values[high]!;\n components = from.map((value, index) => value + (to[index]! - value) * t);\n }\n return track.scalar ? components[0]! : (Array.from(components) as UniformInput);\n};\n\n/**\n * A `UniformSource` that interpolates keyframes per component: floats and\n * vec2–vec4 as tuples. Keys may come in any order; times before the first key\n * or after the last hold that key's value.\n *\n * ```ts\n * fx.bindUniforms(keyframes({\n * camPos: [[0, [0, 1, 6]], [4, [3, 1.5, 2]]],\n * glow: { keys: [[0, 0], [2, 1]], ease: \"smooth\" }\n * }));\n * ```\n */\nexport const keyframes = (\n tracks: Readonly<Record<string, KeyframeTrack>>,\n options: KeyframeOptions = {}\n): UniformSource => {\n const fallback = options.ease ?? \"linear\";\n toEaseFunction(fallback);\n const compiled = Object.entries(tracks).map(\n ([name, track]) => [name, compileTrack(name, track, fallback)] as const\n );\n return {\n get(time) {\n const values: Record<string, UniformInput> = {};\n for (const [name, track] of compiled) values[name] = sampleTrack(track, time);\n return values;\n }\n };\n};\n","import type { GLContext, TextureInput, TextureOptions, TextureSource } from \"../types\";\nimport { TextureLoadError } from \"./errors\";\nimport { toUniformName } from \"./names\";\n\nexport type LoadedTexture = {\n name: string;\n uniformName: string;\n sizeUniformName: string;\n texture: WebGLTexture;\n width: number;\n height: number;\n};\n\nexport const loadTexture = async (\n gl: GLContext,\n name: string,\n input: TextureInput,\n unit: number\n): Promise<LoadedTexture> => {\n const options = normalizeTextureInput(input);\n const source = await resolveSource(options.source);\n const texture = gl.createTexture();\n\n if (!texture) {\n throw new TextureLoadError(`Failed to create texture: ${name}`);\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, options.flipY ?? true);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);\n\n const wrap = getWrap(gl, options.wrap ?? \"clamp\");\n const filter = getFilter(gl, options.filter ?? \"linear\");\n\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n return {\n name,\n uniformName: toUniformName(name),\n sizeUniformName: toUniformName(`${name}Size`),\n texture,\n width: getSourceWidth(source),\n height: getSourceHeight(source)\n };\n};\n\nconst normalizeTextureInput = (input: TextureInput): TextureOptions => {\n if (typeof input === \"string\" || isTextureSource(input)) {\n return { source: input };\n }\n\n return input;\n};\n\nconst resolveSource = async (\n source: TextureSource\n): Promise<HTMLImageElement | HTMLCanvasElement> => {\n if (typeof source !== \"string\") {\n return source;\n }\n\n const image = new Image();\n image.crossOrigin = \"anonymous\";\n image.src = source;\n\n try {\n await image.decode();\n } catch {\n throw new TextureLoadError(`Failed to load texture: ${source}`);\n }\n\n return image;\n};\n\nconst getWrap = (\n gl: GLContext,\n wrap: NonNullable<TextureOptions[\"wrap\"]>\n): number => {\n if (wrap === \"repeat\") return gl.REPEAT;\n if (wrap === \"mirror\") return gl.MIRRORED_REPEAT;\n return gl.CLAMP_TO_EDGE;\n};\n\nconst getFilter = (\n gl: GLContext,\n filter: NonNullable<TextureOptions[\"filter\"]>\n): number => (filter === \"nearest\" ? gl.NEAREST : gl.LINEAR);\n\nconst isTextureSource = (\n input: unknown\n): input is HTMLImageElement | HTMLCanvasElement =>\n typeof HTMLImageElement !== \"undefined\" &&\n (input instanceof HTMLImageElement || input instanceof HTMLCanvasElement);\n\nconst getSourceWidth = (\n source: HTMLImageElement | HTMLCanvasElement\n): number =>\n \"naturalWidth\" in source ? source.naturalWidth : source.width;\n\nconst getSourceHeight = (\n source: HTMLImageElement | HTMLCanvasElement\n): number =>\n \"naturalHeight\" in source ? source.naturalHeight : source.height;\n","import type { GLContext, TextureInput, TextureMap } from \"../types\";\nimport { TextureLoadError } from \"./errors\";\nimport { loadTexture, type LoadedTexture } from \"./textures\";\n\nexport type TextureSet = {\n /** The textures loaded so far, by name. */\n readonly textures: ReadonlyMap<string, LoadedTexture>;\n /** Whether `name` was given as an input, loaded or not. */\n hasInput(name: string): boolean;\n /**\n * Returns the texture unit for `name`, taking the lowest free unit on first\n * use. Runtimes reserve units for their own samplers (feedback, pass inputs)\n * here too, so they never collide with image textures.\n */\n reserveUnit(gl: GLContext, name: string): number;\n /**\n * Loads every input, then replaces the previously loaded textures. Used for\n * the initial load and after a context restore.\n */\n loadAll(gl: GLContext, isCancelled: () => boolean): Promise<void>;\n /**\n * Loads `input` as `name`. Resolves to the loaded texture, or `null` when a\n * later `set()` for the same name or `isCancelled()` superseded it (its\n * texture is deleted). On failure the unit is released if `name` is unused,\n * and the error is rethrown.\n */\n set(\n gl: GLContext,\n name: string,\n input: TextureInput,\n isCancelled: () => boolean\n ): Promise<LoadedTexture | null>;\n /**\n * Binds every loaded texture to its unit and points its sampler uniform at\n * it. Calls `onMissing` with the uniform name when the program lacks it.\n */\n bind(\n gl: GLContext,\n locations: ReadonlyMap<string, WebGLUniformLocation>,\n onMissing?: (uniformName: string) => void\n ): void;\n /** Deletes every loaded texture. */\n dispose(gl: GLContext): void;\n};\n\n/**\n * Tracks named image textures and the texture units they occupy, for a\n * runtime that binds them to one or more programs.\n */\nexport const createTextureSet = (inputs: TextureMap = {}): TextureSet => {\n const textureInputs = new Map<string, TextureInput>(Object.entries(inputs));\n let textures = new Map<string, LoadedTexture>();\n const units = new Map<string, number>();\n const versions = new Map<string, number>();\n\n const reserveUnit = (gl: GLContext, name: string): number => {\n const existing = units.get(name);\n if (existing !== undefined) return existing;\n\n const maxUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) as number;\n const used = new Set(units.values());\n for (let unit = 0; unit < maxUnits; unit += 1) {\n if (!used.has(unit)) {\n units.set(name, unit);\n return unit;\n }\n }\n\n throw new TextureLoadError(\n `Texture unit limit exceeded while loading texture: ${name}`\n );\n };\n\n return {\n get textures() {\n return textures;\n },\n\n hasInput(name) {\n return textureInputs.has(name);\n },\n\n reserveUnit,\n\n async loadAll(gl, isCancelled) {\n const loaded = new Map<string, LoadedTexture>();\n for (const [name, input] of textureInputs) {\n if (isCancelled()) break;\n const unit = reserveUnit(gl, name);\n loaded.set(name, await loadTexture(gl, name, input, unit));\n }\n\n for (const texture of textures.values()) {\n gl.deleteTexture(texture.texture);\n }\n textures = loaded;\n },\n\n async set(gl, name, input, isCancelled) {\n const version = (versions.get(name) ?? 0) + 1;\n versions.set(name, version);\n\n try {\n const unit = reserveUnit(gl, name);\n const loaded = await loadTexture(gl, name, input, unit);\n\n if (isCancelled() || versions.get(name) !== version) {\n gl.deleteTexture(loaded.texture);\n return null;\n }\n\n const previous = textures.get(name);\n textureInputs.set(name, input);\n textures.set(name, loaded);\n if (previous) gl.deleteTexture(previous.texture);\n return loaded;\n } catch (error) {\n if (!textures.has(name) && !textureInputs.has(name)) {\n units.delete(name);\n }\n throw error;\n }\n },\n\n bind(gl, locations, onMissing) {\n for (const texture of textures.values()) {\n const unit = units.get(texture.name);\n if (unit === undefined) continue;\n const location = locations.get(texture.uniformName);\n if (!location) {\n onMissing?.(texture.uniformName);\n continue;\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture.texture);\n gl.uniform1i(location, unit);\n }\n },\n\n dispose(gl) {\n for (const texture of textures.values()) {\n gl.deleteTexture(texture.texture);\n }\n }\n };\n};\n","import type { GLContext } from \"../types\";\nimport { collectUniformLocations } from \"./uniforms\";\nimport {\n createFullscreenBuffer,\n createProgram,\n defaultVertexShader,\n defaultVertexShader300,\n isGLSL300\n} from \"./webgl\";\n\nexport type FullscreenProgram = {\n readonly program: WebGLProgram;\n /** Active uniform locations by name, array uniforms without `[0]`. */\n readonly locations: ReadonlyMap<string, WebGLUniformLocation>;\n /**\n * Binds the program, its quad buffer and `a_position`, so a draw is correct\n * whatever GL state user hooks left behind.\n */\n use(): void;\n /** Draws the fullscreen quad with the current GL state. */\n draw(): void;\n dispose(): void;\n};\n\n/**\n * Compiles `fragment` with a fullscreen-quad vertex shader (the GLSL ES 3.00\n * one when `fragment` starts with `#version 300 es`, unless `vertex` is\n * given) and leaves it bound.\n */\nexport const createFullscreenProgram = (\n gl: GLContext,\n fragment: string,\n vertex?: string\n): FullscreenProgram => {\n const defaultVertex = isGLSL300(fragment)\n ? defaultVertexShader300\n : defaultVertexShader;\n const program = createProgram(gl, vertex ?? defaultVertex, fragment);\n gl.useProgram(program);\n const buffer = createFullscreenBuffer(gl, program);\n const attribLocation = gl.getAttribLocation(program, \"a_position\");\n const locations = collectUniformLocations(gl, program);\n\n return {\n program,\n locations,\n use() {\n gl.useProgram(program);\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n if (attribLocation >= 0) {\n gl.enableVertexAttribArray(attribLocation);\n gl.vertexAttribPointer(attribLocation, 2, gl.FLOAT, false, 0, 0);\n }\n },\n draw() {\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n },\n dispose() {\n gl.deleteBuffer(buffer);\n gl.deleteProgram(program);\n }\n };\n};\n","import type { GLContext } from \"../types\";\nimport {\n createFullscreenBuffer,\n createProgram,\n defaultVertexShader,\n defaultVertexShader300,\n isWebGL2Context\n} from \"./webgl\";\n\nconst blitFragmentShader = `\nprecision mediump float;\nvarying vec2 v_uv;\nuniform sampler2D u_texture;\n\nvoid main() {\n gl_FragColor = texture2D(u_texture, v_uv);\n}\n`;\n\nconst blitFragmentShader300 = `#version 300 es\nprecision mediump float;\nin vec2 v_uv;\nuniform sampler2D u_texture;\nout vec4 fragColor;\n\nvoid main() {\n fragColor = texture(u_texture, v_uv);\n}\n`;\n\nexport type Blitter = {\n /**\n * Draws `texture` as a fullscreen quad into `target` (or the default\n * framebuffer when `target` is `null`), setting the viewport to\n * `width`/`height` first. Does not save or restore any other GL state.\n */\n blit(\n texture: WebGLTexture,\n target: WebGLFramebuffer | null,\n width: number,\n height: number\n ): void;\n /** Releases the GL resources owned by this blitter. */\n dispose(): void;\n};\n\n/**\n * Creates a reusable fullscreen-quad \"blit\" utility: draws a texture into a\n * framebuffer (or the canvas) using a minimal passthrough shader. Intended\n * for hand-rolled multi-pass/FBO pipelines; frapx's own multi-pass features\n * are built on the same primitive.\n */\nexport const createBlitter = (gl: GLContext): Blitter => {\n const program = createProgram(\n gl,\n isWebGL2Context(gl) ? defaultVertexShader300 : defaultVertexShader,\n isWebGL2Context(gl) ? blitFragmentShader300 : blitFragmentShader\n );\n const buffer = createFullscreenBuffer(gl, program);\n const textureUniform = gl.getUniformLocation(program, \"u_texture\");\n\n return {\n blit(\n texture: WebGLTexture,\n target: WebGLFramebuffer | null,\n width: number,\n height: number\n ): void {\n gl.bindFramebuffer(gl.FRAMEBUFFER, target);\n gl.viewport(0, 0, width, height);\n gl.useProgram(program);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n const location = gl.getAttribLocation(program, \"a_position\");\n if (location >= 0) {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);\n }\n\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n if (textureUniform) {\n gl.uniform1i(textureUniform, 0);\n }\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n },\n dispose(): void {\n gl.deleteProgram(program);\n gl.deleteBuffer(buffer);\n }\n };\n};\n","import type {\n GLContext,\n PingPong,\n RenderTarget,\n RenderTargetFormat,\n RenderTargetOptions\n} from \"../types\";\nimport { ShaderCompileError, UnsupportedError } from \"./errors\";\nimport { isWebGL2Context } from \"./webgl\";\n\nconst DEFAULT_CLEAR_COLOR = [0, 0, 0, 0] as const;\n\n/**\n * Whether `format` can be allocated as a color attachment on `gl`. `rgba8` is\n * always available; `rgba16f` and `rgba32f` need WebGL2 and\n * `EXT_color_buffer_float`.\n * Enables the extension as a side effect when present.\n */\nexport const supportsRenderTargetFormat = (\n gl: GLContext,\n format: RenderTargetFormat\n): boolean => {\n if (format === \"rgba8\") return true;\n return isWebGL2Context(gl) && gl.getExtension(\"EXT_color_buffer_float\") !== null;\n};\n\n/**\n * Resolves the format a render target will actually use. When `format` is not\n * supported this warns and returns `rgba8`, or throws `UnsupportedError` when\n * `formatFallback` is `false`.\n */\nexport const resolveRenderTargetFormat = (\n gl: GLContext,\n format: RenderTargetFormat = \"rgba8\",\n formatFallback = true\n): RenderTargetFormat => {\n if (supportsRenderTargetFormat(gl, format)) return format;\n\n const reason = `${format} render targets need WebGL2 with EXT_color_buffer_float.`;\n if (!formatFallback) throw new UnsupportedError(reason);\n console.warn(`[frapx] ${reason} Falling back to rgba8.`);\n return \"rgba8\";\n};\n\n/**\n * Creates a texture-backed framebuffer to render into and sample from. The\n * storage is cleared to `clearColor` on creation and on every resize.\n */\nexport const createRenderTarget = (\n gl: GLContext,\n width: number,\n height: number,\n options: RenderTargetOptions = {}\n): RenderTarget => {\n const format = resolveRenderTargetFormat(\n gl,\n options.format,\n options.formatFallback\n );\n return new Target(gl, width, height, format, options);\n};\n\n/**\n * Creates two render targets of the same size and format for feedback-style\n * rendering: draw into `write` while sampling `read`, then `swap()`.\n */\nexport const createPingPong = (\n gl: GLContext,\n width: number,\n height: number,\n options: RenderTargetOptions = {}\n): PingPong => {\n // Resolve once so a fallback warns a single time for both targets.\n const format = resolveRenderTargetFormat(\n gl,\n options.format,\n options.formatFallback\n );\n let read: RenderTarget = new Target(gl, width, height, format, options);\n let write: RenderTarget;\n try {\n write = new Target(gl, width, height, format, options);\n } catch (error) {\n read.dispose();\n throw error;\n }\n\n return {\n get read() {\n return read;\n },\n get write() {\n return write;\n },\n format,\n swap() {\n const previous = read;\n read = write;\n write = previous;\n },\n resize(nextWidth: number, nextHeight: number) {\n read.resize(nextWidth, nextHeight);\n write.resize(nextWidth, nextHeight);\n },\n clear() {\n read.clear();\n write.clear();\n },\n dispose() {\n read.dispose();\n write.dispose();\n }\n };\n};\n\nclass Target implements RenderTarget {\n texture!: WebGLTexture;\n framebuffer!: WebGLFramebuffer;\n width: number;\n height: number;\n\n constructor(\n private readonly gl: GLContext,\n width: number,\n height: number,\n readonly format: RenderTargetFormat,\n private readonly options: RenderTargetOptions\n ) {\n this.width = width;\n this.height = height;\n this.allocate();\n }\n\n resize(width: number, height: number): void {\n if (width === this.width && height === this.height) return;\n this.release();\n this.width = width;\n this.height = height;\n this.allocate();\n }\n\n clear(): void {\n const gl = this.gl;\n const [r, g, b, a] = this.options.clearColor ?? DEFAULT_CLEAR_COLOR;\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\n gl.viewport(0, 0, this.width, this.height);\n gl.clearColor(r, g, b, a);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n dispose(): void {\n this.release();\n }\n\n private allocate(): void {\n const gl = this.gl;\n const texture = gl.createTexture();\n if (!texture) {\n throw new ShaderCompileError(\"Failed to create render target texture.\");\n }\n\n const framebuffer = gl.createFramebuffer();\n if (!framebuffer) {\n gl.deleteTexture(texture);\n throw new ShaderCompileError(\"Failed to create render target framebuffer.\");\n }\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n if (this.format !== \"rgba8\" && isWebGL2Context(gl)) {\n const half = this.format === \"rgba16f\";\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n half ? gl.RGBA16F : gl.RGBA32F,\n this.width,\n this.height,\n 0,\n gl.RGBA,\n half ? gl.HALF_FLOAT : gl.FLOAT,\n null\n );\n } else {\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n this.width,\n this.height,\n 0,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n null\n );\n }\n\n const wrap = getWrap(gl, this.options.wrap ?? \"clamp\");\n // Linear filtering of 32-bit float textures is an optional extension.\n const linear =\n this.options.filter !== \"nearest\" &&\n (this.format !== \"rgba32f\" || gl.getExtension(\"OES_texture_float_linear\") !== null);\n const filter = linear ? gl.LINEAR : gl.NEAREST;\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n texture,\n 0\n );\n\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.deleteFramebuffer(framebuffer);\n gl.deleteTexture(texture);\n throw new ShaderCompileError(\n `Render target framebuffer (${this.format}) is incomplete: ${status}`\n );\n }\n\n this.texture = texture;\n this.framebuffer = framebuffer;\n this.clear();\n }\n\n private release(): void {\n this.gl.deleteFramebuffer(this.framebuffer);\n this.gl.deleteTexture(this.texture);\n }\n}\n\nconst getWrap = (\n gl: GLContext,\n wrap: NonNullable<RenderTargetOptions[\"wrap\"]>\n): number => {\n if (wrap === \"repeat\") return gl.REPEAT;\n if (wrap === \"mirror\") return gl.MIRRORED_REPEAT;\n return gl.CLAMP_TO_EDGE;\n};\n"],"mappings":"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","names":["size","getWrap"]}
1
+ {"version":3,"sources":["../src/internal/errors.ts","../src/internal/shaderLog.ts","../src/internal/webgl.ts","../src/internal/capture.ts","../src/internal/dom.ts","../src/host.ts","../src/internal/names.ts","../src/internal/uniforms.ts","../src/internal/bindings.ts","../src/internal/textures.ts","../src/internal/textureSet.ts","../src/internal/fullscreenProgram.ts","../src/internal/blit.ts","../src/internal/renderTarget.ts"],"sourcesContent":["export class ShaderError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\n/** One line of a shader compile error, located in the source that was compiled. */\nexport type ShaderErrorLine = {\n /** 1-based line in the compiled source (after `glsl` template interpolation). */\n line: number;\n message: string;\n /** That line of the source, or \"\" when the log points past the end. */\n source: string;\n /** Up to two lines either side, with their numbers, the error line included. */\n context: ReadonlyArray<{ line: number; source: string }>;\n};\n\n/** `\"link\"` for program link errors, which carry no line numbers. */\nexport type ShaderStage = \"vertex\" | \"fragment\" | \"link\";\n\nexport class UnsupportedError extends ShaderError {}\nexport class TargetNotFoundError extends ShaderError {}\nexport class ShaderCompileError extends ShaderError {\n /** The stage that failed, or `null` for errors not tied to compiling a shader. */\n readonly stage: ShaderStage | null;\n /** Errors located in the source, parsed from the driver's info log. Empty when it had none. */\n readonly lines: readonly ShaderErrorLine[];\n\n constructor(\n message: string,\n details: { stage?: ShaderStage; lines?: readonly ShaderErrorLine[] } = {}\n ) {\n super(message);\n this.stage = details.stage ?? null;\n this.lines = details.lines ?? [];\n }\n}\nexport class TextureLoadError extends ShaderError {}\nexport class DestroyedError extends ShaderError {}\n","import type { ShaderErrorLine } from \"./errors\";\n\n// Browsers translate shaders through ANGLE: \"ERROR: 0:12: 'x' : undeclared identifier\".\nconst ANGLE_STYLE = /^\\s*ERROR:\\s*\\d+:(\\d+):\\s*(.*)$/;\n// Native NVIDIA-style drivers: \"0(12) : error C1008: undefined variable\".\nconst NVIDIA_STYLE = /^\\s*\\d+\\((\\d+)\\)\\s*:\\s*error\\s*\\w*\\s*:\\s*(.*)$/i;\n// Follow-up noise after the real error.\nconst NOISE = /compilation terminated|^\\s*''\\s*:\\s*$/i;\n\nconst CONTEXT_LINES = 2;\n\n/**\n * Finds the errors in a shader info log and attaches the source lines they\n * point at. Lines the log does not locate are left out; the log itself stays\n * the error message.\n */\nexport const parseShaderLog = (log: string, source: string): ShaderErrorLine[] => {\n const sourceLines = source.split(/\\r?\\n/);\n const lineAt = (line: number) => sourceLines[line - 1] ?? \"\";\n const results: ShaderErrorLine[] = [];\n const seen = new Set<string>();\n\n for (const entry of log.split(/\\r?\\n/)) {\n const match = ANGLE_STYLE.exec(entry) ?? NVIDIA_STYLE.exec(entry);\n if (!match) continue;\n const line = Number(match[1]);\n const message = match[2]!.trim();\n if (!message || NOISE.test(message)) continue;\n const key = `${line}:${message}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n const context: Array<{ line: number; source: string }> = [];\n const first = Math.max(1, line - CONTEXT_LINES);\n const last = Math.min(sourceLines.length, line + CONTEXT_LINES);\n for (let current = first; current <= last; current++) {\n context.push({ line: current, source: lineAt(current) });\n }\n results.push({ line, message, source: lineAt(line), context });\n }\n return results;\n};\n","import type { GLContext } from \"../types\";\nimport { ShaderCompileError } from \"./errors\";\nimport { parseShaderLog } from \"./shaderLog\";\n\nexport const defaultVertexShader = `\nattribute vec2 a_position;\nvarying vec2 v_uv;\n\nvoid main() {\n v_uv = a_position * 0.5 + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n`;\n\nexport const defaultVertexShader300 = `#version 300 es\nin vec2 a_position;\nout vec2 v_uv;\n\nvoid main() {\n v_uv = a_position * 0.5 + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n`;\n\nexport const isGLSL300 = (src: string): boolean =>\n /^\\s*#version\\s+300\\s+es\\b/.test(src);\n\n// Duck-typed instead of `instanceof WebGL2RenderingContext` so this also works\n// against test mocks and other environments where the global constructor may\n// be unavailable.\nexport const isWebGL2Context = (gl: GLContext): gl is WebGL2RenderingContext =>\n typeof (gl as WebGL2RenderingContext).createVertexArray === \"function\";\n\nexport const createProgram = (\n gl: GLContext,\n vertexSource: string,\n fragmentSource: string\n): WebGLProgram => {\n const vertex = compileShader(gl, gl.VERTEX_SHADER, vertexSource);\n let fragment: WebGLShader;\n try {\n fragment = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);\n } catch (error) {\n gl.deleteShader(vertex);\n throw error;\n }\n const program = gl.createProgram();\n\n if (!program) {\n throw new ShaderCompileError(\"Failed to create WebGL program.\");\n }\n\n gl.attachShader(program, vertex);\n gl.attachShader(program, fragment);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const log = gl.getProgramInfoLog(program) ?? \"Unknown program link error.\";\n gl.deleteProgram(program);\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n throw new ShaderCompileError(log, { stage: \"link\" });\n }\n\n gl.deleteShader(vertex);\n gl.deleteShader(fragment);\n return program;\n};\n\nexport const createFullscreenBuffer = (\n gl: GLContext,\n program: WebGLProgram\n): WebGLBuffer => {\n const buffer = gl.createBuffer();\n if (!buffer) {\n throw new ShaderCompileError(\"Failed to create fullscreen buffer.\");\n }\n\n const location = gl.getAttribLocation(program, \"a_position\");\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(\n gl.ARRAY_BUFFER,\n new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),\n gl.STATIC_DRAW\n );\n\n if (location >= 0) {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n};\n\nconst compileShader = (\n gl: GLContext,\n type: number,\n source: string\n): WebGLShader => {\n const shader = gl.createShader(type);\n if (!shader) {\n throw new ShaderCompileError(\"Failed to create WebGL shader.\");\n }\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const log = gl.getShaderInfoLog(shader) ?? \"Unknown shader compile error.\";\n gl.deleteShader(shader);\n throw new ShaderCompileError(log, {\n stage: type === gl.VERTEX_SHADER ? \"vertex\" : \"fragment\",\n lines: parseShaderLog(log, source)\n });\n }\n\n return shader;\n};\n","import type { GLContext } from \"../types\";\nimport { isWebGL2Context } from \"./webgl\";\n\n/**\n * Resolves once the GPU has finished every command submitted so far, polling\n * a fence between tasks. Waiting between heavy draws keeps each submission\n * short, so a long render never trips the browser's GPU watchdog and loses\n * the context. Resolves immediately on WebGL1.\n */\nexport const waitForGpu = (gl: GLContext): Promise<void> => {\n if (!isWebGL2Context(gl)) return Promise.resolve();\n const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);\n if (!sync) return Promise.resolve();\n gl.flush();\n return new Promise((resolve) => {\n const poll = () => {\n const status = gl.clientWaitSync(sync, 0, 0);\n if (status === gl.TIMEOUT_EXPIRED) {\n setTimeout(poll, 4);\n return;\n }\n gl.deleteSync(sync);\n resolve();\n };\n poll();\n });\n};\n\n/**\n * Reads RGBA pixels from `framebuffer` (or the drawing buffer when `null`) and\n * returns them top row first. Must run in the same task as the draw when\n * reading the drawing buffer, since it is not preserved.\n */\nexport const readPixels = <T extends \"rgba8\" | \"rgba16f\">(\n gl: GLContext,\n framebuffer: WebGLFramebuffer | null,\n width: number,\n height: number,\n format: T\n): T extends \"rgba16f\" ? Float32Array : Uint8Array => {\n const length = width * height * 4;\n const data =\n format === \"rgba16f\" ? new Float32Array(length) : new Uint8Array(length);\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n // RGBA/FLOAT is the read combination EXT_color_buffer_float guarantees.\n gl.readPixels(\n 0,\n 0,\n width,\n height,\n gl.RGBA,\n format === \"rgba16f\" ? gl.FLOAT : gl.UNSIGNED_BYTE,\n data\n );\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n flipRows(data, width * 4, height);\n return data as T extends \"rgba16f\" ? Float32Array : Uint8Array;\n};\n\n/** Encodes the canvas as PNG. The snapshot is taken synchronously. */\nexport const canvasToPng = (canvas: HTMLCanvasElement): Promise<Blob> =>\n new Promise((resolve, reject) => {\n canvas.toBlob((blob) => {\n if (blob) resolve(blob);\n else reject(new Error(\"Failed to encode the canvas as PNG.\"));\n }, \"image/png\");\n });\n\n// WebGL reads bottom-up; captures are top row first like images.\nconst flipRows = (\n data: Uint8Array | Float32Array,\n rowLength: number,\n rows: number\n): void => {\n const temp = data.slice(0, rowLength);\n for (let top = 0, bottom = rows - 1; top < bottom; top++, bottom--) {\n const topStart = top * rowLength;\n const bottomStart = bottom * rowLength;\n temp.set(data.subarray(topStart, topStart + rowLength));\n data.copyWithin(topStart, bottomStart, bottomStart + rowLength);\n data.set(temp, bottomStart);\n }\n};\n","import type { DprOption, Resolution, SetupCanvasOptions } from \"../types\";\n\nexport type DomSetup = {\n target: Element;\n canvas: HTMLCanvasElement;\n createdCanvas: boolean;\n restoredPosition: string | null;\n /** True when the canvas was created without being attached to the document. */\n detached?: boolean;\n};\n\nexport type CanvasSize = {\n width: number;\n height: number;\n viewportWidth: number;\n viewportHeight: number;\n};\n\nexport const resolveElement = (\n target: string | Element | undefined\n): Element | null => {\n if (!target) return null;\n if (typeof target === \"string\") return document.querySelector(target);\n return target;\n};\n\nexport const setupCanvas = (options: SetupCanvasOptions): DomSetup | null => {\n const target = resolveElement(options.target);\n const canvas = options.canvas ?? document.createElement(\"canvas\");\n const measurementTarget = target ?? options.canvas;\n\n if (!measurementTarget) {\n if (!options.detached) return null;\n canvas.dataset.frapxCanvas = \"\";\n return {\n target: canvas,\n canvas,\n createdCanvas: true,\n restoredPosition: null,\n detached: true\n };\n }\n\n const createdCanvas = !options.canvas;\n const restoredPosition =\n target && getComputedStyle(target).position === \"static\"\n ? (target as HTMLElement).style.position\n : null;\n\n if (target && restoredPosition !== null) {\n (target as HTMLElement).style.position = \"relative\";\n }\n\n applyCanvasStyle(canvas, options, createdCanvas);\n\n if (options.canvasClass) {\n canvas.classList.add(options.canvasClass);\n }\n\n if (options.canvasStyle) {\n Object.assign(canvas.style, options.canvasStyle);\n }\n\n if (createdCanvas && target) {\n if ((options.layer ?? \"background\") === \"overlay\") {\n target.append(canvas);\n } else {\n target.prepend(canvas);\n }\n }\n\n return {\n target: measurementTarget,\n canvas,\n createdCanvas,\n restoredPosition\n };\n};\n\nexport const resolveDpr = (\n dpr: DprOption | undefined,\n maxDpr: number | undefined\n): number => {\n const raw =\n typeof dpr === \"function\"\n ? dpr()\n : typeof dpr === \"number\"\n ? dpr\n : typeof window === \"undefined\"\n ? 1\n : window.devicePixelRatio || 1;\n\n return Math.max(1, Math.min(raw, maxDpr ?? 2));\n};\n\nexport const resizeCanvasToTarget = (\n canvas: HTMLCanvasElement,\n target: Element,\n dpr: number\n): CanvasSize => {\n const rect = target.getBoundingClientRect();\n const viewportWidth = Math.max(1, rect.width || canvas.clientWidth || 1);\n const viewportHeight = Math.max(1, rect.height || canvas.clientHeight || 1);\n const width = Math.max(1, Math.round(viewportWidth * dpr));\n const height = Math.max(1, Math.round(viewportHeight * dpr));\n\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n\n return { width, height, viewportWidth, viewportHeight };\n};\n\n/**\n * Sizes the canvas to a fixed internal resolution. The viewport size still\n * comes from the target so `u_viewportSize` reflects the displayed size; a\n * detached canvas has no layout, so its viewport equals the resolution.\n */\nexport const resizeCanvasToResolution = (\n canvas: HTMLCanvasElement,\n target: Element | null,\n resolution: Resolution\n): CanvasSize => {\n const [width, height] = resolution;\n let viewportWidth = width;\n let viewportHeight = height;\n\n if (target) {\n const rect = target.getBoundingClientRect();\n viewportWidth = Math.max(1, rect.width || canvas.clientWidth || 1);\n viewportHeight = Math.max(1, rect.height || canvas.clientHeight || 1);\n }\n\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n\n return { width, height, viewportWidth, viewportHeight };\n};\n\nconst applyCanvasStyle = (\n canvas: HTMLCanvasElement,\n options: SetupCanvasOptions,\n shouldPosition: boolean\n): void => {\n canvas.dataset.frapxCanvas = \"\";\n\n if (!shouldPosition) return;\n\n const layer = options.layer ?? \"background\";\n Object.assign(canvas.style, {\n position: \"absolute\",\n inset: \"0\",\n width: \"100%\",\n height: \"100%\",\n display: \"block\",\n pointerEvents: \"none\",\n zIndex: layer === \"overlay\" ? \"1\" : \"0\"\n });\n};\n","import type {\n CaptureFormat,\n CaptureOptions,\n CaptureResult,\n ClockMode,\n GLContext,\n HostFrameState,\n HostPointer,\n Resolution,\n RuntimeHostInstance,\n RuntimeHostOptions,\n ShaderStatus,\n TimeSource\n} from \"./types\";\nimport { DestroyedError, TargetNotFoundError, UnsupportedError } from \"./internal/errors\";\nimport { canvasToPng, readPixels } from \"./internal/capture\";\nimport {\n resolveDpr,\n resizeCanvasToResolution,\n resizeCanvasToTarget,\n setupCanvas,\n type DomSetup\n} from \"./internal/dom\";\n\nconst MAX_DELTA_SECONDS = 0.1;\n\n// Manual clocks report a neutral pointer so output never depends on input.\nconst IDLE_POINTER: HostPointer = { x: 0, y: 0, uvX: 0, uvY: 0, active: 0 };\n\nconst clampDelta = (delta: number): number =>\n Math.min(Math.max(delta, 0), MAX_DELTA_SECONDS);\n\ntype Gate = \"offscreen\" | \"hidden\" | \"reducedMotion\";\n\nexport const createRuntimeHost = (\n options: RuntimeHostOptions\n): RuntimeHostInstance => {\n return new RuntimeHost(options);\n};\n\nclass RuntimeHost implements RuntimeHostInstance {\n readonly ready: Promise<void>;\n\n private readonly options: RuntimeHostOptions;\n private readyResolve: (() => void) | null = null;\n private readyReject: ((error: Error) => void) | null = null;\n private dom: DomSetup | null = null;\n private context: GLContext | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private intersectionObserver: IntersectionObserver | null = null;\n private rafId = 0;\n private running = false;\n private inRender = false;\n private captureDrawing = false;\n private resizePending = false;\n private destroyed = false;\n private gates = new Set<Gate>();\n private reducedMotionActive = false;\n private frame = 0;\n private elapsed = 0;\n private lastTimestamp = 0;\n private pixelRatio = 1;\n private width = 1;\n private height = 1;\n private viewportWidth = 1;\n private viewportHeight = 1;\n private pointer = { x: 0, y: 0, uvX: 0, uvY: 0, active: 0 };\n private removeListeners: Array<() => void> = [];\n private currentStatus: ShaderStatus = \"idle\";\n private contextRestoredShouldRun = false;\n private statusBeforeLoss: ShaderStatus = \"idle\";\n private clockMode: ClockMode;\n private manualDelta = 0;\n private lastManualTime: number | null = null;\n private source: TimeSource | null;\n // The source's value at the previous loop frame; null restarts u_delta at 0.\n private lastSourceTime: number | null = null;\n private fixedResolution: Resolution | null;\n private objectFitRestore: string | null = null;\n // Letterbox offset (CSS px) of the contained canvas content inside the target.\n private contentOffsetX = 0;\n private contentOffsetY = 0;\n\n constructor(options: RuntimeHostOptions) {\n this.options = options;\n this.clockMode = options.clock ?? \"realtime\";\n this.source = options.timeSource ?? null;\n this.warnIfSourceUnread();\n this.fixedResolution = options.resolution\n ? normalizeResolution(options.resolution)\n : null;\n this.ready = new Promise<void>((resolve, reject) => {\n this.readyResolve = resolve;\n this.readyReject = reject;\n });\n queueMicrotask(() => {\n void this.init();\n });\n }\n\n get canvas(): HTMLCanvasElement | null {\n return this.dom?.canvas ?? null;\n }\n\n get gl(): GLContext | null {\n return this.context;\n }\n\n get status(): ShaderStatus {\n return this.currentStatus;\n }\n\n get supported(): boolean {\n return ![\"unsupported\", \"destroyed\"].includes(this.currentStatus);\n }\n\n get clock(): ClockMode {\n return this.clockMode;\n }\n\n get timeSource(): TimeSource | null {\n return this.source;\n }\n\n start(): void {\n if (this.destroyed || this.currentStatus === \"unsupported\") return;\n this.running = true;\n this.reconcile();\n }\n\n stop(): void {\n this.running = false;\n this.cancelFrame();\n if (!this.destroyed && this.currentStatus !== \"unsupported\") {\n this.currentStatus = \"paused\";\n }\n }\n\n render(): void {\n if (\n this.destroyed ||\n !this.dom ||\n !this.context ||\n this.currentStatus === \"unsupported\" ||\n this.inRender\n )\n return;\n\n if (this.isManual) {\n // The caller decides when to draw; visibility gates do not apply.\n this.renderInternal(this.elapsed, this.manualDelta);\n return;\n }\n\n // Redraws at the last frame's time: refinement and reduced motion must\n // not chase a running source.\n if (this.hasVisibilityBlock) return;\n this.renderInternal(this.elapsed, 0);\n }\n\n setTime(seconds: number): void {\n if (!Number.isFinite(seconds)) {\n throw new RangeError(`setTime() expects a finite number, got ${seconds}`);\n }\n if (this.destroyed) return;\n\n if (this.isManual) {\n this.manualDelta =\n this.lastManualTime === null ? 0 : seconds - this.lastManualTime;\n this.lastManualTime = seconds;\n }\n this.elapsed = seconds;\n }\n\n setClock(clock: ClockMode): void {\n if (this.destroyed || clock === this.clockMode) return;\n this.clockMode = clock;\n this.manualDelta = 0;\n this.lastManualTime = null;\n // Gates kept tracking while manual, so this resumes against current state.\n this.reconcile();\n }\n\n setTimeSource(source: TimeSource | null): void {\n if (this.destroyed) return;\n this.source = source;\n this.lastSourceTime = null;\n this.warnIfSourceUnread();\n }\n\n // Only the realtime loop reads the source, and demand mode runs no loop.\n private warnIfSourceUnread(): void {\n if (this.source && this.options.renderMode === \"demand\") {\n this.debugWarn(\"`timeSource` is not read with renderMode \\\"demand\\\", which runs no frame loop. Call setTime() instead.\");\n }\n }\n\n setResolution(resolution: Resolution | null): void {\n if (this.destroyed) return;\n\n if (resolution === null) {\n if (this.isDetached) {\n throw new TypeError(\n \"A canvas without a target needs a fixed resolution.\"\n );\n }\n this.fixedResolution = null;\n } else {\n const next = normalizeResolution(resolution);\n if (this.context) assertWithinLimits(this.context, next);\n this.fixedResolution = next;\n }\n\n this.applyObjectFit();\n this.resize();\n }\n\n async captureFrame<F extends CaptureFormat = \"png\">(\n options: CaptureOptions<F> = {}\n ): Promise<CaptureResult<F>> {\n const format: CaptureFormat = options.format ?? \"png\";\n if (format !== \"png\" && format !== \"rgba8\" && format !== \"rgba16f\") {\n throw new RangeError(`Unknown capture format: ${String(format)}`);\n }\n\n await this.ready;\n if (this.destroyed) {\n throw new DestroyedError(\"Runtime host was destroyed.\");\n }\n if (!this.dom || !this.context) {\n throw new UnsupportedError(\"Cannot capture without a WebGL context.\");\n }\n if (this.inRender) {\n throw new Error(\"captureFrame() cannot be called while a frame is drawing.\");\n }\n\n // Check before drawing so a rejected capture has no side effects.\n const sourceFormat = this.options.captureSource?.()?.format;\n if (format === \"rgba16f\" && sourceFormat !== \"rgba16f\" && sourceFormat !== \"rgba32f\") {\n throw new UnsupportedError(\n \"rgba16f capture needs a float render target, such as feedback with format rgba16f.\"\n );\n }\n options.signal?.throwIfAborted();\n\n const delta = this.isManual ? this.manualDelta : 0;\n const drawContext = this.context;\n if (!this.options.onCaptureDraw) {\n this.renderInternal(this.elapsed, delta);\n return this.readCapture(format, drawContext);\n }\n\n try {\n await this.renderForCapture(this.options.onCaptureDraw, delta, options.signal);\n return this.readCapture(format, drawContext);\n } finally {\n // Resizes requested while drawing apply once the frame is read.\n if (this.resizePending) {\n this.resizePending = false;\n this.resize();\n }\n }\n }\n\n resize(): void {\n if (this.destroyed || !this.dom) return;\n // Keep the size an asynchronous capture draw started with until it is read.\n if (this.captureDrawing) {\n this.resizePending = true;\n return;\n }\n\n this.syncSize();\n\n if (this.shouldRenderOnDemand && !this.inRender) {\n this.render();\n }\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.running = false;\n this.cancelFrame();\n this.resizeObserver?.disconnect();\n this.intersectionObserver?.disconnect();\n\n for (const remove of this.removeListeners) remove();\n this.removeListeners = [];\n\n this.context = null;\n\n if (this.dom?.createdCanvas) {\n this.dom.canvas.remove();\n } else if (this.dom && this.objectFitRestore !== null) {\n this.dom.canvas.style.objectFit = this.objectFitRestore;\n }\n\n const dom = this.dom;\n if (dom?.restoredPosition !== null && dom && this.options.target) {\n (dom.target as HTMLElement).style.position = dom.restoredPosition!;\n }\n\n this.currentStatus = \"destroyed\";\n this.markReadyHandled();\n this.readyReject?.(new DestroyedError(\"Runtime host was destroyed.\"));\n }\n\n private get isManual(): boolean {\n return this.clockMode === \"manual\";\n }\n\n private get followsSource(): boolean {\n return this.source !== null && !this.isManual;\n }\n\n // A non-finite reading holds the previous time instead of throwing in a frame.\n private readSource(): number | null {\n if (!this.followsSource) return null;\n const now = this.source!();\n return Number.isFinite(now) ? now : null;\n }\n\n // The static frame takes the source's current time without a delta.\n private syncSourceTime(): void {\n const now = this.readSource();\n if (now !== null) this.elapsed = now;\n }\n\n // A loop frame under a source: time is the source's value, never clamped;\n // delta is the step from the previous frame, 0 when it went back.\n private advanceFromSource(): number {\n const now = this.readSource();\n if (now === null) return 0;\n const previous = this.lastSourceTime;\n this.lastSourceTime = now;\n this.elapsed = now;\n return previous === null ? 0 : clampDelta(now - previous);\n }\n\n private get isDetached(): boolean {\n if (this.dom) return this.dom.detached === true;\n return this.options.target === undefined && this.options.canvas === undefined;\n }\n\n // Demand mode re-renders on input changes, except under a manual clock where\n // only explicit render() calls draw.\n private get shouldRenderOnDemand(): boolean {\n return this.options.renderMode === \"demand\" && !this.isManual;\n }\n\n private get hasVisibilityBlock(): boolean {\n return this.gates.has(\"offscreen\") || this.gates.has(\"hidden\");\n }\n\n private get hasMotionBlock(): boolean {\n return (\n this.gates.has(\"reducedMotion\") && this.options.renderMode !== \"demand\"\n );\n }\n\n private setGate(gate: Gate, closed: boolean): void {\n if (closed === this.gates.has(gate)) return;\n if (closed) this.gates.add(gate);\n else this.gates.delete(gate);\n this.reconcile();\n }\n\n private reconcile(): void {\n if (\n this.destroyed ||\n this.currentStatus === \"unsupported\" ||\n this.currentStatus === \"error\" ||\n this.currentStatus === \"context-lost\"\n ) {\n return;\n }\n\n if (this.isManual) {\n this.cancelFrame();\n this.currentStatus = \"paused\";\n return;\n }\n\n if (this.running) {\n if (this.hasVisibilityBlock) {\n this.cancelFrame();\n this.currentStatus = \"paused\";\n return;\n }\n\n if (this.hasMotionBlock) {\n this.cancelFrame();\n this.currentStatus = \"paused\";\n this.renderStaticFrame();\n return;\n }\n\n this.currentStatus = \"running\";\n if (this.options.renderMode === \"demand\") this.render();\n else this.scheduleFrame();\n return;\n }\n\n if (this.options.renderMode === \"demand\") this.render();\n }\n\n private renderStaticFrame(): void {\n if (this.hasVisibilityBlock) return;\n this.syncSourceTime();\n this.renderInternal(this.elapsed, 0);\n }\n\n private renderInternal(time: number, delta: number): void {\n // An asynchronous capture draw holds the lock across tasks.\n if (!this.dom || !this.context || this.inRender) return;\n const gl = this.context;\n\n this.inRender = true;\n try {\n this.syncSize();\n this.options.onDraw(this.createFrameState(time, delta, gl));\n this.frame++;\n } finally {\n this.inRender = false;\n }\n }\n\n // Holds the render lock across an asynchronous capture draw so no other\n // frame interleaves with it.\n private async renderForCapture(\n draw: NonNullable<RuntimeHostOptions[\"onCaptureDraw\"]>,\n delta: number,\n signal: AbortSignal | undefined\n ): Promise<void> {\n if (!this.dom || !this.context) return;\n this.inRender = true;\n this.captureDrawing = true;\n try {\n this.syncSize();\n await draw(this.createFrameState(this.elapsed, delta, this.context), signal);\n this.frame++;\n } finally {\n this.inRender = false;\n this.captureDrawing = false;\n }\n }\n\n // Reads the frame just drawn, in the task that drew it: the drawing buffer\n // is not preserved. Fails if the context drawn into is gone, including when\n // it was lost and restored while an asynchronous draw was pending.\n private readCapture<F extends CaptureFormat>(\n format: CaptureFormat,\n drawContext: GLContext | null\n ): Promise<CaptureResult<F>> | CaptureResult<F> {\n if (this.destroyed) {\n throw new DestroyedError(\"Runtime host was destroyed.\");\n }\n const gl = this.context;\n if (!gl || gl !== drawContext || !this.dom) {\n throw new UnsupportedError(\"The WebGL context was lost while capturing.\");\n }\n\n if (format === \"png\") {\n return canvasToPng(this.dom.canvas) as Promise<CaptureResult<F>>;\n }\n if (format === \"rgba8\") {\n return readPixels(gl, null, this.width, this.height, \"rgba8\") as CaptureResult<F>;\n }\n const source = this.options.captureSource!()!;\n return readPixels(\n gl,\n source.framebuffer,\n source.width,\n source.height,\n \"rgba16f\"\n ) as CaptureResult<F>;\n }\n\n private createFrameState(\n time: number,\n delta: number,\n gl: GLContext = this.context!\n ): HostFrameState {\n return {\n gl,\n canvas: this.dom!.canvas,\n time,\n delta,\n frame: this.frame,\n width: this.width,\n height: this.height,\n viewportWidth: this.viewportWidth,\n viewportHeight: this.viewportHeight,\n pixelRatio: this.pixelRatio,\n reducedMotion: this.isManual ? false : this.reducedMotionActive,\n pointer: this.isManual ? { ...IDLE_POINTER } : { ...this.pointer }\n };\n }\n\n /**\n * Measures the size and calls onResize if it changed. Frames measure too:\n * browsers run animation frames before resize observations, so in a running\n * loop a frame is usually the first to see a new size.\n */\n private syncSize(): void {\n const prevWidth = this.width;\n const prevHeight = this.height;\n const prevViewportWidth = this.viewportWidth;\n const prevViewportHeight = this.viewportHeight;\n\n this.measureSize();\n\n const sizeChanged =\n this.width !== prevWidth ||\n this.height !== prevHeight ||\n this.viewportWidth !== prevViewportWidth ||\n this.viewportHeight !== prevViewportHeight;\n\n if (sizeChanged && this.context) {\n this.options.onResize?.(this.createFrameState(this.elapsed, 0));\n }\n }\n\n private measureSize(): void {\n if (!this.dom) return;\n\n if (this.fixedResolution) {\n const size = resizeCanvasToResolution(\n this.dom.canvas,\n this.dom.detached ? null : this.dom.target,\n this.fixedResolution\n );\n this.width = size.width;\n this.height = size.height;\n this.viewportWidth = size.viewportWidth;\n this.viewportHeight = size.viewportHeight;\n // Internal pixels per displayed CSS pixel under object-fit: contain.\n this.pixelRatio = Math.max(\n size.width / size.viewportWidth,\n size.height / size.viewportHeight\n );\n this.contentOffsetX =\n (size.viewportWidth - size.width / this.pixelRatio) / 2;\n this.contentOffsetY =\n (size.viewportHeight - size.height / this.pixelRatio) / 2;\n return;\n }\n\n this.contentOffsetX = 0;\n this.contentOffsetY = 0;\n this.pixelRatio = resolveDpr(this.options.dpr, this.options.maxDpr);\n const size = resizeCanvasToTarget(\n this.dom.canvas,\n this.dom.target,\n this.pixelRatio\n );\n this.width = size.width;\n this.height = size.height;\n this.viewportWidth = size.viewportWidth;\n this.viewportHeight = size.viewportHeight;\n }\n\n // Letterbox the fixed-resolution canvas instead of stretching it.\n private applyObjectFit(): void {\n if (!this.dom) return;\n const style = this.dom.canvas.style;\n if (this.fixedResolution && this.objectFitRestore === null) {\n this.objectFitRestore = style.objectFit ?? \"\";\n style.objectFit = \"contain\";\n } else if (!this.fixedResolution && this.objectFitRestore !== null) {\n style.objectFit = this.objectFitRestore;\n this.objectFitRestore = null;\n }\n }\n\n private scheduleFrame(): void {\n if (this.rafId || this.options.renderMode === \"demand\" || this.isManual)\n return;\n\n this.rafId = requestAnimationFrame((timestamp) => {\n this.rafId = 0;\n if (!this.running || this.destroyed) return;\n\n const seconds = timestamp / 1000;\n let delta: number;\n if (this.followsSource) {\n delta = this.advanceFromSource();\n } else {\n delta = this.lastTimestamp ? clampDelta(seconds - this.lastTimestamp) : 0;\n this.elapsed += delta;\n }\n this.lastTimestamp = seconds;\n this.renderInternal(this.elapsed, delta);\n this.scheduleFrame();\n });\n }\n\n private cancelFrame(): void {\n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = 0;\n }\n this.lastTimestamp = 0;\n this.lastSourceTime = null;\n }\n\n private async init(): Promise<void> {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n this.failUnsupported(new UnsupportedError(\"WebGL requires a browser.\"));\n return;\n }\n\n this.dom = setupCanvas({\n ...(this.options.target !== undefined && { target: this.options.target }),\n ...(this.options.canvas !== undefined && { canvas: this.options.canvas }),\n ...(this.options.layer !== undefined && { layer: this.options.layer }),\n ...(this.options.canvasClass !== undefined && { canvasClass: this.options.canvasClass }),\n ...(this.options.canvasStyle !== undefined && { canvasStyle: this.options.canvasStyle }),\n // Only a missing target/canvas may fall back to a detached canvas; a\n // target that fails to resolve must still report TargetNotFoundError.\n detached:\n this.fixedResolution !== null &&\n this.options.target === undefined &&\n this.options.canvas === undefined\n });\n\n if (!this.dom) {\n this.failUnsupported(\n new TargetNotFoundError(\n \"Target or canvas not found. Pass `resolution` to render without a target.\"\n )\n );\n return;\n }\n\n let gl: GLContext | null;\n try {\n gl = this.options.createContext(this.dom.canvas);\n } catch (error) {\n this.failUnsupported(\n error instanceof UnsupportedError\n ? error\n : new UnsupportedError(String(error))\n );\n return;\n }\n if (!gl) {\n this.failUnsupported(new UnsupportedError(\"WebGL is not supported.\"));\n return;\n }\n\n if (this.fixedResolution) {\n try {\n assertWithinLimits(gl, this.fixedResolution);\n } catch (error) {\n this.failUnsupported(\n error instanceof Error ? error : new UnsupportedError(String(error))\n );\n return;\n }\n if (this.options.dpr !== undefined || this.options.maxDpr !== undefined) {\n this.debugWarn(\"`dpr` and `maxDpr` are ignored while `resolution` is set.\");\n }\n }\n\n this.context = gl;\n this.currentStatus = \"loading\";\n\n try {\n this.applyObjectFit();\n this.setupDomObservers();\n this.setupContextEvents();\n this.measureSize();\n await this.options.onInit(gl, this.width, this.height);\n if (this.destroyed) return;\n this.currentStatus = \"ready\";\n this.readyResolve?.();\n this.options.onReady?.();\n\n if (this.running || (this.options.autoStart ?? true)) {\n this.start();\n } else if (this.shouldRenderOnDemand) {\n this.render();\n }\n } catch (error) {\n if (error instanceof UnsupportedError) this.failUnsupported(error);\n else this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n private setupDomObservers(): void {\n if (!this.dom) return;\n const detached = this.dom.detached === true;\n\n // A detached canvas has no layout: it can never be measured, scrolled into\n // view or pointed at, so only document-level observers apply.\n if (!detached && (this.options.autoResize ?? true)) {\n this.resizeObserver = new ResizeObserver(() => {\n this.resize();\n });\n this.resizeObserver.observe(this.dom.target);\n }\n\n if (!detached && (this.options.pauseWhenOffscreen ?? true)) {\n this.intersectionObserver = new IntersectionObserver((entries) => {\n const entry = entries[0];\n this.setGate(\"offscreen\", !entry?.isIntersecting);\n });\n this.intersectionObserver.observe(this.dom.target);\n }\n\n if (this.options.pauseWhenHidden ?? true) {\n if (document.hidden) this.gates.add(\"hidden\");\n const onVisibility = () => {\n this.setGate(\"hidden\", document.hidden);\n };\n document.addEventListener(\"visibilitychange\", onVisibility);\n this.removeListeners.push(() => {\n document.removeEventListener(\"visibilitychange\", onVisibility);\n });\n }\n\n this.setupMotionObserver();\n\n if (detached) return;\n\n const onPointerMove = (event: Event) => {\n if (!this.dom) return;\n const pointerEvent = event as PointerEvent;\n const rect = this.dom.target.getBoundingClientRect();\n const x = pointerEvent.clientX - rect.left - this.contentOffsetX;\n const y = pointerEvent.clientY - rect.top - this.contentOffsetY;\n // Displayed content size in CSS px (smaller than rect when letterboxed).\n const contentWidth = this.fixedResolution\n ? this.width / this.pixelRatio\n : rect.width;\n const contentHeight = this.fixedResolution\n ? this.height / this.pixelRatio\n : rect.height;\n this.pointer.x = x * this.pixelRatio;\n this.pointer.y = (contentHeight - y) * this.pixelRatio;\n this.pointer.uvX = contentWidth > 0 ? x / contentWidth : 0;\n this.pointer.uvY = contentHeight > 0 ? 1 - y / contentHeight : 0;\n this.pointer.active = 1;\n\n if (this.shouldRenderOnDemand) this.render();\n };\n const onPointerLeave = () => {\n this.pointer.active = 0;\n if (this.shouldRenderOnDemand) this.render();\n };\n\n this.dom.target.addEventListener(\"pointermove\", onPointerMove);\n this.dom.target.addEventListener(\"pointerenter\", onPointerMove);\n this.dom.target.addEventListener(\"pointerleave\", onPointerLeave);\n this.removeListeners.push(() => {\n this.dom?.target.removeEventListener(\"pointermove\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerenter\", onPointerMove);\n this.dom?.target.removeEventListener(\"pointerleave\", onPointerLeave);\n });\n }\n\n private setupMotionObserver(): void {\n if (typeof window.matchMedia !== \"function\") return;\n\n const query = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n this.reducedMotionActive = query.matches;\n if (this.options.respectReducedMotion && query.matches) {\n this.gates.add(\"reducedMotion\");\n }\n\n const onChange = (event: MediaQueryListEvent) => {\n this.reducedMotionActive = event.matches;\n if (this.options.respectReducedMotion) {\n this.setGate(\"reducedMotion\", event.matches);\n } else if (this.shouldRenderOnDemand) {\n this.render();\n }\n };\n\n query.addEventListener(\"change\", onChange);\n this.removeListeners.push(() => {\n query.removeEventListener(\"change\", onChange);\n });\n }\n\n private setupContextEvents(): void {\n if (!this.dom) return;\n\n const onLost = (event: Event) => {\n event.preventDefault();\n this.contextRestoredShouldRun = this.running;\n this.statusBeforeLoss = this.currentStatus;\n this.cancelFrame();\n this.context = null;\n this.currentStatus = \"context-lost\";\n this.options.onContextLost?.();\n this.options.onError?.(new UnsupportedError(\"WebGL context lost.\"));\n };\n\n const onRestored = () => {\n if (!this.dom || this.destroyed) return;\n const gl = this.options.createContext(this.dom.canvas);\n if (!gl) return;\n this.context = gl;\n\n const afterRestore = async () => {\n try {\n await this.options.onContextRestored?.(gl, this.width, this.height);\n // A stopped or manual-clock instance would otherwise stay\n // \"context-lost\", and render() would refuse to draw.\n if (this.currentStatus === \"context-lost\") this.currentStatus = this.statusBeforeLoss;\n if (this.contextRestoredShouldRun) this.start();\n else if (!this.isManual) this.render();\n } catch (error) {\n this.fail(error instanceof Error ? error : new Error(String(error)));\n }\n };\n void afterRestore();\n };\n\n this.dom.canvas.addEventListener(\"webglcontextlost\", onLost);\n this.dom.canvas.addEventListener(\"webglcontextrestored\", onRestored);\n this.removeListeners.push(() => {\n this.dom?.canvas.removeEventListener(\"webglcontextlost\", onLost);\n this.dom?.canvas.removeEventListener(\"webglcontextrestored\", onRestored);\n });\n }\n\n private failUnsupported(error: Error): void {\n this.currentStatus = \"unsupported\";\n this.debugWarn(error.message);\n this.options.onError?.(error);\n // An unsupported environment is expected; a missing target stays loud.\n if (error instanceof UnsupportedError) this.markReadyHandled();\n this.readyReject?.(error);\n }\n\n private fail(error: Error): void {\n this.currentStatus = \"error\";\n this.debugWarn(error.message);\n this.options.onError?.(error);\n this.readyReject?.(error);\n }\n\n // Keeps an unawaited `ready` from surfacing as an unhandled rejection, e.g.\n // after a StrictMode cleanup or during SSR. Callers still see the rejection.\n private markReadyHandled(): void {\n this.ready.catch(() => {});\n }\n\n private debugWarn(message: string): void {\n if (this.options.debug) {\n console.warn(`[frapx/runtime] ${message}`);\n }\n }\n}\n\nconst normalizeResolution = (resolution: Resolution): Resolution => {\n const [width, height] = resolution;\n if (\n !Number.isFinite(width) ||\n !Number.isFinite(height) ||\n width < 1 ||\n height < 1\n ) {\n throw new RangeError(`Invalid resolution: ${width}x${height}`);\n }\n return [Math.round(width), Math.round(height)];\n};\n\nconst assertWithinLimits = (gl: GLContext, resolution: Resolution): void => {\n const [width, height] = resolution;\n const viewportDims = gl.getParameter(gl.MAX_VIEWPORT_DIMS) as\n | ArrayLike<number>\n | null;\n const renderbufferSize = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE) as\n | number\n | null;\n const limit = (axis: 0 | 1): number =>\n Math.min(\n viewportDims?.[axis] ?? Number.POSITIVE_INFINITY,\n typeof renderbufferSize === \"number\"\n ? renderbufferSize\n : Number.POSITIVE_INFINITY\n );\n\n if (width > limit(0) || height > limit(1)) {\n throw new UnsupportedError(\n `Resolution ${width}x${height} exceeds this GPU's limit of ${limit(0)}x${limit(1)}.`\n );\n }\n};\n","export const toUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name : `u_${name}`;\n\nexport const fromUniformName = (name: string): string =>\n name.startsWith(\"u_\") ? name.slice(2) : name;\n","import type { ExplicitUniformInput, GLContext, UniformInput, UniformType } from \"../types\";\nimport { toUniformName } from \"./names\";\n\nexport type NormalizedUniform = {\n type: UniformType;\n value: number[] | Float32Array;\n};\n\nexport const normalizeUniform = (input: UniformInput): NormalizedUniform => {\n if (typeof input === \"number\") {\n return { type: \"float\", value: [input] };\n }\n\n if (input instanceof Float32Array) {\n if (input.length === 9) return { type: \"mat3\", value: input };\n if (input.length === 16) return { type: \"mat4\", value: input };\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n if (isExplicitUniform(input)) {\n return { type: input.type, value: input.value };\n }\n\n if (Array.isArray(input)) {\n if (input.length === 2) return { type: \"vec2\", value: input };\n if (input.length === 3) return { type: \"vec3\", value: input };\n if (input.length === 4) return { type: \"vec4\", value: input };\n }\n\n return { type: \"float\", value: [0] };\n};\n\nexport const applyUniform = (\n gl: GLContext,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n const value = uniform.value;\n\n switch (uniform.type) {\n case \"float\":\n gl.uniform1f(location, value[0] ?? 0);\n break;\n case \"vec2\":\n gl.uniform2f(location, value[0] ?? 0, value[1] ?? 0);\n break;\n case \"vec3\":\n gl.uniform3f(location, value[0] ?? 0, value[1] ?? 0, value[2] ?? 0);\n break;\n case \"vec4\":\n gl.uniform4f(\n location,\n value[0] ?? 0,\n value[1] ?? 0,\n value[2] ?? 0,\n value[3] ?? 0\n );\n break;\n case \"mat3\":\n gl.uniformMatrix3fv(location, false, value);\n break;\n case \"mat4\":\n gl.uniformMatrix4fv(location, false, value);\n break;\n }\n};\n\nexport const applyProgramUniform = (\n gl: GLContext,\n program: WebGLProgram,\n location: WebGLUniformLocation,\n uniform: NormalizedUniform\n): void => {\n gl.useProgram(program);\n applyUniform(gl, location, uniform);\n};\n\n/**\n * Uploads every cached uniform to the bound program. Calls `onMissing` with\n * the name of each uniform the program lacks or optimized out.\n */\nexport const applyUniforms = (\n gl: GLContext,\n locations: ReadonlyMap<string, WebGLUniformLocation>,\n cache: ReadonlyMap<string, NormalizedUniform>,\n onMissing?: (name: string) => void\n): void => {\n for (const [name, uniform] of cache) {\n const location = locations.get(name);\n if (!location) {\n onMissing?.(name);\n continue;\n }\n applyUniform(gl, location, uniform);\n }\n};\n\nexport const collectUniformLocations = (\n gl: GLContext,\n program: WebGLProgram\n): Map<string, WebGLUniformLocation> => {\n const locations = new Map<string, WebGLUniformLocation>();\n const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS) as number;\n\n for (let index = 0; index < count; index += 1) {\n const active = gl.getActiveUniform(program, index);\n if (!active) continue;\n\n const name = active.name.replace(/\\[0\\]$/, \"\");\n const location = gl.getUniformLocation(program, name);\n if (location) {\n locations.set(name, location);\n }\n }\n\n return locations;\n};\n\nexport const createUniformCache = (\n uniforms: Record<string, UniformInput> | undefined\n): Map<string, NormalizedUniform> => {\n const cache = new Map<string, NormalizedUniform>();\n\n for (const [name, value] of Object.entries(uniforms ?? {})) {\n cache.set(toUniformName(name), normalizeUniform(value));\n }\n\n return cache;\n};\n\nconst isExplicitUniform = (input: unknown): input is ExplicitUniformInput => {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) return false;\n return \"type\" in input && \"value\" in input;\n};\n","import type { UniformInput } from \"../types\";\nimport { toUniformName } from \"./names\";\nimport { normalizeUniform, type NormalizedUniform } from \"./uniforms\";\n\n/**\n * Supplies uniform values for a time, such as a keyframe timeline. Runtimes\n * call `get()` with the same time as `u_time` before drawing.\n */\nexport type UniformSource = {\n get(time: number): Readonly<Record<string, UniformInput>>;\n};\n\n/** Ordered sources whose values override the runtime's own uniforms. */\nexport type UniformBindings = {\n /** Adds `source`; a later source wins for the same name. Returns its removal. */\n add(source: UniformSource): () => void;\n readonly size: number;\n /** Merged, normalized values at `time`, keyed by uniform name (`u_` prefixed). */\n evaluate(time: number): Map<string, NormalizedUniform>;\n /** A stable string of the values at `time`, to notice when they change. */\n signature(time: number): string;\n};\n\nexport const createUniformBindings = (): UniformBindings => {\n const sources: UniformSource[] = [];\n\n const evaluate = (time: number): Map<string, NormalizedUniform> => {\n const merged = new Map<string, NormalizedUniform>();\n for (const source of sources) {\n for (const [name, value] of Object.entries(source.get(time))) {\n merged.set(toUniformName(name), normalizeUniform(value));\n }\n }\n return merged;\n };\n\n return {\n add(source) {\n sources.push(source);\n let removed = false;\n return () => {\n if (removed) return;\n removed = true;\n const index = sources.indexOf(source);\n if (index >= 0) sources.splice(index, 1);\n };\n },\n get size() {\n return sources.length;\n },\n evaluate,\n signature(time) {\n if (sources.length === 0) return \"\";\n let text = \"\";\n for (const [name, uniform] of evaluate(time)) {\n text += `${name}:${uniform.type}:${Array.from(uniform.value).join(\",\")};`;\n }\n return text;\n }\n };\n};\n\n// --- Keyframes -------------------------------------------------------------------\n\nexport type KeyframeValue =\n | number\n | readonly [number, number]\n | readonly [number, number, number]\n | readonly [number, number, number, number];\n\n/** `[time in seconds, value]`. */\nexport type Keyframe = readonly [number, KeyframeValue];\n\n/**\n * How a segment eases from one key to the next: `\"linear\"`, `\"smooth\"`\n * (smoothstep), `\"step\"` (hold the earlier key), or a function of the\n * segment's 0–1 progress.\n */\nexport type Ease = \"linear\" | \"smooth\" | \"step\" | ((t: number) => number);\n\nexport type KeyframeTrack = readonly Keyframe[] | { keys: readonly Keyframe[]; ease?: Ease };\n\nexport type KeyframeOptions = {\n /** Default ease for tracks that do not set their own. Defaults to `\"linear\"`. */\n ease?: Ease;\n};\n\nconst EASES: Record<Exclude<Ease, (t: number) => number>, (t: number) => number> = {\n linear: (t) => t,\n smooth: (t) => t * t * (3 - 2 * t),\n step: () => 0\n};\n\nconst toEaseFunction = (ease: Ease): ((t: number) => number) => {\n if (typeof ease === \"function\") return ease;\n const fn = EASES[ease];\n if (!fn) throw new RangeError(`Unknown ease: ${String(ease)}`);\n return fn;\n};\n\nconst componentsOf = (value: KeyframeValue): readonly number[] =>\n typeof value === \"number\" ? [value] : value;\n\ntype CompiledTrack = {\n times: number[];\n values: Array<readonly number[]>;\n scalar: boolean;\n ease: (t: number) => number;\n};\n\nconst isKeyList = (track: KeyframeTrack): track is readonly Keyframe[] => Array.isArray(track);\n\nconst compileTrack = (name: string, track: KeyframeTrack, fallback: Ease): CompiledTrack => {\n // Not `\"keys\" in track`: arrays have a keys() method.\n const list = isKeyList(track);\n const keys = list ? track : track.keys;\n const ease = toEaseFunction((list ? undefined : track.ease) ?? fallback);\n if (keys.length === 0) throw new TypeError(`Keyframe track ${name} has no keys.`);\n\n const sorted = [...keys].sort((a, b) => a[0] - b[0]);\n const scalar = typeof sorted[0]![1] === \"number\";\n const size = componentsOf(sorted[0]![1]).length;\n for (const [time, value] of sorted) {\n if (!Number.isFinite(time)) throw new TypeError(`Keyframe track ${name} has a non-finite time.`);\n const components = componentsOf(value);\n if ((typeof value === \"number\") !== scalar || components.length !== size) {\n throw new TypeError(`Keyframe track ${name} mixes values of different sizes.`);\n }\n if (!components.every(Number.isFinite)) {\n throw new TypeError(`Keyframe track ${name} has a non-finite value.`);\n }\n }\n return {\n times: sorted.map(([time]) => time),\n values: sorted.map(([, value]) => componentsOf(value)),\n scalar,\n ease\n };\n};\n\nconst sampleTrack = (track: CompiledTrack, time: number): UniformInput => {\n const { times, values } = track;\n const last = times.length - 1;\n let components: readonly number[];\n if (time <= times[0]!) {\n components = values[0]!;\n } else if (time >= times[last]!) {\n components = values[last]!;\n } else {\n // The last key at or before `time`.\n let low = 0;\n let high = last;\n while (high - low > 1) {\n const middle = (low + high) >> 1;\n if (times[middle]! <= time) low = middle;\n else high = middle;\n }\n const span = times[high]! - times[low]!;\n const t = span > 0 ? track.ease((time - times[low]!) / span) : 0;\n const from = values[low]!;\n const to = values[high]!;\n components = from.map((value, index) => value + (to[index]! - value) * t);\n }\n return track.scalar ? components[0]! : (Array.from(components) as UniformInput);\n};\n\n/**\n * A `UniformSource` that interpolates keyframes per component: floats and\n * vec2–vec4 as tuples. Keys may come in any order; times before the first key\n * or after the last hold that key's value.\n *\n * ```ts\n * fx.bindUniforms(keyframes({\n * camPos: [[0, [0, 1, 6]], [4, [3, 1.5, 2]]],\n * glow: { keys: [[0, 0], [2, 1]], ease: \"smooth\" }\n * }));\n * ```\n */\nexport const keyframes = (\n tracks: Readonly<Record<string, KeyframeTrack>>,\n options: KeyframeOptions = {}\n): UniformSource => {\n const fallback = options.ease ?? \"linear\";\n toEaseFunction(fallback);\n const compiled = Object.entries(tracks).map(\n ([name, track]) => [name, compileTrack(name, track, fallback)] as const\n );\n return {\n get(time) {\n const values: Record<string, UniformInput> = {};\n for (const [name, track] of compiled) values[name] = sampleTrack(track, time);\n return values;\n }\n };\n};\n","import type { GLContext, TextureInput, TextureOptions, TextureSource } from \"../types\";\nimport { TextureLoadError } from \"./errors\";\nimport { toUniformName } from \"./names\";\n\nexport type LoadedTexture = {\n name: string;\n uniformName: string;\n sizeUniformName: string;\n texture: WebGLTexture;\n width: number;\n height: number;\n};\n\nexport const loadTexture = async (\n gl: GLContext,\n name: string,\n input: TextureInput,\n unit: number\n): Promise<LoadedTexture> => {\n const options = normalizeTextureInput(input);\n const source = await resolveSource(options.source);\n const texture = gl.createTexture();\n\n if (!texture) {\n throw new TextureLoadError(`Failed to create texture: ${name}`);\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, options.flipY ?? true);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);\n\n const wrap = getWrap(gl, options.wrap ?? \"clamp\");\n const filter = getFilter(gl, options.filter ?? \"linear\");\n\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n return {\n name,\n uniformName: toUniformName(name),\n sizeUniformName: toUniformName(`${name}Size`),\n texture,\n width: getSourceWidth(source),\n height: getSourceHeight(source)\n };\n};\n\nconst normalizeTextureInput = (input: TextureInput): TextureOptions => {\n if (typeof input === \"string\" || isTextureSource(input)) {\n return { source: input };\n }\n\n return input;\n};\n\nconst resolveSource = async (\n source: TextureSource\n): Promise<HTMLImageElement | HTMLCanvasElement> => {\n if (typeof source !== \"string\") {\n return source;\n }\n\n const image = new Image();\n image.crossOrigin = \"anonymous\";\n image.src = source;\n\n try {\n await image.decode();\n } catch {\n throw new TextureLoadError(`Failed to load texture: ${source}`);\n }\n\n return image;\n};\n\nconst getWrap = (\n gl: GLContext,\n wrap: NonNullable<TextureOptions[\"wrap\"]>\n): number => {\n if (wrap === \"repeat\") return gl.REPEAT;\n if (wrap === \"mirror\") return gl.MIRRORED_REPEAT;\n return gl.CLAMP_TO_EDGE;\n};\n\nconst getFilter = (\n gl: GLContext,\n filter: NonNullable<TextureOptions[\"filter\"]>\n): number => (filter === \"nearest\" ? gl.NEAREST : gl.LINEAR);\n\nconst isTextureSource = (\n input: unknown\n): input is HTMLImageElement | HTMLCanvasElement =>\n typeof HTMLImageElement !== \"undefined\" &&\n (input instanceof HTMLImageElement || input instanceof HTMLCanvasElement);\n\nconst getSourceWidth = (\n source: HTMLImageElement | HTMLCanvasElement\n): number =>\n \"naturalWidth\" in source ? source.naturalWidth : source.width;\n\nconst getSourceHeight = (\n source: HTMLImageElement | HTMLCanvasElement\n): number =>\n \"naturalHeight\" in source ? source.naturalHeight : source.height;\n","import type { GLContext, TextureInput, TextureMap } from \"../types\";\nimport { TextureLoadError } from \"./errors\";\nimport { loadTexture, type LoadedTexture } from \"./textures\";\n\nexport type TextureSet = {\n /** The textures loaded so far, by name. */\n readonly textures: ReadonlyMap<string, LoadedTexture>;\n /** Whether `name` was given as an input, loaded or not. */\n hasInput(name: string): boolean;\n /**\n * Returns the texture unit for `name`, taking the lowest free unit on first\n * use. Runtimes reserve units for their own samplers (feedback, pass inputs)\n * here too, so they never collide with image textures.\n */\n reserveUnit(gl: GLContext, name: string): number;\n /**\n * Loads every input, then replaces the previously loaded textures. Used for\n * the initial load and after a context restore.\n */\n loadAll(gl: GLContext, isCancelled: () => boolean): Promise<void>;\n /**\n * Loads `input` as `name`. Resolves to the loaded texture, or `null` when a\n * later `set()` for the same name or `isCancelled()` superseded it (its\n * texture is deleted). On failure the unit is released if `name` is unused,\n * and the error is rethrown.\n */\n set(\n gl: GLContext,\n name: string,\n input: TextureInput,\n isCancelled: () => boolean\n ): Promise<LoadedTexture | null>;\n /**\n * Binds every loaded texture to its unit and points its sampler uniform at\n * it. Calls `onMissing` with the uniform name when the program lacks it.\n */\n bind(\n gl: GLContext,\n locations: ReadonlyMap<string, WebGLUniformLocation>,\n onMissing?: (uniformName: string) => void\n ): void;\n /** Deletes every loaded texture. */\n dispose(gl: GLContext): void;\n};\n\n/**\n * Tracks named image textures and the texture units they occupy, for a\n * runtime that binds them to one or more programs.\n */\nexport const createTextureSet = (inputs: TextureMap = {}): TextureSet => {\n const textureInputs = new Map<string, TextureInput>(Object.entries(inputs));\n let textures = new Map<string, LoadedTexture>();\n const units = new Map<string, number>();\n const versions = new Map<string, number>();\n\n const reserveUnit = (gl: GLContext, name: string): number => {\n const existing = units.get(name);\n if (existing !== undefined) return existing;\n\n const maxUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) as number;\n const used = new Set(units.values());\n for (let unit = 0; unit < maxUnits; unit += 1) {\n if (!used.has(unit)) {\n units.set(name, unit);\n return unit;\n }\n }\n\n throw new TextureLoadError(\n `Texture unit limit exceeded while loading texture: ${name}`\n );\n };\n\n return {\n get textures() {\n return textures;\n },\n\n hasInput(name) {\n return textureInputs.has(name);\n },\n\n reserveUnit,\n\n async loadAll(gl, isCancelled) {\n const loaded = new Map<string, LoadedTexture>();\n for (const [name, input] of textureInputs) {\n if (isCancelled()) break;\n const unit = reserveUnit(gl, name);\n loaded.set(name, await loadTexture(gl, name, input, unit));\n }\n\n for (const texture of textures.values()) {\n gl.deleteTexture(texture.texture);\n }\n textures = loaded;\n },\n\n async set(gl, name, input, isCancelled) {\n const version = (versions.get(name) ?? 0) + 1;\n versions.set(name, version);\n\n try {\n const unit = reserveUnit(gl, name);\n const loaded = await loadTexture(gl, name, input, unit);\n\n if (isCancelled() || versions.get(name) !== version) {\n gl.deleteTexture(loaded.texture);\n return null;\n }\n\n const previous = textures.get(name);\n textureInputs.set(name, input);\n textures.set(name, loaded);\n if (previous) gl.deleteTexture(previous.texture);\n return loaded;\n } catch (error) {\n if (!textures.has(name) && !textureInputs.has(name)) {\n units.delete(name);\n }\n throw error;\n }\n },\n\n bind(gl, locations, onMissing) {\n for (const texture of textures.values()) {\n const unit = units.get(texture.name);\n if (unit === undefined) continue;\n const location = locations.get(texture.uniformName);\n if (!location) {\n onMissing?.(texture.uniformName);\n continue;\n }\n\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, texture.texture);\n gl.uniform1i(location, unit);\n }\n },\n\n dispose(gl) {\n for (const texture of textures.values()) {\n gl.deleteTexture(texture.texture);\n }\n }\n };\n};\n","import type { GLContext } from \"../types\";\nimport { collectUniformLocations } from \"./uniforms\";\nimport {\n createFullscreenBuffer,\n createProgram,\n defaultVertexShader,\n defaultVertexShader300,\n isGLSL300\n} from \"./webgl\";\n\nexport type FullscreenProgram = {\n readonly program: WebGLProgram;\n /** Active uniform locations by name, array uniforms without `[0]`. */\n readonly locations: ReadonlyMap<string, WebGLUniformLocation>;\n /**\n * Binds the program, its quad buffer and `a_position`, so a draw is correct\n * whatever GL state user hooks left behind.\n */\n use(): void;\n /** Draws the fullscreen quad with the current GL state. */\n draw(): void;\n dispose(): void;\n};\n\n/**\n * Compiles `fragment` with a fullscreen-quad vertex shader (the GLSL ES 3.00\n * one when `fragment` starts with `#version 300 es`, unless `vertex` is\n * given) and leaves it bound.\n */\nexport const createFullscreenProgram = (\n gl: GLContext,\n fragment: string,\n vertex?: string\n): FullscreenProgram => {\n const defaultVertex = isGLSL300(fragment)\n ? defaultVertexShader300\n : defaultVertexShader;\n const program = createProgram(gl, vertex ?? defaultVertex, fragment);\n gl.useProgram(program);\n const buffer = createFullscreenBuffer(gl, program);\n const attribLocation = gl.getAttribLocation(program, \"a_position\");\n const locations = collectUniformLocations(gl, program);\n\n return {\n program,\n locations,\n use() {\n gl.useProgram(program);\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n if (attribLocation >= 0) {\n gl.enableVertexAttribArray(attribLocation);\n gl.vertexAttribPointer(attribLocation, 2, gl.FLOAT, false, 0, 0);\n }\n },\n draw() {\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n },\n dispose() {\n gl.deleteBuffer(buffer);\n gl.deleteProgram(program);\n }\n };\n};\n","import type { GLContext } from \"../types\";\nimport {\n createFullscreenBuffer,\n createProgram,\n defaultVertexShader,\n defaultVertexShader300,\n isWebGL2Context\n} from \"./webgl\";\n\nconst blitFragmentShader = `\nprecision mediump float;\nvarying vec2 v_uv;\nuniform sampler2D u_texture;\n\nvoid main() {\n gl_FragColor = texture2D(u_texture, v_uv);\n}\n`;\n\nconst blitFragmentShader300 = `#version 300 es\nprecision mediump float;\nin vec2 v_uv;\nuniform sampler2D u_texture;\nout vec4 fragColor;\n\nvoid main() {\n fragColor = texture(u_texture, v_uv);\n}\n`;\n\nexport type Blitter = {\n /**\n * Draws `texture` as a fullscreen quad into `target` (or the default\n * framebuffer when `target` is `null`), setting the viewport to\n * `width`/`height` first. Does not save or restore any other GL state.\n */\n blit(\n texture: WebGLTexture,\n target: WebGLFramebuffer | null,\n width: number,\n height: number\n ): void;\n /** Releases the GL resources owned by this blitter. */\n dispose(): void;\n};\n\n/**\n * Creates a reusable fullscreen-quad \"blit\" utility: draws a texture into a\n * framebuffer (or the canvas) using a minimal passthrough shader. Intended\n * for hand-rolled multi-pass/FBO pipelines; frapx's own multi-pass features\n * are built on the same primitive.\n */\nexport const createBlitter = (gl: GLContext): Blitter => {\n const program = createProgram(\n gl,\n isWebGL2Context(gl) ? defaultVertexShader300 : defaultVertexShader,\n isWebGL2Context(gl) ? blitFragmentShader300 : blitFragmentShader\n );\n const buffer = createFullscreenBuffer(gl, program);\n const textureUniform = gl.getUniformLocation(program, \"u_texture\");\n\n return {\n blit(\n texture: WebGLTexture,\n target: WebGLFramebuffer | null,\n width: number,\n height: number\n ): void {\n gl.bindFramebuffer(gl.FRAMEBUFFER, target);\n gl.viewport(0, 0, width, height);\n gl.useProgram(program);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n const location = gl.getAttribLocation(program, \"a_position\");\n if (location >= 0) {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);\n }\n\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n if (textureUniform) {\n gl.uniform1i(textureUniform, 0);\n }\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n },\n dispose(): void {\n gl.deleteProgram(program);\n gl.deleteBuffer(buffer);\n }\n };\n};\n","import type {\n GLContext,\n PingPong,\n RenderTarget,\n RenderTargetFormat,\n RenderTargetOptions\n} from \"../types\";\nimport { ShaderCompileError, UnsupportedError } from \"./errors\";\nimport { isWebGL2Context } from \"./webgl\";\n\nconst DEFAULT_CLEAR_COLOR = [0, 0, 0, 0] as const;\n\n/**\n * Whether `format` can be allocated as a color attachment on `gl`. `rgba8` is\n * always available; `rgba16f` and `rgba32f` need WebGL2 and\n * `EXT_color_buffer_float`.\n * Enables the extension as a side effect when present.\n */\nexport const supportsRenderTargetFormat = (\n gl: GLContext,\n format: RenderTargetFormat\n): boolean => {\n if (format === \"rgba8\") return true;\n return isWebGL2Context(gl) && gl.getExtension(\"EXT_color_buffer_float\") !== null;\n};\n\n/**\n * Resolves the format a render target will actually use. When `format` is not\n * supported this warns and returns `rgba8`, or throws `UnsupportedError` when\n * `formatFallback` is `false`.\n */\nexport const resolveRenderTargetFormat = (\n gl: GLContext,\n format: RenderTargetFormat = \"rgba8\",\n formatFallback = true\n): RenderTargetFormat => {\n if (supportsRenderTargetFormat(gl, format)) return format;\n\n const reason = `${format} render targets need WebGL2 with EXT_color_buffer_float.`;\n if (!formatFallback) throw new UnsupportedError(reason);\n console.warn(`[frapx] ${reason} Falling back to rgba8.`);\n return \"rgba8\";\n};\n\n/**\n * Creates a texture-backed framebuffer to render into and sample from. The\n * storage is cleared to `clearColor` on creation and on every resize.\n */\nexport const createRenderTarget = (\n gl: GLContext,\n width: number,\n height: number,\n options: RenderTargetOptions = {}\n): RenderTarget => {\n const format = resolveRenderTargetFormat(\n gl,\n options.format,\n options.formatFallback\n );\n return new Target(gl, width, height, format, options);\n};\n\n/**\n * Creates two render targets of the same size and format for feedback-style\n * rendering: draw into `write` while sampling `read`, then `swap()`.\n */\nexport const createPingPong = (\n gl: GLContext,\n width: number,\n height: number,\n options: RenderTargetOptions = {}\n): PingPong => {\n // Resolve once so a fallback warns a single time for both targets.\n const format = resolveRenderTargetFormat(\n gl,\n options.format,\n options.formatFallback\n );\n let read: RenderTarget = new Target(gl, width, height, format, options);\n let write: RenderTarget;\n try {\n write = new Target(gl, width, height, format, options);\n } catch (error) {\n read.dispose();\n throw error;\n }\n\n return {\n get read() {\n return read;\n },\n get write() {\n return write;\n },\n format,\n swap() {\n const previous = read;\n read = write;\n write = previous;\n },\n resize(nextWidth: number, nextHeight: number) {\n read.resize(nextWidth, nextHeight);\n write.resize(nextWidth, nextHeight);\n },\n clear() {\n read.clear();\n write.clear();\n },\n dispose() {\n read.dispose();\n write.dispose();\n }\n };\n};\n\nclass Target implements RenderTarget {\n texture!: WebGLTexture;\n framebuffer!: WebGLFramebuffer;\n width: number;\n height: number;\n\n constructor(\n private readonly gl: GLContext,\n width: number,\n height: number,\n readonly format: RenderTargetFormat,\n private readonly options: RenderTargetOptions\n ) {\n this.width = width;\n this.height = height;\n this.allocate();\n }\n\n resize(width: number, height: number): void {\n if (width === this.width && height === this.height) return;\n this.release();\n this.width = width;\n this.height = height;\n this.allocate();\n }\n\n clear(): void {\n const gl = this.gl;\n const [r, g, b, a] = this.options.clearColor ?? DEFAULT_CLEAR_COLOR;\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\n gl.viewport(0, 0, this.width, this.height);\n gl.clearColor(r, g, b, a);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n dispose(): void {\n this.release();\n }\n\n private allocate(): void {\n const gl = this.gl;\n const texture = gl.createTexture();\n if (!texture) {\n throw new ShaderCompileError(\"Failed to create render target texture.\");\n }\n\n const framebuffer = gl.createFramebuffer();\n if (!framebuffer) {\n gl.deleteTexture(texture);\n throw new ShaderCompileError(\"Failed to create render target framebuffer.\");\n }\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n if (this.format !== \"rgba8\" && isWebGL2Context(gl)) {\n const half = this.format === \"rgba16f\";\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n half ? gl.RGBA16F : gl.RGBA32F,\n this.width,\n this.height,\n 0,\n gl.RGBA,\n half ? gl.HALF_FLOAT : gl.FLOAT,\n null\n );\n } else {\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n this.width,\n this.height,\n 0,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n null\n );\n }\n\n const wrap = getWrap(gl, this.options.wrap ?? \"clamp\");\n // Linear filtering of 32-bit float textures is an optional extension.\n const linear =\n this.options.filter !== \"nearest\" &&\n (this.format !== \"rgba32f\" || gl.getExtension(\"OES_texture_float_linear\") !== null);\n const filter = linear ? gl.LINEAR : gl.NEAREST;\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n texture,\n 0\n );\n\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.deleteFramebuffer(framebuffer);\n gl.deleteTexture(texture);\n throw new ShaderCompileError(\n `Render target framebuffer (${this.format}) is incomplete: ${status}`\n );\n }\n\n this.texture = texture;\n this.framebuffer = framebuffer;\n this.clear();\n }\n\n private release(): void {\n this.gl.deleteFramebuffer(this.framebuffer);\n this.gl.deleteTexture(this.texture);\n }\n}\n\nconst getWrap = (\n gl: GLContext,\n wrap: NonNullable<RenderTargetOptions[\"wrap\"]>\n): number => {\n if (wrap === \"repeat\") return gl.REPEAT;\n if (wrap === \"mirror\") return gl.MIRRORED_REPEAT;\n return gl.CLAMP_TO_EDGE;\n};\n"],"mappings":"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","names":["size","getWrap"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frapx/core",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Shared WebGL runtime host for frapx packages.",
5
5
  "type": "module",
6
6
  "sideEffects": false,