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

@maal/svelte-data

v0.5.0

Published

Package aiming to make it easier to manage data with advanced features in Svelte apps

Downloads

13

Readme

Svelte.Data - Svelte

Logo

Package aiming to make it easier to manage data with advanced features in Svelte apps

Important

Your tsconfig.json must be set to "moduleResolution": "bundler"

Components

EnhancedSelect

For scenarios when the native <select> element does not suffice.

Example

<form on:submit|preventDefault={onSubmit} style="width: 100%;">
	<EnhancedSelect name="users" pool={users} values={[1, 3]} force multiple let:values let:pool>
		<svelte:fragment slot="summary">
			{@const filtered = pool.filter((user) => values.includes(user.id))}
			<input type="text" readonly style="width: 100%" value={filtered.map((user) => user.username).join(", ")} />
		</svelte:fragment>
		<div class="selector">
			{@const filtered = filterOptions(users)}
			<input type="search" style="width: 100%" placeholder="Employee" name="name" />
			<input type="search" style="width: 100%" placeholder="Employee" name="username" />
			<EnhancedOption {registerOption} togglesAll>
				<input tabindex="-1" type="checkbox" checked={allChecked} />
				{#if allChecked}Uncheck all{:else}Check all{/if} ({filtered.length})
			</EnhancedOption>
			{#each filtered as user (user.id)}
				<EnhancedOption {registerOption} value={user.id} item={user} let:checked
					><input tabindex="-1" type="checkbox" {checked} />{user.name}</EnhancedOption>
			{/each}
		</div>
	</EnhancedSelect>
	<button type="submit">submit</button>
</form>

Syncer

Handle pulling and pushing a value to and from a replication source

| Name | Replication source | | -------------------- | ----------------------- | | LocalStorageSyncer | window.localStorage | | SessionStorageSyncer | window.sessionStorage | | CookieSyncer | document.cookie |

Scenarios

Examples on how you can employ these components in different scenarios:

Sync value to window.localStorage

import { LocalStorageSyncer } from "@maal/svelte-data/sync";
import { writable } from "svelte/store";

const syncer = new LocalStorageSyncer("key", "initialValue");
export const someStore = writable<string>(syncer.pull());
someStore.subscribe((value) => syncer.push(value));

Recommendations for handling remote data

Recommendation: For models, use classes. Not interfaces.
Reason: interfaces exist to tell TypeScript that "this object is guaranteed to have these members".
This is fine at build-time, but when dealing with data stored at various locations at runtime, we can't guarantee that.

Did the REST endpoint you are calling change? Did the user modify the data stored in localStorage? Was there a JSON property that could be null that your code has not accounted for?

All of these problems are dealt with when doing the following:

1. Make sure the Response is what you expect it to be

import { ensureArray } from "@maal/svelte-data/types";

Response.prototype.ensureSuccess = function (): Response {
	if (!this.ok) {
		throw new Error(`Expected status code indicating success, got: ${this.status} ${this.statusText}`);
	}
	return this;
};

export class TestHTTP {
	public async getForecasts(): Promise<WeatherForecast[]> {
		const res = await window.fetch("http://localhost:5173/api/weatherforecast");
		return ensureArray(await res.ensureSuccess().json()).map((el) => new WeatherForecast(el));
	}
}

2. Make sure the JSON is what you expect it to be

import { ensureObject, ensureDateString, ensureNumber, ensureString } from "@maal/svelte-data";

export class WeatherForecast {
	date: Date;

	temperatureC: number;

	temperatureF: number;

	summary: string | null;

	public constructor(something: unknown) {
		const o = ensureObject(something);
		this.date = ensureDateString(o.date);
		this.temperatureC = ensureNumber(o.temperatureC);
		this.temperatureF = ensureNumber(o.temperatureF);
		this.summary = ensureString(o.summary);
	}
}

HTTPClient

Using HTTPClient does these things for you:

import { HTTPClient } from "@maal/svelte-data/http";
import { WeatherForecast } from "$lib/models/WeatherForecast.js";

/** @static */
export class TestHTTP {
	/** TODOC */
	private static httpClient = new HTTPClient("http://localhost:5173/api/", { redirect: "manual", credentials: "include" });

	/** @param fetch This is only needed for SSR */
	public static async getForecasts(fetch?: typeof window.fetch): Promise<WeatherForecast[]> {
		return await this.httpClient
			.get("weatherforecast")
			.withFetch(fetch) // If you are fetching server-side in SvelteKit's `load` function
			.fromJSONArray((something) => new WeatherForecast(something));
	}
}