@computekit/react 0.1.0 → 0.1.1

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 ADDED
@@ -0,0 +1,280 @@
1
+ # @computekit/react
2
+
3
+ React bindings for ComputeKit - run heavy computations in Web Workers with simple hooks.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @computekit/core @computekit/react
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```tsx
14
+ import { ComputeKitProvider, useComputeKit, useCompute } from '@computekit/react';
15
+
16
+ // 1. Wrap your app with the provider
17
+ function App() {
18
+ return (
19
+ <ComputeKitProvider options={{ maxWorkers: 4 }}>
20
+ <MyApp />
21
+ </ComputeKitProvider>
22
+ );
23
+ }
24
+
25
+ // 2. Register functions and use them
26
+ function MyApp() {
27
+ const kit = useComputeKit();
28
+
29
+ useEffect(() => {
30
+ kit.register('fibonacci', (n: number) => {
31
+ let a = 0,
32
+ b = 1;
33
+ for (let i = 0; i < n; i++) {
34
+ [a, b] = [b, a + b];
35
+ }
36
+ return a;
37
+ });
38
+ }, [kit]);
39
+
40
+ return <FibCalculator />;
41
+ }
42
+
43
+ // 3. Use the compute function
44
+ function FibCalculator() {
45
+ const { data, loading, error, run } = useCompute<number, number>('fibonacci');
46
+
47
+ return (
48
+ <div>
49
+ <button onClick={() => run(50)} disabled={loading}>
50
+ Calculate Fibonacci(50)
51
+ </button>
52
+ {loading && <p>Computing...</p>}
53
+ {error && <p>Error: {error.message}</p>}
54
+ {data !== null && <p>Result: {data}</p>}
55
+ </div>
56
+ );
57
+ }
58
+ ```
59
+
60
+ ## API Reference
61
+
62
+ ### `<ComputeKitProvider>`
63
+
64
+ Provider component that creates and manages the ComputeKit instance.
65
+
66
+ ```tsx
67
+ <ComputeKitProvider
68
+ options={{
69
+ maxWorkers: 4, // Max workers in pool (default: CPU cores)
70
+ timeout: 30000, // Default timeout in ms
71
+ debug: false, // Enable debug logging
72
+ }}
73
+ >
74
+ {children}
75
+ </ComputeKitProvider>
76
+ ```
77
+
78
+ **Props:**
79
+
80
+ | Prop | Type | Description |
81
+ | ---------- | ------------------- | ------------------------------------- |
82
+ | `options` | `ComputeKitOptions` | Configuration options |
83
+ | `instance` | `ComputeKit` | Custom ComputeKit instance (optional) |
84
+ | `children` | `ReactNode` | Child components |
85
+
86
+ ### `useComputeKit()`
87
+
88
+ Get the ComputeKit instance from context.
89
+
90
+ ```tsx
91
+ const kit = useComputeKit();
92
+
93
+ // Register functions
94
+ kit.register('myFunc', (input) => /* ... */);
95
+
96
+ // Run directly
97
+ const result = await kit.run('myFunc', data);
98
+ ```
99
+
100
+ ### `useCompute<TInput, TOutput>(name, options?)`
101
+
102
+ Hook for running compute functions with full state management.
103
+
104
+ ```tsx
105
+ const {
106
+ data, // Result (null until complete)
107
+ loading, // Boolean loading state
108
+ error, // Error object if failed
109
+ progress, // Progress info for long tasks
110
+ run, // Function to execute
111
+ reset, // Reset state
112
+ cancel, // Cancel ongoing computation
113
+ } = useCompute<number, number>('fibonacci');
114
+
115
+ // Execute
116
+ await run(50);
117
+
118
+ // With options
119
+ await run(50, { timeout: 5000 });
120
+ ```
121
+
122
+ **Options:**
123
+
124
+ | Option | Type | Description |
125
+ | -------------- | -------------------- | -------------------------------------- |
126
+ | `timeout` | `number` | Operation timeout in ms |
127
+ | `autoRun` | `boolean` | Auto-run on mount |
128
+ | `initialInput` | `unknown` | Input for autoRun |
129
+ | `resetOnRun` | `boolean` | Reset state on new run (default: true) |
130
+ | `onProgress` | `(progress) => void` | Progress callback |
131
+
132
+ ### `useComputeCallback<TInput, TOutput>(name, options?)`
133
+
134
+ Returns a memoized async function for simple use cases.
135
+
136
+ ```tsx
137
+ const calculate = useComputeCallback<number[], number>('sum');
138
+
139
+ const handleClick = async () => {
140
+ const result = await calculate([1, 2, 3, 4, 5]);
141
+ console.log(result); // 15
142
+ };
143
+ ```
144
+
145
+ ### `useComputeFunction<TInput, TOutput>(name, fn, options?)`
146
+
147
+ Register and use a function in one hook. Useful for component-local compute functions.
148
+
149
+ ```tsx
150
+ const { data, loading, run } = useComputeFunction('double', (n: number) => n * 2);
151
+
152
+ // Function is registered automatically
153
+ run(21); // data will be 42
154
+ ```
155
+
156
+ ### `usePoolStats(refreshInterval?)`
157
+
158
+ Get worker pool statistics.
159
+
160
+ ```tsx
161
+ const stats = usePoolStats(1000); // Refresh every second
162
+
163
+ return (
164
+ <div>
165
+ <p>
166
+ Active: {stats.activeWorkers}/{stats.totalWorkers}
167
+ </p>
168
+ <p>Queue: {stats.queueLength}</p>
169
+ <p>Completed: {stats.tasksCompleted}</p>
170
+ </div>
171
+ );
172
+ ```
173
+
174
+ **Returns `PoolStats`:**
175
+
176
+ | Property | Type | Description |
177
+ | ---------------- | -------- | ---------------------- |
178
+ | `totalWorkers` | `number` | Total worker count |
179
+ | `activeWorkers` | `number` | Currently busy workers |
180
+ | `idleWorkers` | `number` | Currently idle workers |
181
+ | `queueLength` | `number` | Tasks waiting in queue |
182
+ | `tasksCompleted` | `number` | Total completed tasks |
183
+ | `tasksFailed` | `number` | Total failed tasks |
184
+
185
+ ### `useWasmSupport()`
186
+
187
+ Check if WebAssembly is supported.
188
+
189
+ ```tsx
190
+ const isSupported = useWasmSupport();
191
+
192
+ if (!isSupported) {
193
+ return <p>WebAssembly not supported</p>;
194
+ }
195
+ ```
196
+
197
+ ## Patterns
198
+
199
+ ### Cancellation on Unmount
200
+
201
+ The `useCompute` hook automatically cancels pending operations when the component unmounts:
202
+
203
+ ```tsx
204
+ function MyComponent() {
205
+ const { run, loading } = useCompute('heavyTask');
206
+
207
+ useEffect(() => {
208
+ run(data); // Automatically cancelled if component unmounts
209
+ }, []);
210
+
211
+ // ...
212
+ }
213
+ ```
214
+
215
+ ### Manual Cancellation
216
+
217
+ ```tsx
218
+ function MyComponent() {
219
+ const { run, cancel, loading } = useCompute('heavyTask');
220
+
221
+ return (
222
+ <>
223
+ <button onClick={() => run(data)}>Start</button>
224
+ <button onClick={cancel} disabled={!loading}>
225
+ Cancel
226
+ </button>
227
+ </>
228
+ );
229
+ }
230
+ ```
231
+
232
+ ### Progress Tracking
233
+
234
+ ```tsx
235
+ function MyComponent() {
236
+ const { run, progress, loading } = useCompute('heavyTask', {
237
+ onProgress: (p) => console.log(`${p.percent}%`),
238
+ });
239
+
240
+ return (
241
+ <div>{loading && progress && <progress value={progress.percent} max={100} />}</div>
242
+ );
243
+ }
244
+ ```
245
+
246
+ ### With AbortController
247
+
248
+ ```tsx
249
+ function MyComponent() {
250
+ const controller = useRef(new AbortController());
251
+ const { run } = useCompute('task');
252
+
253
+ const handleRun = () => {
254
+ run(data, { signal: controller.current.signal });
255
+ };
256
+
257
+ const handleCancel = () => {
258
+ controller.current.abort();
259
+ controller.current = new AbortController();
260
+ };
261
+ }
262
+ ```
263
+
264
+ ## TypeScript
265
+
266
+ Full type inference is supported:
267
+
268
+ ```tsx
269
+ // Types are inferred from registration
270
+ kit.register('add', (nums: number[]) => nums.reduce((a, b) => a + b, 0));
271
+
272
+ // Explicit types for hooks
273
+ const { data, run } = useCompute<number[], number>('add');
274
+ // data: number | null
275
+ // run: (input: number[]) => Promise<void>
276
+ ```
277
+
278
+ ## License
279
+
280
+ MIT
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx"],"names":["createContext","useMemo","ComputeKit","useEffect","useContext","useRef","useState","useCallback"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * ComputeKit React Bindings\n * React hooks and utilities for ComputeKit\n */\n\nimport {\n useState,\n useEffect,\n useCallback,\n useRef,\n useMemo,\n createContext,\n useContext,\n type ReactNode,\n} from 'react';\n\nimport {\n ComputeKit,\n type ComputeKitOptions,\n type ComputeOptions,\n type ComputeProgress,\n type PoolStats,\n} from '@computekit/core';\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst ComputeKitContext = createContext<ComputeKit | null>(null);\n\n/**\n * Props for ComputeKitProvider\n */\nexport interface ComputeKitProviderProps {\n /** ComputeKit options */\n options?: ComputeKitOptions;\n /** Custom ComputeKit instance */\n instance?: ComputeKit;\n /** Children */\n children: ReactNode;\n}\n\n/**\n * Provider component for ComputeKit\n *\n * @example\n * ```tsx\n * import { ComputeKitProvider } from '@computekit/react';\n *\n * function App() {\n * return (\n * <ComputeKitProvider options={{ maxWorkers: 4 }}>\n * <MyApp />\n * </ComputeKitProvider>\n * );\n * }\n * ```\n */\nexport function ComputeKitProvider({\n options,\n instance,\n children,\n}: ComputeKitProviderProps): JSX.Element {\n const kit = useMemo(() => {\n return instance ?? new ComputeKit(options);\n }, [instance, options]);\n\n useEffect(() => {\n return () => {\n // Only terminate if we created the instance\n if (!instance) {\n kit.terminate();\n }\n };\n }, [kit, instance]);\n\n return <ComputeKitContext.Provider value={kit}>{children}</ComputeKitContext.Provider>;\n}\n\n/**\n * Get the ComputeKit instance from context\n */\nexport function useComputeKit(): ComputeKit {\n const kit = useContext(ComputeKitContext);\n if (!kit) {\n throw new Error('useComputeKit must be used within a ComputeKitProvider');\n }\n return kit;\n}\n\n// ============================================================================\n// useCompute Hook\n// ============================================================================\n\n/**\n * State returned by useCompute\n */\nexport interface UseComputeState<T> {\n /** The computed result */\n data: T | null;\n /** Loading state */\n loading: boolean;\n /** Error if computation failed */\n error: Error | null;\n /** Progress information */\n progress: ComputeProgress | null;\n}\n\n/**\n * Actions returned by useCompute\n */\nexport interface UseComputeActions<TInput> {\n /** Execute the compute function */\n run: (input: TInput, options?: ComputeOptions) => Promise<void>;\n /** Reset the state */\n reset: () => void;\n /** Cancel ongoing computation */\n cancel: () => void;\n}\n\n/**\n * Return type for useCompute\n */\nexport type UseComputeReturn<TInput, TOutput> = UseComputeState<TOutput> &\n UseComputeActions<TInput>;\n\n/**\n * Options for useCompute hook\n */\nexport interface UseComputeOptions extends ComputeOptions {\n /** Automatically run on mount with initial input */\n autoRun?: boolean;\n /** Initial input for autoRun */\n initialInput?: unknown;\n /** Reset state on new run */\n resetOnRun?: boolean;\n}\n\n/**\n * Hook for running compute functions\n *\n * @example\n * ```tsx\n * function FibonacciCalculator() {\n * const { data, loading, error, run } = useCompute<number, number>('fibonacci');\n *\n * return (\n * <div>\n * <button onClick={() => run(50)} disabled={loading}>\n * Calculate Fibonacci(50)\n * </button>\n * {loading && <p>Computing...</p>}\n * {error && <p>Error: {error.message}</p>}\n * {data !== null && <p>Result: {data}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useCompute<TInput = unknown, TOutput = unknown>(\n functionName: string,\n options: UseComputeOptions = {}\n): UseComputeReturn<TInput, TOutput> {\n const kit = useComputeKit();\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const [state, setState] = useState<UseComputeState<TOutput>>({\n data: null,\n loading: false,\n error: null,\n progress: null,\n });\n\n const reset = useCallback(() => {\n setState({\n data: null,\n loading: false,\n error: null,\n progress: null,\n });\n }, []);\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const run = useCallback(\n async (input: TInput, runOptions?: ComputeOptions) => {\n // Cancel any ongoing computation\n cancel();\n\n // Create new abort controller\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n // Reset state if configured\n if (options.resetOnRun !== false) {\n setState((prev) => ({\n ...prev,\n loading: true,\n error: null,\n progress: null,\n }));\n } else {\n setState((prev) => ({ ...prev, loading: true }));\n }\n\n try {\n const result = await kit.run<TInput, TOutput>(functionName, input, {\n ...options,\n ...runOptions,\n signal: runOptions?.signal ?? abortController.signal,\n onProgress: (progress) => {\n setState((prev) => ({ ...prev, progress }));\n options.onProgress?.(progress);\n runOptions?.onProgress?.(progress);\n },\n });\n\n if (!abortController.signal.aborted) {\n setState({\n data: result,\n loading: false,\n error: null,\n progress: null,\n });\n }\n } catch (err) {\n if (!abortController.signal.aborted) {\n setState({\n data: null,\n loading: false,\n error: err instanceof Error ? err : new Error(String(err)),\n progress: null,\n });\n }\n }\n },\n [kit, functionName, options, cancel]\n );\n\n // Auto-run on mount if configured\n useEffect(() => {\n if (options.autoRun && options.initialInput !== undefined) {\n run(options.initialInput as TInput);\n }\n // Only run on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n cancel();\n };\n }, [cancel]);\n\n return {\n ...state,\n run,\n reset,\n cancel,\n };\n}\n\n// ============================================================================\n// useComputeCallback Hook\n// ============================================================================\n\n/**\n * Hook that returns a memoized async function for compute operations\n *\n * @example\n * ```tsx\n * function Calculator() {\n * const calculate = useComputeCallback<number[], number>('sum');\n *\n * const handleClick = async () => {\n * const result = await calculate([1, 2, 3, 4, 5]);\n * console.log(result);\n * };\n *\n * return <button onClick={handleClick}>Calculate Sum</button>;\n * }\n * ```\n */\nexport function useComputeCallback<TInput = unknown, TOutput = unknown>(\n functionName: string,\n options?: ComputeOptions\n): (input: TInput, runOptions?: ComputeOptions) => Promise<TOutput> {\n const kit = useComputeKit();\n\n return useCallback(\n (input: TInput, runOptions?: ComputeOptions) => {\n return kit.run<TInput, TOutput>(functionName, input, {\n ...options,\n ...runOptions,\n });\n },\n [kit, functionName, options]\n );\n}\n\n// ============================================================================\n// useComputeFunction Hook\n// ============================================================================\n\n/**\n * Hook to register and use a compute function\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { run, loading, data } = useComputeFunction(\n * 'myFunction',\n * (input: number) => input * 2\n * );\n *\n * return (\n * <button onClick={() => run(5)} disabled={loading}>\n * {loading ? 'Computing...' : `Result: ${data}`}\n * </button>\n * );\n * }\n * ```\n */\nexport function useComputeFunction<TInput = unknown, TOutput = unknown>(\n name: string,\n fn: (input: TInput) => TOutput | Promise<TOutput>,\n options?: UseComputeOptions\n): UseComputeReturn<TInput, TOutput> {\n const kit = useComputeKit();\n\n // Register function on mount\n useEffect(() => {\n kit.register(name, fn);\n }, [kit, name, fn]);\n\n return useCompute<TInput, TOutput>(name, options);\n}\n\n// ============================================================================\n// usePoolStats Hook\n// ============================================================================\n\n/**\n * Hook to get worker pool statistics\n *\n * @example\n * ```tsx\n * function PoolMonitor() {\n * const stats = usePoolStats(1000); // Update every second\n *\n * return (\n * <div>\n * <p>Active Workers: {stats.activeWorkers}</p>\n * <p>Queue Length: {stats.queueLength}</p>\n * <p>Tasks Completed: {stats.tasksCompleted}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function usePoolStats(refreshInterval: number = 0): PoolStats {\n const kit = useComputeKit();\n const [stats, setStats] = useState<PoolStats>(() => kit.getStats());\n\n useEffect(() => {\n // For one-time fetch (refreshInterval <= 0), we rely on the initial state\n if (refreshInterval <= 0) {\n return;\n }\n\n const interval = setInterval(() => {\n setStats(kit.getStats());\n }, refreshInterval);\n\n return () => clearInterval(interval);\n }, [kit, refreshInterval]);\n\n return stats;\n}\n\n// ============================================================================\n// useWasmSupport Hook\n// ============================================================================\n\n/**\n * Hook to check WASM support\n */\nexport function useWasmSupport(): boolean {\n const kit = useComputeKit();\n return kit.isWasmSupported();\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport type {\n ComputeKitOptions,\n ComputeOptions,\n ComputeProgress,\n PoolStats,\n} from '@computekit/core';\n\nexport { ComputeKit } from '@computekit/core';\n"]}
1
+ {"version":3,"sources":["../src/index.tsx"],"names":["createContext","useMemo","ComputeKit","useEffect","useContext","useRef","useState","useCallback"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * ComputeKit React Bindings\n * React hooks and utilities for ComputeKit\n */\n\nimport React, {\n useState,\n useEffect,\n useCallback,\n useRef,\n useMemo,\n createContext,\n useContext,\n type ReactNode,\n} from 'react';\n\nimport {\n ComputeKit,\n type ComputeKitOptions,\n type ComputeOptions,\n type ComputeProgress,\n type PoolStats,\n} from '@computekit/core';\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst ComputeKitContext = createContext<ComputeKit | null>(null);\n\n/**\n * Props for ComputeKitProvider\n */\nexport interface ComputeKitProviderProps {\n /** ComputeKit options */\n options?: ComputeKitOptions;\n /** Custom ComputeKit instance */\n instance?: ComputeKit;\n /** Children */\n children: ReactNode;\n}\n\n/**\n * Provider component for ComputeKit\n *\n * @example\n * ```tsx\n * import { ComputeKitProvider } from '@computekit/react';\n *\n * function App() {\n * return (\n * <ComputeKitProvider options={{ maxWorkers: 4 }}>\n * <MyApp />\n * </ComputeKitProvider>\n * );\n * }\n * ```\n */\nexport function ComputeKitProvider({\n options,\n instance,\n children,\n}: ComputeKitProviderProps): React.ReactElement {\n const kit = useMemo(() => {\n return instance ?? new ComputeKit(options);\n }, [instance, options]);\n\n useEffect(() => {\n return () => {\n // Only terminate if we created the instance\n if (!instance) {\n kit.terminate();\n }\n };\n }, [kit, instance]);\n\n return <ComputeKitContext.Provider value={kit}>{children}</ComputeKitContext.Provider>;\n}\n\n/**\n * Get the ComputeKit instance from context\n */\nexport function useComputeKit(): ComputeKit {\n const kit = useContext(ComputeKitContext);\n if (!kit) {\n throw new Error('useComputeKit must be used within a ComputeKitProvider');\n }\n return kit;\n}\n\n// ============================================================================\n// useCompute Hook\n// ============================================================================\n\n/**\n * State returned by useCompute\n */\nexport interface UseComputeState<T> {\n /** The computed result */\n data: T | null;\n /** Loading state */\n loading: boolean;\n /** Error if computation failed */\n error: Error | null;\n /** Progress information */\n progress: ComputeProgress | null;\n}\n\n/**\n * Actions returned by useCompute\n */\nexport interface UseComputeActions<TInput> {\n /** Execute the compute function */\n run: (input: TInput, options?: ComputeOptions) => Promise<void>;\n /** Reset the state */\n reset: () => void;\n /** Cancel ongoing computation */\n cancel: () => void;\n}\n\n/**\n * Return type for useCompute\n */\nexport type UseComputeReturn<TInput, TOutput> = UseComputeState<TOutput> &\n UseComputeActions<TInput>;\n\n/**\n * Options for useCompute hook\n */\nexport interface UseComputeOptions extends ComputeOptions {\n /** Automatically run on mount with initial input */\n autoRun?: boolean;\n /** Initial input for autoRun */\n initialInput?: unknown;\n /** Reset state on new run */\n resetOnRun?: boolean;\n}\n\n/**\n * Hook for running compute functions\n *\n * @example\n * ```tsx\n * function FibonacciCalculator() {\n * const { data, loading, error, run } = useCompute<number, number>('fibonacci');\n *\n * return (\n * <div>\n * <button onClick={() => run(50)} disabled={loading}>\n * Calculate Fibonacci(50)\n * </button>\n * {loading && <p>Computing...</p>}\n * {error && <p>Error: {error.message}</p>}\n * {data !== null && <p>Result: {data}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useCompute<TInput = unknown, TOutput = unknown>(\n functionName: string,\n options: UseComputeOptions = {}\n): UseComputeReturn<TInput, TOutput> {\n const kit = useComputeKit();\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const [state, setState] = useState<UseComputeState<TOutput>>({\n data: null,\n loading: false,\n error: null,\n progress: null,\n });\n\n const reset = useCallback(() => {\n setState({\n data: null,\n loading: false,\n error: null,\n progress: null,\n });\n }, []);\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const run = useCallback(\n async (input: TInput, runOptions?: ComputeOptions) => {\n // Cancel any ongoing computation\n cancel();\n\n // Create new abort controller\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n // Reset state if configured\n if (options.resetOnRun !== false) {\n setState((prev) => ({\n ...prev,\n loading: true,\n error: null,\n progress: null,\n }));\n } else {\n setState((prev) => ({ ...prev, loading: true }));\n }\n\n try {\n const result = await kit.run<TInput, TOutput>(functionName, input, {\n ...options,\n ...runOptions,\n signal: runOptions?.signal ?? abortController.signal,\n onProgress: (progress) => {\n setState((prev) => ({ ...prev, progress }));\n options.onProgress?.(progress);\n runOptions?.onProgress?.(progress);\n },\n });\n\n if (!abortController.signal.aborted) {\n setState({\n data: result,\n loading: false,\n error: null,\n progress: null,\n });\n }\n } catch (err) {\n if (!abortController.signal.aborted) {\n setState({\n data: null,\n loading: false,\n error: err instanceof Error ? err : new Error(String(err)),\n progress: null,\n });\n }\n }\n },\n [kit, functionName, options, cancel]\n );\n\n // Auto-run on mount if configured\n useEffect(() => {\n if (options.autoRun && options.initialInput !== undefined) {\n run(options.initialInput as TInput);\n }\n // Only run on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n cancel();\n };\n }, [cancel]);\n\n return {\n ...state,\n run,\n reset,\n cancel,\n };\n}\n\n// ============================================================================\n// useComputeCallback Hook\n// ============================================================================\n\n/**\n * Hook that returns a memoized async function for compute operations\n *\n * @example\n * ```tsx\n * function Calculator() {\n * const calculate = useComputeCallback<number[], number>('sum');\n *\n * const handleClick = async () => {\n * const result = await calculate([1, 2, 3, 4, 5]);\n * console.log(result);\n * };\n *\n * return <button onClick={handleClick}>Calculate Sum</button>;\n * }\n * ```\n */\nexport function useComputeCallback<TInput = unknown, TOutput = unknown>(\n functionName: string,\n options?: ComputeOptions\n): (input: TInput, runOptions?: ComputeOptions) => Promise<TOutput> {\n const kit = useComputeKit();\n\n return useCallback(\n (input: TInput, runOptions?: ComputeOptions) => {\n return kit.run<TInput, TOutput>(functionName, input, {\n ...options,\n ...runOptions,\n });\n },\n [kit, functionName, options]\n );\n}\n\n// ============================================================================\n// useComputeFunction Hook\n// ============================================================================\n\n/**\n * Hook to register and use a compute function\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { run, loading, data } = useComputeFunction(\n * 'myFunction',\n * (input: number) => input * 2\n * );\n *\n * return (\n * <button onClick={() => run(5)} disabled={loading}>\n * {loading ? 'Computing...' : `Result: ${data}`}\n * </button>\n * );\n * }\n * ```\n */\nexport function useComputeFunction<TInput = unknown, TOutput = unknown>(\n name: string,\n fn: (input: TInput) => TOutput | Promise<TOutput>,\n options?: UseComputeOptions\n): UseComputeReturn<TInput, TOutput> {\n const kit = useComputeKit();\n\n // Register function on mount\n useEffect(() => {\n kit.register(name, fn);\n }, [kit, name, fn]);\n\n return useCompute<TInput, TOutput>(name, options);\n}\n\n// ============================================================================\n// usePoolStats Hook\n// ============================================================================\n\n/**\n * Hook to get worker pool statistics\n *\n * @example\n * ```tsx\n * function PoolMonitor() {\n * const stats = usePoolStats(1000); // Update every second\n *\n * return (\n * <div>\n * <p>Active Workers: {stats.activeWorkers}</p>\n * <p>Queue Length: {stats.queueLength}</p>\n * <p>Tasks Completed: {stats.tasksCompleted}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function usePoolStats(refreshInterval: number = 0): PoolStats {\n const kit = useComputeKit();\n const [stats, setStats] = useState<PoolStats>(() => kit.getStats());\n\n useEffect(() => {\n // For one-time fetch (refreshInterval <= 0), we rely on the initial state\n if (refreshInterval <= 0) {\n return;\n }\n\n const interval = setInterval(() => {\n setStats(kit.getStats());\n }, refreshInterval);\n\n return () => clearInterval(interval);\n }, [kit, refreshInterval]);\n\n return stats;\n}\n\n// ============================================================================\n// useWasmSupport Hook\n// ============================================================================\n\n/**\n * Hook to check WASM support\n */\nexport function useWasmSupport(): boolean {\n const kit = useComputeKit();\n return kit.isWasmSupported();\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport type {\n ComputeKitOptions,\n ComputeOptions,\n ComputeProgress,\n PoolStats,\n} from '@computekit/core';\n\nexport { ComputeKit } from '@computekit/core';\n"]}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { ReactNode } from 'react';
1
+ import React, { ReactNode } from 'react';
2
2
  import { ComputeKitOptions, ComputeKit, ComputeProgress, ComputeOptions, PoolStats } from '@computekit/core';
3
3
  export { ComputeKit, ComputeKitOptions, ComputeOptions, ComputeProgress, PoolStats } from '@computekit/core';
4
4
 
@@ -34,7 +34,7 @@ interface ComputeKitProviderProps {
34
34
  * }
35
35
  * ```
36
36
  */
37
- declare function ComputeKitProvider({ options, instance, children, }: ComputeKitProviderProps): JSX.Element;
37
+ declare function ComputeKitProvider({ options, instance, children, }: ComputeKitProviderProps): React.ReactElement;
38
38
  /**
39
39
  * Get the ComputeKit instance from context
40
40
  */
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ReactNode } from 'react';
1
+ import React, { ReactNode } from 'react';
2
2
  import { ComputeKitOptions, ComputeKit, ComputeProgress, ComputeOptions, PoolStats } from '@computekit/core';
3
3
  export { ComputeKit, ComputeKitOptions, ComputeOptions, ComputeProgress, PoolStats } from '@computekit/core';
4
4
 
@@ -34,7 +34,7 @@ interface ComputeKitProviderProps {
34
34
  * }
35
35
  * ```
36
36
  */
37
- declare function ComputeKitProvider({ options, instance, children, }: ComputeKitProviderProps): JSX.Element;
37
+ declare function ComputeKitProvider({ options, instance, children, }: ComputeKitProviderProps): React.ReactElement;
38
38
  /**
39
39
  * Get the ComputeKit instance from context
40
40
  */
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * ComputeKit React Bindings\n * React hooks and utilities for ComputeKit\n */\n\nimport {\n useState,\n useEffect,\n useCallback,\n useRef,\n useMemo,\n createContext,\n useContext,\n type ReactNode,\n} from 'react';\n\nimport {\n ComputeKit,\n type ComputeKitOptions,\n type ComputeOptions,\n type ComputeProgress,\n type PoolStats,\n} from '@computekit/core';\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst ComputeKitContext = createContext<ComputeKit | null>(null);\n\n/**\n * Props for ComputeKitProvider\n */\nexport interface ComputeKitProviderProps {\n /** ComputeKit options */\n options?: ComputeKitOptions;\n /** Custom ComputeKit instance */\n instance?: ComputeKit;\n /** Children */\n children: ReactNode;\n}\n\n/**\n * Provider component for ComputeKit\n *\n * @example\n * ```tsx\n * import { ComputeKitProvider } from '@computekit/react';\n *\n * function App() {\n * return (\n * <ComputeKitProvider options={{ maxWorkers: 4 }}>\n * <MyApp />\n * </ComputeKitProvider>\n * );\n * }\n * ```\n */\nexport function ComputeKitProvider({\n options,\n instance,\n children,\n}: ComputeKitProviderProps): JSX.Element {\n const kit = useMemo(() => {\n return instance ?? new ComputeKit(options);\n }, [instance, options]);\n\n useEffect(() => {\n return () => {\n // Only terminate if we created the instance\n if (!instance) {\n kit.terminate();\n }\n };\n }, [kit, instance]);\n\n return <ComputeKitContext.Provider value={kit}>{children}</ComputeKitContext.Provider>;\n}\n\n/**\n * Get the ComputeKit instance from context\n */\nexport function useComputeKit(): ComputeKit {\n const kit = useContext(ComputeKitContext);\n if (!kit) {\n throw new Error('useComputeKit must be used within a ComputeKitProvider');\n }\n return kit;\n}\n\n// ============================================================================\n// useCompute Hook\n// ============================================================================\n\n/**\n * State returned by useCompute\n */\nexport interface UseComputeState<T> {\n /** The computed result */\n data: T | null;\n /** Loading state */\n loading: boolean;\n /** Error if computation failed */\n error: Error | null;\n /** Progress information */\n progress: ComputeProgress | null;\n}\n\n/**\n * Actions returned by useCompute\n */\nexport interface UseComputeActions<TInput> {\n /** Execute the compute function */\n run: (input: TInput, options?: ComputeOptions) => Promise<void>;\n /** Reset the state */\n reset: () => void;\n /** Cancel ongoing computation */\n cancel: () => void;\n}\n\n/**\n * Return type for useCompute\n */\nexport type UseComputeReturn<TInput, TOutput> = UseComputeState<TOutput> &\n UseComputeActions<TInput>;\n\n/**\n * Options for useCompute hook\n */\nexport interface UseComputeOptions extends ComputeOptions {\n /** Automatically run on mount with initial input */\n autoRun?: boolean;\n /** Initial input for autoRun */\n initialInput?: unknown;\n /** Reset state on new run */\n resetOnRun?: boolean;\n}\n\n/**\n * Hook for running compute functions\n *\n * @example\n * ```tsx\n * function FibonacciCalculator() {\n * const { data, loading, error, run } = useCompute<number, number>('fibonacci');\n *\n * return (\n * <div>\n * <button onClick={() => run(50)} disabled={loading}>\n * Calculate Fibonacci(50)\n * </button>\n * {loading && <p>Computing...</p>}\n * {error && <p>Error: {error.message}</p>}\n * {data !== null && <p>Result: {data}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useCompute<TInput = unknown, TOutput = unknown>(\n functionName: string,\n options: UseComputeOptions = {}\n): UseComputeReturn<TInput, TOutput> {\n const kit = useComputeKit();\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const [state, setState] = useState<UseComputeState<TOutput>>({\n data: null,\n loading: false,\n error: null,\n progress: null,\n });\n\n const reset = useCallback(() => {\n setState({\n data: null,\n loading: false,\n error: null,\n progress: null,\n });\n }, []);\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const run = useCallback(\n async (input: TInput, runOptions?: ComputeOptions) => {\n // Cancel any ongoing computation\n cancel();\n\n // Create new abort controller\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n // Reset state if configured\n if (options.resetOnRun !== false) {\n setState((prev) => ({\n ...prev,\n loading: true,\n error: null,\n progress: null,\n }));\n } else {\n setState((prev) => ({ ...prev, loading: true }));\n }\n\n try {\n const result = await kit.run<TInput, TOutput>(functionName, input, {\n ...options,\n ...runOptions,\n signal: runOptions?.signal ?? abortController.signal,\n onProgress: (progress) => {\n setState((prev) => ({ ...prev, progress }));\n options.onProgress?.(progress);\n runOptions?.onProgress?.(progress);\n },\n });\n\n if (!abortController.signal.aborted) {\n setState({\n data: result,\n loading: false,\n error: null,\n progress: null,\n });\n }\n } catch (err) {\n if (!abortController.signal.aborted) {\n setState({\n data: null,\n loading: false,\n error: err instanceof Error ? err : new Error(String(err)),\n progress: null,\n });\n }\n }\n },\n [kit, functionName, options, cancel]\n );\n\n // Auto-run on mount if configured\n useEffect(() => {\n if (options.autoRun && options.initialInput !== undefined) {\n run(options.initialInput as TInput);\n }\n // Only run on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n cancel();\n };\n }, [cancel]);\n\n return {\n ...state,\n run,\n reset,\n cancel,\n };\n}\n\n// ============================================================================\n// useComputeCallback Hook\n// ============================================================================\n\n/**\n * Hook that returns a memoized async function for compute operations\n *\n * @example\n * ```tsx\n * function Calculator() {\n * const calculate = useComputeCallback<number[], number>('sum');\n *\n * const handleClick = async () => {\n * const result = await calculate([1, 2, 3, 4, 5]);\n * console.log(result);\n * };\n *\n * return <button onClick={handleClick}>Calculate Sum</button>;\n * }\n * ```\n */\nexport function useComputeCallback<TInput = unknown, TOutput = unknown>(\n functionName: string,\n options?: ComputeOptions\n): (input: TInput, runOptions?: ComputeOptions) => Promise<TOutput> {\n const kit = useComputeKit();\n\n return useCallback(\n (input: TInput, runOptions?: ComputeOptions) => {\n return kit.run<TInput, TOutput>(functionName, input, {\n ...options,\n ...runOptions,\n });\n },\n [kit, functionName, options]\n );\n}\n\n// ============================================================================\n// useComputeFunction Hook\n// ============================================================================\n\n/**\n * Hook to register and use a compute function\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { run, loading, data } = useComputeFunction(\n * 'myFunction',\n * (input: number) => input * 2\n * );\n *\n * return (\n * <button onClick={() => run(5)} disabled={loading}>\n * {loading ? 'Computing...' : `Result: ${data}`}\n * </button>\n * );\n * }\n * ```\n */\nexport function useComputeFunction<TInput = unknown, TOutput = unknown>(\n name: string,\n fn: (input: TInput) => TOutput | Promise<TOutput>,\n options?: UseComputeOptions\n): UseComputeReturn<TInput, TOutput> {\n const kit = useComputeKit();\n\n // Register function on mount\n useEffect(() => {\n kit.register(name, fn);\n }, [kit, name, fn]);\n\n return useCompute<TInput, TOutput>(name, options);\n}\n\n// ============================================================================\n// usePoolStats Hook\n// ============================================================================\n\n/**\n * Hook to get worker pool statistics\n *\n * @example\n * ```tsx\n * function PoolMonitor() {\n * const stats = usePoolStats(1000); // Update every second\n *\n * return (\n * <div>\n * <p>Active Workers: {stats.activeWorkers}</p>\n * <p>Queue Length: {stats.queueLength}</p>\n * <p>Tasks Completed: {stats.tasksCompleted}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function usePoolStats(refreshInterval: number = 0): PoolStats {\n const kit = useComputeKit();\n const [stats, setStats] = useState<PoolStats>(() => kit.getStats());\n\n useEffect(() => {\n // For one-time fetch (refreshInterval <= 0), we rely on the initial state\n if (refreshInterval <= 0) {\n return;\n }\n\n const interval = setInterval(() => {\n setStats(kit.getStats());\n }, refreshInterval);\n\n return () => clearInterval(interval);\n }, [kit, refreshInterval]);\n\n return stats;\n}\n\n// ============================================================================\n// useWasmSupport Hook\n// ============================================================================\n\n/**\n * Hook to check WASM support\n */\nexport function useWasmSupport(): boolean {\n const kit = useComputeKit();\n return kit.isWasmSupported();\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport type {\n ComputeKitOptions,\n ComputeOptions,\n ComputeProgress,\n PoolStats,\n} from '@computekit/core';\n\nexport { ComputeKit } from '@computekit/core';\n"]}
1
+ {"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * ComputeKit React Bindings\n * React hooks and utilities for ComputeKit\n */\n\nimport React, {\n useState,\n useEffect,\n useCallback,\n useRef,\n useMemo,\n createContext,\n useContext,\n type ReactNode,\n} from 'react';\n\nimport {\n ComputeKit,\n type ComputeKitOptions,\n type ComputeOptions,\n type ComputeProgress,\n type PoolStats,\n} from '@computekit/core';\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst ComputeKitContext = createContext<ComputeKit | null>(null);\n\n/**\n * Props for ComputeKitProvider\n */\nexport interface ComputeKitProviderProps {\n /** ComputeKit options */\n options?: ComputeKitOptions;\n /** Custom ComputeKit instance */\n instance?: ComputeKit;\n /** Children */\n children: ReactNode;\n}\n\n/**\n * Provider component for ComputeKit\n *\n * @example\n * ```tsx\n * import { ComputeKitProvider } from '@computekit/react';\n *\n * function App() {\n * return (\n * <ComputeKitProvider options={{ maxWorkers: 4 }}>\n * <MyApp />\n * </ComputeKitProvider>\n * );\n * }\n * ```\n */\nexport function ComputeKitProvider({\n options,\n instance,\n children,\n}: ComputeKitProviderProps): React.ReactElement {\n const kit = useMemo(() => {\n return instance ?? new ComputeKit(options);\n }, [instance, options]);\n\n useEffect(() => {\n return () => {\n // Only terminate if we created the instance\n if (!instance) {\n kit.terminate();\n }\n };\n }, [kit, instance]);\n\n return <ComputeKitContext.Provider value={kit}>{children}</ComputeKitContext.Provider>;\n}\n\n/**\n * Get the ComputeKit instance from context\n */\nexport function useComputeKit(): ComputeKit {\n const kit = useContext(ComputeKitContext);\n if (!kit) {\n throw new Error('useComputeKit must be used within a ComputeKitProvider');\n }\n return kit;\n}\n\n// ============================================================================\n// useCompute Hook\n// ============================================================================\n\n/**\n * State returned by useCompute\n */\nexport interface UseComputeState<T> {\n /** The computed result */\n data: T | null;\n /** Loading state */\n loading: boolean;\n /** Error if computation failed */\n error: Error | null;\n /** Progress information */\n progress: ComputeProgress | null;\n}\n\n/**\n * Actions returned by useCompute\n */\nexport interface UseComputeActions<TInput> {\n /** Execute the compute function */\n run: (input: TInput, options?: ComputeOptions) => Promise<void>;\n /** Reset the state */\n reset: () => void;\n /** Cancel ongoing computation */\n cancel: () => void;\n}\n\n/**\n * Return type for useCompute\n */\nexport type UseComputeReturn<TInput, TOutput> = UseComputeState<TOutput> &\n UseComputeActions<TInput>;\n\n/**\n * Options for useCompute hook\n */\nexport interface UseComputeOptions extends ComputeOptions {\n /** Automatically run on mount with initial input */\n autoRun?: boolean;\n /** Initial input for autoRun */\n initialInput?: unknown;\n /** Reset state on new run */\n resetOnRun?: boolean;\n}\n\n/**\n * Hook for running compute functions\n *\n * @example\n * ```tsx\n * function FibonacciCalculator() {\n * const { data, loading, error, run } = useCompute<number, number>('fibonacci');\n *\n * return (\n * <div>\n * <button onClick={() => run(50)} disabled={loading}>\n * Calculate Fibonacci(50)\n * </button>\n * {loading && <p>Computing...</p>}\n * {error && <p>Error: {error.message}</p>}\n * {data !== null && <p>Result: {data}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useCompute<TInput = unknown, TOutput = unknown>(\n functionName: string,\n options: UseComputeOptions = {}\n): UseComputeReturn<TInput, TOutput> {\n const kit = useComputeKit();\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const [state, setState] = useState<UseComputeState<TOutput>>({\n data: null,\n loading: false,\n error: null,\n progress: null,\n });\n\n const reset = useCallback(() => {\n setState({\n data: null,\n loading: false,\n error: null,\n progress: null,\n });\n }, []);\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const run = useCallback(\n async (input: TInput, runOptions?: ComputeOptions) => {\n // Cancel any ongoing computation\n cancel();\n\n // Create new abort controller\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n // Reset state if configured\n if (options.resetOnRun !== false) {\n setState((prev) => ({\n ...prev,\n loading: true,\n error: null,\n progress: null,\n }));\n } else {\n setState((prev) => ({ ...prev, loading: true }));\n }\n\n try {\n const result = await kit.run<TInput, TOutput>(functionName, input, {\n ...options,\n ...runOptions,\n signal: runOptions?.signal ?? abortController.signal,\n onProgress: (progress) => {\n setState((prev) => ({ ...prev, progress }));\n options.onProgress?.(progress);\n runOptions?.onProgress?.(progress);\n },\n });\n\n if (!abortController.signal.aborted) {\n setState({\n data: result,\n loading: false,\n error: null,\n progress: null,\n });\n }\n } catch (err) {\n if (!abortController.signal.aborted) {\n setState({\n data: null,\n loading: false,\n error: err instanceof Error ? err : new Error(String(err)),\n progress: null,\n });\n }\n }\n },\n [kit, functionName, options, cancel]\n );\n\n // Auto-run on mount if configured\n useEffect(() => {\n if (options.autoRun && options.initialInput !== undefined) {\n run(options.initialInput as TInput);\n }\n // Only run on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n cancel();\n };\n }, [cancel]);\n\n return {\n ...state,\n run,\n reset,\n cancel,\n };\n}\n\n// ============================================================================\n// useComputeCallback Hook\n// ============================================================================\n\n/**\n * Hook that returns a memoized async function for compute operations\n *\n * @example\n * ```tsx\n * function Calculator() {\n * const calculate = useComputeCallback<number[], number>('sum');\n *\n * const handleClick = async () => {\n * const result = await calculate([1, 2, 3, 4, 5]);\n * console.log(result);\n * };\n *\n * return <button onClick={handleClick}>Calculate Sum</button>;\n * }\n * ```\n */\nexport function useComputeCallback<TInput = unknown, TOutput = unknown>(\n functionName: string,\n options?: ComputeOptions\n): (input: TInput, runOptions?: ComputeOptions) => Promise<TOutput> {\n const kit = useComputeKit();\n\n return useCallback(\n (input: TInput, runOptions?: ComputeOptions) => {\n return kit.run<TInput, TOutput>(functionName, input, {\n ...options,\n ...runOptions,\n });\n },\n [kit, functionName, options]\n );\n}\n\n// ============================================================================\n// useComputeFunction Hook\n// ============================================================================\n\n/**\n * Hook to register and use a compute function\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { run, loading, data } = useComputeFunction(\n * 'myFunction',\n * (input: number) => input * 2\n * );\n *\n * return (\n * <button onClick={() => run(5)} disabled={loading}>\n * {loading ? 'Computing...' : `Result: ${data}`}\n * </button>\n * );\n * }\n * ```\n */\nexport function useComputeFunction<TInput = unknown, TOutput = unknown>(\n name: string,\n fn: (input: TInput) => TOutput | Promise<TOutput>,\n options?: UseComputeOptions\n): UseComputeReturn<TInput, TOutput> {\n const kit = useComputeKit();\n\n // Register function on mount\n useEffect(() => {\n kit.register(name, fn);\n }, [kit, name, fn]);\n\n return useCompute<TInput, TOutput>(name, options);\n}\n\n// ============================================================================\n// usePoolStats Hook\n// ============================================================================\n\n/**\n * Hook to get worker pool statistics\n *\n * @example\n * ```tsx\n * function PoolMonitor() {\n * const stats = usePoolStats(1000); // Update every second\n *\n * return (\n * <div>\n * <p>Active Workers: {stats.activeWorkers}</p>\n * <p>Queue Length: {stats.queueLength}</p>\n * <p>Tasks Completed: {stats.tasksCompleted}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function usePoolStats(refreshInterval: number = 0): PoolStats {\n const kit = useComputeKit();\n const [stats, setStats] = useState<PoolStats>(() => kit.getStats());\n\n useEffect(() => {\n // For one-time fetch (refreshInterval <= 0), we rely on the initial state\n if (refreshInterval <= 0) {\n return;\n }\n\n const interval = setInterval(() => {\n setStats(kit.getStats());\n }, refreshInterval);\n\n return () => clearInterval(interval);\n }, [kit, refreshInterval]);\n\n return stats;\n}\n\n// ============================================================================\n// useWasmSupport Hook\n// ============================================================================\n\n/**\n * Hook to check WASM support\n */\nexport function useWasmSupport(): boolean {\n const kit = useComputeKit();\n return kit.isWasmSupported();\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport type {\n ComputeKitOptions,\n ComputeOptions,\n ComputeProgress,\n PoolStats,\n} from '@computekit/core';\n\nexport { ComputeKit } from '@computekit/core';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@computekit/react",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "React bindings for ComputeKit - WASM + Worker toolkit",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -15,7 +15,8 @@
15
15
  },
16
16
  "files": [
17
17
  "dist",
18
- "src"
18
+ "src",
19
+ "README.md"
19
20
  ],
20
21
  "scripts": {
21
22
  "build": "tsup",
@@ -27,7 +28,13 @@
27
28
  "@computekit/core": "*"
28
29
  },
29
30
  "peerDependencies": {
30
- "react": ">=17.0.0"
31
+ "react": ">=17.0.0",
32
+ "@types/react": ">=17.0.0"
33
+ },
34
+ "peerDependenciesMeta": {
35
+ "@types/react": {
36
+ "optional": true
37
+ }
31
38
  },
32
39
  "devDependencies": {
33
40
  "@types/react": "^18.2.45",
package/src/index.tsx CHANGED
@@ -3,7 +3,7 @@
3
3
  * React hooks and utilities for ComputeKit
4
4
  */
5
5
 
6
- import {
6
+ import React, {
7
7
  useState,
8
8
  useEffect,
9
9
  useCallback,
@@ -60,7 +60,7 @@ export function ComputeKitProvider({
60
60
  options,
61
61
  instance,
62
62
  children,
63
- }: ComputeKitProviderProps): JSX.Element {
63
+ }: ComputeKitProviderProps): React.ReactElement {
64
64
  const kit = useMemo(() => {
65
65
  return instance ?? new ComputeKit(options);
66
66
  }, [instance, options]);