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

@vegajs/storage

v1.0.0-beta.31

Published

A flexible and type-safe storage service adapter for TypeScript and JavaScript. Supports various storage mechanisms like localStorage, query strings, and mock storage with both asynchronous and synchronous APIs.

Downloads

1,158

Readme

@vegajs/storage

npm version

Overview

@vegajs/storage is a flexible, type-safe storage service interface that allows you to easily implement different storage mechanisms such as localStorage, query-string, and mock storage solutions. The service leverages the adapter pattern, making it easy to swap or implement custom storage adapters while maintaining a consistent API.

Key Features

  • Adapter Pattern: Decouple the storage logic from your app by providing interchangeable storage adapters.
  • Type safety: Provides strong typing with generics for different value types, ensuring type safety.
  • Multiple Adapters: Supports out-of-the-box adapters for localStorage, query-string, and a mock service for testing.
  • Synchronous and Asynchronous Support: Choose between synchronous and asynchronous methods depending on your needs.

Installation

Install the package via npm:

npm install @vegajs/storage

Quick Start

Using the LocalStorage Adapter

The package provides an adapter for localStorage, making it easy to persist data in the browser.

import { StorageService, LocalStorageAdapter } from '@vegajs/storage';

const storageService = new StorageService(new LocalStorageAdapter());

// Set an item asynchronously
await storageService.setItem('key', 'value');

// Retrieve the item
const value = await storageService.getItem('key');
console.log(value); // Output: 'value'

// Check if the item exists
const hasKey = storageService.has('key');
console.log(hasKey); // Output: true

// Remove the item
storageService.clearItem('key');

Synchronous Usage Example

For applications that require synchronous access to storage, the storage service also supports synchronous methods.

// Set an item synchronously
storageService.setItemSync('syncKey', 'syncValue');

// Get an item synchronously
const syncValue = storageService.getItemSync('syncKey');
console.log(syncValue); // Output: 'syncValue'

// Check if the key exists
console.log(storageService.has('syncKey')); // Output: true

// Clear the item
storageService.clearItem('syncKey');

Using the Query String Adapter

You can also store and retrieve data via the URL query string. This can be useful for persisting state or filters.

import { StorageService } from '@vegajs/storage-service-adapter';
import { QueryStringAdapter } from '@vegajs/storage/adapters';

const queryStringStorage = new StorageService(new QueryStringAdapter());

// Set a value in the query string
await queryStringStorage.setItem('filter', { type: 'category', id: 123 });

// Get a value from the query string
const filter = await queryStringStorage.getItem('filter');
console.log(filter); // Output: { type: 'category', id: 123 }

// Check if the query string contains a key
console.log(queryStringStorage.has('filter')); // Output: true

// Clear all query string parameters
queryStringStorage.clear();

Mock Storage Service (For Testing)

Use the mock adapter for unit tests or when you need an in-memory storage implementation.

import { StorageService, MockStorageService } from '@vegajs/storage';

const mockStorage = new StorageService(new MockStorageService());

await mockStorage.setItem('key', 'mock value');

const value = await mockStorage.getItem('key');
console.log(value); // Output: 'mock value'

mockStorage.clearItem('key');

Extending with Custom Adapters

You can easily create your own adapter by implementing the StorageService interface. This allows you to plug in any storage mechanism that meets your needs.

import { StorageService } from '@vegajs/storage';

class CustomStorageAdapter implements StorageService {
  private data = new Map<string, unknown>();

  async getItem<Value>(key: string): Promise<Value | null> {
    return this.data.get(key) || null;
  }

  getItemSync<Value>(key: string): Value | null {
    return this.data.get(key) || null;
  }

  async setItem<Value>(key: string, value: Value): Promise<void> {
    this.data.set(key, value);
  }

  setItemSync<Value>(key: string, value: Value): void {
    this.data.set(key, value);
  }

  has(key: string): boolean {
    return this.data.has(key);
  }

  clearItem(key: string): void {
    this.data.delete(key);
  }

  clear(): void {
    this.data.clear();
  }
}

// Usage
const customStorage = new StorageService(new CustomStorageAdapter());
await customStorage.setItem('customKey', 'customValue');
console.log(await customStorage.getItem('customKey')); // Output: 'customValue'

Advanced Usage

Working with JSON Values

All adapters handle JSON values seamlessly. You can store and retrieve complex objects without having to manually serialize or deserialize them.

await storageService.setItem('user', { id: 1, name: 'Alice' });

const user = await storageService.getItem<{ id: number; name: string }>('user');
console.log(user?.name); // Output: 'Alice'

Error Handling

When using storage adapters like localStorage that might not be available in all environments, you can wrap your code in try-catch blocks to handle errors gracefully.

try {
  await storageService.setItem('session', { token: '12345' });
} catch (error) {
  console.error('Failed to store session data:', error);
}

API Reference

StorageService Interface

The StorageService interface defines the core methods that any storage adapter must implement.

export interface StorageService {
  getItem<Value>(key: string): Promise<Value | null>;
  getItemSync<Value>(key: string): Value | null;
  setItem<Value>(key: string, value: Value): Promise<void>;
  setItemSync<Value>(key: string, value: Value): void;
  has(key: string): boolean;
  clearItem(key: string): void;
  clear(): void;
}

LocalStorageAdapter

The LocalStorageAdapter is a concrete implementation of the StorageService interface using the browser's localStorage.

export class LocalStorageAdapter implements StorageService {
  constructor();
  public getItem<Value = unknown>(key: string): Promise<Value | null>;
  public getItemSync<Value = unknown>(key: string): Value | null;
  public setItem<Value = unknown>(key: string, value: Value): Promise<void>;
  public setItemSync<Value = unknown>(key: string, value: Value): void;
  public has(key: string): boolean;
  public clearItem(key: string): void;
  public clear(): void;
}

QueryStringAdapter

The QueryStringAdapter manages key-value pairs in the URL query string.

export class QueryStringAdapter implements StorageService {
  constructor();
  public getItem<Value = unknown>(key: string): Promise<Value | null>;
  public getItemSync<Value = unknown>(key: string): Value | null;
  public setItem<Value = unknown>(key: string, value: Value): Promise<void>;
  public setItemSync<Value = unknown>(key: string, value: Value): void;
  public has(key: string): boolean;
  public clearItem(key: string): void;
  public clear(): void;
}

MockStorageAdapter

The MockStorageService is an in-memory mock implementation of the StorageService interface. It is useful for testing purposes.

export class MockStorageService implements StorageService {
  constructor();
  public getItem<Value = unknown>(key: string): Promise<Value | null>;
  public getItemSync<Value = unknown>(key: string): Value | null;
  public setItem<Value = unknown>(key: string, value: Value): Promise<void>;
  public setItemSync<Value = unknown>(key: string, value: Value): void;
  public has(key: string): boolean;
  public clearItem(key: string): void;
  public clear(): void;
}

Conclusion

@vegajs/storage is a powerful and flexible library that simplifies working with storage in your applications. The library provides strong typing and offers multiple ready-to-use storage adapters. Whether you need to work with localStorage, query strings, or mock storage for testing, this library has you covered.