シンプルなストレージとしてlocalStorage的なものが欲しくなることはよくあるのですが、Node.jsで動かなかったり、インメモリ版が欲しくなったりと色々な状況があります。

毎回そういうときに考えるのが面倒だったので、modeで全部の状況を切り分けできるlocalStorageのponyfill的なライブラリを作りました。 ponyfillとはmonkey patch的にグローバルを書き換えるのではなく、同じAPIを持ったオブジェクトを返すようなpolyfillライブラリです。

インストール

Install with npm:

npm install localstorage-ponyfill

TypeScriptで書いてあるので、型定義ファイルは同梱されています。

使い方

Auto(Browser or Node.js)

デフォルトではmodeautoなので、実行環境によって自動的にstorageを切り分けします。

次のような条件式なので、ブラウザはlocalStorage、Node.jsはファイルを使ったnode-localstorageになります。

  • If the environment defined window.localStorage -> “browser”
  • else -> “node”
import { createLocalStorage } from "localstorage-ponyfill";
const localStorage = createLocalStorage();
localStorage.setItem("key", "value");
const value = localStorage.getItem("key");
assert.strictEqual(value, "value");        

Browser

mode"browser"に明示的に指定した場合は、ネイティブのlocalStorageになります。 Node.jsの場合でも指定できますが、localStoragewindowにないとエラーです。

import { createLocalStorage } from "localstorage-ponyfill";
const localStorage = createLocalStorage({ mode : "browser" });

Node.js

modeを”node"にした場合はnode-localstorageを使います。

デフォルトは <app-root>/.cache/localstorage-ponyfill/* にファイルとして保存されます。

import { createLocalStorage } from "localstorage-ponyfill";
const localStorage = createLocalStorage({ mode : "node" });

storeFilePathオプションで保存先を指定できます。

import { createLocalStorage } from "localstorage-ponyfill";
const localStorage = createLocalStorage({ mode : "node", storeFilePath: "./path/to/dir" });

Note: ブラウザでnode modeは使えない

ブラウザとNode.jsのentry pointは分けているので、ブラウザでnodeは指定できません。 ブラウザに余計な依存が入らないようにするためにこういう構造にしています。

InMemory

インメモリ版はブラウザとNode.jsどちらでも動きます。 localstorage-memoryを使っています。

import { createLocalStorage } from "localstorage-ponyfill";
const localStorage = createLocalStorage({ mode : "memory" });

API

Window.localStorageと同じです。

export interface LocalStoragePonyfill {
    readonly length: number;

    clear(): void;

    getItem(key: string): string | null;

    key(index: number): string | null;

    removeItem(key: string): void;

    setItem(key: string, data: string): void;

    [key: string]: any;

    [index: number]: string;
}

作った後はlocalStorageと同じAPIを使って読み書きします。

import { createLocalStorage } from "localstorage-ponyfill";
const localStorage = createLocalStorage();
localStorage.setItem("key", "value");
const value = localStorage.getItem("key");
assert.strictEqual(value, "value");        

リポジトリ