remoteFunctionCache Svelte Themes

Remotefunctioncache

A caching wrapper to place around Sveltekit Remote Functions

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

Install with your preferred package manager:

# npm
npm install remotefunctioncache

# pnpm
pnpm add remotefunctioncache

# yarn
yarn add 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

Development

To run the demo and develop the library:

# Install dependencies
pnpm install

# Start development server
pnpm dev

# Build the library
pnpm build

# Run tests
pnpm test

# Package for distribution
pnpm 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.

Top categories

Loading Svelte Themes