@supunlakmal/hooks
Version:
A collection of reusable React hooks
65 lines • 2.28 kB
JavaScript
import { useCallback, useEffect, useRef, useState } from 'react';
/** */
export const useWorker = (workerFn) => {
const [result, setResult] = useState(null);
const [error, setError] = useState(null);
const [status, setStatus] = useState('idle');
const workerRef = useRef(null);
const execute = useCallback((...args) => {
setStatus('working');
setError(null);
setResult(null);
if (workerRef.current) {
workerRef.current.terminate();
workerRef.current = null;
}
const workerCode = `
self.onmessage = async (event) => {
try {
const result = await (${workerFn.toString()})(...event.data);
self.postMessage({ type: 'success', result });
} catch (error) {
self.postMessage({ type: 'error', error: error.message });
}
};
`;
const blob = new Blob([workerCode], { type: 'text/javascript' });
const workerUrl = URL.createObjectURL(blob);
const worker = new Worker(workerUrl);
workerRef.current = worker;
worker.onmessage = (event) => {
const { type, result, error } = event.data;
if (type === 'success') {
setResult(result !== null && result !== void 0 ? result : null);
setStatus('success');
}
else if (type === 'error') {
setError(new Error(error !== null && error !== void 0 ? error : 'Unknown worker error'));
setStatus('error');
}
URL.revokeObjectURL(workerUrl);
};
worker.onerror = (event) => {
setError(new Error(event.message));
setStatus('error');
URL.revokeObjectURL(workerUrl);
};
worker.postMessage(args);
}, [workerFn]);
const kill = useCallback(() => {
if (workerRef.current) {
workerRef.current.terminate();
workerRef.current = null;
setStatus('idle');
setError(null);
setResult(null);
}
}, []);
useEffect(() => {
return () => {
kill();
};
}, [kill]);
return { execute, result, error, status, kill };
};
//# sourceMappingURL=useWorker.js.map