mirror of
https://github.com/morten-olsen/bob.git
synced 2026-02-08 01:46:29 +01:00
feat: init
This commit is contained in:
98
packages/playground/src/features/runner/block.tsx
Normal file
98
packages/playground/src/features/runner/block.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import {
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { RunnerContext } from './context';
|
||||
|
||||
type BlockProps = {
|
||||
worker: Worker;
|
||||
action: string;
|
||||
presenter?: React.FC<any>;
|
||||
};
|
||||
|
||||
const id = (function* () {
|
||||
let i = 0;
|
||||
while (true) {
|
||||
yield i++;
|
||||
}
|
||||
})();
|
||||
|
||||
const Block: React.FC<BlockProps> = ({
|
||||
worker,
|
||||
action,
|
||||
presenter: Presenter,
|
||||
}) => {
|
||||
const currentId = useRef(id.next().value);
|
||||
const { vars } = useContext(RunnerContext);
|
||||
const [output, setOutput] = useState<unknown>();
|
||||
const [error, setError] = useState<unknown>();
|
||||
const [running, setRunning] = useState<boolean>();
|
||||
const [duration, setDuration] = useState<number>();
|
||||
|
||||
const view = useMemo(() => {
|
||||
if (error) {
|
||||
return error.toString();
|
||||
}
|
||||
if (Presenter) {
|
||||
return <Presenter output={output} />;
|
||||
}
|
||||
return JSON.stringify(output, null, 2);
|
||||
}, [output, error, Presenter]);
|
||||
|
||||
const runBlock = useCallback(async () => {
|
||||
setRunning(true);
|
||||
setError(undefined);
|
||||
setOutput(undefined);
|
||||
|
||||
try {
|
||||
worker.postMessage({
|
||||
type: 'run',
|
||||
action,
|
||||
vars,
|
||||
id: currentId.current,
|
||||
});
|
||||
} catch (error) {
|
||||
setError(error);
|
||||
}
|
||||
|
||||
setRunning(false);
|
||||
}, [worker, vars, action]);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = (event: MessageEvent) => {
|
||||
const { type, payload, id, duration } = event.data;
|
||||
if (id !== currentId.current) {
|
||||
return;
|
||||
}
|
||||
setDuration(duration);
|
||||
setRunning(false);
|
||||
if (type === 'output') {
|
||||
setOutput(payload);
|
||||
}
|
||||
if (type === 'error') {
|
||||
setError(payload);
|
||||
}
|
||||
};
|
||||
worker.addEventListener('message', listener);
|
||||
return () => {
|
||||
worker.removeEventListener('message', listener);
|
||||
};
|
||||
}, [worker]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button onClick={runBlock} disabled={running}>
|
||||
Run
|
||||
</button>
|
||||
{duration && <div>Duration: {duration.toFixed(2)}ms</div>}
|
||||
{running && <div>Running...</div>}
|
||||
{view}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { Block };
|
||||
Reference in New Issue
Block a user