react-hooks-worker
Advanced tools
Comparing version 0.3.0 to 0.4.0
@@ -5,2 +5,9 @@ # Change Log | ||
## [0.4.0] - 2019-05-16 | ||
### Changed | ||
- Update dependencies | ||
### Added | ||
- Inline function support | ||
- Async generator support | ||
## [0.3.0] - 2019-03-11 | ||
@@ -7,0 +14,0 @@ ### Changed |
@@ -18,3 +18,22 @@ "use strict"; | ||
var useWorker = function useWorker(workerInfo, message) { | ||
var batchedUpdates = function batchedUpdates(callback) { | ||
if (_react.unstable_batchedUpdates) { | ||
(0, _react.unstable_batchedUpdates)(callback); | ||
} else { | ||
callback(); | ||
} | ||
}; | ||
var createWorker = function createWorker(func) { | ||
if (func instanceof Worker) return func; | ||
if (typeof func === 'string' && func.endsWith('.js')) return new Worker(func); | ||
var code = ["self.func = ".concat(func.toString(), ";"), 'self.onmessage = async (e) => {', ' const r = self.func(...e.data);', ' if (r[Symbol.asyncIterator]) {', ' for await (const i of r) self.postMessage(i)', ' } else if (r[Symbol.iterator]){', ' for (const i of r) self.postMessage(i)', ' } else {', ' self.postMessage(await r)', ' }', '};']; | ||
var blob = new Blob(code, { | ||
type: 'text/javascript' | ||
}); | ||
var url = URL.createObjectURL(blob); | ||
return new Worker(url); | ||
}; | ||
var useWorker = function useWorker(func, args) { | ||
var _useState = (0, _react.useState)(null), | ||
@@ -30,32 +49,43 @@ _useState2 = _slicedToArray(_useState, 2), | ||
var worker = (0, _react.useRef)(null); | ||
var worker = (0, _react.useMemo)(function () { | ||
return createWorker(func); | ||
}, [func]); | ||
var lastWorker = (0, _react.useRef)(null); | ||
(0, _react.useEffect)(function () { | ||
var w = workerInfo instanceof Worker ? workerInfo : new Worker(workerInfo); | ||
lastWorker.current = worker; | ||
w.onmessage = function (e) { | ||
setResult(e.data); | ||
setError(null); | ||
worker.onmessage = function (e) { | ||
if (lastWorker.current !== worker) return; | ||
batchedUpdates(function () { | ||
setResult(e.data); | ||
setError(null); | ||
}); | ||
}; | ||
w.onerror = function () { | ||
setResult(null); | ||
setError('error'); | ||
worker.onerror = function () { | ||
if (lastWorker.current !== worker) return; | ||
batchedUpdates(function () { | ||
setResult(null); | ||
setError('error'); | ||
}); | ||
}; | ||
w.onmessageerror = function () { | ||
setResult(null); | ||
setError('messageerror'); | ||
worker.onmessageerror = function () { | ||
if (lastWorker.current !== worker) return; | ||
batchedUpdates(function () { | ||
setResult(null); | ||
setError('messageerror'); | ||
}); | ||
}; | ||
worker.current = w; | ||
var cleanup = function cleanup() { | ||
w.terminate(); | ||
worker.terminate(); | ||
}; | ||
return cleanup; | ||
}, [workerInfo]); | ||
}, [worker]); | ||
(0, _react.useEffect)(function () { | ||
worker.current.postMessage(message); | ||
}, [message]); | ||
var message = Array.isArray(args) ? args : [args]; | ||
lastWorker.current.postMessage(message); | ||
}, [args]); | ||
return { | ||
@@ -62,0 +92,0 @@ result: result, |
{ | ||
"name": "react-hooks-worker", | ||
"description": "React custom hooks for web workers", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"author": "Daishi Kato", | ||
@@ -25,3 +25,5 @@ "repository": { | ||
"examples:typescript": "DIR=02_typescript webpack-dev-server", | ||
"examples:comparison": "DIR=03_comparison webpack-dev-server" | ||
"examples:comparison": "DIR=03_comparison webpack-dev-server", | ||
"examples:inline": "DIR=04_inline webpack-dev-server", | ||
"examples:generator": "DIR=05_generator webpack-dev-server" | ||
}, | ||
@@ -37,28 +39,28 @@ "keywords": [ | ||
"devDependencies": { | ||
"@babel/cli": "^7.2.3", | ||
"@babel/core": "^7.2.2", | ||
"@babel/preset-env": "^7.3.1", | ||
"@babel/cli": "^7.4.4", | ||
"@babel/core": "^7.4.4", | ||
"@babel/preset-env": "^7.4.4", | ||
"@babel/preset-react": "^7.0.0", | ||
"@types/react": "^16.8.2", | ||
"@types/react-dom": "^16.8.0", | ||
"@typescript-eslint/eslint-plugin": "^1.3.0", | ||
"@types/react": "^16.8.17", | ||
"@types/react-dom": "^16.8.4", | ||
"@typescript-eslint/eslint-plugin": "^1.9.0", | ||
"babel-core": "^7.0.0-bridge.0", | ||
"babel-eslint": "^10.0.1", | ||
"babel-loader": "^8.0.5", | ||
"core-js": "^2.6.4", | ||
"eslint": "^5.13.0", | ||
"babel-loader": "^8.0.6", | ||
"eslint": "^5.16.0", | ||
"eslint-config-airbnb": "^17.1.0", | ||
"eslint-plugin-import": "^2.16.0", | ||
"eslint-plugin-import": "^2.17.2", | ||
"eslint-plugin-jsx-a11y": "^6.2.1", | ||
"eslint-plugin-react": "^7.12.4", | ||
"eslint-plugin-react": "^7.13.0", | ||
"eslint-plugin-react-hooks": "^1.6.0", | ||
"html-webpack-plugin": "^3.2.0", | ||
"jest": "^24.1.0", | ||
"react": "16.8.1", | ||
"react-dom": "16.8.1", | ||
"react-test-renderer": "^16.8.1", | ||
"ts-loader": "^5.3.3", | ||
"typescript": "^3.3.3", | ||
"webpack": "^4.29.3", | ||
"webpack-cli": "^3.2.3", | ||
"webpack-dev-server": "^3.1.14" | ||
"jest": "^24.8.0", | ||
"react": "^16.8.6", | ||
"react-dom": "^16.8.6", | ||
"react-test-renderer": "^16.8.6", | ||
"ts-loader": "^6.0.0", | ||
"typescript": "^3.4.5", | ||
"webpack": "^4.31.0", | ||
"webpack-cli": "^3.3.2", | ||
"webpack-dev-server": "^3.3.1" | ||
}, | ||
@@ -65,0 +67,0 @@ "peerDependencies": { |
@@ -32,4 +32,9 @@ # react-hooks-worker | ||
const CalcFib = ({ count }) => { | ||
const { result, error } = useWorker('./slow_fib.js', count); | ||
const calcFib = (x) => { | ||
const fib = i => (i <= 1 ? i : fib(i - 1) + fib(i - 2)); | ||
return fib(x); | ||
}; | ||
const CalcFib: React.FC<{ count: number }> = ({ count }) => { | ||
const { result, error } = useWorker(calcFib, count); | ||
if (error) return <div>Error:{error}</div>; | ||
@@ -71,2 +76,4 @@ return <div>Result:{result}</div>; | ||
[03](https://codesandbox.io/s/github/dai-shi/react-hooks-worker/tree/master/examples/03_comparison) | ||
[04](https://codesandbox.io/s/github/dai-shi/react-hooks-worker/tree/master/examples/04_inline) | ||
[05](https://codesandbox.io/s/github/dai-shi/react-hooks-worker/tree/master/examples/05_generator) | ||
@@ -73,0 +80,0 @@ ## Blogs |
export type UseWorker = <Result>( | ||
workerInfo: string | Worker, | ||
message: unknown | ||
func: Function | string | Worker, | ||
args: unknown | ||
) => { | ||
@@ -5,0 +5,0 @@ result: Result | null; |
@@ -1,31 +0,76 @@ | ||
import { useEffect, useRef, useState } from 'react'; | ||
import { | ||
useEffect, | ||
useMemo, | ||
useRef, | ||
useState, | ||
unstable_batchedUpdates, | ||
} from 'react'; | ||
export const useWorker = (workerInfo, message) => { | ||
const batchedUpdates = (callback) => { | ||
if (unstable_batchedUpdates) { | ||
unstable_batchedUpdates(callback); | ||
} else { | ||
callback(); | ||
} | ||
}; | ||
const createWorker = (func) => { | ||
if (func instanceof Worker) return func; | ||
if (typeof func === 'string' && func.endsWith('.js')) return new Worker(func); | ||
const code = [ | ||
`self.func = ${func.toString()};`, | ||
'self.onmessage = async (e) => {', | ||
' const r = self.func(...e.data);', | ||
' if (r[Symbol.asyncIterator]) {', | ||
' for await (const i of r) self.postMessage(i)', | ||
' } else if (r[Symbol.iterator]){', | ||
' for (const i of r) self.postMessage(i)', | ||
' } else {', | ||
' self.postMessage(await r)', | ||
' }', | ||
'};', | ||
]; | ||
const blob = new Blob(code, { type: 'text/javascript' }); | ||
const url = URL.createObjectURL(blob); | ||
return new Worker(url); | ||
}; | ||
export const useWorker = (func, args) => { | ||
const [result, setResult] = useState(null); | ||
const [error, setError] = useState(null); | ||
const worker = useRef(null); | ||
const worker = useMemo(() => createWorker(func), [func]); | ||
const lastWorker = useRef(null); | ||
useEffect(() => { | ||
const w = workerInfo instanceof Worker ? workerInfo : new Worker(workerInfo); | ||
w.onmessage = (e) => { | ||
setResult(e.data); | ||
setError(null); | ||
lastWorker.current = worker; | ||
worker.onmessage = (e) => { | ||
if (lastWorker.current !== worker) return; | ||
batchedUpdates(() => { | ||
setResult(e.data); | ||
setError(null); | ||
}); | ||
}; | ||
w.onerror = () => { | ||
setResult(null); | ||
setError('error'); | ||
worker.onerror = () => { | ||
if (lastWorker.current !== worker) return; | ||
batchedUpdates(() => { | ||
setResult(null); | ||
setError('error'); | ||
}); | ||
}; | ||
w.onmessageerror = () => { | ||
setResult(null); | ||
setError('messageerror'); | ||
worker.onmessageerror = () => { | ||
if (lastWorker.current !== worker) return; | ||
batchedUpdates(() => { | ||
setResult(null); | ||
setError('messageerror'); | ||
}); | ||
}; | ||
worker.current = w; | ||
const cleanup = () => { | ||
w.terminate(); | ||
worker.terminate(); | ||
}; | ||
return cleanup; | ||
}, [workerInfo]); | ||
}, [worker]); | ||
useEffect(() => { | ||
worker.current.postMessage(message); | ||
}, [message]); | ||
const message = Array.isArray(args) ? args : [args]; | ||
lastWorker.current.postMessage(message); | ||
}, [args]); | ||
return { result, error }; | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
11353
160
81