@octane-xplat/shaders 0.14.0 → 0.15.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/README.md CHANGED
@@ -20,7 +20,7 @@ pnpm add @octane-xplat/shaders
20
20
  import { Canvas } from '@octane-xplat/canvas'
21
21
  import { createShader } from '@octane-xplat/shaders'
22
22
 
23
- <Canvas
23
+ ;<Canvas
24
24
  width={320}
25
25
  height={180}
26
26
  style={{ width: 320, height: 180 }}
@@ -66,13 +66,13 @@ static fallback, reduced-motion still frame, disposal on unmount).
66
66
 
67
67
  ## Target status
68
68
 
69
- | Target | Status |
70
- | --- | --- |
71
- | Web (DOM) | Implemented. Upstream engine on the browser WebGPU canvas; reached ready + submissions in the headless-Chromium spike (SwiftShader). Hardware GPU correctness, sustained lifecycle, and visual output are unverified — a SwiftShader device-loss observed in the spike was reproduced without the library (raw WebGPU loop) and is attributed to the headless backend, not the package. |
72
- | NativeScript iOS | Implemented, experimental. `@nativescript/canvas` WebGPU (wgpu over Metal). Build/bundle/type verified; device execution pending. |
73
- | NativeScript Android | Implemented, experimental. Same native route over Vulkan. Build/type verified; device/driver execution pending. |
74
- | AppKit macOS / desktop native | Explicitly unsupported. Importing the package is inert (no GPU work, no engine load); `createShader` resolves to a no-op instance with `getFailureReason() === 'unsupported'` so fallback handling is identical. |
75
- | Web code inside a desktop webview | Follows the browser's own WebGPU support; no separate integration. |
69
+ | Target | Status |
70
+ | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
71
+ | Web (DOM) | Implemented. Upstream engine on the browser WebGPU canvas; reached ready + submissions in the headless-Chromium spike (SwiftShader). Hardware GPU correctness, sustained lifecycle, and visual output are unverified — a SwiftShader device-loss observed in the spike was reproduced without the library (raw WebGPU loop) and is attributed to the headless backend, not the package. |
72
+ | NativeScript iOS | Implemented, experimental. `@nativescript/canvas` WebGPU (wgpu over Metal). Build/bundle/type verified; device execution pending. |
73
+ | NativeScript Android | Implemented, experimental. Same native route over Vulkan. Build/type verified; device/driver execution pending. |
74
+ | AppKit macOS / desktop native | Explicitly unsupported. Importing the package is inert (no GPU work, no engine load); `createShader` resolves to a no-op instance with `getFailureReason() === 'unsupported'` so fallback handling is identical. |
75
+ | Web code inside a desktop webview | Follows the browser's own WebGPU support; no separate integration. |
76
76
 
77
77
  Adapter-owned native defaults: `navigator.gpu` is bound lazily to the
78
78
  `@nativescript/canvas` GPU shim on first use (upstream reads it unconditionally);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octane-xplat/shaders",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "Thin adapter that runs the published `shaders` WebGPU library on Octane xplat Canvas surfaces — web (implemented) and NativeScript iOS/Android (experimental, device verification pending)",
5
5
  "keywords": [
6
6
  "canvas",
@@ -22,9 +22,10 @@
22
22
  "directory": "packages/shaders"
23
23
  },
24
24
  "files": [
25
- "dist",
26
25
  "types",
27
- "src"
26
+ "src",
27
+ "!src/**/*.test.*",
28
+ "!src/**/*.spec.*"
28
29
  ],
29
30
  "type": "module",
30
31
  "exports": {
@@ -34,24 +35,24 @@
34
35
  "default": "./src/index.macos.ts"
35
36
  },
36
37
  "types": "./types/index.d.ts",
37
- "web": "./dist/web/index.js",
38
- "native": "./dist/native/index.js",
39
- "default": "./dist/native/index.js"
38
+ "web": "./src/index.web.ts",
39
+ "native": "./src/index.ts",
40
+ "default": "./src/index.ts"
40
41
  }
41
42
  },
42
43
  "publishConfig": {
43
44
  "access": "public"
44
45
  },
45
46
  "dependencies": {
46
- "@octane-xplat/canvas": "0.14.0",
47
+ "@octane-xplat/canvas": "0.15.0",
47
48
  "shaders": "4.0.0"
48
49
  },
49
50
  "devDependencies": {
50
- "@nativescript-community/octane": "0.2.4",
51
+ "@nativescript-community/octane": "0.2.5",
51
52
  "@nativescript/core": "9.1.3",
52
53
  "@octanejs/vite-plugin": "0.1.61",
53
54
  "octane": "0.11.0",
54
- "tsrx-typegen": "0.2.2",
55
+ "tsrx-typegen": "0.3.0",
55
56
  "typescript": "5.9.3",
56
57
  "vite": "8.3.0"
57
58
  },
@@ -70,7 +71,6 @@
70
71
  }
71
72
  },
72
73
  "scripts": {
73
- "build": "vite build && vite build --mode native && pnpm typegen && node ../../scripts/check-native-dist.mjs",
74
74
  "typegen": "tsc -p tsconfig.types.json",
75
75
  "check-types": "tsc -p tsconfig.check.json",
76
76
  "test:packed": "node tests/packed-consumer.mjs",
package/src/host.ts CHANGED
@@ -26,7 +26,14 @@ import {
26
26
  isWebGPUSupported as upstreamIsWebGPUSupported,
27
27
  } from 'shaders/js'
28
28
 
29
- import type { CreateShaderOptions, PresetConfig, SharedGpu, ShaderInstance, WebGPUSupportInfo } from './types'
29
+ import type {
30
+ CreateShaderOptions,
31
+ PresetConfig,
32
+ SharedGpu,
33
+ ShaderInstance,
34
+ WebGPUSupportInfo,
35
+ } from './types'
36
+
30
37
  import { resolveOptions, throwIfAborted, waitForPositiveSize, wrapInstance } from './shared'
31
38
  import type { Size } from './shared'
32
39
 
@@ -46,10 +53,16 @@ function ensureGpu(): any {
46
53
  }
47
54
 
48
55
  const gpu = gpuShim
49
- if (!gpu) {return null}
56
+ if (!gpu) {
57
+ return null
58
+ }
59
+
50
60
  const g = globalThis as any
51
61
  try {
52
- if (!g.navigator) {g.navigator = {}}
62
+ if (!g.navigator) {
63
+ g.navigator = {}
64
+ }
65
+
53
66
  if (!g.navigator.gpu) {
54
67
  try {
55
68
  g.navigator.gpu = gpu
@@ -110,10 +123,16 @@ function hostCanvas(view: any): any {
110
123
 
111
124
  async function acquireInjectedGpu(): Promise<SharedGpu | null> {
112
125
  const gpu = ensureGpu()
113
- if (!gpu?.requestAdapter) {return null}
126
+ if (!gpu?.requestAdapter) {
127
+ return null
128
+ }
129
+
114
130
  try {
115
131
  const adapter = await gpu.requestAdapter()
116
- if (!adapter) {return null}
132
+ if (!adapter) {
133
+ return null
134
+ }
135
+
117
136
  const device = await adapter.requestDevice()
118
137
  return device ? { device, adapter } : null
119
138
  } catch {
@@ -135,7 +154,9 @@ export async function createShader(
135
154
  // cannot kill another's shared device.
136
155
  if (!upstream.gpu) {
137
156
  const gpu = await acquireInjectedGpu()
138
- if (gpu) {upstream.gpu = gpu}
157
+ if (gpu) {
158
+ upstream.gpu = gpu
159
+ }
139
160
  }
140
161
 
141
162
  throwIfAborted(signal)
@@ -165,7 +186,9 @@ export async function createShader(
165
186
  return wrapInstance(inner, attach)
166
187
  }
167
188
 
168
- export async function createSharedDevice(options?: { powerPreference?: string }): Promise<SharedGpu | null> {
189
+ export async function createSharedDevice(options?: {
190
+ powerPreference?: string
191
+ }): Promise<SharedGpu | null> {
169
192
  ensureGpu()
170
193
  return upstreamCreateSharedDevice(options as any)
171
194
  }
@@ -190,7 +213,10 @@ export function prefersReducedMotion(): boolean {
190
213
  if (isAndroid) {
191
214
  const context = Application.android?.context
192
215
  const settings = (globalThis as any).android?.provider?.Settings
193
- if (!context || !settings?.Global) {return false}
216
+ if (!context || !settings?.Global) {
217
+ return false
218
+ }
219
+
194
220
  const scale = settings.Global.getFloat(
195
221
  context.getContentResolver(),
196
222
  settings.Global.ANIMATOR_DURATION_SCALE,
package/src/host.web.ts CHANGED
@@ -12,7 +12,14 @@ import {
12
12
  isWebGPUSupported as upstreamIsWebGPUSupported,
13
13
  } from 'shaders/js'
14
14
 
15
- import type { CreateShaderOptions, PresetConfig, SharedGpu, ShaderInstance, WebGPUSupportInfo } from './types'
15
+ import type {
16
+ CreateShaderOptions,
17
+ PresetConfig,
18
+ SharedGpu,
19
+ ShaderInstance,
20
+ WebGPUSupportInfo,
21
+ } from './types'
22
+
16
23
  import { resolveOptions, throwIfAborted, waitForPositiveSize, wrapInstance } from './shared'
17
24
  import type { Size } from './shared'
18
25
 
@@ -25,7 +32,10 @@ function measure(canvas: any): Size {
25
32
 
26
33
  function attachVisibility(hide: () => void, show: () => void): () => void {
27
34
  const doc = (globalThis as any).document
28
- if (!doc?.addEventListener) {return () => {}}
35
+ if (!doc?.addEventListener) {
36
+ return () => {}
37
+ }
38
+
29
39
  const onChange = () => (doc.visibilityState === 'hidden' ? hide() : show())
30
40
  doc.addEventListener('visibilitychange', onChange)
31
41
  return () => doc.removeEventListener('visibilitychange', onChange)
@@ -50,7 +60,9 @@ export async function createShader(
50
60
  return wrapInstance(inner, attachVisibility)
51
61
  }
52
62
 
53
- export function createSharedDevice(options?: { powerPreference?: string }): Promise<SharedGpu | null> {
63
+ export function createSharedDevice(options?: {
64
+ powerPreference?: string
65
+ }): Promise<SharedGpu | null> {
54
66
  return upstreamCreateSharedDevice(options as any)
55
67
  }
56
68
 
@@ -64,5 +76,7 @@ export function getWebGPUSupport(): Promise<WebGPUSupportInfo> {
64
76
 
65
77
  export function prefersReducedMotion(): boolean {
66
78
  const matchMedia = (globalThis as any).matchMedia
67
- return typeof matchMedia === 'function' ? !!matchMedia('(prefers-reduced-motion: reduce)').matches : false
79
+ return typeof matchMedia === 'function'
80
+ ? !!matchMedia('(prefers-reduced-motion: reduce)').matches
81
+ : false
68
82
  }
@@ -4,7 +4,13 @@
4
4
  // no-op instance reporting the upstream-style 'unsupported' failure
5
5
  // reason so callers keep their static fallback path identical to web's.
6
6
  export * from './types'
7
- import type { CreateShaderOptions, PresetConfig, SharedGpu, ShaderInstance, WebGPUSupportInfo } from './types'
7
+ import type {
8
+ CreateShaderOptions,
9
+ PresetConfig,
10
+ SharedGpu,
11
+ ShaderInstance,
12
+ WebGPUSupportInfo,
13
+ } from './types'
8
14
 
9
15
  const UNSUPPORTED: ShaderInstance = {
10
16
  getFailureReason: () => 'unsupported',
@@ -24,7 +30,9 @@ export async function createShader(
24
30
  return UNSUPPORTED
25
31
  }
26
32
 
27
- export async function createSharedDevice(_options?: { powerPreference?: string }): Promise<SharedGpu | null> {
33
+ export async function createSharedDevice(_options?: {
34
+ powerPreference?: string
35
+ }): Promise<SharedGpu | null> {
28
36
  return null
29
37
  }
30
38
 
package/src/shared.ts CHANGED
@@ -11,7 +11,9 @@ export function abortError(): Error {
11
11
  }
12
12
 
13
13
  export function throwIfAborted(signal?: AbortSignalLike): void {
14
- if (signal?.aborted) {throw abortError()}
14
+ if (signal?.aborted) {
15
+ throw abortError()
16
+ }
15
17
  }
16
18
 
17
19
  export interface Size {
@@ -21,16 +23,19 @@ export interface Size {
21
23
 
22
24
  /** Defer until the surface reports a positive size (surface not attached /
23
25
  * zero-size layout → wait, don't init). Aborts via `signal`. */
24
- export function waitForPositiveSize(
25
- measure: () => Size,
26
- signal?: AbortSignalLike,
27
- ): Promise<void> {
26
+ export function waitForPositiveSize(measure: () => Size, signal?: AbortSignalLike): Promise<void> {
28
27
  const first = measure()
29
- if (first.width > 0 && first.height > 0) {return Promise.resolve()}
28
+ if (first.width > 0 && first.height > 0) {
29
+ return Promise.resolve()
30
+ }
31
+
30
32
  return new Promise<void>((resolve, reject) => {
31
33
  let timer: ReturnType<typeof setTimeout> | undefined
32
34
  const stop = () => {
33
- if (timer !== undefined) {clearTimeout(timer)}
35
+ if (timer !== undefined) {
36
+ clearTimeout(timer)
37
+ }
38
+
34
39
  signal?.removeEventListener?.('abort', onAbort)
35
40
  }
36
41
 
@@ -40,7 +45,10 @@ export function waitForPositiveSize(
40
45
  }
41
46
 
42
47
  const poll = () => {
43
- if (signal?.aborted) {return onAbort()}
48
+ if (signal?.aborted) {
49
+ return onAbort()
50
+ }
51
+
44
52
  const size = measure()
45
53
  if (size.width > 0 && size.height > 0) {
46
54
  stop()
@@ -88,13 +96,18 @@ export function wrapInstance(inner: ShaderInstance, attach: AttachLifecycle): Sh
88
96
  let destroyed = false
89
97
  const detach = attach(
90
98
  () => {
91
- if (destroyed) {return}
99
+ if (destroyed) {
100
+ return
101
+ }
102
+
92
103
  hostSuspended = true
93
104
  inner.pause()
94
105
  },
95
106
  () => {
96
107
  hostSuspended = false
97
- if (!destroyed && !callerPaused) {inner.resume()}
108
+ if (!destroyed && !callerPaused) {
109
+ inner.resume()
110
+ }
98
111
  },
99
112
  )
100
113
 
@@ -108,10 +121,15 @@ export function wrapInstance(inner: ShaderInstance, attach: AttachLifecycle): Sh
108
121
  },
109
122
  resume: () => {
110
123
  callerPaused = false
111
- if (!hostSuspended) {inner.resume()}
124
+ if (!hostSuspended) {
125
+ inner.resume()
126
+ }
112
127
  },
113
128
  destroy: () => {
114
- if (destroyed) {return}
129
+ if (destroyed) {
130
+ return
131
+ }
132
+
115
133
  destroyed = true
116
134
  detach()
117
135
  inner.destroy()
@@ -1,2 +0,0 @@
1
- import { createShader, createSharedDevice, getWebGPUSupport, isWebGPUSupported, prefersReducedMotion } from "./index3.js";
2
- export { createShader, createSharedDevice, getWebGPUSupport, isWebGPUSupported, prefersReducedMotion };
@@ -1,90 +0,0 @@
1
- //#region src/shared.ts
2
- function abortError() {
3
- const error = /* @__PURE__ */ new Error("createShader aborted before initialization completed");
4
- error.name = "AbortError";
5
- return error;
6
- }
7
- function throwIfAborted(signal) {
8
- if (signal?.aborted) throw abortError();
9
- }
10
- /** Defer until the surface reports a positive size (surface not attached /
11
- * zero-size layout → wait, don't init). Aborts via `signal`. */
12
- function waitForPositiveSize(measure, signal) {
13
- const first = measure();
14
- if (first.width > 0 && first.height > 0) return Promise.resolve();
15
- return new Promise((resolve, reject) => {
16
- let timer;
17
- const stop = () => {
18
- if (timer !== void 0) clearTimeout(timer);
19
- signal?.removeEventListener?.("abort", onAbort);
20
- };
21
- const onAbort = () => {
22
- stop();
23
- reject(abortError());
24
- };
25
- const poll = () => {
26
- if (signal?.aborted) return onAbort();
27
- const size = measure();
28
- if (size.width > 0 && size.height > 0) {
29
- stop();
30
- resolve();
31
- return;
32
- }
33
- timer = setTimeout(poll, 50);
34
- };
35
- signal?.addEventListener?.("abort", onAbort);
36
- timer = setTimeout(poll, 50);
37
- });
38
- }
39
- /** Merge caller options with adapter defaults. `disableTelemetry` defaults
40
- * on for this package's local/preset-driven use; callers may re-enable it.
41
- * The adapter-only `signal` key is stripped before reaching upstream. */
42
- function resolveOptions(options, platformDefaults) {
43
- const { signal, ...rest } = options ?? {};
44
- return {
45
- signal,
46
- upstream: {
47
- ...platformDefaults,
48
- ...rest,
49
- disableTelemetry: options?.disableTelemetry ?? true
50
- }
51
- };
52
- }
53
- /** Wrap the upstream instance so host suspension composes with caller
54
- * pause instead of overriding it: host hide pauses, host show resumes
55
- * only when the caller did not explicitly pause. `destroy` detaches all
56
- * adapter-owned listeners before delegating. */
57
- function wrapInstance(inner, attach) {
58
- let callerPaused = false;
59
- let hostSuspended = false;
60
- let destroyed = false;
61
- const detach = attach(() => {
62
- if (destroyed) return;
63
- hostSuspended = true;
64
- inner.pause();
65
- }, () => {
66
- hostSuspended = false;
67
- if (!destroyed && !callerPaused) inner.resume();
68
- });
69
- return {
70
- getFailureReason: () => inner.getFailureReason(),
71
- update: (id, props) => inner.update(id, props),
72
- resize: (width, height) => inner.resize(width, height),
73
- pause: () => {
74
- callerPaused = true;
75
- inner.pause();
76
- },
77
- resume: () => {
78
- callerPaused = false;
79
- if (!hostSuspended) inner.resume();
80
- },
81
- destroy: () => {
82
- if (destroyed) return;
83
- destroyed = true;
84
- detach();
85
- inner.destroy();
86
- }
87
- };
88
- }
89
- //#endregion
90
- export { abortError, resolveOptions, throwIfAborted, waitForPositiveSize, wrapInstance };
@@ -1,167 +0,0 @@
1
- import { resolveOptions, throwIfAborted, waitForPositiveSize, wrapInstance } from "./index2.js";
2
- import { Application, View, isAndroid, isIOS } from "@nativescript/core";
3
- import { getGPU } from "@octane-xplat/canvas";
4
- import { createShader, createSharedDevice, getWebGPUSupport, isWebGPUSupported } from "shaders/js";
5
- //#region src/host.ts
6
- var gpuShim;
7
- var gpuResolved = false;
8
- /** The plugin's GPU shim is also installed as `navigator.gpu` — upstream
9
- * (and TypeGPU's `configureContext`) reads it unconditionally. */
10
- function ensureGpu() {
11
- if (!gpuResolved) {
12
- gpuResolved = true;
13
- try {
14
- gpuShim = getGPU();
15
- } catch {
16
- gpuShim = null;
17
- }
18
- }
19
- const gpu = gpuShim;
20
- if (!gpu) return null;
21
- const g = globalThis;
22
- try {
23
- if (!g.navigator) g.navigator = {};
24
- if (!g.navigator.gpu) try {
25
- g.navigator.gpu = gpu;
26
- } catch {
27
- Object.defineProperty(g.navigator, "gpu", {
28
- configurable: true,
29
- value: gpu
30
- });
31
- }
32
- } catch {}
33
- return gpu;
34
- }
35
- function measure(view) {
36
- const rect = view?.getBoundingClientRect?.();
37
- const actual = view?.getActualSize?.();
38
- return {
39
- width: Number(rect?.width) || Number(actual?.width) || Number(view?.width) || 0,
40
- height: Number(rect?.height) || Number(actual?.height) || Number(view?.height) || 0
41
- };
42
- }
43
- /** DOM-canvas-shaped facade over the plugin view. `width`/`height` writes
44
- * (upstream's drawing-buffer bookkeeping) are stored locally so the
45
- * plugin view's layout size is never mutated by buffer pixel counts. */
46
- function hostCanvas(view) {
47
- const bag = {
48
- style: {},
49
- width: 0,
50
- height: 0
51
- };
52
- return {
53
- getContext: (kind, options) => view.getContext(kind, options),
54
- getBoundingClientRect: () => {
55
- const { width, height } = measure(view);
56
- return {
57
- x: 0,
58
- y: 0,
59
- top: 0,
60
- left: 0,
61
- right: width,
62
- bottom: height,
63
- width,
64
- height
65
- };
66
- },
67
- get clientWidth() {
68
- return measure(view).width;
69
- },
70
- get clientHeight() {
71
- return measure(view).height;
72
- },
73
- get width() {
74
- return bag.width || measure(view).width;
75
- },
76
- set width(value) {
77
- bag.width = value;
78
- },
79
- get height() {
80
- return bag.height || measure(view).height;
81
- },
82
- set height(value) {
83
- bag.height = value;
84
- },
85
- get style() {
86
- return bag.style;
87
- },
88
- parentElement: null
89
- };
90
- }
91
- async function acquireInjectedGpu() {
92
- const gpu = ensureGpu();
93
- if (!gpu?.requestAdapter) return null;
94
- try {
95
- const adapter = await gpu.requestAdapter();
96
- if (!adapter) return null;
97
- const device = await adapter.requestDevice();
98
- return device ? {
99
- device,
100
- adapter
101
- } : null;
102
- } catch {
103
- return null;
104
- }
105
- }
106
- async function createShader$1(canvas, preset, options) {
107
- const { upstream, signal } = resolveOptions(options, { observeElement: false });
108
- throwIfAborted(signal);
109
- const host = hostCanvas(canvas);
110
- await waitForPositiveSize(() => measure(canvas), signal);
111
- if (!upstream.gpu) {
112
- const gpu = await acquireInjectedGpu();
113
- if (gpu) upstream.gpu = gpu;
114
- }
115
- throwIfAborted(signal);
116
- const inner = await createShader(host, preset, upstream);
117
- if (signal?.aborted) {
118
- inner.destroy();
119
- throwIfAborted(signal);
120
- }
121
- const view = canvas;
122
- const attach = (hide, show) => {
123
- const onLayout = () => inner.resize();
124
- Application.on(Application.suspendEvent, hide);
125
- Application.on(Application.resumeEvent, show);
126
- view?.on?.(View.unloadedEvent, hide);
127
- view?.on?.(View.loadedEvent, show);
128
- view?.on?.(View.layoutChangedEvent, onLayout);
129
- return () => {
130
- Application.off(Application.suspendEvent, hide);
131
- Application.off(Application.resumeEvent, show);
132
- view?.off?.(View.unloadedEvent, hide);
133
- view?.off?.(View.loadedEvent, show);
134
- view?.off?.(View.layoutChangedEvent, onLayout);
135
- };
136
- };
137
- return wrapInstance(inner, attach);
138
- }
139
- async function createSharedDevice$1(options) {
140
- ensureGpu();
141
- return createSharedDevice(options);
142
- }
143
- function isWebGPUSupported$1() {
144
- ensureGpu();
145
- return isWebGPUSupported();
146
- }
147
- function getWebGPUSupport$1() {
148
- ensureGpu();
149
- return getWebGPUSupport();
150
- }
151
- function prefersReducedMotion() {
152
- try {
153
- if (isIOS) {
154
- const check = globalThis.UIAccessibilityIsReduceMotionEnabled;
155
- return typeof check === "function" ? !!check() : false;
156
- }
157
- if (isAndroid) {
158
- const context = Application.android?.context;
159
- const settings = globalThis.android?.provider?.Settings;
160
- if (!context || !settings?.Global) return false;
161
- return settings.Global.getFloat(context.getContentResolver(), settings.Global.ANIMATOR_DURATION_SCALE, 1) === 0;
162
- }
163
- } catch {}
164
- return false;
165
- }
166
- //#endregion
167
- export { createShader$1 as createShader, createSharedDevice$1 as createSharedDevice, getWebGPUSupport$1 as getWebGPUSupport, isWebGPUSupported$1 as isWebGPUSupported, prefersReducedMotion };
@@ -1,8 +0,0 @@
1
- {
2
- "version": 1,
3
- "buildId": "48a0411d-c5f1-4fb2-9859-af2be6c7a013",
4
- "mode": "production",
5
- "capabilities": {
6
- "independentHydration": false
7
- }
8
- }
package/dist/web/index.js DELETED
@@ -1,2 +0,0 @@
1
- import { createShader, createSharedDevice, getWebGPUSupport, isWebGPUSupported, prefersReducedMotion } from "./index3.js";
2
- export { createShader, createSharedDevice, getWebGPUSupport, isWebGPUSupported, prefersReducedMotion };
@@ -1,90 +0,0 @@
1
- //#region src/shared.ts
2
- function abortError() {
3
- const error = /* @__PURE__ */ new Error("createShader aborted before initialization completed");
4
- error.name = "AbortError";
5
- return error;
6
- }
7
- function throwIfAborted(signal) {
8
- if (signal?.aborted) throw abortError();
9
- }
10
- /** Defer until the surface reports a positive size (surface not attached /
11
- * zero-size layout → wait, don't init). Aborts via `signal`. */
12
- function waitForPositiveSize(measure, signal) {
13
- const first = measure();
14
- if (first.width > 0 && first.height > 0) return Promise.resolve();
15
- return new Promise((resolve, reject) => {
16
- let timer;
17
- const stop = () => {
18
- if (timer !== void 0) clearTimeout(timer);
19
- signal?.removeEventListener?.("abort", onAbort);
20
- };
21
- const onAbort = () => {
22
- stop();
23
- reject(abortError());
24
- };
25
- const poll = () => {
26
- if (signal?.aborted) return onAbort();
27
- const size = measure();
28
- if (size.width > 0 && size.height > 0) {
29
- stop();
30
- resolve();
31
- return;
32
- }
33
- timer = setTimeout(poll, 50);
34
- };
35
- signal?.addEventListener?.("abort", onAbort);
36
- timer = setTimeout(poll, 50);
37
- });
38
- }
39
- /** Merge caller options with adapter defaults. `disableTelemetry` defaults
40
- * on for this package's local/preset-driven use; callers may re-enable it.
41
- * The adapter-only `signal` key is stripped before reaching upstream. */
42
- function resolveOptions(options, platformDefaults) {
43
- const { signal, ...rest } = options ?? {};
44
- return {
45
- signal,
46
- upstream: {
47
- ...platformDefaults,
48
- ...rest,
49
- disableTelemetry: options?.disableTelemetry ?? true
50
- }
51
- };
52
- }
53
- /** Wrap the upstream instance so host suspension composes with caller
54
- * pause instead of overriding it: host hide pauses, host show resumes
55
- * only when the caller did not explicitly pause. `destroy` detaches all
56
- * adapter-owned listeners before delegating. */
57
- function wrapInstance(inner, attach) {
58
- let callerPaused = false;
59
- let hostSuspended = false;
60
- let destroyed = false;
61
- const detach = attach(() => {
62
- if (destroyed) return;
63
- hostSuspended = true;
64
- inner.pause();
65
- }, () => {
66
- hostSuspended = false;
67
- if (!destroyed && !callerPaused) inner.resume();
68
- });
69
- return {
70
- getFailureReason: () => inner.getFailureReason(),
71
- update: (id, props) => inner.update(id, props),
72
- resize: (width, height) => inner.resize(width, height),
73
- pause: () => {
74
- callerPaused = true;
75
- inner.pause();
76
- },
77
- resume: () => {
78
- callerPaused = false;
79
- if (!hostSuspended) inner.resume();
80
- },
81
- destroy: () => {
82
- if (destroyed) return;
83
- destroyed = true;
84
- detach();
85
- inner.destroy();
86
- }
87
- };
88
- }
89
- //#endregion
90
- export { abortError, resolveOptions, throwIfAborted, waitForPositiveSize, wrapInstance };
@@ -1,43 +0,0 @@
1
- import { resolveOptions, throwIfAborted, waitForPositiveSize, wrapInstance } from "./index2.js";
2
- import { createShader, createSharedDevice, getWebGPUSupport, isWebGPUSupported } from "shaders/js";
3
- //#region src/host.web.ts
4
- function measure(canvas) {
5
- const rect = canvas?.getBoundingClientRect?.();
6
- return {
7
- width: Number(rect?.width) || Number(canvas?.width) || 0,
8
- height: Number(rect?.height) || Number(canvas?.height) || 0
9
- };
10
- }
11
- function attachVisibility(hide, show) {
12
- const doc = globalThis.document;
13
- if (!doc?.addEventListener) return () => {};
14
- const onChange = () => doc.visibilityState === "hidden" ? hide() : show();
15
- doc.addEventListener("visibilitychange", onChange);
16
- return () => doc.removeEventListener("visibilitychange", onChange);
17
- }
18
- async function createShader$1(canvas, preset, options) {
19
- const { upstream, signal } = resolveOptions(options, {});
20
- throwIfAborted(signal);
21
- await waitForPositiveSize(() => measure(canvas), signal);
22
- const inner = await createShader(canvas, preset, upstream);
23
- if (signal?.aborted) {
24
- inner.destroy();
25
- throwIfAborted(signal);
26
- }
27
- return wrapInstance(inner, attachVisibility);
28
- }
29
- function createSharedDevice$1(options) {
30
- return createSharedDevice(options);
31
- }
32
- function isWebGPUSupported$1() {
33
- return isWebGPUSupported();
34
- }
35
- function getWebGPUSupport$1() {
36
- return getWebGPUSupport();
37
- }
38
- function prefersReducedMotion() {
39
- const matchMedia = globalThis.matchMedia;
40
- return typeof matchMedia === "function" ? !!matchMedia("(prefers-reduced-motion: reduce)").matches : false;
41
- }
42
- //#endregion
43
- export { createShader$1 as createShader, createSharedDevice$1 as createSharedDevice, getWebGPUSupport$1 as getWebGPUSupport, isWebGPUSupported$1 as isWebGPUSupported, prefersReducedMotion };
@@ -1,8 +0,0 @@
1
- {
2
- "version": 1,
3
- "buildId": "6fb8a5a7-cf83-42dd-9ae3-f873fdb2e8f2",
4
- "mode": "production",
5
- "capabilities": {
6
- "independentHydration": false
7
- }
8
- }