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

spino

v1.0.3

Published

A super-tiny, fully-fledged, preact drop-in

Downloads

3

Readme

Spino

A simple and fast component library written in ES6 and meant for direct execution as an ES module in browsers. It is compatible to Preact's API but is smaller and requires a smaller memory footprint while being similarily fast.

Installation

If you want to use it in conjunction with some bundler, you can install it as a regular node module:

$ npm i spino

or alternatively using it in your scripts directly from unpkg, provided you aren't using an ES6 bundler such as webpack or rollup:

import * as Spino from 'https://unkpg.com/spino';

export default class MyComponent from Spino.Component {
    // ...
}

Using such a module inside your HTML you can do:

<div id="my-component"></div>
<script type="module">
    import MyComponent from './my-component.mjs';

    const props = {
        name: 'World',
    };

    new MyComponent(props).mount(document.getElementById('my-component'));
</script>

Core API

The module exports the following properties / functions / classes:

class Component

Your components can inherit directly from it in order to implement themselves.

Example:

/** @jsx Spino.h */
import * as Spino from 'spino';

export default class FirstComponent extends Spino.Component {
    render(props, state) {
        return (
            <em>
                Hello world!
            </em>
        );
    }
}

Every component based on this class can be mounted into the DOM using the mount(targetElement : DOMElement) method.

Example:

import FirstComponent from './first-component.mjs';

new FirstComponent().mount(document.querySelector('[data-module="first-component"]'));

class AsyncComponent extends Component

If your components need to retrieve their props asynchronously during their execution, then you can use AsyncComponent instead of Component.

Example:

/** @jsx Spino.h */
import * as Spino from 'spino';

export default class SecondComponent extends Spino.AsyncComponent {
    // this function is called before it is mounted in the DOM
    getInitialProps() {
        // do some asynchronous call to the backend
        return fetch('/data.json').then(response => response.json()).then(data => ({
            title: data.name,
            content: data.description,
        }));
    }

    render(props) {
        return (
            <dl class="second-component">
                <dt>{props.title}</dt>
                <dd>{props.content}</dd>
            </dl>
        );
    }
}

options

The following options can be used:

options.applyVDOM(target : DOMElement, sourceElement : VDOMNode, context : Object) : DOMElement

  • Allows for replacing the regular rendering algorithm of a component into the DOM - helpful for testing or to do server-side rendering

options.baseClass

  • this defines what the default base-class should be for components. It defaults to Spino.Component

options.afterMount(self : Component)

  • if you set this function, you will be notified whenever a component mounted itself into the DOM.

options.afterUpdate(self : Component)

  • this will notify you whenever a component finished updating itself. This is called before the component's own componentDidUpdate() lifecycle function

options.beforeUnmount(self : Component)

  • setting this function will notify you whenever a component is about to be unmounted from the DOM.

h(name : String, attrs : Object, ...children)

This is the equivalent of Preact's h function or React's createElement function. It will generate a VDOM which can subsequently be rendered using the Component's render function or by directly calling render(vdom : VDOMNode, target : DOMElement).

In order to use Spino with a transpiler to convert your JSX into regular Javascript, you can set the Babel pragma to Spino.h . Alternatively, you can also use tagged templates such as from template2jsx as to avoid having to transpile your Javascript.

render(vdom : VDOMNode, target : DOMElement)

Renders a (functional) component or a VDOM tree.

Example:

/** @jsx Spino.h */
import * as Spino from 'spino';
import AppCore from './app-core';

function App(props) {
    return (
        <div class="my-app">
            <AppCore url={props.url}/>
        </div>
    );
}

Spino.render(App({ url: 'https://www.google.com/' }), document.body);

rerender()

Re-renders all components that require an update at this moment in time. This function is specifically helpful for test environments since in a regular browser, the rerender() function is called for every rendered frame.

HTML Renderer

Spino comes with an HTML renderer so that server-side rendering (or rendering inside tests) becomes easier and you don't need to import a separate package for it. This module provides two functions:

render(vdom : VDOMNode[, options : Object[, context : Object]]) : String

renders the given VDOM tree and returns a string of the rendered result.

Example:

/** @jsx Spino.h */
import MyComponent from './my-component';
import * as Spino from 'spino';
import { render } from 'spino/html-renderer.mjs';

renderResult = render(<MyComponent name="World"/>);

console.log(renderResult);

renderShallow(vdom : VDOMNode) : String

renders the given VDOM node in such a way that sub components will be kept as is - without rendering them as well. This is very useful for testing purposes, where you only want to render the actual component in order to unit-test it.

Example:

/** @jsx Spino.h */
import * as Spino from 'spino';
import ListItem from './list-item';
import { renderShallow } from 'spino/html-renderer.mjs';

class List extends Spino.Component {
    render(props) {
        return (
            <ul>
                {props.items.map(item => (
                    <li><ListItem value={item}/></li>
                ))}
            </ul>
        );
    }
}

const renderResult = renderShallow(<List items={[1, 2, 3]}/>);

console.log(renderResult); // === '<ul><li><ListItem value="1"></li><li><ListItem value="2"/></li><li><ListItem value="3"/></li></ul>'

License

MIT