yarn-spinner-runner-ts
Version:
TypeScript parser, compiler, and runtime for Yarn Spinner 3.x with React adapter [NPM package](https://www.npmjs.com/package/yarn-spinner-runner-ts)
71 lines • 2.67 kB
JavaScript
import { useState, useCallback, useRef, useEffect } from "react";
import { YarnRunner } from "../runtime/runner.js";
function haveFunctionsChanged(prev, next) {
const prevFns = prev ?? {};
const nextFns = next ?? {};
const prevKeys = Object.keys(prevFns);
const nextKeys = Object.keys(nextFns);
if (prevKeys.length !== nextKeys.length) {
return true;
}
for (const key of prevKeys) {
if (!Object.prototype.hasOwnProperty.call(nextFns, key) || prevFns[key] !== nextFns[key]) {
return true;
}
}
return false;
}
function haveVariablesChanged(prev, next) {
const prevVars = prev ?? {};
const nextVars = next ?? {};
return JSON.stringify(prevVars) !== JSON.stringify(nextVars);
}
export function useYarnRunner(program, options) {
const runnerRef = useRef(null);
const optionsRef = useRef(options);
const programRef = useRef(program);
const [result, setResult] = useState(() => {
const runner = new YarnRunner(program, options);
runnerRef.current = runner;
optionsRef.current = options;
programRef.current = program;
return runner.currentResult;
});
useEffect(() => {
const prevProgram = programRef.current;
const prevOptions = optionsRef.current;
const programChanged = prevProgram !== program;
const functionsChanged = haveFunctionsChanged(prevOptions?.functions, options.functions);
const startNodeChanged = prevOptions?.startAt !== options.startAt;
const variablesChanged = haveVariablesChanged(prevOptions?.variables, options.variables);
const handlersChanged = prevOptions?.handleCommand !== options.handleCommand ||
prevOptions?.commandHandler !== options.commandHandler ||
prevOptions?.onStoryEnd !== options.onStoryEnd;
if (!runnerRef.current ||
programChanged ||
functionsChanged ||
startNodeChanged ||
variablesChanged ||
handlersChanged) {
const runner = new YarnRunner(program, options);
runnerRef.current = runner;
setResult(runner.currentResult);
}
programRef.current = program;
optionsRef.current = options;
}, [program, options]);
const advance = useCallback((optionIndex) => {
const runner = runnerRef.current;
if (!runner) {
return;
}
runner.advance(optionIndex);
setResult(runner.currentResult);
}, []);
return {
result,
advance,
runner: runnerRef.current,
};
}
//# sourceMappingURL=useYarnRunner.js.map