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

storables

v0.2.0

Published

Svelte's built-in stores are not always ergonomic when you have to mix them with imperative code. Storables remedy this by letting you to embed logic within a store's lifetime.

Downloads

65

Readme

storables

Svelte's built-in stores are not always ergonomic when you have to mix them with imperative code. Storables remedy this by letting you to embed logic within a store's lifetime.

checkable

checkable works like Svelte's writable but with built-in asynchronous validation.

Features

  • const initialValue = "John Smith";
    const { username, usernameCheckStatus } = checkable({
        name: "username",
        async check(newUsername) {
            // This value is invalid, but I know what I'm doing.
            if (userIsTyping) return false;
            // This value is invalid, scream!
            if (await alreadyExists(newUsername)) {
                throw Error("Username already taken");
            }
            // This value is valid
            return true;
        },
    }, initialValue);

    $usernameCheckStatus is "pending" while validating the value asynchronously.

    $usernameCheckStatus is "done" when validation is complete.

    $usernameCheckStatus is "error" if the validation throws an error.

    In the above example, usernameCheckStatus.error is Error("Username is already taken") if $usernameCheckStatus === "error". It is null otherwise.

    Unlike the transformable's assert, check is not write-blocking.

    The default/initial value is not validated.

persistable

Persist your store's value in localStorage or your database —store it anywhere.

Features

  • const defaultValue = 0;
    const { count } = persistable({
        name: "count",
        io: {
            read: async () => await readFromDatabase(),
            update(set) {
                const cleanUp = onDatabaseChange((value) => set(value));
                return cleanUp;
            },
            write: async (value) => await writeToDatabase(value),
        },
    }, defaultValue);
  • const defaultValue = 0;
    const { count, countWriteStatus } = persistable({
        name: "count",
        io: {
            read: () => JSON.parse(localStorage.getItem("count")),
            write: (value) => {
                if (isInvalid(value)) {
                    throw Error("Could not write invalid value");
                }
                localStorage.setItem("count", JSON.stringify(value));
            },
        },
    }, defaultValue);

    $countWriteStatus is "pending" while writing value.

    $countWriteStatus is "done" when writing is complete.

    $countWriteStatus is "error" if the write throws an error.

    In the above example, countWriteStatus.error is Error("Could not write invalid value") if $countWriteStatus === "error". It is null otherwise.

transformable

If Svelte's built-in writable and derived stores had a baby, it would be transformable.

Features

  • const { dateObject, number } = transformable({
        name: "number",
        transforms: {
            dateObject: {
                to: (date) => date.getTime(),
                from: (number) => new Date(number),
            },
        },
    }, new Date().getTime());

    Updating number will call its own subscribers with $number and subscribers of dateObject with new Date($number). Updating dateObject will call its own subscribers with $dateObject and subscribers of number with $dateObject.getTime().

    This is handy if, for example, you want to display minutes to a user but your code thinks in milliseconds.

  • const now = new Date().getTime()
    const { number, numberAssertStatus } = transformable({
        name: "number",
        assert(number) {
            // This is an invalid value, but I know what I'm doing.
            if (number === undefined) return false;
            // This is an error, scream!
            if (number < now) throw Error("Date must be after now");
            // This is a valid number
            return true;
        }
    }, now);

    numberAssertStatus.error is Error("Date must be after now") if $numberAssertStatus === "error". It is null otherwise.

    assert is write-blocking. If it throws or returns false the value of the store will not change and subscribers will not be called.

    The default/initial value is not validated.