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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@johanhalse/musculus

v0.3.0

Published

![Mus Musculus Musculus](https://github.com/johanhalse/musculus/blob/main/musculus.png?raw=true)

Downloads

127

Readme

Musculus

Mus Musculus Musculus

Like Stimulus, but a lot smaller and a bit more webcomponenty? The entire library weighs less than 5kB unminified.

Installation

Add it to your package.json somehow:

npm install -S @johanhalse/musculus

Importing and using

After installing it to your computer, you are free to import it in your JavaScript files, like this:

import { Application, Controller } from "@johanhalse/musculus";

The package is published as a JavaScript module with the extension .mjs. Maybe that's not your jam! But I have no idea which formats or transpilation targets are du jour in the greater JS world at the moment. ES Modules are what browsers enjoy working with, so that's what I'll enjoy too. I think this means you have to set "type": "module" in your package.json.

Usage

If you've used Stimulus before, you pretty much know how to use Musculus. You wire up Controllers to the already-existing markup you've sent to someone's browser.

Initialization

One key difference is that Musculus leverages Web Components to handle its lifecycle. The components themselves are very similar. While the controller itself might just as well have come from Stimulus:

import { Controller } from "@johanhalse/musculus";

export default class ThingController extends Controller {
  connect() {
    console.log("Hello world.");
  }

  runFunction() {
    this.innerHTML = "I'm clicked!";
  }
}

The Stimulus HTML to initialize a controller would look something like this, however:

<div data-controller="thing">
  <span data-action="click->thing#runFunction">Click me</span>
</div>

Whereas in Musculus it looks like this:

<thing-controller>
  <span data-action="click->thing#runFunction">Click me</span>
</thing-controller>

Using Web Components we get a good-looking wrapper and a component lifecycle handled for us by the browser, and everybody wins! If you're wondering how to layer two or more controllers on an element, this would be a good way:

<thing-controller>
  <bling-controller>
    <span data-action="click->thing#runFunction click->bling#runAnotherFunction">Click me</span>
  </bling-controller>
</thing-controller>

The Application object

The Application object is a little singleton object that sits on top of your controllers and handles the global responsibilities of your app. In order to actually get your controllers working, you need to call Application.start():

import { Application } from "@johanhalse/musculus";
import ThingController from "./controllers/thing-controller.js";
import BlingController from "./controllers/bling-controller.js";

Application.register(ThingController);
Application.register(BlingController);
Application.start(window);

Note how you don't have to give the register function a name! It'll register a web component with the correct name, inferred from your class. If you're uglifying your JS, that might not work! Let's see if that can be solved later.

Testing

The story around testing Stimulus has always been "run it through a browser or something, idk" and that never sat well with me. So Musculus has been designed for quick and painless testing from the beginning! It ships with a test adapter and CLI that lets you set up markup and assertions using TestDouble's brilliant teenytest framework. To test the ThingController above, you should create a file in your application called test/lib/thing-controller-test.mjs and put this in there:

import { TestApplication, assert } from "@johanhalse/musculus/testing";
import ThingController from "../../thing-controller.js";

TestApplication.html(`
<thing-controller>
  <span data-action="click->thing#runFunction">Click me</span>
</thing-controller>
`)

export default function canUpdateHTML() {
  TestApplication.register(ThingController);
  TestApplication.start(globalThis.window);
  assert.contains("Click me", TestApplication.html());

  TestApplication.click("span");
  assert.contains("I'm clicked!", TestApplication.html());
}

Then you run the command musculus and your test should pass, really quickly!

The TestApplication singleton works like the Application you use in production, but sets up a jsdom window for you to play around in. It's very fast and doesn't require any fiddling with headless browsers. The assert class is passed along from node, and extended with a contains function you can use to check your application's markup. There's also a handy click convenience function as demonstrated above, and a more generic TestApplication.fire(event, element) function you can use for other HTML events.

We might need more functions going forward, but between jsdom and teenytest there's a lot of depth already. Musculus supplies the glue and lets you set up your test environment quickly and easily.

What's missing?

Musculus isn't intended to be a 1:1 copy of Stimulus, feature-wise. The goal is to have something simpler and a lot smaller, that should be reasonably easy to move to if you have an existing Stimulus codebase and you're tired of having to ship dozens of kilobytes to your users before you've even written a controller. That means that any features that are deemed less mainstream (currently defined as "do I use these?") or that carry a large enough footprint, won't be included. That currently means quite a lot of stuff! But there are also some things I'd like to implement going forward, for instance:

  • Some kind of data binding for values (documented here)
  • Better event dispatching (documented here)
  • CSS Classes (documented here although I'm a little on the fence about this one: the API is just so wordy)

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/johanhalse/musculus.

License

The library is available as open source under the terms of the MIT License.