JSPM

shopkit-asset-cache

1.0.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1
  • Score
    100M100P100Q23415F
  • License MIT

Browser-side asset caching solution with service worker integration, intelligent caching strategies, and Next.js components for optimal performance in e-commerce storefronts

Package Exports

  • shopkit-asset-cache
  • shopkit-asset-cache/config
  • shopkit-asset-cache/core
  • shopkit-asset-cache/models
  • shopkit-asset-cache/strategies
  • shopkit-asset-cache/utils

Readme

@shopkit/asset-cache

A comprehensive browser-side asset caching solution providing intelligent caching strategies, service worker integration, and Next.js components for optimal performance in e-commerce storefronts.

Features

  • 🚀 Intelligent Caching: Multiple caching strategies (cache-first, network-first, stale-while-revalidate)
  • 🔄 Service Worker Integration: Offline support and background asset management
  • Next.js Components: Drop-in replacements for images and media with built-in caching
  • 🏷️ Tag-based Invalidation: Efficient cache invalidation using tags
  • 📦 Version Management: Content-based versioning for reliable cache invalidation
  • 🎯 TypeScript Support: Full type safety and IntelliSense support
  • 🔧 Configurable: Flexible configuration options for different use cases

Installation

npm install @shopkit/asset-cache
# or
yarn add @shopkit/asset-cache
# or
bun add @shopkit/asset-cache

Quick Start

1. Initialize the Asset Cache

import { initAssetCache } from '@shopkit/asset-cache';

// Initialize with default settings
await initAssetCache();

// Or with custom configuration
await initAssetCache({
  storageName: 'my-app-cache',
  serviceWorkerEnabled: true,
  serviceWorkerPath: '/custom-sw.js', // Custom service worker path
  manifestPath: '/cache-manifest.json', // Custom manifest path
  debug: true,
  maxSize: 100, // 100MB cache size
  maxAge: 604800 // 7 days TTL
});

2. Use with Next.js

The package includes Next.js integration templates in the templates/nextjs-integration/ folder. Copy these files to your project:

# Copy the Next.js integration files to your project
cp -r node_modules/@shopkit/asset-cache/templates/nextjs-integration/* ./src/lib/asset-cache/

Then use the components:

import { AssetCacheInitializer, AssetCacheImage } from './lib/asset-cache';

// In your app layout
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <AssetCacheInitializer
          storageName="my-app-cache"
          serviceWorkerEnabled={true}
          debug={process.env.NODE_ENV === 'development'}
          maxSize={100}
          onInitialized={() => console.log('Asset cache ready!')}
          onError={(error) => console.error('Cache init failed:', error)}
        />
        {children}
      </body>
    </html>
  );
}

// Or with default settings
export default function SimpleLayout({ children }) {
  return (
    <html>
      <body>
        <AssetCacheInitializer />
        {children}
      </body>
    </html>
  );
}

// In your components
export function ProductImage({ src, alt }) {
  return (
    <AssetCacheImage
      src={src}
      alt={alt}
      width={300}
      height={300}
      cacheOptions={{
        ttl: 7 * 24 * 60 * 60, // 7 days
        tags: ['product-images'],
        priority: 'high'
      }}
    />
  );
}

3. Manual Asset Loading

import { AssetLoader } from '@shopkit/asset-cache';

// Preload an asset
await AssetLoader.preload('/images/hero.jpg', {
  ttl: 3600, // 1 hour
  tags: ['hero-images']
});

// Load an asset with caching
const result = await AssetLoader.load('/images/product.jpg');
if (result.success) {
  console.log('Loaded from:', result.fromCache ? 'cache' : 'network');
  // Use result.data (Blob)
}

// Check if an asset is cached
const isCached = await AssetLoader.isCached('/images/product.jpg');

// Invalidate specific assets
await AssetLoader.invalidate('/images/old-product.jpg');

// Invalidate by tag
await AssetLoader.invalidateByTag('product-images');

API Reference

Core Classes

AssetLoader

The main class for loading and managing cached assets.

class AssetLoader {
  static async init(config?: AssetLoaderConfig): Promise<void>
  static async preload(url: string, options?: CacheOptions): Promise<void>
  static async load<T>(url: string, options?: CacheOptions): Promise<CacheResult<T>>
  static async isCached(url: string): Promise<boolean>
  static async invalidate(url: string): Promise<void>
  static async invalidateByTag(tag: string): Promise<void>
}

CacheManager

Manages cache storage and metadata.

class CacheManager {
  static async init(cacheName?: string): Promise<void>
  static async addToManifest(url: string, metadata: AssetMetadata): Promise<void>
  static async getAssetMetadata(url: string): Promise<AssetMetadata | null>
  static async removeFromManifest(url: string): Promise<void>
  static async getAssetsByTag(tag: string): Promise<AssetMetadata[]>
}

VersionManager

Handles asset versioning and cache invalidation.

class VersionManager {
  static init(deploymentId?: string): void
  static createVersionedUrl(url: string): string
  static hasVersion(url: string): boolean
  static extractVersion(url: string): string | null
}

Configuration

AssetCacheConfig

interface AssetCacheConfig {
  enabled?: boolean;            // Default: true - Enable/disable asset cache
  version?: string;             // Default: '1.0.0' - Cache version for invalidation
  debug?: boolean;              // Default: false - Enable debug logging
  storageName?: string;         // Default: 'asset-cache-v1' - Cache storage name
  maxSize?: number;             // Default: 50 - Maximum cache size in MB
  maxAge?: number;              // Default: 86400 - Maximum age in seconds (24 hours)
  serviceWorkerEnabled?: boolean; // Default: true - Enable service worker
  serviceWorkerPath?: string;   // Default: '/sw.js' - Service worker file path
  manifestPath?: string;        // Default: '/manifest.json' - Cache manifest file path
}

CacheOptions

interface CacheOptions {
  ttl?: number;                 // Time to live in seconds
  revalidate?: boolean;         // Whether to revalidate on access
  tags?: string[];              // Cache tags for invalidation
  priority?: 'high' | 'medium' | 'low'; // Priority for preloading
}

Next.js Integration

Components

// Asset Cache Initializer Component
<AssetCacheInitializer
  storageName="my-app-cache"        // Custom cache name
  serviceWorkerEnabled={true}       // Enable service worker
  debug={false}                     // Enable debug logging
  version="v1.2.3"                 // Cache version for invalidation
  maxSize={100}                     // Maximum cache size in MB
  maxAge={604800}                   // Maximum age in seconds (7 days)
  onInitialized={() => {}}          // Success callback
  onError={(error) => {}}           // Error callback
/>

// Cached Image Component
<AssetCacheImage
  src="/image.jpg"
  alt="Description"
  width={300}
  height={200}
  cacheOptions={{
    ttl: 3600,
    tags: ['images'],
    priority: 'high'
  }}
/>

// Cached Video Component
<AssetCacheVideo
  src="/video.mp4"
  width={640}
  height={360}
  cacheOptions={{
    ttl: 7200,
    tags: ['videos']
  }}
/>

Hooks

// Image caching hook
const { src, loading, error } = useAssetCacheImage('/image.jpg', {
  ttl: 3600,
  tags: ['images']
});

// Video caching hook
const { src, loading, error } = useAssetCacheVideo('/video.mp4', {
  ttl: 7200,
  tags: ['videos']
});

// Asset preloading hook
useAssetCachePreload([
  { url: '/image1.jpg', options: { tags: ['hero'] } },
  { url: '/image2.jpg', options: { tags: ['products'] } }
]);

Caching Strategies

The package includes three built-in caching strategies:

Cache First

Serves from cache if available, falls back to network.

import { cacheFirstStrategy } from '@shopkit/asset-cache/strategies';

const response = await cacheFirstStrategy(request, cacheName);

Network First

Tries network first, falls back to cache if network fails.

import { networkFirstStrategy } from '@shopkit/asset-cache/strategies';

const response = await networkFirstStrategy(request, cacheName);

Stale While Revalidate

Serves from cache immediately, updates cache in background.

import { staleWhileRevalidateStrategy } from '@shopkit/asset-cache/strategies';

const response = await staleWhileRevalidateStrategy(request, cacheName);

Service Worker Integration

The package automatically registers and manages a service worker for enhanced caching capabilities:

import { 
  registerServiceWorker, 
  isServiceWorkerActive,
  sendMessageToSW 
} from '@shopkit/asset-cache/core';

// Register service worker
await registerServiceWorker('/sw.js');

// Check if active
if (isServiceWorkerActive()) {
  // Send message to service worker
  await sendMessageToSW('CACHE_ASSET', { url: '/image.jpg' });
}

Cache Invalidation

By URL

await AssetLoader.invalidate('/specific-image.jpg');

By Tags

// Invalidate all product images
await AssetLoader.invalidateByTag('product-images');

// Invalidate multiple tags
await AssetLoader.invalidateByTag('hero-images');
await AssetLoader.invalidateByTag('banner-images');

Version-based

Assets are automatically versioned using content hashes, ensuring cache invalidation when content changes.

Performance Considerations

  • Selective Caching: Only cache assets that benefit from caching
  • Size Limits: Configurable maximum size limits for cached assets
  • TTL Management: Flexible time-to-live settings per asset type
  • Storage Quotas: Automatic monitoring of browser storage limits
  • Background Updates: Stale-while-revalidate for optimal performance

Browser Support

  • Chrome 40+
  • Firefox 44+
  • Safari 11.1+
  • Edge 17+

Requires support for:

  • Service Workers
  • Cache API
  • IndexedDB
  • Fetch API

Templates

The package includes ready-to-use templates for popular frameworks:

Next.js Integration (templates/nextjs-integration/)

Complete Next.js integration with:

  • AssetCacheInitializer.tsx - Component for app initialization
  • AssetCachedImage.tsx - Drop-in replacement for Next.js Image (AssetCacheImage component, useAssetCacheImage hook)
  • AssetCachedVideo.tsx - Cached video component (AssetCacheVideo component, useAssetCacheVideo hook)
  • usePreloadAssets.ts - Hook for asset preloading (useAssetCachePreload)
  • initializeAssetCache.ts - Initialization utilities
  • nextjsConfig.ts - Next.js specific configuration
  • index.ts - Main exports file

Vanilla JavaScript (templates/vanilla-javascript/)

Basic implementation examples:

  • basicAssetCaching.ts - Simple asset caching implementation
  • README.md - Usage instructions

Examples

import { AssetLoader } from '@shopkit/asset-cache';

// Preload product images
const productImages = [
  '/products/shoe-1.jpg',
  '/products/shoe-2.jpg',
  '/products/shoe-3.jpg'
];

await Promise.all(
  productImages.map(url => 
    AssetLoader.preload(url, {
      ttl: 24 * 60 * 60, // 24 hours
      tags: ['product-gallery'],
      priority: 'high'
    })
  )
);

Dynamic Content Updates

// When products are updated, invalidate related caches
await AssetLoader.invalidateByTag('product-images');
await AssetLoader.invalidateByTag('product-thumbnails');

// Preload new content
await AssetLoader.preload('/new-product-image.jpg', {
  tags: ['product-images']
});

Contributing

See CONTRIBUTING.md for development setup and contribution guidelines.

License

MIT License - see LICENSE file for details.