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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lytjs/store

v6.9.6

Published

LytJS Signal-based state management with Option Store and Setup Store patterns

Readme

@lytjs/store

LytJS 基于 Signal 的状态管理库,支持 Option Store 和 Setup Store 模式。

npm version license

简介

@lytjs/store 是 LytJS 框架的官方状态管理库,灵感来源于 Pinia,专为 LytJS 的响应式 Signal 系统设计。它提供了简洁而强大的状态管理方案,支持两种定义风格:Option Store 和 Setup Store。

核心特性

  • 双模式定义:支持 Option Store 和 Setup Store 两种定义方式
  • 完全类型安全:完整的 TypeScript 类型推导
  • 极小的打包体积:零外部依赖
  • 响应式集成:深度集成 LytJS Signal 响应式系统
  • 插件系统:支持自定义插件扩展
  • DevTools 支持:与 @lytjs/devtools 无缝集成
  • 自动订阅:组件中自动订阅,卸载时自动取消

安装

npm install @lytjs/store

或使用 pnpm:

pnpm add @lytjs/store

依赖关系

@lytjs/store 依赖以下 LytJS 核心包:

  • @lytjs/reactivity - 响应式系统
  • @lytjs/component - 组件系统
  • @lytjs/common-is - 工具函数
  • @lytjs/common-object - 对象工具函数

快速开始

初始化 Pinia

import { createPinia } from '@lytjs/store';

const pinia = createPinia();

export { pinia };

在应用中使用

import { mount } from '@lytjs/vdom';
import App from './App';
import { pinia } from './stores';

const app = mount(document.getElementById('app'), App, {
  plugins: [pinia],
});

Option Store 模式

使用选项式 API 定义 Store,适合简单到中等复杂度的状态管理。

定义 Store

import { defineStore } from '@lytjs/store';

export const useUserStore = defineStore('user', {
  state: () => ({
    id: '',
    name: '',
    email: '',
    avatar: '',
    isLoggedIn: false,
    permissions: [],
  }),

  getters: {
    displayName: (state) => state.name || state.email || '匿名用户',
    isAdmin: (state) => state.permissions.includes('admin'),
    hasPermission: (state) => (permission: string) => state.permissions.includes(permission),
  },

  actions: {
    async login(credentials: { email: string; password: string }) {
      const response = await api.login(credentials);
      this.id = response.user.id;
      this.name = response.user.name;
      this.email = response.user.email;
      this.avatar = response.user.avatar;
      this.isLoggedIn = true;
      this.permissions = response.user.permissions;
    },

    logout() {
      this.id = '';
      this.name = '';
      this.email = '';
      this.avatar = '';
      this.isLoggedIn = false;
      this.permissions = [];
    },

    updateProfile(data: Partial<{ name: string; avatar: string }>) {
      if (data.name) this.name = data.name;
      if (data.avatar) this.avatar = data.avatar;
    },
  },
});

使用 Store

import { useUserStore } from './stores/user';

export function UserProfile() {
  const userStore = useUserStore();

  return () => (
    <div class="user-profile">
      <img src={userStore.avatar} alt={userStore.name} />
      <h1>{userStore.displayName}</h1>
      {userStore.isAdmin && <span class="badge">管理员</span>}
      <button onClick={() => userStore.logout()}>退出登录</button>
    </div>
  );
}

Setup Store 模式

使用组合式函数定义 Store,适合复杂的状态逻辑和复用。

定义 Store

import { defineStore } from '@lytjs/store';
import { ref, computed } from '@lytjs/reactivity';

export const useCartStore = defineStore('cart', () => {
  const items = ref([]);
  const couponCode = ref('');

  const itemCount = computed(() => items.value.length);

  const totalPrice = computed(() =>
    items.value.reduce((sum, item) => sum + item.price * item.quantity, 0),
  );

  const discountedPrice = computed(() => {
    if (couponCode.value === 'SAVE10') {
      return totalPrice.value * 0.9;
    }
    if (couponCode.value === 'SAVE20') {
      return totalPrice.value * 0.8;
    }
    return totalPrice.value;
  });

  function addItem(product: { id: string; name: string; price: number }) {
    const existing = items.value.find((item) => item.id === product.id);
    if (existing) {
      existing.quantity++;
    } else {
      items.value.push({ ...product, quantity: 1 });
    }
  }

  function removeItem(productId: string) {
    const index = items.value.findIndex((item) => item.id === productId);
    if (index !== -1) {
      items.value.splice(index, 1);
    }
  }

  function updateQuantity(productId: string, quantity: number) {
    const item = items.value.find((item) => item.id === productId);
    if (item) {
      if (quantity <= 0) {
        removeItem(productId);
      } else {
        item.quantity = quantity;
      }
    }
  }

  function applyCoupon(code: string) {
    couponCode.value = code;
  }

  function clearCart() {
    items.value = [];
    couponCode.value = '';
  }

  async function checkout() {
    const order = await api.createOrder({
      items: items.value,
      total: discountedPrice.value,
    });
    clearCart();
    return order;
  }

  return {
    items,
    couponCode,
    itemCount,
    totalPrice,
    discountedPrice,
    addItem,
    removeItem,
    updateQuantity,
    applyCoupon,
    clearCart,
    checkout,
  };
});

使用 Store

import { useCartStore } from './stores/cart';

export function ShoppingCart() {
  const cartStore = useCartStore();

  return () => (
    <div class="cart">
      <h2>购物车 ({cartStore.itemCount})</h2>

      <div class="items">
        {cartStore.items.map(item => (
          <div key={item.id} class="cart-item">
            <span>{item.name}</span>
            <span>¥{item.price}</span>
            <input
              type="number"
              value={item.quantity}
              onInput={(e) => cartStore.updateQuantity(item.id, +e.target.value)}
            />
            <button onClick={() => cartStore.removeItem(item.id)}>删除</button>
          </div>
        ))}
      </div>

      <div class="coupon">
        <input
          placeholder="输入优惠码"
          value={cartStore.couponCode}
          onInput={(e) => cartStore.applyCoupon(e.target.value)}
        />
      </div>

      <div class="totals">
        <p>原价: ¥{cartStore.totalPrice.toFixed(2)}</p>
        <p>折后价: ¥{cartStore.discountedPrice.toFixed(2)}</p>
      </div>

      <button onClick={() => cartStore.checkout()}>结算</button>
    </div>
  );
}

主要 API

defineStore(id, options)

定义 Option Store。

import { defineStore } from '@lytjs/store';

const useStore = defineStore('storeId', {
  state: () => ({ count: 0 }),
  getters: {
    /* ... */
  },
  actions: {
    /* ... */
  },
});

defineStoresetupFn)

定义 Setup Store。

import { defineStore } from '@lytjs/store';

const useStore = defineStore('storeId', () => {
  const count = ref(0);
  const doubled = computed(() => count.value * 2);

  function increment() {
    count.value++;
  }

  return { count, doubled, increment };
});

createPinia()

创建 Pinia 实例。

import { createPinia } from '@lytjs/store';

const pinia = createPinia({
  plugins: [logPlugin],
  depGroups: {},
});

storeToRefs(store)

将 Store 状态转换为响应式引用。

import { storeToRefs } from '@lytjs/store';

const store = useStore();
const { name, isActive } = storeToRefs(store);

getActivePinia()

获取当前活跃的 Pinia 实例。

import { getActivePinia } from '@lytjs/store';

const pinia = getActivePinia();

setActivePinia(pinia)

设置当前活跃的 Pinia 实例。

import { setActivePinia } from '@lytjs/store';

setActivePinia(pinia);

clearStoreCache()

清除 Store 缓存。

import { clearStoreCache } from '@lytjs/store';

clearStoreCache();

插件系统

创建插件

import { defineStore } from '@lytjs/store';
import type { PiniaPlugin } from '@lytjs/store';

const persistPlugin: PiniaPlugin = ({ store, options }) => {
  const savedState = localStorage.getItem(store.$id);
  if (savedState) {
    store.$patch(JSON.parse(savedState));
  }

  store.$subscribe((mutation, state) => {
    localStorage.setItem(store.$id, JSON.stringify(state));
  });
};

使用插件

import { createPinia } from '@lytjs/store';

const pinia = createPinia({
  plugins: [persistPlugin],
});

Store 实例方法

const store = useStore();

// 读取状态
store.$state.count;

// 更新状态
store.$patch({ count: 10 });
store.$patch((state) => {
  state.count++;
});

// 重置状态
store.$reset();

// 替换状态
store.$state = { count: 0 };

// 订阅变化
store.$subscribe((mutation, state) => {
  console.log('状态变化:', mutation.type);
});

// 订阅动作
store.$onAction((context) => {
  console.log('动作执行:', context.name);
});

// 持久化
store.$persist();

TypeScript 类型

interface Store<G = any, S = any, A = any> {
  $id: string;
  $state: S;
  $ getters: G;
  $actions: A;
  $patch: (partial: Partial<S> | ((state: S) => void)) => void;
  $reset: () => void;
  $subscribe: (callback: SubscriptionCallback<S>) => () => void;
  $onAction: (callback: ActionCallback<S, A>) => () => void;
  $persist: () => void;
}

最佳实践

Store 命名

// ✅ 推荐:使用 use 前缀
const useUserStore = defineStore('user', {
  /* ... */
});
const useCartStore = defineStore('cart', {
  /* ... */
});

// ❌ 避免:不使用 use 前缀
const useUser = defineStore('user', {
  /* ... */
});

状态结构

// ✅ 推荐:使用扁平状态结构
state: () => ({
  user: { id: '', name: '', email: '' },
  preferences: { theme: 'light', language: 'zh-CN' },
});

// ❌ 避免:过深的嵌套
state: () => ({
  app: {
    user: {
      profile: {
        name: '',
      },
    },
  },
});

动作命名

// ✅ 推荐:使用动词前缀
actions: {
  fetchUser() { /* 获取用户 */ },
  updateUser() { /* 更新用户 */ },
  deleteUser() { /* 删除用户 */ }
}

浏览器兼容性

@lytjs/store 支持所有现代浏览器。如果需要支持旧版浏览器,可能需要引入 polyfill。

许可证

MIT License - 查看许可证

贡献指南

欢迎提交 Issue 和 Pull Request!