Skip to content

feat: ship ES modules, tighten routine types, cross-fade scenes - #3

Merged
mhweiner merged 5 commits into
mainfrom
feat/routine-union-and-esm
Sep 3, 2026
Merged

feat: ship ES modules, tighten routine types, cross-fade scenes#3
mhweiner merged 5 commits into
mainfrom
feat/routine-union-and-esm

Conversation

@logfox-agent

@logfox-agent logfox-agent commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Four changes to @logfox/busker, all of which want to land before anything else depends on the published package.

Ship ES modules

0.1.0 published CommonJS only. The package is now "type": "module" with ESM output, which is what every consumer of a browser library expects. Tests run through the tsx ESM loader so Node 20 (no native type stripping) passes CI alongside 22 and 24.

Tighten the routine types

Routine was one interface where steps, duration, and moves were all optional, so {steps, duration} typechecked and busker had to guess at runtime. It is now a discriminated union — ScriptRoutine (steps) or TimedRoutine (duration) — and the invalid combination is a compile error. Step got the same treatment, so {click, to} no longer typechecks.

Two fields were renamed for clarity: scene is now initialScene (it is only the scene busker starts on), and Countdown.seconds is now startSeconds (it counts down from there).

Keep the click ring on target

When a click changed the scene, the pressed button stopped having a box, and the cursor slid to the corner of the mock while the ring finished playing. It now holds the last place the target was seen, so the ring lands where you pressed.

Cross-fade scene changes

Scene switching was display: none / block, so any consumer wanting screens to change without popping reimplemented stacking and fading themselves — the logfox site did exactly that. That now lives in busker.css: scenes stack, cross-fade over --busker-scene-ms, and leave the accessibility tree when the fade ends.

Stacked scenes take no space, so the element holding them needs a height. In exchange the mock never changes height mid-demo. Getting started and Styling both say so.

Test plan

  • npm run validate green
  • CI green on Node 20, 22, 24
  • Docs demo: scenes cross-fade, mock height constant across 1400 frames, cursor never hidden or occluded
  • Logfox site on this build: same, and its four mocks render off busker.css with only colour tokens overridden

busker published as CommonJS, so it could not be imported as a module in
the browser without a bundler. It now builds and ships ESM.

The Routine type also let you write shapes that cannot work — steps with a
duration, or moves with no duration at all — and silently picked one. It is
now a union of ScriptRoutine and TimedRoutine, so the compiler rejects the
mix instead of the runtime guessing. Step is tightened the same way.

Two fields go back to names that say what they hold: scene -> initialScene
and Countdown.seconds -> startSeconds.
kizu hooks TypeScript in with `-r tsx/cjs`, which an ESM package never
reaches, so Node was left to handle the spec files itself. Node 22 and 24
strip types natively and passed; Node 20 does not and could not load a
single spec. Loading tsx with `--import` covers all three.
A press that changes the scene takes its own target out of layout, and the
ring outlives the press on purpose. With no box left to measure, the target
resolved to the root's top-left corner, so the cursor teleported off the
mock and the click animation finished where nobody was looking.

Selectors now remember where they last had a box, so the ring plays out on
the spot that was pressed.
@logfox-agent logfox-agent changed the title feat: ship ES modules and make routine shapes mutually exclusive feat: ship ES modules, tighten routine types, keep the click ring on target Sep 3, 2026
Scene switching was display: none / block, so every consumer that wanted
a mock to change screens without popping had to reimplement stacking and
fading in its own stylesheet. Logfox did exactly that. Move it into
busker.css: scenes stack, cross-fade over --busker-scene-ms, and drop out
of the accessibility tree once the fade finishes.

Because stacked scenes take no space, the element holding them needs a
height of its own. In exchange the mock never changes height mid-demo.
@logfox-agent logfox-agent changed the title feat: ship ES modules, tighten routine types, keep the click ring on target feat: ship ES modules, tighten routine types, cross-fade scenes Sep 3, 2026
Both sites already loaded the same two typefaces, but the busker splash
never set the display treatment, so the headline fell back to Starlight's
default weight and tracking and the lead read as body copy. Borrow
callspec's scale, weight 600 headline with -0.045em tracking and a
weight 550 lead, so the two docs sites look like one family.
@mhweiner
mhweiner merged commit b1f3ff4 into main Sep 3, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants