@computekit/react 0.1.3 → 0.2.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/src/index.tsx CHANGED
@@ -20,6 +20,11 @@ import {
20
20
  type ComputeOptions,
21
21
  type ComputeProgress,
22
22
  type PoolStats,
23
+ type ComputeFunctionRegistry,
24
+ type RegisteredFunctionName,
25
+ type FunctionInput,
26
+ type FunctionOutput,
27
+ type ComputeFn,
23
28
  } from '@computekit/core';
24
29
 
25
30
  // ============================================================================
@@ -303,6 +308,7 @@ export interface UseComputeOptions extends ComputeOptions {
303
308
  *
304
309
  * @example
305
310
  * ```tsx
311
+ * // Basic usage with explicit types
306
312
  * function FibonacciCalculator() {
307
313
  * const { data, loading, error, run } = useCompute<number, number>('fibonacci');
308
314
  *
@@ -317,17 +323,43 @@ export interface UseComputeOptions extends ComputeOptions {
317
323
  * </div>
318
324
  * );
319
325
  * }
326
+ *
327
+ * // With typed registry (extend ComputeFunctionRegistry for autocomplete)
328
+ * // declare module '@computekit/core' {
329
+ * // interface ComputeFunctionRegistry {
330
+ * // fibonacci: { input: number; output: number };
331
+ * // }
332
+ * // }
333
+ * // const { data, run } = useCompute('fibonacci'); // Types are inferred!
320
334
  * ```
321
335
  */
322
- export function useCompute<TInput = unknown, TOutput = unknown>(
323
- functionName: string,
336
+ export function useCompute<
337
+ TName extends RegisteredFunctionName,
338
+ TInput = FunctionInput<TName extends string ? TName : never>,
339
+ TOutput = FunctionOutput<TName extends string ? TName : never>,
340
+ >(
341
+ functionName: TName,
324
342
  options: UseComputeOptions = {}
325
- ): UseComputeReturn<TInput, TOutput> {
343
+ ): UseComputeReturn<
344
+ TName extends keyof ComputeFunctionRegistry
345
+ ? ComputeFunctionRegistry[TName]['input']
346
+ : TInput,
347
+ TName extends keyof ComputeFunctionRegistry
348
+ ? ComputeFunctionRegistry[TName]['output']
349
+ : TOutput
350
+ > {
351
+ type ActualInput = TName extends keyof ComputeFunctionRegistry
352
+ ? ComputeFunctionRegistry[TName]['input']
353
+ : TInput;
354
+ type ActualOutput = TName extends keyof ComputeFunctionRegistry
355
+ ? ComputeFunctionRegistry[TName]['output']
356
+ : TOutput;
357
+
326
358
  const kit = useComputeKit();
327
359
  const abortControllerRef = useRef<AbortController | null>(null);
328
360
  const cancelledRef = useRef(false);
329
361
 
330
- const [state, setState] = useState<UseComputeState<TOutput>>({
362
+ const [state, setState] = useState<UseComputeState<ActualOutput>>({
331
363
  data: null,
332
364
  loading: false,
333
365
  error: null,
@@ -360,7 +392,7 @@ export function useCompute<TInput = unknown, TOutput = unknown>(
360
392
  }, []);
361
393
 
362
394
  const run = useCallback(
363
- async (input: TInput, runOptions?: ComputeOptions) => {
395
+ async (input: ActualInput, runOptions?: ComputeOptions) => {
364
396
  // Cancel any ongoing computation
365
397
  cancel();
366
398
  cancelledRef.current = false;
@@ -383,7 +415,7 @@ export function useCompute<TInput = unknown, TOutput = unknown>(
383
415
  }
384
416
 
385
417
  try {
386
- const result = await kit.run<TInput, TOutput>(functionName, input, {
418
+ const result = (await kit.run(functionName, input, {
387
419
  ...options,
388
420
  ...runOptions,
389
421
  signal: runOptions?.signal ?? abortController.signal,
@@ -392,7 +424,7 @@ export function useCompute<TInput = unknown, TOutput = unknown>(
392
424
  options.onProgress?.(progress);
393
425
  runOptions?.onProgress?.(progress);
394
426
  },
395
- });
427
+ })) as ActualOutput;
396
428
 
397
429
  if (!abortController.signal.aborted) {
398
430
  setState({
@@ -421,7 +453,7 @@ export function useCompute<TInput = unknown, TOutput = unknown>(
421
453
  // Auto-run on mount if configured
422
454
  useEffect(() => {
423
455
  if (options.autoRun && options.initialInput !== undefined) {
424
- run(options.initialInput as TInput);
456
+ run(options.initialInput as ActualInput);
425
457
  }
426
458
  // Only run on mount
427
459
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -439,7 +471,7 @@ export function useCompute<TInput = unknown, TOutput = unknown>(
439
471
  run,
440
472
  reset,
441
473
  cancel,
442
- };
474
+ } as UseComputeReturn<ActualInput, ActualOutput>;
443
475
  }
444
476
 
445
477
  // ============================================================================
@@ -451,6 +483,7 @@ export function useCompute<TInput = unknown, TOutput = unknown>(
451
483
  *
452
484
  * @example
453
485
  * ```tsx
486
+ * // Basic usage with explicit types
454
487
  * function Calculator() {
455
488
  * const calculate = useComputeCallback<number[], number>('sum');
456
489
  *
@@ -461,20 +494,43 @@ export function useCompute<TInput = unknown, TOutput = unknown>(
461
494
  *
462
495
  * return <button onClick={handleClick}>Calculate Sum</button>;
463
496
  * }
497
+ *
498
+ * // With typed registry - types are inferred!
499
+ * // const calculate = useComputeCallback('sum');
464
500
  * ```
465
501
  */
466
- export function useComputeCallback<TInput = unknown, TOutput = unknown>(
467
- functionName: string,
502
+ export function useComputeCallback<
503
+ TName extends RegisteredFunctionName,
504
+ TInput = FunctionInput<TName extends string ? TName : never>,
505
+ TOutput = FunctionOutput<TName extends string ? TName : never>,
506
+ >(
507
+ functionName: TName,
468
508
  options?: ComputeOptions
469
- ): (input: TInput, runOptions?: ComputeOptions) => Promise<TOutput> {
509
+ ): (
510
+ input: TName extends keyof ComputeFunctionRegistry
511
+ ? ComputeFunctionRegistry[TName]['input']
512
+ : TInput,
513
+ runOptions?: ComputeOptions
514
+ ) => Promise<
515
+ TName extends keyof ComputeFunctionRegistry
516
+ ? ComputeFunctionRegistry[TName]['output']
517
+ : TOutput
518
+ > {
519
+ type ActualInput = TName extends keyof ComputeFunctionRegistry
520
+ ? ComputeFunctionRegistry[TName]['input']
521
+ : TInput;
522
+ type ActualOutput = TName extends keyof ComputeFunctionRegistry
523
+ ? ComputeFunctionRegistry[TName]['output']
524
+ : TOutput;
525
+
470
526
  const kit = useComputeKit();
471
527
 
472
528
  return useCallback(
473
- (input: TInput, runOptions?: ComputeOptions) => {
474
- return kit.run<TInput, TOutput>(functionName, input, {
529
+ (input: ActualInput, runOptions?: ComputeOptions): Promise<ActualOutput> => {
530
+ return kit.run(functionName, input, {
475
531
  ...options,
476
532
  ...runOptions,
477
- });
533
+ }) as Promise<ActualOutput>;
478
534
  },
479
535
  [kit, functionName, options]
480
536
  );
@@ -489,6 +545,7 @@ export function useComputeCallback<TInput = unknown, TOutput = unknown>(
489
545
  *
490
546
  * @example
491
547
  * ```tsx
548
+ * // Basic usage
492
549
  * function MyComponent() {
493
550
  * const { run, loading, data } = useComputeFunction(
494
551
  * 'myFunction',
@@ -501,13 +558,36 @@ export function useComputeCallback<TInput = unknown, TOutput = unknown>(
501
558
  * </button>
502
559
  * );
503
560
  * }
561
+ *
562
+ * // With typed registry - provides autocomplete and type safety
563
+ * // declare module '@computekit/core' {
564
+ * // interface ComputeFunctionRegistry {
565
+ * // myFunction: { input: number; output: number };
566
+ * // }
567
+ * // }
504
568
  * ```
505
569
  */
506
- export function useComputeFunction<TInput = unknown, TOutput = unknown>(
507
- name: string,
508
- fn: (input: TInput) => TOutput | Promise<TOutput>,
570
+ export function useComputeFunction<
571
+ TName extends RegisteredFunctionName,
572
+ TInput = FunctionInput<TName extends string ? TName : never>,
573
+ TOutput = FunctionOutput<TName extends string ? TName : never>,
574
+ >(
575
+ name: TName,
576
+ fn: TName extends keyof ComputeFunctionRegistry
577
+ ? ComputeFn<
578
+ ComputeFunctionRegistry[TName]['input'],
579
+ ComputeFunctionRegistry[TName]['output']
580
+ >
581
+ : ComputeFn<TInput, TOutput>,
509
582
  options?: UseComputeOptions
510
- ): UseComputeReturn<TInput, TOutput> {
583
+ ): UseComputeReturn<
584
+ TName extends keyof ComputeFunctionRegistry
585
+ ? ComputeFunctionRegistry[TName]['input']
586
+ : TInput,
587
+ TName extends keyof ComputeFunctionRegistry
588
+ ? ComputeFunctionRegistry[TName]['output']
589
+ : TOutput
590
+ > {
511
591
  const kit = useComputeKit();
512
592
 
513
593
  // Register function on mount
@@ -515,7 +595,7 @@ export function useComputeFunction<TInput = unknown, TOutput = unknown>(
515
595
  kit.register(name, fn);
516
596
  }, [kit, name, fn]);
517
597
 
518
- return useCompute<TInput, TOutput>(name, options);
598
+ return useCompute(name, options);
519
599
  }
520
600
 
521
601
  // ============================================================================
@@ -1397,6 +1477,7 @@ export interface UseParallelBatchReturn<TItem, TOutput> {
1397
1477
  *
1398
1478
  * @example
1399
1479
  * ```tsx
1480
+ * // Basic usage with explicit types
1400
1481
  * function BatchProcessor() {
1401
1482
  * const batch = useParallelBatch<string, ProcessedFile>('processFile', {
1402
1483
  * concurrency: 4
@@ -1427,20 +1508,41 @@ export interface UseParallelBatchReturn<TItem, TOutput> {
1427
1508
  * </div>
1428
1509
  * );
1429
1510
  * }
1511
+ *
1512
+ * // With typed registry - types are inferred!
1513
+ * // const batch = useParallelBatch('processFile');
1430
1514
  * ```
1431
1515
  */
1432
- export function useParallelBatch<TItem = unknown, TOutput = unknown>(
1433
- functionName: string,
1516
+ export function useParallelBatch<
1517
+ TName extends RegisteredFunctionName,
1518
+ TItem = FunctionInput<TName extends string ? TName : never>,
1519
+ TOutput = FunctionOutput<TName extends string ? TName : never>,
1520
+ >(
1521
+ functionName: TName,
1434
1522
  options: {
1435
1523
  concurrency?: number;
1436
1524
  computeOptions?: ComputeOptions;
1437
1525
  } = {}
1438
- ): UseParallelBatchReturn<TItem, TOutput> {
1526
+ ): UseParallelBatchReturn<
1527
+ TName extends keyof ComputeFunctionRegistry
1528
+ ? ComputeFunctionRegistry[TName]['input']
1529
+ : TItem,
1530
+ TName extends keyof ComputeFunctionRegistry
1531
+ ? ComputeFunctionRegistry[TName]['output']
1532
+ : TOutput
1533
+ > {
1534
+ type ActualItem = TName extends keyof ComputeFunctionRegistry
1535
+ ? ComputeFunctionRegistry[TName]['input']
1536
+ : TItem;
1537
+ type ActualOutput = TName extends keyof ComputeFunctionRegistry
1538
+ ? ComputeFunctionRegistry[TName]['output']
1539
+ : TOutput;
1540
+
1439
1541
  const kit = useComputeKit();
1440
1542
  const abortControllerRef = useRef<AbortController | null>(null);
1441
1543
 
1442
1544
  const [state, setState] = useState<{
1443
- result: ParallelBatchResult<TOutput> | null;
1545
+ result: ParallelBatchResult<ActualOutput> | null;
1444
1546
  loading: boolean;
1445
1547
  progress: number;
1446
1548
  completedCount: number;
@@ -1454,7 +1556,7 @@ export function useParallelBatch<TItem = unknown, TOutput = unknown>(
1454
1556
  });
1455
1557
 
1456
1558
  const run = useCallback(
1457
- async (items: TItem[]): Promise<ParallelBatchResult<TOutput>> => {
1559
+ async (items: ActualItem[]): Promise<ParallelBatchResult<ActualOutput>> => {
1458
1560
  // Cancel any existing batch
1459
1561
  if (abortControllerRef.current) {
1460
1562
  abortControllerRef.current.abort();
@@ -1472,7 +1574,7 @@ export function useParallelBatch<TItem = unknown, TOutput = unknown>(
1472
1574
  });
1473
1575
 
1474
1576
  const startTime = performance.now();
1475
- const results: BatchItemResult<TOutput>[] = [];
1577
+ const results: BatchItemResult<ActualOutput>[] = [];
1476
1578
  const concurrency = options.concurrency ?? items.length;
1477
1579
 
1478
1580
  // Process in batches based on concurrency
@@ -1487,12 +1589,12 @@ export function useParallelBatch<TItem = unknown, TOutput = unknown>(
1487
1589
  const itemStart = performance.now();
1488
1590
 
1489
1591
  try {
1490
- const data = await kit.run<TItem, TOutput>(functionName, item, {
1592
+ const data = (await kit.run(functionName, item, {
1491
1593
  ...options.computeOptions,
1492
1594
  signal: abortController.signal,
1493
- });
1595
+ })) as ActualOutput;
1494
1596
 
1495
- const itemResult: BatchItemResult<TOutput> = {
1597
+ const itemResult: BatchItemResult<ActualOutput> = {
1496
1598
  index,
1497
1599
  success: true,
1498
1600
  data,
@@ -1501,7 +1603,7 @@ export function useParallelBatch<TItem = unknown, TOutput = unknown>(
1501
1603
 
1502
1604
  return itemResult;
1503
1605
  } catch (err) {
1504
- const itemResult: BatchItemResult<TOutput> = {
1606
+ const itemResult: BatchItemResult<ActualOutput> = {
1505
1607
  index,
1506
1608
  success: false,
1507
1609
  error: err instanceof Error ? err : new Error(String(err)),
@@ -1527,12 +1629,12 @@ export function useParallelBatch<TItem = unknown, TOutput = unknown>(
1527
1629
  const totalDuration = performance.now() - startTime;
1528
1630
  const successful = results
1529
1631
  .filter((r) => r.success && r.data !== undefined)
1530
- .map((r) => r.data as TOutput);
1632
+ .map((r) => r.data as ActualOutput);
1531
1633
  const failed = results
1532
1634
  .filter((r) => !r.success)
1533
1635
  .map((r) => ({ index: r.index, error: r.error! }));
1534
1636
 
1535
- const finalResult: ParallelBatchResult<TOutput> = {
1637
+ const finalResult: ParallelBatchResult<ActualOutput> = {
1536
1638
  results,
1537
1639
  successful,
1538
1640
  failed,
@@ -1587,7 +1689,7 @@ export function useParallelBatch<TItem = unknown, TOutput = unknown>(
1587
1689
  run,
1588
1690
  cancel,
1589
1691
  reset,
1590
- };
1692
+ } as UseParallelBatchReturn<ActualItem, ActualOutput>;
1591
1693
  }
1592
1694
 
1593
1695
  // ============================================================================
@@ -1599,6 +1701,15 @@ export type {
1599
1701
  ComputeOptions,
1600
1702
  ComputeProgress,
1601
1703
  PoolStats,
1704
+ // Typed registry exports
1705
+ ComputeFunctionRegistry,
1706
+ RegisteredFunctionName,
1707
+ FunctionInput,
1708
+ FunctionOutput,
1709
+ ComputeFn,
1710
+ InferComputeFn,
1711
+ DefineFunction,
1712
+ HasRegisteredFunctions,
1602
1713
  } from '@computekit/core';
1603
1714
 
1604
1715
  export { ComputeKit } from '@computekit/core';