{"_id":"@armniko/ticker","_rev":"8-18cf88ac6780601058dd3bcd95391bac","name":"@armniko/ticker","dist-tags":{"latest":"2.4.0"},"versions":{"1.0.0":{"name":"@armniko/ticker","version":"1.0.0","keywords":["ticker","loop","fps"],"author":{"name":"Armīns Nikolajevs","email":"armins.nikolajevs@gmail.com"},"license":"MIT","_id":"@armniko/ticker@1.0.0","maintainers":[{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"}],"bugs":{"email":"armins.nikolajevs@gmail.com"},"dist":{"shasum":"60c365dcab1fd26a461e0bc4dc242ef18e4eeb9c","tarball":"https://registry.npmjs.org/@armniko/ticker/-/ticker-1.0.0.tgz","fileCount":15,"integrity":"sha512-Vw3LMutjxmEpuIpw2uXLalUbOyXIHjCtPz9c/VAPcQLDSpfln0gCR7KdbzaQGlhH+upDblxNmZ8zrrgRsbq9hw==","signatures":[{"sig":"MEMCH1uxNOeaNAl2y4Frx14mpl/I8wzvyNgatf0b91P0QNMCIBsfuQxaludskA3t+52dx/oCAutS0MpLeMO02l2A+UNE","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":12717},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"b8950ffc5f292c40d36dc7b8cb7d1945d4bc03ca","scripts":{"dev":"node test/server/main.js & tsc --watch","lint":"eslint src --max-warnings=0","test":"jest --runInBand","build":"tsc --project tsconfig.build.json","lint:fix":"npm run lint -- --fix","test:coverage":"npm run test -- --collect-coverage"},"_npmUser":{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"},"_npmVersion":"10.5.0","description":"Javascript/typescript library for running app loop with separate logical/drawing ticks and FPS limitation.","directories":{},"_nodeVersion":"18.20.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","prettier":"^3.2.5","typescript":"^5.4.3","@types/jest":"^29.5.12","@armniko/canvas":"^1.1.1","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.3","jest-environment-jsdom":"^29.7.0","@typescript-eslint/parser":"^7.4.0","@typescript-eslint/eslint-plugin":"^7.4.0"},"_npmOperationalInternal":{"tmp":"tmp/ticker_1.0.0_1711990200921_0.14195791844942662","host":"s3://npm-registry-packages"}},"1.1.0":{"name":"@armniko/ticker","version":"1.1.0","keywords":["ticker","loop","fps"],"author":{"name":"Armīns Nikolajevs","email":"armins.nikolajevs@gmail.com"},"license":"MIT","_id":"@armniko/ticker@1.1.0","maintainers":[{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"}],"bugs":{"email":"armins.nikolajevs@gmail.com"},"dist":{"shasum":"5aa54b83f00026bca8ca955239d29a953520ae8f","tarball":"https://registry.npmjs.org/@armniko/ticker/-/ticker-1.1.0.tgz","fileCount":11,"integrity":"sha512-HJIVbUxcT6VNZDVxUdjvOktVGAhsvZve+nhONGrnY2W3b/f2CCQqgeCJfeRl4EFPJUB2LPS9yHW8865mKMWt/g==","signatures":[{"sig":"MEUCIQDAs92zVGYPg97ZdLV8uYB/HadHwnQQBUY15lO8UqH10QIgMSSe+zvYG6wplAxJGviRIXcNZ5ZFGmdtoL3dP8Gdf2o=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":14765},"main":"./dist/index.umd.js","type":"module","module":"./dist/index.esm.js","gitHead":"990e7b7cf0f6e71e7c732ac568a31e9119d6cb70","scripts":{"dev":"node test/server/main.js & webpack --watch","lint":"tsc --noEmit && eslint src --max-warnings=0","test":"npm run build && jest","build":"rimraf dist && webpack","lint:fix":"npm run lint -- --fix","test:coverage":"npm run test -- --collect-coverage"},"typings":"./dist/index.d.ts","_npmUser":{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"},"_npmVersion":"10.5.0","description":"Javascript/typescript library for running app loop with separate logical/drawing ticks and FPS limitation.","directories":{},"_nodeVersion":"18.20.2","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","webpack":"^5.91.0","prettier":"^3.2.5","ts-loader":"^9.5.1","typescript":"^5.4.3","@types/jest":"^29.5.12","webpack-cli":"^5.1.4","@armniko/canvas":"^1.1.1","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.3","jest-environment-jsdom":"^29.7.0","@typescript-eslint/parser":"^7.4.0","@typescript-eslint/eslint-plugin":"^7.4.0"},"_npmOperationalInternal":{"tmp":"tmp/ticker_1.1.0_1714245770734_0.9105035449641425","host":"s3://npm-registry-packages"}},"2.0.0":{"name":"@armniko/ticker","version":"2.0.0","keywords":["ticker","loop","fps"],"author":{"name":"Armīns Nikolajevs","email":"armins.nikolajevs@gmail.com"},"license":"MIT","_id":"@armniko/ticker@2.0.0","bugs":{"email":"armins.nikolajevs@gmail.com"},"dist":{"shasum":"81d0e67d0ba1eeb10719307fb354dde54314a3a4","tarball":"https://registry.npmjs.org/@armniko/ticker/-/ticker-2.0.0.tgz","fileCount":15,"integrity":"sha512-YgYjBc1f1vJ+L8XZqYb0KnSEXky85oS6YI48YQ9gbbfSY9pD3El7XkKX8kiOs5wwi2GGGzhsxJSJnMEIRiyDmQ==","signatures":[{"sig":"MEUCIDB4Vx0OXLrqf8rNTo6baeN8cxHc4xjtkXnkqP7PDfBWAiEA9oxuPd8hyUjASRxisfUoIGDsSIEH5OT93P6yi9e7cmM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":18040},"main":"./dist/index.umd.js","type":"module","module":"./dist/index.esm.js","gitHead":"57f9c9406198500fa09bad693a8cdd99c057b301","scripts":{"dev":"node test/server/main.js & webpack --watch","lint":"tsc --noEmit && eslint src --max-warnings=0","test":"npm run build && jest","build":"rimraf dist && webpack","lint:fix":"npm run lint -- --fix","test:coverage":"npm run test -- --collect-coverage"},"typings":"./dist/index.d.ts","_npmUser":{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"},"_npmVersion":"10.7.0","description":"Javascript/typescript library for running app loop with separate logical/drawing ticks and FPS limitation.","directories":{},"_nodeVersion":"18.20.3","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","ts-jest":"^29.1.2","webpack":"^5.91.0","prettier":"^3.2.5","ts-loader":"^9.5.1","typescript":"^5.4.3","@types/jest":"^29.5.12","webpack-cli":"^5.1.4","@armniko/canvas":"^1.1.1","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.3","jest-environment-jsdom":"^29.7.0","@typescript-eslint/parser":"^7.4.0","@typescript-eslint/eslint-plugin":"^7.4.0"},"_npmOperationalInternal":{"tmp":"tmp/ticker_2.0.0_1719672847401_0.45299095205888373","host":"s3://npm-registry-packages"}},"2.1.0":{"name":"@armniko/ticker","version":"2.1.0","keywords":["ticker","loop","fps"],"author":{"name":"Armīns Nikolajevs","email":"armins.nikolajevs@gmail.com"},"license":"MIT","_id":"@armniko/ticker@2.1.0","maintainers":[{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"}],"bugs":{"email":"armins.nikolajevs@gmail.com"},"dist":{"shasum":"c2bd5fb7ee963213848b9ace5e7c4ad8b0bc5273","tarball":"https://registry.npmjs.org/@armniko/ticker/-/ticker-2.1.0.tgz","fileCount":15,"integrity":"sha512-dWX5Y+B0E8fExWUpvMq1xGk08ofRcBJimaNBuC00drLT7A0roqB+kttSeZP8tl8WELHovhgcemAfhhlES3abCw==","signatures":[{"sig":"MEQCIHNTcp40IvTYrgeyuHAVgwRVoqYKTniciv7Iw4oxdvbfAiAMtx8hbsfz5sGrA9GhpedemkW0UNn58cajRvfHdV4JFQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":19000},"main":"./dist/index.umd.js","type":"module","module":"./dist/index.esm.js","gitHead":"dfc5962a06fc3325a1c2d4c8d84c87c12ac21af1","scripts":{"dev":"vite build --watch","lint":"tsc --noEmit && eslint ./src --max-warnings=0 && npm run lint --prefix=demo","test":"vitest","build":"vite build","lint:fix":"npm run lint -- --fix && npm run lint:fix --prefix=demo","test:coverage":"vitest run --coverage"},"typings":"./dist/index.d.ts","_npmUser":{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"},"_npmVersion":"11.6.2","description":"Javascript/typescript library for running app loop with separate logical/drawing ticks and FPS limitation.","directories":{},"_nodeVersion":"24.12.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.0","eslint":"^9.39.2","vitest":"^4.0.16","prettier":"^3.7.4","happy-dom":"^20.0.11","@eslint/js":"^9.39.2","typescript":"^5.9.3","@types/node":"^25.0.3","vite-plugin-dts":"^4.5.4","typescript-eslint":"^8.50.1","@vitest/coverage-v8":"^4.0.16","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4"},"_npmOperationalInternal":{"tmp":"tmp/ticker_2.1.0_1766873509402_0.148222627988861","host":"s3://npm-registry-packages-npm-production"}},"2.1.1":{"name":"@armniko/ticker","version":"2.1.1","keywords":["ticker","loop","fps","game-loop"],"author":{"name":"Armīns Nikolajevs","email":"armins.nikolajevs@gmail.com"},"license":"MIT","_id":"@armniko/ticker@2.1.1","maintainers":[{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"}],"bugs":{"email":"armins.nikolajevs@gmail.com"},"dist":{"shasum":"e94cc5b37d09dfcf105b866f707199f6e752a738","tarball":"https://registry.npmjs.org/@armniko/ticker/-/ticker-2.1.1.tgz","fileCount":10,"integrity":"sha512-yuMoTW90zDi1+KDT7LWF1NTBZi/chFZ2Lu9J2fbMwUbiDDVtLo8alLqUI5giYXn+nvp1KKJsSKMPCNTBo5w6MQ==","signatures":[{"sig":"MEYCIQCWyhXGV9+WPsh4oOFR+G4RUG24NnfjmkEzCr7qf8b1GAIhAJjbGEdlvaqqzAXxPIGnLxcNrWzRLcp5MTQ20LbsBiiy","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17233},"main":"./dist/index.umd.js","type":"module","module":"./dist/index.esm.js","gitHead":"decce8bc6f306f3baa8353125a36895b4b7c1578","scripts":{"dev":"vite build --watch","lint":"tsc --noEmit && eslint ./src --max-warnings=0","test":"vitest","build":"vite build","lint:fix":"npm run lint -- --fix","test:coverage":"vitest run --coverage"},"typings":"./dist/index.d.ts","_npmUser":{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"},"_npmVersion":"11.12.1","description":"Javascript/typescript library for running app loop with separate logical/drawing ticks and FPS limitation.","directories":{},"_nodeVersion":"24.15.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.8","eslint":"^10.2.1","terser":"^5.46.1","vitest":"^4.1.4","prettier":"^3.8.3","happy-dom":"^20.9.0","@eslint/js":"^10.0.1","typescript":"^6.0.3","vite-plugin-dts":"^4.5.4","typescript-eslint":"^8.58.2","@vitest/coverage-v8":"^4.1.4","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.5"},"_npmOperationalInternal":{"tmp":"tmp/ticker_2.1.1_1776614863483_0.8058690577753294","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"@armniko/ticker","version":"2.2.0","keywords":["ticker","game-loop","animation-loop","requestanimationframe","fps","fps-limit","fps-limiter","delta-time","tick","render-loop","update-loop","frame-rate","typescript","game-engine"],"author":{"name":"Armīns Nikolajevs","email":"armins.nikolajevs@gmail.com"},"license":"MIT","_id":"@armniko/ticker@2.2.0","maintainers":[{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"}],"bugs":{"email":"armins.nikolajevs@gmail.com"},"dist":{"shasum":"deb7826a43c478bfcee8931488a121b647fa02c2","tarball":"https://registry.npmjs.org/@armniko/ticker/-/ticker-2.2.0.tgz","fileCount":10,"integrity":"sha512-Yp0cyZOUyabB+mCK6J6norHEQ4iJiwMixbP5he2z41kSX8wHekt4hf0AB9Q1pjkg5BK9sj17zBBrhE7qNzZIxg==","signatures":[{"sig":"MEUCIQCaO/dk2CBne0eehg4iNKxK4gjcENcgAAZ3bJh4y0A1ngIgchhZvlr1yQXf9tWjvW4+tko9dLQivMZjx9KQdCBoZ4A=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22288},"main":"./dist/index.umd.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","default":"./dist/index.umd.js","require":"./dist/index.umd.js"},"./package.json":"./package.json"},"gitHead":"a911cf31c78e386eb99493aa2a345885a9e66c24","scripts":{"dev":"vite build --watch","lint":"tsc --noEmit && eslint ./src --max-warnings=0","test":"vitest","build":"vite build","lint:fix":"npm run lint -- --fix","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"},"_npmVersion":"11.12.1","description":"A lightweight, zero-dependency JavaScript/TypeScript library for running an application loop with separate logic and draw ticks, FPS limiting, and low-FPS detection.","directories":{},"sideEffects":false,"_nodeVersion":"24.15.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.10","eslint":"^10.2.1","vitest":"^4.1.5","prettier":"^3.8.3","happy-dom":"^20.9.0","@eslint/js":"^10.0.1","typescript":"^6.0.3","vite-plugin-dts":"^4.5.4","typescript-eslint":"^8.59.0","@vitest/coverage-v8":"^4.1.5","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.5"},"_npmOperationalInternal":{"tmp":"tmp/ticker_2.2.0_1777138183993_0.6264210985890966","host":"s3://npm-registry-packages-npm-production"}},"2.3.0":{"name":"@armniko/ticker","version":"2.3.0","keywords":["ticker","game-loop","animation-loop","requestanimationframe","rAF","fps","fps-limit","fps-limiter","delta-time","time-scale","tick","render-loop","update-loop","frame-rate","typescript","game-engine"],"author":{"name":"Armīns Nikolajevs","email":"armins.nikolajevs@gmail.com"},"license":"MIT","_id":"@armniko/ticker@2.3.0","maintainers":[{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"}],"bugs":{"email":"armins.nikolajevs@gmail.com"},"dist":{"shasum":"b9455523db3dbd8b5d9719c7a305ab2652c5cd2f","tarball":"https://registry.npmjs.org/@armniko/ticker/-/ticker-2.3.0.tgz","fileCount":10,"integrity":"sha512-ZgoZsdx77igUwb+EK29w73h0IgGaFLNnP4OHJpudvZrhcg/y297v4HSy8MtAsIm26eOLk3JLvAZBVc4f/3bUIQ==","signatures":[{"sig":"MEYCIQD7EEM7xkKyQy7yqZIq0sdH7PdjK/gAV6/0nVjpH7HDygIhANEBdTJq9lcbO74hBgvR0/s5isjO+lvV3d5O2lEOj/W4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":25996},"main":"./dist/index.umd.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","default":"./dist/index.umd.js","require":"./dist/index.umd.js"},"./package.json":"./package.json"},"gitHead":"66da9312009d23c28ac184ea5e36fe4a31f3d9ba","scripts":{"dev":"vite build --watch","lint":"tsc --noEmit && eslint ./src --max-warnings=0","test":"vitest","build":"vite build","lint:fix":"npm run lint -- --fix","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"},"_npmVersion":"11.12.1","description":"A lightweight, zero-dependency JavaScript/TypeScript library for running an application loop with separate logic and draw ticks, time scaling, FPS limiting, and low-FPS detection.","directories":{},"sideEffects":false,"_nodeVersion":"24.15.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.10","eslint":"^10.2.1","vitest":"^4.1.5","prettier":"^3.8.3","happy-dom":"^20.9.0","@eslint/js":"^10.0.1","typescript":"^6.0.3","vite-plugin-dts":"^4.5.4","typescript-eslint":"^8.59.0","@vitest/coverage-v8":"^4.1.5","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.5"},"_npmOperationalInternal":{"tmp":"tmp/ticker_2.3.0_1777807891033_0.4345348719412192","host":"s3://npm-registry-packages-npm-production"}},"2.4.0":{"_id":"@armniko/ticker@2.4.0","bugs":{"email":"armins.nikolajevs@gmail.com"},"dist":{"shasum":"d5c2ab64396698487d023373ab6d3777948ee21e","tarball":"https://registry.npmjs.org/@armniko/ticker/-/ticker-2.4.0.tgz","fileCount":10,"integrity":"sha512-tdqetSenhuwt9m/WCILZJ3DwZJuFR7fqjumKBGl580D001kpZUyqlbXE0awTej8Vy2C0+uO/h4oppuPKLreH3Q==","signatures":[{"sig":"MEUCIQD6Wa0Gd+nWB2qMYz2YH4rLiLUJLiK1ubvWTlhO2vndDAIgQ7huLKp15PtZBMc4REQBq8SS9VmQW/cQ93w/CGflVBE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC/6RBxKnrpKPRreJEGpt4E9W72QwmRELGmoTYtR0Oz4AIgBk27UY8AXdZRE/TQfsRNYwyV2DgxnX8r5vSY0InoNVE="}],"unpackedSize":27755},"main":"./dist/index.umd.js","name":"@armniko/ticker","type":"module","types":"./dist/index.d.ts","author":{"name":"Armīns Nikolajevs","email":"armins.nikolajevs@gmail.com"},"module":"./dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","default":"./dist/index.umd.js","require":"./dist/index.umd.js"},"./package.json":"./package.json"},"gitHead":"5d4e99a3f1d0fac0885ec1fda1555f159202d995","license":"MIT","scripts":{"dev":"vite build --watch","lint":"tsc --noEmit && eslint ./src --max-warnings=0","test":"vitest","build":"vite build","lint:fix":"npm run lint -- --fix","test:coverage":"vitest run --coverage"},"version":"2.4.0","_npmUser":{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"},"keywords":["ticker","game-loop","animation-loop","requestanimationframe","rAF","fps","fps-limit","fps-limiter","delta-time","time-scale","tick","render-loop","update-loop","frame-rate","typescript","game-engine"],"_npmVersion":"11.19.1","description":"A lightweight, zero-dependency JavaScript/TypeScript library for running an application loop with separate logic and draw ticks, time scaling, FPS limiting, and low-FPS detection.","directories":{},"maintainers":[{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"}],"sideEffects":false,"_nodeVersion":"26.10.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.3.0","eslint":"^10.11.0","vitest":"^5.0.1","prettier":"^3.9.9","happy-dom":"^20.14.5","@eslint/js":"^10.0.1","typescript":"^6.0.3","vite-plugin-dts":"^5.1.1","typescript-eslint":"^8.70.1","@vitest/coverage-v8":"^5.0.1","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.6"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ticker_2.4.0_1790192773662_0.025953619727738797"}}},"time":{"created":"2024-04-01T16:50:00.786Z","modified":"2026-09-23T19:46:13.957Z","1.0.0":"2024-04-01T16:50:01.065Z","1.1.0":"2024-04-27T19:22:50.911Z","2.0.0":"2024-06-29T14:54:07.610Z","2.1.0":"2025-12-27T22:11:49.588Z","2.1.1":"2026-04-19T16:07:43.623Z","2.2.0":"2026-04-25T17:29:44.144Z","2.3.0":"2026-05-03T11:31:31.170Z","2.4.0":"2026-09-23T19:46:13.779Z"},"bugs":{"email":"armins.nikolajevs@gmail.com"},"author":{"name":"Armīns Nikolajevs","email":"armins.nikolajevs@gmail.com"},"license":"MIT","keywords":["ticker","game-loop","animation-loop","requestanimationframe","rAF","fps","fps-limit","fps-limiter","delta-time","time-scale","tick","render-loop","update-loop","frame-rate","typescript","game-engine"],"description":"A lightweight, zero-dependency JavaScript/TypeScript library for running an application loop with separate logic and draw ticks, time scaling, FPS limiting, and low-FPS detection.","maintainers":[{"name":"armins.nikolajevs","email":"armins.nikolajevs@gmail.com"}],"readme":"# Ticker\n\n[![npm](https://img.shields.io/npm/v/@armniko/ticker)](https://www.npmjs.com/package/@armniko/canvas)\n![last published](https://img.shields.io/npm/last-update/@armniko/ticker)\n![zero dependencies](https://img.shields.io/badge/zero-dependencies-brightgreen)\n[![types](https://img.shields.io/npm/types/@armniko/ticker)](https://www.npmjs.com/package/@armniko/ticker)\n\nA lightweight, zero-dependency JavaScript/TypeScript library for running an application loop with **separate logic and\ndraw ticks**, **time scaling**, **FPS limiting** and **low-FPS detection**.\n<hr>\n\n### Why Ticker?\n\n- 🎯 **Decoupled logic & rendering** — update game state and draw frames independently\n- 🎚️ **FPS control** — cap your draw rate to save CPU/battery\n- ⏱️ **Time scaling** — slow down or speed up time without touching your game logic\n- 📉 **Low-FPS callbacks** — react when performance degrades (e.g. lower visual quality)\n- 🧪 **Test-friendly** — ships with `TickerMock` for deterministic unit tests\n- 📦 **Zero dependencies** and fully typed\n\n### Installation\n\n```bash\nnpm install @armniko/ticker\n```\n\n### Usage\n\n```typescript\nimport { Ticker, Time } from '@armniko/ticker';\n\nconst ticker: Ticker = new Ticker();\nticker.addLogicTask((time: Time): void => {\n    // calculate\n});\nticker.addDrawTask((): void => {\n    // draw\n});\nticker.start();\n```\n\nTicker instance methods:\n\n- start() – starts ticker.\n- stop() – stops ticker.\n- isStarted() – checks if ticker is started.\n- setFps(options: { min?: number; max?: number; expected?: number }) - set min, max or expected FPS\n    - min (default: 0) – defines value at which lowFps task callbacks will be called.\n    - max (default: 60) – defines drawing FPS limit.\n    - expected (default: 60) - defines expected logical and drawing FPS at which app should work in normal conditions.\n- setTimeScale(scale: number) – set time scale.\n- addLogicTask(callback) – register callback for update app logic. Returns TickerTaskId.\n- addDrawTask(callback) – register callback for update app screen. Returns TickerTaskId.\n- addLowFpsTask(callback) – register callback that will be called when reached min FPS. Returns TickerTaskId.\n- remove(taskId: TickerTaskId) – removes the provided task.\n- fps() – current FPS at which app operates.\n- timeScale() – current time scale at which app operates.\n- interpolationAlpha() – fraction (0..1) of the next logic step already elapsed; use it in draw tasks to interpolate between the previous and current logic state when max FPS is higher than expected FPS.\n\n### Migration\n\n#### v1 -> v2\n\nBefore (v1):\n\n```typescript\nimport { Ticker } from '@armniko/ticker';\n\nconst element: { position: { x: number, y: number } } = { position: { x: 0, y: 0 } };\nconst animation: { durationMs: number, distancePx: number } = {\n    durationMs: 2000,\n    distancePx: 500,\n}\nconst ticker: Ticker = new Ticker({\n    onLogicTick: (): void => {\n        const pxPerMs: number = animation.distancePx / animation.durationMs;\n        element.position.x += pxPerMs * ticker.msBetweenTicks();\n    },\n    onDrawTick: (): void => {\n        // draw element\n    },\n});\nticker.start();\n```\n\nAfter (v2):\n\n```typescript\nimport { Ticker, Time } from '@armniko/ticker';\n\nconst element: { position: { x: number, y: number } } = { position: { x: 0, y: 0 } };\nconst animation: { durationMs: number, distancePx: number } = {\n    durationMs: 2000,\n    distancePx: 500,\n}\nconst ticker: Ticker = new Ticker();\nticker.addLogicTask((time: Time): void => {\n    const pxPerMs: number = animation.distancePx / animation.durationMs;\n    element.position.x += pxPerMs * time.deltaMs;\n});\nticker.addDrawTask((): void => {\n    // draw element\n});\nticker.start();\n```\n\n### Changelog\n\n<table>\n<tr>\n    <td>v2.4.0</td>\n    <td>\n      Added <code>interpolationAlpha</code> method.<br>\n      Updated packages.\n    </td>\n</tr>\n<tr>\n    <td>v2.3.0</td>\n    <td>\n      Added time scale feature.<br>\n      Minor performance improvements.<br>\n      Fixed low-fps callback to be called gain after fps recovery.<br>\n      Fixed edge case bug with a removing task where an incorrect task could be removed.\n    </td>\n</tr>\n<tr>\n    <td>v2.2.0</td>\n    <td>\n      Removed minification of build.<br>\n      Added <code>exports</code> field for proper module resolution and types.<br>\n      Marked package as side-effect free.\n    </td>\n</tr>\n<tr>\n    <td>v2.1.1</td>\n    <td>\n        Updated packages.\n    </td>\n</tr>\n<tr>\n    <td>v2.1.0</td>\n    <td>\n        Added option to provide Time for TickerMock.<br>\n        Migrated from webpack to vite.\n    </td>\n</tr>\n<tr>\n    <td>v2.0.0</td>\n    <td>\n        Multiple tick callbacks support.<br>\n        Added TickerMock for testing.<br>\n        Deprecated: constructor options, msBetweenTicks(), ticksMissed(). (See migration v1 -> v2)\n    </td>\n</tr>\n<tr>\n    <td>v1.1.0</td>\n    <td>\n        Precompiled UMD and ESM.\n    </td>\n</tr>\n<tr>\n    <td>v1.0.0</td>\n    <td>\n        Initial version.\n    </td>\n</tr>\n</table>\n","readmeFilename":"README.md"}