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 🙏

© 2025 – Pkg Stats / Ryan Hefner

remotefunctioncache

v0.1.0

Published

A powerful caching library for SvelteKit's remote functions that provides intelligent client-side caching with multiple storage backends, automatic expiration, and cross-tab synchronization.

Readme

Remote Function Cache

A powerful caching library for SvelteKit's remote functions that provides intelligent client-side caching with multiple storage backends, automatic expiration, and cross-tab synchronization.

Features

  • 🚀 Intelligent Caching: Automatically caches remote function results
  • 💾 Multiple Storage Options: localStorage, sessionStorage, IndexedDB, and memory support
  • Automatic Expiration: Configurable timeout with automatic cleanup
  • 🔄 Cross-tab Synchronization: Share cache updates across browser tabs
  • 📱 Reactive Arguments: Automatically handles reactive argument changes
  • 🎯 Loading States: Built-in loading, error, and refreshing states
  • 🔧 Manual Control: Programmatic cache management and refresh capabilities
  • 📊 Type Safe: Full TypeScript support with proper type inference
  • 🔄 Auto-Sync: Automatically syncs with SvelteKit invalidations and mutations
  • 🐛 Debug Mode: Optional debug logging for development and troubleshooting

Installation

npm install remotefunctioncache

Prerequisites

This library requires SvelteKit with remote functions enabled. Add the following to your svelte.config.js:

/** @type {import('@sveltejs/kit').Config} */
const config = {
	kit: {
		experimental: {
			remoteFunctions: true
		}
	},
	compilerOptions: {
		experimental: {
			async: true
		}
	}
};

export default config;

Quick Start

<script>
	import { remoteFunctionCache } from 'remotefunctioncache';
	import { getUsers } from './data.remote.js';

	// Create a cached version of your remote function
	const usersCache = remoteFunctionCache(getUsers, () => undefined, {
		key: 'users-list',
		storage: 'local',
		timeoutMinutes: 10,
		syncTabs: true,
		autoSync: true // Enable automatic sync with SvelteKit
	});
</script>

{#if usersCache.loading}
	<p>Loading users...</p>
{:else if usersCache.error}
	<p>Error: {usersCache.error.message}</p>
{:else if usersCache.value?.current}
	<ul>
		{#each usersCache.value.current as user}
			<li>{user.name}</li>
		{/each}
	</ul>
{/if}

<button onclick={() => usersCache.refresh()}> Refresh Data </button>

API Reference

remoteFunctionCache(fn, argFn, options)

Creates a cached version of a remote function.

Parameters

  • fn: The remote function to cache
  • argFn: A function that returns the argument(s) for the remote function
  • options: Configuration object

Options

{
	key?: string;              // Cache key (defaults to function name)
	storage?: 'local' | 'session' | 'indexeddb' | 'memory';  // Storage type
	syncTabs?: boolean;        // Enable cross-tab synchronization
	timeoutMinutes?: number | null;  // Cache expiration (null = no expiry)
	initialValue?: TReturn;    // Initial value before first load
	autoSync?: boolean;        // Enable automatic sync with SvelteKit invalidations (default: true)
	debug?: boolean;          // Enable debug logging (default: false)
}

Returns

{
	loading: boolean;          // True during initial load
	refreshing: boolean;       // True during refresh operations
	error: any;               // Last error that occurred
	value: CustomPersistedState<TReturn>;  // Cached value container
	updateTime: Date;         // Last update timestamp
	autoSync: boolean;        // Current auto-sync setting
	refresh: () => void;      // Force refresh from server
	setValue: (val: TReturn) => void;  // Set cache value manually
	destroy: () => void;      // Clean up the cache instance
}

Usage Examples

Basic Caching

<script>
	import { remoteFunctionCache } from 'remotefunctioncache';
	import { getPosts } from './data.remote.js';

	const postsCache = remoteFunctionCache(getPosts, () => undefined, {
		key: 'blog-posts',
		timeoutMinutes: 30
	});
</script>

With Arguments

<script>
	import { remoteFunctionCache } from 'remotefunctioncache';
	import { getPost } from './data.remote.js';

	let postId = $state(1);

	const postCache = remoteFunctionCache(getPost, () => postId, {
		key: 'single-post',
		timeoutMinutes: 15
	});
</script>

<select bind:value={postId}>
	<option value={1}>Post 1</option>
	<option value={2}>Post 2</option>
	<option value={3}>Post 3</option>
</select>

{#if postCache.value?.current}
	<h1>{postCache.value.current.title}</h1>
	<p>{postCache.value.current.content}</p>
{/if}

Cross-tab Synchronization

<script>
	const sharedCache = remoteFunctionCache(getData, () => undefined, {
		key: 'shared-data',
		storage: 'local',
		syncTabs: true,
		timeoutMinutes: 60,
		autoSync: true
	});
</script>

IndexedDB for Large Data

<script>
	const largeDataCache = remoteFunctionCache(getBigDataset, () => undefined, {
		key: 'large-dataset',
		storage: 'indexeddb',
		syncTabs: true,
		timeoutMinutes: null, // Never expires
		autoSync: true
	});
</script>

Memory for Testing and Temporary Data

<script>
	const tempCache = remoteFunctionCache(getTestData, () => undefined, {
		key: 'temporary-data',
		storage: 'memory',
		syncTabs: false, // Memory storage doesn't support cross-tab sync
		timeoutMinutes: null, // No expiry (lost on page reload anyway)
		autoSync: true
	});
</script>

Manual Cache Management

<script>
	// Set custom data
	const setCustomData = () => {
		usersCache.setValue([{ id: 1, name: 'Custom User' }]);
	};

	// Force refresh
	const forceRefresh = () => {
		usersCache.refresh();
	};

	// Clean up when component is destroyed
	const cleanup = () => {
		usersCache.destroy();
	};
</script>

Storage Types

localStorage

  • ✅ Persistent across browser sessions
  • ✅ Cross-tab synchronization support
  • ⚠️ ~5-10MB storage limit
  • ⚠️ Synchronous API (may block UI)
  • ⚠️ String-only storage (JSON serialization)

sessionStorage

  • ⚠️ Cleared when tab/browser closes
  • ❌ No cross-tab synchronization (automatically upgrades to localStorage if syncTabs is enabled)
  • ⚠️ ~5-10MB storage limit
  • ⚠️ Synchronous API (may block UI)
  • ⚠️ String-only storage (JSON serialization)

IndexedDB

  • ✅ Persistent across browser sessions
  • ✅ Cross-tab sync via BroadcastChannel
  • ✅ Large storage capacity (~GB)
  • ✅ Asynchronous API (non-blocking)
  • ✅ Rich data type support

Memory

  • ⚠️ Lost on page reload
  • ❌ No cross-tab synchronization
  • ✅ No storage limit (RAM-based)
  • ✅ Fastest access (synchronous)
  • ✅ Rich data types (native JavaScript objects)
  • 🔧 Ideal for testing and temporary data

Performance Benefits

The cache provides significant performance improvements:

  • Network Request: ~500ms average
  • Cache Hit: ~0.1ms average
  • Improvement: 99.98% faster for cached data

Load testing shows exponential performance gains with concurrent requests:

| Concurrent Requests | Uncached | Cached | Improvement | | ------------------- | -------- | ------ | ----------- | | 10 | 2.1s | 0.3s | 85% faster | | 50 | 8.5s | 0.8s | 90% faster | | 100 | 15.2s | 1.2s | 92% faster |

Development

To run the demo and develop the library:

# Install dependencies
npm install

# Start development server
npm run dev

# Build the library
npm run build

# Run tests
npm test

# Package for distribution
npm pack

Demo Pages

The library includes comprehensive demo pages:

  • Basic Usage (/): Core functionality and basic examples
  • Advanced Features (/advanced): Cross-tab sync, multiple instances, search
  • Storage Comparison (/storage-comparison): Compare all storage backends (localStorage, sessionStorage, IndexedDB, Memory)
  • Performance Analysis (/performance): Load testing and performance metrics

Browser Support

  • localStorage/sessionStorage: All modern browsers
  • IndexedDB: All modern browsers (IE 10+)
  • BroadcastChannel: Chrome 54+, Firefox 38+, Safari 15.4+

For cross-tab synchronization with IndexedDB, a BroadcastChannel polyfill may be needed for older browsers.

TypeScript Support

Full TypeScript support is included with proper type inference:

import type { RemoteQueryFunction } from '@sveltejs/kit';

const typedCache = remoteFunctionCache<void, User[]>(getUsers, () => undefined, {
	key: 'typed-users'
});

// usersCache.value?.current is properly typed as User[] | undefined

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

License

MIT License - see LICENSE file for details.

Related