Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 30 additions & 21 deletions apps/examples/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
import React from 'react'
import { Toaster } from 'react-hot-toast'
import { Link, Route, BrowserRouter as Router, Switch } from 'react-router-dom'
import React from "react";
import { Toaster } from "react-hot-toast";
import { Link, Route, BrowserRouter as Router, Switch } from "react-router-dom";

import CsvPage from './pages/Csv/index.jsx'
import ExternalScriptsPage from './pages/ExternalScripts/index.jsx'
import SortingPage from './pages/Sorting/index.jsx'
import TransferablePage from './pages/Transferable'
import logo from './react.png'
import './style.css'
import CsvPage from "./pages/Csv/index.jsx";
import ExternalScriptsPage from "./pages/ExternalScripts/index.jsx";
import SortingPage from "./pages/Sorting/index.jsx";
import TransferablePage from "./pages/Transferable";
import LocalDepsPage from "./pages/LocalDeps";
import logo from "./react.png";
import "./style.css";

let turn = 0
let turn = 0;
function infiniteLoop() {
const lgoo = document.querySelector('.App-logo')
turn += 8
lgoo.style.transform = `rotate(${turn % 360}deg)`
const lgoo = document.querySelector(".App-logo");
turn += 8;
lgoo.style.transform = `rotate(${turn % 360}deg)`;
}

export default function App() {
React.useEffect(() => {
const loopInterval = setInterval(infiniteLoop, 100)
return () => clearInterval(loopInterval)
}, [])
const loopInterval = setInterval(infiniteLoop, 100);
return () => clearInterval(loopInterval);
}, []);

return (
<>
Expand All @@ -31,25 +32,30 @@ export default function App() {
<img src={logo} className="App-logo" alt="logo" />
<ul>
<li>
<Link style={{ color: 'white' }} to="/sorting">
<Link style={{ color: "white" }} to="/sorting">
Sorting Demo
</Link>
</li>
<li>
<Link style={{ color: 'white' }} to="/csv">
<Link style={{ color: "white" }} to="/csv">
Csv Demo
</Link>
</li>
<li>
<Link style={{ color: 'white' }} to="/external">
<Link style={{ color: "white" }} to="/external">
External Scripts Demo
</Link>
</li>
<li>
<Link style={{ color: 'white' }} to="/transferable">
<Link style={{ color: "white" }} to="/transferable">
Transferable Demo
</Link>
</li>
<li>
<Link style={{ color: "white" }} to="/localdeps">
LocalDeps Demo
</Link>
</li>
</ul>
</header>
<hr />
Expand All @@ -68,10 +74,13 @@ export default function App() {
<Route path="/transferable">
<TransferablePage />
</Route>
<Route path="/localdeps">
<LocalDepsPage />
</Route>
</Switch>
</div>
</Router>
<Toaster />
</>
)
);
}
77 changes: 77 additions & 0 deletions apps/examples/src/pages/LocalDeps/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { WORKER_STATUS, useWorker } from "@koale/useworker";
import React, { useState } from "react";
import toast from "react-hot-toast";

const pow = (a) => a * a;

function App() {
const [inputValue, setInputValue] = useState(2); // State for input value
const [localDepsWorker, { status: localDepsWorkerStatus, kill: killWorker }] =
useWorker((numbers) => pow(numbers), {
autoTerminate: false,
localDependencies: [pow],
});

React.useEffect(() => {
console.log("WORKER:", localDepsWorkerStatus);
}, [localDepsWorkerStatus]);

const onWorkerSortClick = () => {
// Use the inputValue from state
localDepsWorker(Number(inputValue)).then((result) => {
console.log("localdeps useWorker()", result);
toast.success(
"Finished: localdeps using useWorker." + `The result is ${result}`
);
});
};

// Handle input change
const handleInputChange = (e) => {
setInputValue(e.target.value);
};

return (
<div>
<section className="App-section">
{/* Input field for dynamic value */}
<div style={{ display: "flex", flexDirection: "column" }}>
<pre>{"const pow = (a) => a * a;"}</pre>
<input
type="number"
value={inputValue}
onChange={handleInputChange}
placeholder="Enter a number"
className="App-input"
/>
<button
type="button"
disabled={localDepsWorkerStatus === WORKER_STATUS.RUNNING}
className="App-button"
onClick={() => onWorkerSortClick()}
>
{localDepsWorkerStatus === WORKER_STATUS.RUNNING
? `Loading...`
: `LocalDeps useWorker()`}
</button>
{localDepsWorkerStatus === WORKER_STATUS.RUNNING ? (
<button
type="button"
className="App-button"
onClick={() => killWorker()}
>
Kill Worker
</button>
) : null}
</div>
</section>
<section className="App-section">
<span style={{ color: "white" }}>
Open DevTools console to see the results.
</span>
</section>
</div>
);
}

export default App;
23 changes: 12 additions & 11 deletions packages/useWorker/src/lib/createWorkerBlobUrl.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// import isoworker from 'isoworker'
import { TRANSFERABLE_TYPE } from '../useWorker'
import jobRunner from './jobRunner'
import remoteDepsParser from './remoteDepsParser'
import { TRANSFERABLE_TYPE } from "../useWorker";
import jobRunner from "./jobRunner";
import remoteDepsParser from "./remoteDepsParser";

/**
* Converts the "fn" function into the syntax needed to be executed within a web worker
Expand All @@ -20,19 +20,20 @@ import remoteDepsParser from './remoteDepsParser'
const createWorkerBlobUrl = (
fn: Function,
deps: string[],
transferable: TRANSFERABLE_TYPE /* localDeps: () => unknown[], */,
localDeps: Function[],
transferable: TRANSFERABLE_TYPE /* localDeps: () => unknown[], */
) => {
// const [context] = isoworker.createContext(localDeps)
const blobCode = `
${remoteDepsParser(deps)};
${remoteDepsParser(deps, localDeps)};
onmessage=(${jobRunner})({
fn: (${fn}),
transferable: '${transferable}'
})
`
const blob = new Blob([blobCode], { type: 'text/javascript' })
const url = URL.createObjectURL(blob)
return url
}
`;
const blob = new Blob([blobCode], { type: "text/javascript" });
const url = URL.createObjectURL(blob);
return url;
};

export default createWorkerBlobUrl
export default createWorkerBlobUrl;
30 changes: 23 additions & 7 deletions packages/useWorker/src/lib/remoteDepsParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,34 @@
* Concatenates the remote dependencies into a comma separated string.
* this string will then be passed as an argument to the "importScripts" function
*
* @param {Array.<String>}} deps array of string
* @param {Array.<String>} deps array of string
* @param {Array.<Function>} localDeps array of function
* @returns {String} a string composed by the concatenation of the array
* elements "deps" and "importScripts".
*
* @example
* remoteDepsParser(['http://js.com/1.js', 'http://js.com/2.js']) // importScripts('http://js.com/1.js', 'http://js.com/2.js')
*/
const remoteDepsParser = (deps: string[]) => {
if (deps.length === 0) return ''
const remoteDepsParser = (deps: string[], localDeps: Function[]) => {
if (deps.length === 0 && localDeps.length === 0) return "";

const depsString = deps.map((dep) => `'${dep}'`).toString()
return `importScripts(${depsString})`
}
const depsString = deps.map((dep) => `'${dep}'`).toString();
const depsFunctionString = localDeps
.filter((dep) => typeof dep === "function")
.map((fn) => {
const str = fn.toString();
if (str.trim().startsWith("function")) {
return str;
} else {
const name = fn.name;
return `const ${name} = ${str}`;
}
})
.join(";");
const importString = `importScripts(${depsString});`;
return `${
depsString.trim() === "" ? "" : importString
} ${depsFunctionString}`;
};

export default remoteDepsParser
export default remoteDepsParser;
Loading
Loading