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

@sfdl/blep

v0.1.5

Published

A small utility toolkit for DOM components

Downloads

9

Readme

Blep

Blep is a little toolkit for managing bootstrapping components into the DOM. It is ultra-lightweight, feature-sparse and opinion-free (just like the author). Blep will help you get your encapsulated code into the DOM tree but will leave you there to get on with what you need to do. It is designed to let you hack stuff together with minimal effort.

Registration and hydration

Blep works in the intersection between the static page markup and the attachment of DOM scripting. To make it work you first update your HTML to add an element which Blep can recognise:

<div data-component="true" data-component-type="examplecomponent"></div>

Blep can now be used to mount this block as a JS component. Blep components are merely functions which receive a Blep.BindingProps object as their argument:

import {BindingProps} from @sfdl/blep;

const ExampleComponent = (props:BindingProps) => {
    // your component logic goes here
}

export default ExampleComponent;

All that now remains is to register your component with Blep and hydrate it. Usually the best place to do this is in a top level JS function (perhaps an IIFE or a dom-ready event handler):

import ExampleComponent from './ExampleComponent.js'
import { register, getMap, init } from '@sfdl/blep';

// get all the hydrateable elements on the page
const domList = document.querySelectorAll('[data-component]');

//register the component against Blep with the matching DOM element
register('examplecomponent', ExampleComponent);

// get the list of Blep components and hook it to the DOM
const map = getMap();
init(map, domList)

...and you have... nothing. Or at least nothing displayed. But this is just the start. Your component now has a reference to its relative place in the DOM and some other useful information with which to run.

Why do this?

Or maybe "Why not use React/Angular/Vue/Svelte" etc etc. The short answer is that this is something very different. I write code on top of React pretty regularly and for building complex web apps at scale that kind of approach is perfect. Blep is intended for a world in which web pages are the target. It's trivial, of course, to write a chunk of JS and stick it in a script tag on the page. Blep provides a small toolset for modularity, separation of concerns and encapsulation for interactive elements on web pages. It doesn't need to do much to enable this; really it just offers hydration of DOM elements, a small rendering loop and some basic cross-component message passing. But with these tools in hand, a developer can write sophisticated, modular components in modern code.

How can I use it?

Pretty much any way you like. Your component is essentially a function which provides an entry point to any structure you like. You can just write imperative JS now if you like, perhaps with a little bit of encapsulation of your DOM access using the element reference provided to you in the props passed into your function. But you could do other things to - that DOM reference could also be a suitable entry point for one or more React applications - meaning that you could coexist React and non-React JS componentry in the same page and in the same codebase.

I like to use the imperative approach but with a minor enhancement to use the element reference returned from the render function to build a recursive rendering loop:

import {BindingProps, render} from @sfdl/blep;

const ExampleComponent = (props:BindingProps) => {

    let element = props.domElement;

    const doRender = () => {

        const date = new Date().getTime();

        const body = document.createElement('p');
        body.innerHTML = date;

        element = render(element, body)

        element.querySelector('p').addEventListener('click', () => {
            doRender();
        })

    }

    doRender();
}

export default ExampleComponent;

This (somewhat naive) example will drop an updated timestamp into the component on the page every time you click it, refreshing the DOM element with the newly created paragraph. render destroys all of the bound event listeners inside its container on call so you start from a clean sheet and can safely add new ones.

Messaging

Through the props argument passed into every component, a pair of message related functions is received:

ready: is a callback function from the initializer. Call this once on component initialization with a handler function reference to receive messages from the bus.

sendMessage: is a function reference - call this when you want to send a message to every Blep component on the page. It should be called with a Message type, which contains two keys: message (string) and type (string, optional).