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

phimpal-tv

v0.2.3

Published

D-pad (TV remote) navigation for phimpal.com on Samsung Tizen TVs, as a TizenBrew site-modification module.

Readme

phimpal-tv

D-pad navigation for phimpal.com on a Samsung TV, shipped as a TizenBrew site-modification module. The Samsung browser's pointer is replaced by block-to-block navigation with the remote: focus rings, a card popup, a control-bar mode and a preview-based seek that never stutters the stream.

| File | Role | |---|---| | phimpal-tv.user.js | The source. Desktop test build (Tampermonkey), keyboard stands in for the remote | | mod.js | Generated TV build injected by TizenBrew — do not edit by hand | | build.js | Derives mod.js from the userscript (npm run build) | | package.json | TizenBrew manifest | | SPECS.md | Site analysis, key map, mode state machine, algorithms |

Remote keys

| Button | Everywhere | On the player | |---|---|---| | ↑ ↓ ← → | move the focus ring between blocks | ←/→ open the seek cursor, ↓ the control bar | | OK | open the focused item | fullscreen, then play/pause; commits a seek | | Return | back / close a menu / exit fullscreen | | | Play/Pause | direct Xem on a focused card | play/pause | | Ch ▲ / ▼ | previous / next row | ±5 min in the seek cursor |

Volume, Home and the app shortcuts stay with the TV. Colour keys are not used — on the Frame's remote they only exist behind the 123 keypad.

Two behaviours worth knowing:

  • Seeking never jumps immediately. ←/→ move a preview cursor along the red timeline with the site's own thumbnail; the step accelerates (10 s → 30 s → 1 min → 5 min). OK commits, Return cancels — nothing is re-buffered until you confirm.
  • Cards open their popup on focus, exactly like the mouse hover: OK opens the title page, ↓ then OK plays straight away.

Install on the TV

  1. Install TizenBrew on the Frame — follow the official guide (developer mode + TizenBrew Installer). Nothing here works without it.

  2. Publish this module to npm — TizenBrew installs modules as npm packages:

    cd phimpal-tizen
    npm run build          # regenerates mod.js from the userscript
    npm login
    npm publish --access public

    The package name is phimpal-tv (change name in package.json if it is taken, e.g. @yourname/phimpal-tv).

  3. Add it in TizenBrew → module manager → add an NPM module → type the package name → launch it. TizenBrew opens https://phimpal.com/, injects mod.js and registers the media/channel keys listed in package.json.

  4. First run: log in. The site is account-gated. Focus the email field, press OK, and the TV's on-screen keyboard appears; Return leaves the field. The session cookie persists in the webview, so this is a one-time chore.

Updating

Bump version in package.json, npm run build, npm publish, then update the module in TizenBrew.

Desktop testing (before touching the TV)

Install phimpal-tv.user.js in Violentmonkey/Tampermonkey and open phimpal.com. The keyboard emulates the remote:

| Keyboard | Remote | |---|---| | Arrows / Enter | D-pad / OK | | Esc or Backspace | Return | | Space | Play/Pause | | PageUp / PageDown | Ch ▲ / ▼ |

A badge in the top-right shows the current mode and the last key code. In the TV build the badge is off; enable it on the TV by running localStorage['tv-debug'] = '1' once (TizenBrew's dev console) and reloading.

What the TV build changes

build.js only flips a few switches, so both builds share one engine:

  • keyboard emulation off — only real remote codes are accepted;
  • the debug badge is off unless tv-debug is set;
  • the pointer is hidden;
  • the keys from package.json are also registered defensively if the Tizen API is reachable.

Three TV-specific behaviours live in the engine itself:

  • Return on the home page is not swallowed, so TizenBrew can close the module. Anywhere else it means back / close.
  • Fullscreen has a fallback: if the webview refuses requestFullscreen, the player is stretched over the viewport with CSS instead (header and footer hidden).
  • Hover menus are forced visible. The avatar menu is mounted on mouseenter but the site fades it in only while the element really matches :hover, which never happens with a remote — so the module reveals it itself.

If it freezes on the TV

Every key is intercepted before it is handled, so an exception inside the module used to swallow all input — that looked like a frozen cursor with a dead Return key. Since 0.2.1:

  • Return ×3 within 1.5 s always resets the module (mode, menus, seek cursor) — the universal escape hatch.
  • any exception is caught, the state is reset automatically, and a red box bottom-left shows the error for 10 s. Photograph it: that text is the bug report. The last one is also kept in localStorage['tv-lasterror'].
  • page scans are memoised (a TV CPU was re-computing the same styles hundreds of times per key), held keys are coalesced, and carousels are recognised structurally so paging also works on Tizen ≤ 6.5, whose Chromium ignores overflow-x: clip.
  • (0.2.2) a black box: the last 40 steps (key, mode, focus, scope, paging…) are written to localStorage['tv-trace'] as they happen. If a session ends in the middle of a key, the next launch shows the last 12 steps in the same red box for 25 s — so after a freeze, relaunch the module and photograph that box.
  • (0.2.2) a navigation scope (dialog/menu) now has to be on screen and contain something focusable; an element merely carrying role="dialog" cannot trap the keys any more, and a scope that refuses to close is ignored afterwards.
  • (0.2.3) low-gfx rendering on the TV: all CSS transitions, backdrop-filter, and the filters/shadows on the card popup and the player are removed. A freeze with no error and no trace points at the renderer, not at the script — TV compositors are known to stall on backdrop-blur and on a 500 ms transform over a row of 4K posters. Restore the site's effects with localStorage['tv-gfx'] = 'full'.
  • (0.2.3) the running version is announced bottom-right for 2 s at startup (PhimPal TV 0.2.3 · low-gfx). If you don't see the version you just published, TizenBrew is still serving a cached module: remove and re-add it in the module manager.

Known limits

  • The per-track timing button (clock icon) in the subtitle panel is not reachable with the D-pad: it sits inside a track row and would trap horizontal moves.
  • The hero row auto-rotates; if it moves under the focus, the focus jumps to the first visible card of that row.
  • Selectors follow the site. Svelte's hashed classes are never used, but a redesign of the cards, the carousels or the player would need a pass over SPECS.md.
  • Tizen's WebKit is older than desktop Chrome; the engine sticks to ES5-compatible syntax in spirit but does use const/arrow functions/template literals, which Tizen 5.5+ (2020 Frame and newer) supports. For a 2017–2019 set, transpile before publishing.