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

@mojawork/web-components

v0.1.2

Published

mojawork web components: mwork-banner and a complete C64 BASIC V2 interpreter (mwork-basic-interpreter), built with Stencil.

Readme

@mojawork/web-components

Standalone web components (Stencil 4, namespace mwork) — usable in any framework or in plain HTML.

Live demo: C64 BASIC interpreter in the moja.work Storybook — full docs, playable stories, type your own BASIC.

npm i @mojawork/web-components

| Tag | What it is | | --- | --- | | <mwork-banner> | Marquee text banner (text, colors, speed as attributes). | | <mwork-basic-interpreter> | A Commodore 64 with a complete BASIC V2 interpreter, 40×25 PETSCII screen, keyboard, datasette and demo programs. |

Quick start

npm install
npm start        # dev server with the demo page (www/)
npm run build    # dist + custom elements + docs + www
npm test         # unit suite (interpreter core) + browser suite (Playwright)
npm run watch:bas  # rebuild on .bas changes (hot-reload workflow)

<mwork-basic-interpreter>

<mwork-basic-interpreter
  src="my-program.bas"
  hot-reload="true"
  print-delay="100"
  load-delay="3000"
></mwork-basic-interpreter>

Click the screen and type — you are at an authentic READY. prompt.

Architecture

The interpreter core is plain, DOM-free TypeScript under src/components/basic-interpreter/core/ (tokenizer → parser → step-machine executor, screen/color RAM model, PETSCII tables, key queue, datasette). The Stencil component is a thin shell: it renders the 40×25 screen model, maps keydown events to PETSCII and pumps the machine with a statement budget, so even 10 GOTO 10 stays interruptible (Escape or the STOP button = RUN/STOP).

Language coverage (BASIC V2)

  • Statements: PRINT (;/, zones, TAB, SPC), LET, INPUT, GET, IF..THEN (incl. statement tails), GOTO, GOSUB/RETURN, ON..GOTO/GOSUB, FOR/TO/STEP/NEXT (nested, NEXT A,B), DIM (multi-dimensional), DATA/READ/RESTORE, DEF FN, REM, STOP/CONT, END, CLR, NEW, LIST, RUN, WAIT, POKE/PEEK, SYS/USR (no-op stubs), LOAD/SAVE/VERIFY, LOAD"$" directory.
  • Functions: ABS ASC ATN CHR$ COS EXP FRE INT LEFT$ LEN LOG MID$ PEEK POS RIGHT$ RND SGN SIN SPC SQR STR$ TAB TAN USR VAL, plus TI/TI$/ST.
  • Expressions: full precedence (-2^2 = -4), string concat/compare, AND/OR/NOT as 16-bit integer ops, typed variables (A, A%, A$, 2-significant-character names), arrays, authentic error messages (?SYNTAX ERROR IN 10, ?REDO FROM START, …).
  • Screen: real screen RAM (PEEK/POKE 1024+), color RAM (55296+), border/ background via POKE 53280/53281, PETSCII control codes (CLR/HOME/cursor/ RVS/colors via Ctrl+1..8, Ctrl+9/0), scrolling, blinking cursor.
  • Datasette: SAVE"NAME" / LOAD"NAME" / VERIFY"NAME" persist to localStorage; LOAD"$" lists the directory.

Documented simplifications: line-input editing instead of the full-screen editor; LIST echoes the stored source text (no de-tokenization); device I/O (OPEN/PRINT#/…) raises authentic errors; no SID sound; keyword crunching means variable names cannot contain keywords (TOTAL = TO TAL) — that one is authentic.

Properties, methods, events

See the auto-generated component readme. Highlights: props src, hot-reload, polling-interval-ms, print-delay, load-delay, show-toolbar (hide the button bar for embeddings with their own controls); methods run(), stop(), loadProgram(text), reset(); events mworkBasicState (idle | running | stopped) and exit (fired by the EXIT button so the embedding app can close the C64).

Demo programs

Buttons on the component (inline copies in scripts.ts, files in basic-scripts/ — keep both in sync): Credits, Pacman (fills the screen with dots via POKE, eats them in a spiral from the outside in — GOSUB routine, TI-clock pacing — then blinks at the last dot and vanishes), Maze (10 PRINT CHR$(205.5+RND(1)); : GOTO 20 — stop with STOP), Guess (INPUT game), Colors (border/RVS demo).

Font

Ships with Pet Me 64 by Kreative Korp, redistributed unmodified under the Kreative Software Relay Fonts Free Use License (see src/components/basic-interpreter/assets/PETME64-LICENSE.txt). Loaded at runtime via the FontFace API; falls back to a monospace stack.

Tests

  • core/*.unit.test.ts — fast headless suite for the interpreter core (tokenizer crunching, expression precedence, per-statement behaviour, screen/memory model, golden runs of the demo .bas programs).
  • *.cmp.test.tsx — browser tests (Playwright/Chromium) driving the real component: typed keyboard input, INPUT, LOAD/SAVE via localStorage, POKE 53280 border changes, hot reload, STOP.

Browser tests import the built bundle — run npm run build before the first npm test. A posttest hook restores the full production dist after every test run (stencil-test emits a pruned dev build).