npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xenosystem/time-core

v0.1.0

Published

The canonical XENO time model shared by the timeline family — integer XenoTick, a linear wall-clock XenoTimebase, the four label-only display formatters, and the dead-reckoning XenoPlayheadClock that renders 60fps from a 2-10Hz push. Zero dependencies, ze

Readme

@xenosystem/time-core

The canonical XENO time model. Integer ticks, a linear wall-clock timebase, four label-only display formatters, and a dead-reckoning playhead clock that renders 60 fps from a 2–10 Hz push. Zero dependencies, zero DOM.

Tier 0 infrastructure, alongside @xenosystem/data-core and @xenosystem/tree-core. Consumed by xeno.core.transport, xeno.core.timeline, and (later) xeno.core.curve.

Why this is a package and not a copy

Every other shared helper in this catalog was deliberately copied rather than extracted — throttle and virtualize live in several panels with attribution, and a shared find/comments cursor helper was rejected outright. The test each time was whether the semantics matched, not whether the shape did.

The time model passes that test in a way nothing else has. XENO TIMELINE PANELS - UNION SPEC.md §2 does not describe a helper that two panels happen to need; it locks one model for the whole family. Transport and Timeline are on screen together, over the same ruler and the same playhead. A formatter that drifts by one frame between two copies is not a cosmetic difference — it is a transport and a ruler disagreeing about where the playhead is.

That is the same test that produced @xenosystem/tree-core, where tree and layers genuinely shared semantics.

The model

XenoTick is an integer, always. Never a float.

The host supplies a XenoTimebase: { ticksPerSecond, display, fps?, dropFrame?, bpm?, timeSignature?, tempoMap?, displayOrigin? }.

Ticks are linear wall-clock, which is what keeps zoom a single scalar (pxPerTick) and stops hit-testing ever having to invert a tempo curve. Bars and beats are a ruler-formatting concern — the formatter may consult tempoMap, but pixel geometry stays linear.

formatTimecode / timecodeToFrame are inverses (Duncan/Heidelberger drop-frame). Parse is the half Motion's EDL round-trip needs. That parity gate has run (packages/time-core/test/motion-parity.test.ts matches Motion's 29.97 drop-frame at 1800 / 17982 / 107892). Motion's local algorithm is gone; engine/interchange/types.ts is a product-signature wrapper over this pair.

This package is on the umbrella: @xenosystem/core/time re-exports every symbol here (xeno-core/src/time.ts → dist/time.*). Products should import @xenosystem/core/time. Panels that already depend on @xenosystem/time-core keep that path — both resolve to this source. Never a production file: dep of the inner package.

| Host | Bridge | |---|---| | Motion | tick = frame, tps = frameRate — preserves frame accuracy; never float seconds for an edit point | | Sound | tick = round(sec × 48000), display: 'bars' | | Pixel | tps = 1000 (milliseconds) | | 3D | tick = frame, displayOrigin: 1 — the one 1-based host, and the origin is applied at format time only |

The playhead clock

60 fps without streaming 60 messages a second across a sandbox boundary.

The host pushes { playing, originTick, originTime, rateTicksPerSecond, loop? } at 2–10 Hz. The panel runs a display-only RAF extrapolating tick = originTick + (now − originTime) × rate, snaps to each push as it arrives, and clamps against the live duration every tick.

Dead reckoning is sandbox-safe, cheaper than polling, and incidentally fixes the 10–12 fps playhead stutter the reference implementation has today.

playing is host-authoritative. The panel never infers it.

Usage

// Products (Motion, Sound, …):
import { normalizeTimebase, extrapolateTick, formatTick } from '@xenosystem/core/time'
// Panels that already depend on the inner package may keep:
import { normalizeTimebase, extrapolateTick, formatTick } from '@xenosystem/time-core'

const timebase = normalizeTimebase({ ticksPerSecond: 30, display: 'timecode', fps: 30 })
const tick = extrapolateTick(clock, performance.now(), durationTicks)
const label = formatTick(tick, timebase)   // '00:00:04:12'

Compatibility

@xenosystem/panel-transport re-exports every symbol here, so its public API is unchanged and no existing import path had to move.