{"version":3,"sources":["jsdelivr-header.js","/npm/tape-ui@0.12.0/src/index.js"],"names":[],"mappings":"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","file":"/npm/tape-ui@0.12.0/src/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/tape-ui@0.12.0/src/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","const blessed = require(\"neo-blessed\")\nconst {\n  all,\n  hasKey,\n  pipe,\n  reduce,\n  forEach,\n  read,\n  readMany,\n} = require(\"@asd14/m\")\n\nconst projectPkg = require(`${process.cwd()}/package.json`)\n\nconst { homePage } = require(\"./page.home/home\")\nconst { loaderPage } = require(\"./page.loader/loader\")\n\nconst { FileList, store } = require(\"./index.state\")\nconst { useScanner } = require(\"./core.hooks/use-scanner/scanner.hook\")\nconst { useRunner } = require(\"./core.hooks/use-runner/runner.hook\")\n\n/**\n * Main app function, called from \"bin/cli.js\"\n *\n * @param {string[]} props.requireModules asd\n * @param {string[]} props.fileGlob       asd\n */\nmodule.exports = ({ requireModules, fileGlob }) => {\n  const testRunArgs = reduce(\n    (acc, item) => [...acc, \"-r\", item],\n    [],\n    requireModules\n  )\n\n  // Separate node process for offloading test execution\n  const runnerWorker = useRunner({\n    runArgs: testRunArgs,\n    onFinish: ({ path, stdout, stderr, code }) => {\n      FileList.update(path, {\n        isRunning: false,\n        stdout,\n        stderr,\n        code,\n      })\n    },\n  })\n\n  //\n  const screen = blessed.screen({\n    title: `${projectPkg.name} v${projectPkg.version}`,\n\n    // The width of tabs within an element's content\n    tabSize: 2,\n\n    // Automatically position child elements with border and padding in mind\n    autoPadding: true,\n\n    // Whether the focused element grabs all keypresses\n    grabKeys: false,\n\n    // Prevent keypresses from being received by any element\n    lockKeys: true,\n\n    // Automatically \"dock\" borders with other elements instead of overlapping,\n    // depending on position\n    dockBorders: true,\n\n    // Allow for rendering of East Asian double-width characters, utf-16\n    // surrogate pairs, and unicode combining characters.\n    fullUnicode: true,\n\n    debug: true,\n  })\n\n  // Left/Right arrow switch focus between file list and results\n  screen.on(\"keypress\", (code, key) => {\n    if (key.full === \"right\") {\n      store.dispatch({\n        type: \"USE-STATE.SET\",\n        payload: { id: \"focusId\", value: \"result\" },\n      })\n    }\n\n    if (key.full === \"left\") {\n      store.dispatch({\n        type: \"USE-STATE.SET\",\n        payload: { id: \"focusId\", value: \"files\" },\n      })\n    }\n  })\n\n  // Cycle through focusable elements\n  screen.key(\"S-tab\", () => {\n    screen.focusPrevious()\n  })\n\n  screen.key(\"tab\", () => {\n    screen.focusNext()\n  })\n\n  // Switch to file result tab\n  screen.key(\"1\", () => {\n    store.dispatch({\n      type: \"USE-STATE.SET\",\n      payload: { id: \"tabsSelectId\", value: \"results\" },\n    })\n  })\n\n  // Switch to file details tab\n  screen.key(\"2\", () => {\n    store.dispatch({\n      type: \"USE-STATE.SET\",\n      payload: { id: \"tabsSelectId\", value: \"details\" },\n    })\n  })\n\n  // Open filter/cli input\n  screen.key([\"/\", \":\"], () => {\n    store.dispatch({\n      type: \"USE-STATE.SET\",\n      payload: { id: \"isCLIVisible\", value: true },\n    })\n  })\n\n  // Run all test files at once\n  screen.key(\"S-r\", () => {\n    const { items } = FileList.selector(store.getState())\n\n    forEach(({ id }) => {\n      runnerWorker.send({\n        path: id,\n        runArgs: testRunArgs,\n      })\n\n      FileList.update(id, {\n        isRunning: true,\n      })\n    })(items())\n  })\n\n  /**\n   * High level UI components\n   */\n\n  const [homePageRef, renderHomePage] = homePage({\n    parent: screen,\n\n    onFileSelect: id => {\n      store.dispatch({\n        type: \"USE-STATE.SET\",\n        payload: { id: \"fileSelectId\", value: id },\n      })\n    },\n\n    onFileRun: id => {\n      runnerWorker.send({ path: id, runArgs: testRunArgs })\n\n      store.dispatch({\n        type: \"USE-STATE.SET\",\n        payload: { id: \"fileSelectId\", value: id },\n      })\n\n      FileList.update(id, {\n        isRunning: true,\n      })\n    },\n  })\n\n  // Offload test file dependency scanning to separate node process\n  const dependencyScannerWorker = useScanner({\n    onFinish: ({ path, dependsOnFiles }) => {\n      FileList.update(path, { dependsOnFiles })\n    },\n  })\n\n  const [loaderPageRef, renderLoaderPage] = loaderPage({ parent: screen })\n\n  /* eslint-disable unicorn/no-process-exit */\n  screen.key([\"C-c\"], () => {\n    dependencyScannerWorker.kill()\n    runnerWorker.kill()\n  })\n\n  dependencyScannerWorker.on(\"close\", () =>\n    runnerWorker.killed ? process.exit() : null\n  )\n  runnerWorker.on(\"close\", () =>\n    dependencyScannerWorker.killed ? process.exit() : null\n  )\n\n  const renderApp = () => {\n    const currentState = store.getState()\n    const { items, byId, isLoaded, isLoading } = FileList.selector(currentState)\n    const isFileDependencyScanFinished = all(hasKey(\"dependsOnFiles\"), items())\n\n    // Find all test files and scan for each file's dependencies\n    if (!isLoading() && !isLoaded()) {\n      FileList.read(fileGlob).then(({ result }) => {\n        dependencyScannerWorker.send(readMany(\"id\", null, result))\n      })\n    }\n\n    if (isFileDependencyScanFinished) {\n      renderHomePage({\n        files: items(),\n        fileSelected: pipe(\n          read([\"USE-STATE\", \"fileSelectId\"]),\n          byId\n        )(currentState),\n        tab: read([\"USE-STATE\", \"tabsSelectId\"], \"results\", currentState),\n        cliQuery: read([\"USE-STATE\", \"cliQuery\"], \"\", currentState),\n        isCLIVisible: read([\"USE-STATE\", \"isCLIVisible\"], false, currentState),\n      })\n\n      loaderPageRef.hide()\n      homePageRef.show()\n    } else {\n      renderLoaderPage({\n        fileGlob,\n        files: items(),\n        isLoaded: isLoaded(),\n        isFileDependencyScanFinished,\n      })\n\n      loaderPageRef.show()\n      homePageRef.hide()\n    }\n\n    // Only call to screen.render in the app\n    screen.render()\n  }\n\n  // When any change occures in the Redux store, render the app\n  store.subscribe(() => renderApp())\n\n  // Kickstart the app\n  renderApp()\n}\n"]}