{"_id":"@basementuniverse/stopwatch","_rev":"3-59e9c16d6323ead8a6ece7df7c87dd46","name":"@basementuniverse/stopwatch","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@basementuniverse/stopwatch","version":"1.0.0","author":{"name":"gordon"},"license":"MIT","_id":"@basementuniverse/stopwatch@1.0.0","maintainers":[{"name":"basementuniverse","email":"gordonlarrigan@gmail.com"}],"dist":{"shasum":"4dbf5f4fc1f6e8f4b3146bd3755d7a694cc2ef42","tarball":"https://registry.npmjs.org/@basementuniverse/stopwatch/-/stopwatch-1.0.0.tgz","fileCount":11,"integrity":"sha512-TbMgtaxSpFNHaSg+0GS2pw7yCzXMM9HMM7Xt5q9vWvrE3pw/mRTUWz4y/DFFmKUVKPTHEFtPNM+xFfHOFEPoiA==","signatures":[{"sig":"MEQCIBBNS5QuvoFNyGn23qjmNj+1I80DDrEWc0C0z15TVamHAiB0/uaIxG2AYo6dqYmXy4f/UidsrGBZhO/yUl2s7Vy1PQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47118},"main":"build/index.js","types":"./build/index.d.ts","gitHead":"959a70cc0f98b9c00228e7eec82c786331619a83","scripts":{"build":"webpack","watch":"webpack --watch"},"_npmUser":{"name":"basementuniverse","email":"gordonlarrigan@gmail.com"},"_npmVersion":"11.6.2","description":"A somewhat accurate timer for use in browser games.","directories":{},"_nodeVersion":"24.12.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"webpack":"^5.3.2","ts-loader":"^8.0.7","typescript":"^4.9.4","@types/node":"^18.11.12","webpack-cli":"^4.1.0","clean-webpack-plugin":"^4.0.0-alpha.0"},"_npmOperationalInternal":{"tmp":"tmp/stopwatch_1.0.0_1776592105964_0.3363196338163341","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@basementuniverse/stopwatch","version":"1.0.1","author":{"name":"gordon"},"license":"MIT","_id":"@basementuniverse/stopwatch@1.0.1","maintainers":[{"name":"basementuniverse","email":"gordonlarrigan@gmail.com"}],"dist":{"shasum":"757cf47fce0464d47b8d6a8f4164ccdd57e0b767","tarball":"https://registry.npmjs.org/@basementuniverse/stopwatch/-/stopwatch-1.0.1.tgz","fileCount":11,"integrity":"sha512-3VIB8TK8MB7JXZm18o1cMTEv/GeWZW9BKo7Rh2CrqxkjI2W4ldPWDgCCAHCEtvSShKCYBCS9rzkZrmr0rEoscQ==","signatures":[{"sig":"MEUCIEE+UOSkOeQ4cdU/Zzr1TGTxeFHJLOsfPjIw1ho9//xrAiEAh8RrNAUysSv2UkCktL9TefdyMQ2te5oOVdVCQekopHg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47050},"main":"build/index.js","types":"./build/index.d.ts","gitHead":"6b0ab3fa4066c5f478a3b27e04eda67171f0cc8e","scripts":{"build":"webpack","watch":"webpack --watch"},"_npmUser":{"name":"basementuniverse","email":"gordonlarrigan@gmail.com"},"_npmVersion":"11.6.2","description":"A somewhat accurate timer for use in browser games.","directories":{},"_nodeVersion":"24.12.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"webpack":"^5.3.2","ts-loader":"^8.0.7","typescript":"^4.9.4","@types/node":"^18.11.12","webpack-cli":"^4.1.0","clean-webpack-plugin":"^4.0.0-alpha.0"},"_npmOperationalInternal":{"tmp":"tmp/stopwatch_1.0.1_1776597287313_0.3848029459580118","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@basementuniverse/stopwatch","version":"1.1.0","description":"A somewhat accurate timer for use in browser games.","main":"build/index.js","scripts":{"build":"webpack --mode production","build:dev":"webpack --mode development","watch":"webpack --watch"},"author":{"name":"gordon"},"license":"MIT","dependencies":{},"devDependencies":{"@types/node":"^18.11.12","clean-webpack-plugin":"^4.0.0-alpha.0","ts-loader":"^8.0.7","typescript":"^4.9.4","webpack":"^5.3.2","webpack-cli":"^4.1.0"},"gitHead":"48d835d5caac509a97901a7908f4540ff3992716","types":"./build/index.d.ts","_id":"@basementuniverse/stopwatch@1.1.0","_nodeVersion":"24.12.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-XBeZMIjO3EUYHvJBMtNKXkYWVnG30cI/ChKitBtNfPCxNwxJ3ySCUpcTJF4tHAADEpN+Iz/l+dOdUZpwrGCWaQ==","shasum":"397ac0b4c0b9bd501f17ac09fed38f7477135aa6","tarball":"https://registry.npmjs.org/@basementuniverse/stopwatch/-/stopwatch-1.1.0.tgz","fileCount":14,"unpackedSize":64978,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCKRq1QVy3GDEcMjeTWa2hDHe+ZxS7Bo/OSTbL13pyAvgIhAIrGCTE6RWOygW47rLBxKRyvkiXOa2hwqXTe+6K7NvOr"}]},"_npmUser":{"name":"basementuniverse","email":"gordonlarrigan@gmail.com"},"directories":{},"maintainers":[{"name":"basementuniverse","email":"gordonlarrigan@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/stopwatch_1.1.0_1786899998261_0.8098962703833061"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-19T09:48:25.846Z","modified":"2026-08-16T17:06:38.667Z","1.0.0":"2026-04-19T09:48:26.110Z","1.0.1":"2026-04-19T11:14:47.459Z","1.1.0":"2026-08-16T17:06:38.537Z"},"author":{"name":"gordon"},"license":"MIT","description":"A somewhat accurate timer for use in browser games.","maintainers":[{"name":"basementuniverse","email":"gordonlarrigan@gmail.com"}],"readme":"# Game Component: Stopwatch\n\nA somewhat accurate timer for use in browser games.\n\n## Installation\n\n```bash\nnpm install @basementuniverse/stopwatch\n```\n\nFor direct browser usage, include the UMD build with a script tag:\n\n```html\n<script src=\"build/index.js\"></script>\n```\n\nThe build exposes the package's main class as the `BasementUniverseStopwatch` browser\nglobal. It does not add each export directly to `window`.\n\n## How to use\n\n```ts\nimport Stopwatch from '@basementuniverse/stopwatch';\n\nconst stopwatch = new Stopwatch({\n  unit: 's',\n  rate: 1,\n  direction: 'forward',\n  max: Infinity,\n});\n\n// Update the stopwatch every frame\nfunction gameLoop() {\n  stopwatch.update();\n  requestAnimationFrame(gameLoop);\n}\n\n// Start and stop the stopwatch\nstopwatch.start();\nstopwatch.stop(); // optionally pass StopwatchStopOptions to control reset behavior\nstopwatch.running = true; // Start the stopwatch\nstopwatch.running = false; // Stop the stopwatch\n\n// Pause and resume the stopwatch\nstopwatch.pause();\nstopwatch.resume();\nstopwatch.paused = true; // Pause the stopwatch\nstopwatch.paused = false; // Resume the stopwatch\n\n// Reset the stopwatch\nstopwatch.reset();\n\n// Manually adjust the time\nstopwatch.adjustTime(5); // +5 seconds\nstopwatch.adjustTime(-2); // -2 seconds\n\n// Get values from the stopwatch\nstopwatch.running; // boolean\nstopwatch.paused; // boolean\nstopwatch.time; // number\nstopwatch.elapsed; // number\nstopwatch.remaining; // number\nstopwatch.progress; // number, [0, 1]\nstopwatch.pausedDuration; // number\n```\n\n## Options\n\n```ts\ntype StopwatchOptions = {\n  /**\n   * The unit of time used by the stopwatch. This determines how the time values\n   * are interpreted and displayed. The default unit is 'milliseconds'.\n   */\n  unit: 'ms' | 's';\n\n  /**\n   * The rate at which the stopwatch progresses. A rate of 1 means real-time,\n   * 2 means twice as fast, and 0.5 means half as fast.\n   */\n  rate: number;\n\n  /**\n   * The direction in which the stopwatch counts.\n   * 'forward' means it counts up, 'backward' means it counts down.\n   */\n  direction: 'forward' | 'backward';\n\n  /**\n   * The maximum value the stopwatch can reach. Must be finite when counting\n   * backward.\n   */\n  max: number;\n\n  /**\n   * An array of milestone values. When the stopwatch reaches a milestone, it\n   * can trigger a callback or perform an action.\n   */\n  milestones?: number[];\n\n  /**\n   * Callback function that is called when the stopwatch is started.\n   */\n  onStart: () => void;\n\n  /**\n   * Callback function that is called when the stopwatch is stopped.\n   */\n  onStop: () => void;\n\n  /**\n   * Callback function that is called when the stopwatch is paused.\n   */\n  onPause: () => void;\n\n  /**\n   * Callback function that is called when the stopwatch is resumed.\n   */\n  onResume: () => void;\n\n  /**\n   * Callback function that is called when the stopwatch finishes.\n   *\n   * When counting forward, the stopwatch finishes when it reaches the maximum\n   * value. When counting backward, the stopwatch finishes when it reaches zero.\n   *\n   * If counting forward and max is Infinity, the stopwatch will never finish.\n   */\n  onFinish: () => void;\n\n  /**\n   * Callback function that is called when the stopwatch reaches a milestone\n   * value.\n   *\n   * The milestone parameter is the index ofconst { Stopwatch } = the milestone in the milestones\n   * array that was reached.\n   */\n  onMilestone?: (milestone: number) => void;\n};\n```\n\nWhen using the library directly from a browser script, use the\n`BasementUniverseStopwatch` global:\n\n```html\n<script src=\"build/index.js\"></script>\n<script>\n  const stopwatch = new BasementUniverseStopwatch({ unit: 's' });\n\n  stopwatch.start();\n  stopwatch.update();\n  console.log(stopwatch.time);\n</script>\n```\n\nWhen stopping the stopwatch, you can specify options to control whether to reset the time and paused duration:\n\n```ts\ntype StopwatchStopOptions = {\n  /**\n   * Whether to reset the time to 0 when stopping the stopwatch.\n   *\n   * Default is true.\n   */\n  resetTime: boolean;\n\n  /**\n   * Whether to reset the paused duration to 0 when stopping the stopwatch.\n   *\n   * Default is true.\n   */\n  resetPausedDuration: boolean;\n};\n```\n","readmeFilename":"README.md"}