| |
| |
| |
|
|
| import { useState, useCallback, useEffect, useRef } from 'react'; |
|
|
| |
| |
| |
| export function useLiveUMAP() { |
| const [isCalculating, setIsCalculating] = useState(false); |
| const [progress, setProgress] = useState(null); |
| const [error, setError] = useState(null); |
| const [result, setResult] = useState(null); |
|
|
| const workerRef = useRef(null); |
| const resolveRef = useRef(null); |
| const rejectRef = useRef(null); |
|
|
| |
| useEffect(() => { |
| |
| |
| const worker = new Worker(new URL('../workers/umap.worker.js', import.meta.url)); |
|
|
| worker.onmessage = (e) => { |
| const { type, payload } = e.data; |
|
|
| if (type === 'PROGRESS') { |
| setProgress(payload); |
| } else if (type === 'RESULT') { |
| setResult(payload); |
| setIsCalculating(false); |
| if (resolveRef.current) { |
| resolveRef.current(payload); |
| resolveRef.current = null; |
| } |
| } else if (type === 'ERROR') { |
| setError(payload); |
| setIsCalculating(false); |
| if (rejectRef.current) { |
| rejectRef.current(new Error(payload)); |
| rejectRef.current = null; |
| } |
| } |
| }; |
|
|
| workerRef.current = worker; |
|
|
| return () => { |
| worker.terminate(); |
| }; |
| }, []); |
|
|
| |
| |
| |
| const calculate = useCallback((config) => { |
| return new Promise((resolve, reject) => { |
| if (!workerRef.current) { |
| reject(new Error('Worker non initialisé')); |
| return; |
| } |
|
|
| setIsCalculating(true); |
| setError(null); |
| setProgress({ stage: 'starting', progress: 0 }); |
|
|
| resolveRef.current = resolve; |
| rejectRef.current = reject; |
|
|
| workerRef.current.postMessage({ |
| type: 'CALCULATE', |
| payload: config |
| }); |
| }); |
| }, []); |
|
|
| |
| |
| |
| const reset = useCallback(() => { |
| setResult(null); |
| setError(null); |
| setProgress(null); |
| setIsCalculating(false); |
| }, []); |
|
|
| return { |
| calculate, |
| reset, |
| isCalculating, |
| progress, |
| error, |
| result |
| }; |
| } |
|
|