Move 'mouse.config.autoDelayMs = 0' from module-load to runKeeper

The assignment used to run at import time, mutating the shared nut.js
singleton the second anything imported keeper.ts. Moved into the top
of runKeeper(), where the only caller actually needs it.

Same observable behavior — runKeeper is called exactly once per process
— but keeper.ts is now import-side-effect-free, which makes it
straightforward to import for tests or future tooling without touching
global mouse state.
This commit is contained in:
2026-06-17 16:24:24 -05:00
parent 8eac51cd45
commit d5656efe5b
+13 -10
View File
@@ -5,8 +5,8 @@
* real-user-wins semantics, plus the idle-watch loop that drives it. * real-user-wins semantics, plus the idle-watch loop that drives it.
* *
* Runtime: Bun (uses `@nut-tree-fork/nut-js` for cross-platform mouse + * Runtime: Bun (uses `@nut-tree-fork/nut-js` for cross-platform mouse +
* screen). Importing this module sets `mouse.config.autoDelayMs = 0` as a * screen). The nut.js auto-delay is disabled inside `runKeeper`, not at
* side effect — see below. * module load, so importing this module is side-effect-free.
* *
* Logging policy: * Logging policy:
* - The startup banner in `runKeeper` is unconditional so the user always * - The startup banner in `runKeeper` is unconditional so the user always
@@ -20,14 +20,6 @@ import { mouse, Point, screen } from "@nut-tree-fork/nut-js";
import type { Config } from "./config.ts"; import type { Config } from "./config.ts";
/**
* nut.js inserts a configurable delay after every action (default 100ms).
* That default would silently more-than-double the duration of every
* `setPosition` and `getPosition` call. We drive cadence ourselves via
* `Config.stepDelay`, so disable nut.js's implicit delay entirely.
*/
mouse.config.autoDelayMs = 0;
/** /**
* Promise-based `setTimeout` wrapper. Allows `await sleep(ms)` ergonomics. * Promise-based `setTimeout` wrapper. Allows `await sleep(ms)` ergonomics.
* *
@@ -145,6 +137,17 @@ async function simulateActivity(config: Config, log: ReturnType<typeof makeLogge
* iteration sees the user's new position and correctly resets the clock. * iteration sees the user's new position and correctly resets the clock.
*/ */
export async function runKeeper(config: Config): Promise<void> { export async function runKeeper(config: Config): Promise<void> {
// nut.js inserts a configurable delay after every action (default 100ms).
// That default would silently more-than-double the duration of every
// setPosition and getPosition call. We drive cadence ourselves via
// config.stepDelay, so disable nut.js's implicit delay entirely.
//
// Setting this here (rather than at module load) keeps `keeper.ts` free
// of import-time side effects on the shared nut.js singleton — useful
// for tests and any future code path that imports this module without
// actually running the loop.
mouse.config.autoDelayMs = 0;
const log = makeLogger(config.verbose); const log = makeLogger(config.verbose);
log.info("Teams Status Keeper started. Press Ctrl+C to stop."); log.info("Teams Status Keeper started. Press Ctrl+C to stop.");