@motion-core/motion-gpu 0.3.0 → 0.4.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.
@@ -17,6 +17,14 @@ export interface SetMotionGPUUserContextOptions {
17
17
  * @default 'skip'
18
18
  */
19
19
  existing?: 'merge' | 'replace' | 'skip';
20
+ /**
21
+ * How function inputs should be interpreted:
22
+ * - `factory`: call function and store its return value
23
+ * - `value`: store function itself
24
+ *
25
+ * @default 'factory'
26
+ */
27
+ functionValue?: 'factory' | 'value';
20
28
  }
21
29
  /**
22
30
  * Returns a read-only view of the entire motiongpu user context store.
@@ -25,7 +33,7 @@ export declare function useMotionGPUUserContext<UC extends UserContextStore = Us
25
33
  /**
26
34
  * Reads a namespaced user context value as a reactive readable store.
27
35
  */
28
- export declare function useMotionGPUUserContext<UCT = unknown>(namespace: MotionGPUUserNamespace): CurrentReadable<UCT | undefined>;
36
+ export declare function useMotionGPUUserContext<UC extends UserContextStore = UserContextStore, K extends keyof UC & MotionGPUUserNamespace = keyof UC & MotionGPUUserNamespace>(namespace: K): CurrentReadable<UC[K] | undefined>;
29
37
  /**
30
38
  * Sets a namespaced user context value with explicit write semantics.
31
39
  *
@@ -43,6 +43,7 @@ export function useMotionGPUUserContext(namespace) {
43
43
  export function setMotionGPUUserContext(namespace, value, options) {
44
44
  const userStore = useMotionGPU().user;
45
45
  const mode = options?.existing ?? 'skip';
46
+ const functionValueMode = options?.functionValue ?? 'factory';
46
47
  let resolvedValue;
47
48
  userStore.update((context) => {
48
49
  const hasExisting = namespace in context;
@@ -50,7 +51,9 @@ export function setMotionGPUUserContext(namespace, value, options) {
50
51
  resolvedValue = context[namespace];
51
52
  return context;
52
53
  }
53
- const nextValue = typeof value === 'function' ? value() : value;
54
+ const nextValue = typeof value === 'function' && functionValueMode === 'factory'
55
+ ? value()
56
+ : value;
54
57
  if (hasExisting && mode === 'merge') {
55
58
  const currentValue = context[namespace];
56
59
  if (isObjectEntry(currentValue) && isObjectEntry(nextValue)) {
@@ -30,11 +30,15 @@ export interface UseTextureResult {
30
30
  * Supported URL input variants for `useTexture`.
31
31
  */
32
32
  export type TextureUrlInput = string[] | (() => string[]);
33
+ /**
34
+ * Supported options input variants for `useTexture`.
35
+ */
36
+ export type TextureOptionsInput = TextureLoadOptions | (() => TextureLoadOptions);
33
37
  /**
34
38
  * Loads textures from URLs and exposes reactive loading/error state.
35
39
  *
36
40
  * @param urlInput - URLs array or lazy URL provider.
37
- * @param options - Loader options passed to URL fetch/decode pipeline.
41
+ * @param optionsInput - Loader options object or lazy options provider.
38
42
  * @returns Reactive texture loading state with reload support.
39
43
  */
40
- export declare function useTexture(urlInput: TextureUrlInput, options?: TextureLoadOptions): UseTextureResult;
44
+ export declare function useTexture(urlInput: TextureUrlInput, optionsInput?: TextureOptionsInput): UseTextureResult;
@@ -54,10 +54,10 @@ function mergeAbortSignals(primary, secondary) {
54
54
  * Loads textures from URLs and exposes reactive loading/error state.
55
55
  *
56
56
  * @param urlInput - URLs array or lazy URL provider.
57
- * @param options - Loader options passed to URL fetch/decode pipeline.
57
+ * @param optionsInput - Loader options object or lazy options provider.
58
58
  * @returns Reactive texture loading state with reload support.
59
59
  */
60
- export function useTexture(urlInput, options = {}) {
60
+ export function useTexture(urlInput, optionsInput = {}) {
61
61
  const textures = currentWritable(null);
62
62
  const loading = currentWritable(true);
63
63
  const error = currentWritable(null);
@@ -68,6 +68,9 @@ export function useTexture(urlInput, options = {}) {
68
68
  let runningLoad = null;
69
69
  let reloadQueued = false;
70
70
  const getUrls = typeof urlInput === 'function' ? urlInput : () => urlInput;
71
+ const getOptions = typeof optionsInput === 'function'
72
+ ? optionsInput
73
+ : () => optionsInput;
71
74
  const executeLoad = async () => {
72
75
  if (disposed) {
73
76
  return;
@@ -79,6 +82,7 @@ export function useTexture(urlInput, options = {}) {
79
82
  error.set(null);
80
83
  errorReport.set(null);
81
84
  const previous = textures.current;
85
+ const options = getOptions() ?? {};
82
86
  const mergedSignal = mergeAbortSignals(controller.signal, options.signal);
83
87
  try {
84
88
  const loaded = await loadTexturesFromUrls(getUrls(), {
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "@motion-core/motion-gpu",
3
- "version": "0.3.0",
4
- "description": "Framework-agnostic WebGPU runtime for fullscreen WGSL shaders with explicit Svelte adapter entrypoints.",
3
+ "version": "0.4.0",
4
+ "description": "Framework-agnostic WebGPU runtime for fullscreen WGSL shaders with explicit Svelte and React adapter entrypoints.",
5
5
  "keywords": [
6
6
  "svelte",
7
7
  "svelte5",
8
+ "react",
9
+ "react18",
8
10
  "webgpu",
9
11
  "wgsl",
10
12
  "shader",
@@ -46,6 +48,14 @@
46
48
  "svelte": "./dist/svelte/advanced.js",
47
49
  "default": "./dist/svelte/advanced.js"
48
50
  },
51
+ "./react": {
52
+ "types": "./dist/react/index.d.ts",
53
+ "default": "./dist/react/index.js"
54
+ },
55
+ "./react/advanced": {
56
+ "types": "./dist/react/advanced.d.ts",
57
+ "default": "./dist/react/advanced.js"
58
+ },
49
59
  "./core": {
50
60
  "types": "./dist/core/index.d.ts",
51
61
  "default": "./dist/core/index.js"
@@ -59,7 +69,7 @@
59
69
  "dist"
60
70
  ],
61
71
  "scripts": {
62
- "build": "svelte-package -i src/lib -o dist",
72
+ "build": "svelte-package -i src/lib -o dist && node ./scripts/build/transpile-react-tsx.mjs",
63
73
  "prepack": "bun run build",
64
74
  "check": "svelte-check --tsconfig ./tsconfig.json && publint",
65
75
  "test": "vitest run",
@@ -68,6 +78,8 @@
68
78
  "test:e2e": "playwright test",
69
79
  "test:e2e:headed": "playwright test --headed",
70
80
  "e2e:serve": "vite --config e2e/vite.config.ts",
81
+ "e2e:serve:svelte": "MOTION_GPU_E2E_FRAMEWORK=svelte vite --config e2e/vite.config.ts",
82
+ "e2e:serve:react": "MOTION_GPU_E2E_FRAMEWORK=react vite --config e2e/vite.config.ts",
71
83
  "perf:core": "bun run ./scripts/perf/core-benchmark.ts",
72
84
  "perf:core:check": "bun run ./scripts/perf/core-benchmark.ts --strict",
73
85
  "perf:core:baseline": "bun run ./scripts/perf/core-benchmark.ts --update-baseline",
@@ -78,9 +90,17 @@
78
90
  "format": "prettier --write ."
79
91
  },
80
92
  "peerDependencies": {
93
+ "react": "^18.0.0 || ^19.0.0",
94
+ "react-dom": "^18.0.0 || ^19.0.0",
81
95
  "svelte": "^5.0.0"
82
96
  },
83
97
  "peerDependenciesMeta": {
98
+ "react": {
99
+ "optional": true
100
+ },
101
+ "react-dom": {
102
+ "optional": true
103
+ },
84
104
  "svelte": {
85
105
  "optional": true
86
106
  }
@@ -91,7 +111,10 @@
91
111
  "@playwright/test": "^1.58.2",
92
112
  "@sveltejs/package": "^2.5.0",
93
113
  "@sveltejs/vite-plugin-svelte": "^6.2.4",
114
+ "@testing-library/react": "^16.3.0",
94
115
  "@testing-library/svelte": "^5.2.8",
116
+ "@types/react": "^19.2.2",
117
+ "@types/react-dom": "^19.2.2",
95
118
  "@vitest/coverage-v8": "^4.0.18",
96
119
  "@types/node": "^25.3.3",
97
120
  "@webgpu/types": "^0.1.66",
@@ -104,6 +127,8 @@
104
127
  "prettier-plugin-svelte": "^3.4.1",
105
128
  "prettier-plugin-tailwindcss": "^0.7.2",
106
129
  "publint": "^0.3.15",
130
+ "react": "^19.2.0",
131
+ "react-dom": "^19.2.0",
107
132
  "svelte": "^5.51.0",
108
133
  "svelte-check": "^4.3.6",
109
134
  "typescript": "^5.9.3",