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

@stevenleep/storage

v0.0.4

Published

enhanced local storage

Downloads

7

Readme

@stevenleep/storage

统一前端本地存储层工具

安装

pnpm install @stevenleep/storage

内部依赖

pnpm --filter <YourPackageName> add @stevenleep/storage

@*表示默认同步最新版本

pnpm --filter <YourPackageName> add @stevenleep/storage@* #
pnpm --filter <YourPackageName> add @stevenleep/storage@\* # mac-zsh 终端

快速上手

import EnhancedStorage from "@stevenleep/storage";

const xxStorage = new EnhancedStorage();

// EnhancedStorage设计时完全遵从StorageAPI

// 写数据,默认存在localstorage中
// 可更改位置,稍后提及
xxStorage.setItem("foo", "bar");
xxStorage.setItem("bar", "baz");

// 获取数据
xxStorage.getItem("foo"); // bar
xxStorage.getItem("bar"); // baz

// 删除
xxStorage.removeItem("foo");
xxStorage.removeItem("bar");

// 清空
xx.clear();

使用 Namespace

namespace 可以在调用当前时为每一个 key 都增加一个前前缀,默认的前缀为:@app/, 这意味着如果不做任何处理,你的 key 格式如下:

// 你在存储和获取时候的key为a,实际存储到数据层的key为 @app/a
xxStorage.setItem("a");

这样更改 namespace

import EnhancedStorage from "@stevenleep/storage";

const doActionStorage = new EnhancedStorage({
  namespace: "__app__/", // 后续的key前面都有一个 __app__/
});

使用内置其他存储层

内部默认实现了以下存储层

export enum StorageType {
  LocalStorage = "localStorage",
  SessionStorage = "sessionStorage",
  MemoryStorage = "memoryStorage",
  Cookie = "cookie",
}

这样替换存储层

import EnhancedStorage, { StorageType } from "@stevenleep/storage";

const xxStorage = new EnhancedStorage({
  storage: StorageType.SessionStorage, // 使用SessionStorage存储
});

自定义存储逻辑

为所有的实例增加一种存储层

import { Storages } from "@stevenleep/storage";
Storages.set("key", {
  getItem: function (key) {
    // ...
  },
  // ...
});

完全替换

import EnhancedStorage, { BaseStorageInterface } from "@stevenleep/storage";

class CusterStorage implements BaseStorageInterface {
  // ...
}
const customStorage = new EnhancedStorage({
  storage: new CusterStorage(),
});

高级自定义 - 基于核心层定制

依赖关系如下

  • EnhancedStorage 对外暴露的存储层
    • extends BaseStorage 实现了最基础的存储层能力,数据的增删查清空等,以及抹平多种本地存储 API
      • deps:data: AbsStorage 真实的数据存储位置,即 localStorage/sessionStorage/cookie/memoryStorage
    • deps BaseReactive 实现了数据变更时候的通知机制
import { BaseStorage } from "@stevenleep/storage";

class MyStorage extends BaseStorage {
  constructor() {
    super(); // 默认使用localStorage

    // super({
    // storage: CustomStorage, // 自定义的存储层
    // namespace: '' // 自定义namespace
    // )
  }
}

高级 APIS

监听某个 key 值的变化

import EnhancedStorage from "@stevenleep/storage";
const storage = new EnhancedStorage();

storage.setItem("a", "aaaa");

function handleChange(newValue, oldValue) {
  // ...
}
const cancel = storage.observer.subscribe("a", handleChange);

// 取消
cancel(); // 通过返回的cancel函数

// 通过取消API
storage.observer.unsubscribe("a", handleChange);

监听整个 Storage 层数据变化

import EnhancedStorage from "@stevenleep/storage";
const storage = new EnhancedStorage();

function handleChange(newValue, oldValue, key) {
  // ...
}
storage.observer.subscribeStateChange(handleChange); // 订阅
storage.observer.unsubscribeStateChange(handleChange); // 取消

给所由订阅者广播 - 默认清空使用

import EnhancedStorage from "@stevenleep/storage";
const storage = new EnhancedStorage();
storage.observer.broadcast(newvalue, oldvalue);

跨实例通信 - 跨服聊天

一些时候我们会为可能会在 LocalStorage 的逻辑中增加对 SessionStorage/Cookie 的监听,类似场景下使用实例上 subscribeWithScope 方法即可实现

import EnhancedStorage, { StorageType } from "@stevenleep/storage";

const enhancedLocalStorageNamespace = "@app1/";
const enhancedLocalStorage = new EnhancedStorage({
  namespace: enhancedLocalStorageNamespace,
  storage: StorageType.LocalStorage,
});

const enhancedSessionStorageNamespace = "@app2/";
const enhancedSessionStorage = new EnhancedStorage({
  namespace: enhancedSessionStorageNamespace,
  storage: StorageType.SessionStorage,
});

enhancedLocalStorage.observer.subscribeWithScope(
  enhancedSessionStorageNamespace, // 目标存储层的namespace
  "a", // 下面的key
  function (newValue, oldValue) {
    // ...
  }
);

enhancedSessionStorage.setItem("a", "20"); // 存储数值并会触发上面👆监听