@lytjs/store 4.0.5 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,303 @@
1
+ # @lytjs/store
2
+
3
+ Lyt.js 状态管理 - Pinia 风格的简单直观的状态管理库。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install @lytjs/store
9
+
10
+ # 或使用 pnpm
11
+ pnpm add @lytjs/store
12
+ ```
13
+
14
+ ## 特性
15
+
16
+ - 🚀 DevTools 支持
17
+ - 🔄 热模块替换 (HMR)
18
+ - 📦 插件系统
19
+ - 🎯 TypeScript 友好
20
+ - 🔌 零运行时依赖
21
+ - 💾 可通过插件支持持久化
22
+
23
+ ## 快速开始
24
+
25
+ ```javascript
26
+ import { defineStore } from '@lytjs/store';
27
+
28
+ // 1. 定义 Store
29
+ export const useCounterStore = defineStore('counter', {
30
+ state: () => ({
31
+ count: 0,
32
+ name: 'Lyt.js'
33
+ }),
34
+ getters: {
35
+ doubleCount: (state) => state.count * 2
36
+ },
37
+ actions: {
38
+ increment() {
39
+ this.count++;
40
+ },
41
+ async fetchData() {
42
+ const res = await api.get('/data');
43
+ this.data = res.data;
44
+ }
45
+ }
46
+ });
47
+
48
+ // 2. 在组件中使用
49
+ import { useCounterStore } from './store';
50
+
51
+ const counter = useCounterStore();
52
+
53
+ counter.increment();
54
+ console.log(counter.count);
55
+ console.log(counter.doubleCount);
56
+ ```
57
+
58
+ ## 组合式 Store
59
+
60
+ ```javascript
61
+ import { defineStore } from '@lytjs/store';
62
+ import { ref, computed } from '@lytjs/reactivity';
63
+
64
+ export const useCounterStore = defineStore('counter', () => {
65
+ const count = ref(0);
66
+ const name = ref('Lyt.js');
67
+ const doubleCount = computed(() => count.value * 2);
68
+
69
+ function increment() {
70
+ count.value++;
71
+ }
72
+
73
+ return { count, name, doubleCount, increment };
74
+ });
75
+ ```
76
+
77
+ ## 核心概念
78
+
79
+ ### State
80
+
81
+ ```javascript
82
+ export const useStore = defineStore('main', {
83
+ state: () => ({
84
+ counter: 0,
85
+ user: null
86
+ })
87
+ });
88
+ ```
89
+
90
+ ### Getters
91
+
92
+ ```javascript
93
+ export const useStore = defineStore('main', {
94
+ state: () => ({ counter: 0 }),
95
+ getters: {
96
+ doubleCount: (state) => state.counter * 2,
97
+ doublePlusOne() {
98
+ return this.doubleCount + 1;
99
+ }
100
+ }
101
+ });
102
+ ```
103
+
104
+ ### Actions
105
+
106
+ ```javascript
107
+ export const useStore = defineStore('main', {
108
+ state: () => ({ counter: 0 }),
109
+ actions: {
110
+ increment() {
111
+ this.counter++;
112
+ },
113
+ randomizeCounter() {
114
+ this.counter = Math.round(100 * Math.random());
115
+ }
116
+ }
117
+ });
118
+ ```
119
+
120
+ ## 在 Setup 中使用
121
+
122
+ ```javascript
123
+ import { useCounterStore } from '@/stores/counter';
124
+ import { storeToRefs } from '@lytjs/store';
125
+
126
+ export default {
127
+ setup() {
128
+ const store = useCounterStore();
129
+
130
+ // 直接读取
131
+ store.increment();
132
+
133
+ // 解构,保持响应式
134
+ const { count, doubleCount } = storeToRefs(store);
135
+ const { increment } = store;
136
+
137
+ return { count, doubleCount, increment };
138
+ }
139
+ };
140
+ ```
141
+
142
+ ## 订阅 State
143
+
144
+ ```javascript
145
+ const store = useStore();
146
+
147
+ // 订阅 state 的变化
148
+ const unsubscribe = store.$subscribe((mutation, state) => {
149
+ console.log(mutation);
150
+ localStorage.setItem('cart', JSON.stringify(state));
151
+ });
152
+
153
+ // 订阅 actions 的调用
154
+ const unsubscribeAction = store.$onAction(({ name, after, onError }) => {
155
+ console.log(`Action ${name} called`);
156
+
157
+ after((result) => {
158
+ console.log(`Action ${name} finished with result:`, result);
159
+ });
160
+
161
+ onError((error) => {
162
+ console.error(`Action ${name} failed:`, error);
163
+ });
164
+ });
165
+ ```
166
+
167
+ ## 插件
168
+
169
+ ```javascript
170
+ import { createPinia } from '@lytjs/store';
171
+
172
+ const pinia = createPinia();
173
+
174
+ // 持久化插件示例
175
+ function localStoragePlugin(context) {
176
+ const { store } = context;
177
+
178
+ const savedState = localStorage.getItem(store.$id);
179
+ if (savedState) {
180
+ store.$patch(JSON.parse(savedState));
181
+ }
182
+
183
+ store.$subscribe((mutation, state) => {
184
+ localStorage.setItem(store.$id, JSON.stringify(state));
185
+ });
186
+ }
187
+
188
+ pinia.use(localStoragePlugin);
189
+ ```
190
+
191
+ ## DevTools
192
+
193
+ ```javascript
194
+ import { createPinia } from '@lytjs/store';
195
+
196
+ const pinia = createPinia();
197
+
198
+ // 启用 DevTools
199
+ pinia.use(({ store }) => {
200
+ store.$onAction(({ name, after }) => {
201
+ after(() => {
202
+ console.log(`[Store] ${name}`);
203
+ });
204
+ });
205
+ });
206
+ ```
207
+
208
+ ## 示例
209
+
210
+ ### 完整示例
211
+
212
+ ```javascript
213
+ import { defineStore } from '@lytjs/store';
214
+
215
+ export const useUserStore = defineStore('user', {
216
+ state: () => ({
217
+ user: null,
218
+ isAuthenticated: false,
219
+ token: null
220
+ }),
221
+
222
+ getters: {
223
+ userName: (state) => state.user?.name,
224
+ isLoggedIn: (state) => state.isAuthenticated
225
+ },
226
+
227
+ actions: {
228
+ async login(credentials) {
229
+ try {
230
+ const response = await api.post('/login', credentials);
231
+ this.user = response.data.user;
232
+ this.token = response.data.token;
233
+ this.isAuthenticated = true;
234
+ localStorage.setItem('token', this.token);
235
+ } catch (error) {
236
+ console.error('Login failed:', error);
237
+ throw error;
238
+ }
239
+ },
240
+
241
+ logout() {
242
+ this.user = null;
243
+ this.token = null;
244
+ this.isAuthenticated = false;
245
+ localStorage.removeItem('token');
246
+ }
247
+ }
248
+ });
249
+ ```
250
+
251
+ ### 组合式 API 示例
252
+
253
+ ```javascript
254
+ import { defineStore } from '@lytjs/store';
255
+ import { ref, computed } from '@lytjs/reactivity';
256
+
257
+ export const useTodoStore = defineStore('todo', () => {
258
+ const todos = ref([]);
259
+
260
+ const completedTodos = computed(() =>
261
+ todos.value.filter(todo => todo.completed)
262
+ );
263
+
264
+ const pendingTodos = computed(() =>
265
+ todos.value.filter(todo => !todo.completed)
266
+ );
267
+
268
+ function addTodo(text) {
269
+ todos.value.push({
270
+ id: Date.now(),
271
+ text,
272
+ completed: false
273
+ });
274
+ }
275
+
276
+ function toggleTodo(id) {
277
+ const todo = todos.value.find(t => t.id === id);
278
+ if (todo) {
279
+ todo.completed = !todo.completed;
280
+ }
281
+ }
282
+
283
+ return { todos, completedTodos, pendingTodos, addTodo, toggleTodo };
284
+ });
285
+ ```
286
+
287
+ ## 性能
288
+
289
+ - 轻量级,零运行时依赖
290
+ - 基于 Proxy 的响应式系统
291
+ - 高效的订阅机制
292
+
293
+ ## 兼容性
294
+
295
+ - Node.js >= 18.0.0
296
+ - Chrome 64+
297
+ - Firefox 63+
298
+ - Safari 12+
299
+ - Edge 79+
300
+
301
+ ## License
302
+
303
+ MIT
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- var x=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var V=Object.prototype.hasOwnProperty;var W=(o,t)=>{for(var S in t)x(o,S,{get:t[S],enumerable:!0})},F=(o,t,S,f)=>{if(t&&typeof t=="object"||typeof t=="function")for(let c of L(t))!V.call(o,c)&&c!==S&&x(o,c,{get:()=>t[c],enumerable:!(f=P(t,c))||f.enumerable});return o};var H=o=>F(x({},"__esModule",{value:!0}),o);var K={};W(K,{clearAllStores:()=>C,createStore:()=>w,getStore:()=>O,getStoreIds:()=>j});module.exports=H(K);var y=require("@lytjs/reactivity"),i=require("@lytjs/common"),l=new Map;function O(o){return l.get(o)}function w(o,t={}){if(l.has(o))return()=>l.get(o);let S=typeof t.state=="function"?t.state():t.state||{},f={};if(t.modules)for(let e of Object.keys(t.modules)){let n=t.modules[e],r=typeof n.state=="function"?n.state():n.state||{};f[e]={...r}}let c={...S,...f},a=(0,y.reactive)({...c}),m={};if(t.getters)for(let e of Object.keys(t.getters)){let n=t.getters[e],r=(0,y.computed)(()=>n(a));Object.defineProperty(m,e,{get(){return r.value},enumerable:!0})}if(t.modules)for(let e of Object.keys(t.modules)){let n=t.modules[e];if(n.getters)for(let r of Object.keys(n.getters)){let s=n.getters[r],k=`${e}/${r}`,R=(0,y.computed)(()=>{let A=a[e];return s(A)});Object.defineProperty(m,k,{get(){return R.value},enumerable:!0})}}let $={},g=[];if(t.actions)for(let e of Object.keys(t.actions)){let n=t.actions[e];$[e]=function(...r){for(let s of g)s({name:e,args:r});return n.apply(b,r)}}if(t.modules)for(let e of Object.keys(t.modules)){let n=t.modules[e];if(n.actions)for(let r of Object.keys(n.actions)){let s=n.actions[r],k=`${e}/${r}`;$[k]=function(...R){for(let A of g)A({name:k,args:R});return s.apply(b,R)}}}let v=new i.SubscriptionManager,d=!1,p=[];function h(e){v.notify([e,a])}let u=null;function I(){if(u||d)return;let e=(0,i.createSnapshot)(a);u=(0,y.watch)(a,()=>{let n=(0,i.createSnapshot)(a),r=(0,i.diffObjects)(e,n);for(let s in r.added)h({storeId:o,type:"add",key:s,newValue:r.added[s]});for(let s in r.removed)h({storeId:o,type:"delete",key:s,oldValue:r.removed[s]});for(let s in r.changed)h({storeId:o,type:"set",key:s,newValue:r.changed[s].new,oldValue:r.changed[s].old});e=n},{deep:!0}),p.push(u)}function M(){if(!v.hasSubscribers()&&u){u();let e=p.indexOf(u);e!==-1&&p.splice(e,1),u=null}}let b={$id:o,get state(){return a},get getters(){return m},get actions(){return $},$expose(){return{state:a,getters:m}},$reset(){if(d)return;let e=Object.keys(a),n=Object.keys(c);for(let r of n)a[r]=c[r];for(let r of e)n.includes(r)||delete a[r]},$subscribe(e){if(d)return()=>{};let n=v.subscribe(([r,s])=>{e(r,s)});return I(),()=>{n(),M()}},$dispose(){if(!d){for(let e of p)e();p.length=0,u=null,v.clear(),l.delete(o),d=!0}},$patch(e){d||((0,i.isFunction)(e)?e(a):(0,i.mergeObjects)(a,e))},use(e){if(d)return()=>{};let n=e.install(b);return()=>{typeof n=="function"&&n()}},$onAction(e){return d?()=>{}:(g.push(e),()=>{let n=g.indexOf(e);n!==-1&&g.splice(n,1)})}};return l.set(o,b),()=>b}function j(){return Array.from(l.keys())}function C(){for(let[o,t]of l)t.$dispose();l.clear()}
1
+ var x=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var V=Object.prototype.hasOwnProperty;var W=(o,t)=>{for(var S in t)x(o,S,{get:t[S],enumerable:!0})},F=(o,t,S,f)=>{if(t&&typeof t=="object"||typeof t=="function")for(let c of L(t))!V.call(o,c)&&c!==S&&x(o,c,{get:()=>t[c],enumerable:!(f=P(t,c))||f.enumerable});return o};var H=o=>F(x({},"__esModule",{value:!0}),o);var K={};W(K,{clearAllStores:()=>C,createStore:()=>w,getStore:()=>O,getStoreIds:()=>j});module.exports=H(K);var y=require("@lytjs/reactivity"),i=require("@lytjs/common"),l=new Map;function O(o){return l.get(o)}function w(o,t={}){if(l.has(o))return()=>l.get(o);let S=typeof t.state=="function"?t.state():t.state||{},f={};if(t.modules)for(let e of Object.keys(t.modules)){let n=t.modules[e],r=typeof n.state=="function"?n.state():n.state||{};f[e]={...r}}let c={...S,...f},a=(0,y.reactive)({...c}),m={};if(t.getters)for(let e of Object.keys(t.getters)){let n=t.getters[e],r=(0,y.computed)(()=>n(a));Object.defineProperty(m,e,{get(){return r.value},enumerable:!0})}if(t.modules)for(let e of Object.keys(t.modules)){let n=t.modules[e];if(n.getters)for(let r of Object.keys(n.getters)){let s=n.getters[r],v=`${e}/${r}`,R=(0,y.computed)(()=>{let A=a[e];return s(A)});Object.defineProperty(m,v,{get(){return R.value},enumerable:!0})}}let $={},g=[];if(t.actions)for(let e of Object.keys(t.actions)){let n=t.actions[e];$[e]=function(...r){for(let s of g)s({name:e,args:r});return n.apply(b,r)}}if(t.modules)for(let e of Object.keys(t.modules)){let n=t.modules[e];if(n.actions)for(let r of Object.keys(n.actions)){let s=n.actions[r],v=`${e}/${r}`;$[v]=function(...R){for(let A of g)A({name:v,args:R});return s.apply(b,R)}}}let k=new i.SubscriptionManager,d=!1,p=[];function h(e){k.notify([e,a])}let u=null;function I(){if(u||d)return;let e=(0,i.createSnapshot)(a);u=(0,y.watch)(a,()=>{let n=(0,i.createSnapshot)(a),r=(0,i.diffObjects)(e,n);for(let s in r.added)h({storeId:o,type:"add",key:s,newValue:r.added[s]});for(let s in r.removed)h({storeId:o,type:"delete",key:s,oldValue:r.removed[s]});for(let s in r.changed)h({storeId:o,type:"set",key:s,newValue:r.changed[s].new,oldValue:r.changed[s].old});e=n},{deep:!0}),p.push(u)}function M(){if(!k.hasSubscribers()&&u){u();let e=p.indexOf(u);e!==-1&&p.splice(e,1),u=null}}let b={$id:o,get state(){return a},get getters(){return m},get actions(){return $},$expose(){return{state:a,getters:m}},$reset(){if(d)return;let e=Object.keys(a),n=Object.keys(c);for(let r of n)a[r]=c[r];for(let r of e)n.includes(r)||delete a[r]},$subscribe(e){if(d)return()=>{};let n=k.subscribe(([r,s])=>{e(r,s)});return I(),()=>{n(),M()}},$dispose(){if(!d){for(let e of p)e();p.length=0,u=null,k.clear(),l.delete(o),d=!0}},$patch(e){d||((0,i.isFunction)(e)?e(a):(0,i.mergeObjects)(a,e))},use(e){if(d)return()=>{};let n=e.install(b);return()=>{typeof n=="function"&&n()}},$onAction(e){return d?()=>{}:(g.push(e),()=>{let n=g.indexOf(e);n!==-1&&g.splice(n,1)})}};return l.set(o,b),()=>b}function j(){return Array.from(l.keys())}function C(){for(let[o,t]of l)t.$dispose();l.clear()}
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{reactive as w,computed as $,watch as j}from"@lytjs/reactivity";import{createSnapshot as h,diffObjects as C,mergeObjects as I,isFunction as M,SubscriptionManager as P}from"@lytjs/common";var d=new Map;function L(a){return d.get(a)}function V(a,r={}){if(d.has(a))return()=>d.get(a);let A=typeof r.state=="function"?r.state():r.state||{},R={};if(r.modules)for(let e of Object.keys(r.modules)){let t=r.modules[e],n=typeof t.state=="function"?t.state():t.state||{};R[e]={...n}}let b={...A,...R},s=w({...b}),S={};if(r.getters)for(let e of Object.keys(r.getters)){let t=r.getters[e],n=$(()=>t(s));Object.defineProperty(S,e,{get(){return n.value},enumerable:!0})}if(r.modules)for(let e of Object.keys(r.modules)){let t=r.modules[e];if(t.getters)for(let n of Object.keys(t.getters)){let o=t.getters[n],g=`${e}/${n}`,p=$(()=>{let k=s[e];return o(k)});Object.defineProperty(S,g,{get(){return p.value},enumerable:!0})}}let m={},u=[];if(r.actions)for(let e of Object.keys(r.actions)){let t=r.actions[e];m[e]=function(...n){for(let o of u)o({name:e,args:n});return t.apply(y,n)}}if(r.modules)for(let e of Object.keys(r.modules)){let t=r.modules[e];if(t.actions)for(let n of Object.keys(t.actions)){let o=t.actions[n],g=`${e}/${n}`;m[g]=function(...p){for(let k of u)k({name:g,args:p});return o.apply(y,p)}}}let f=new P,i=!1,l=[];function v(e){f.notify([e,s])}let c=null;function x(){if(c||i)return;let e=h(s);c=j(s,()=>{let t=h(s),n=C(e,t);for(let o in n.added)v({storeId:a,type:"add",key:o,newValue:n.added[o]});for(let o in n.removed)v({storeId:a,type:"delete",key:o,oldValue:n.removed[o]});for(let o in n.changed)v({storeId:a,type:"set",key:o,newValue:n.changed[o].new,oldValue:n.changed[o].old});e=t},{deep:!0}),l.push(c)}function O(){if(!f.hasSubscribers()&&c){c();let e=l.indexOf(c);e!==-1&&l.splice(e,1),c=null}}let y={$id:a,get state(){return s},get getters(){return S},get actions(){return m},$expose(){return{state:s,getters:S}},$reset(){if(i)return;let e=Object.keys(s),t=Object.keys(b);for(let n of t)s[n]=b[n];for(let n of e)t.includes(n)||delete s[n]},$subscribe(e){if(i)return()=>{};let t=f.subscribe(([n,o])=>{e(n,o)});return x(),()=>{t(),O()}},$dispose(){if(!i){for(let e of l)e();l.length=0,c=null,f.clear(),d.delete(a),i=!0}},$patch(e){i||(M(e)?e(s):I(s,e))},use(e){if(i)return()=>{};let t=e.install(y);return()=>{typeof t=="function"&&t()}},$onAction(e){return i?()=>{}:(u.push(e),()=>{let t=u.indexOf(e);t!==-1&&u.splice(t,1)})}};return d.set(a,y),()=>y}function W(){return Array.from(d.keys())}function F(){for(let[a,r]of d)r.$dispose();d.clear()}export{F as clearAllStores,V as createStore,L as getStore,W as getStoreIds};
1
+ import{reactive as w,computed as $,watch as j}from"@lytjs/reactivity";import{createSnapshot as h,diffObjects as C,mergeObjects as I,isFunction as M,SubscriptionManager as P}from"@lytjs/common";var d=new Map;function L(a){return d.get(a)}function V(a,r={}){if(d.has(a))return()=>d.get(a);let A=typeof r.state=="function"?r.state():r.state||{},R={};if(r.modules)for(let e of Object.keys(r.modules)){let t=r.modules[e],n=typeof t.state=="function"?t.state():t.state||{};R[e]={...n}}let b={...A,...R},s=w({...b}),S={};if(r.getters)for(let e of Object.keys(r.getters)){let t=r.getters[e],n=$(()=>t(s));Object.defineProperty(S,e,{get(){return n.value},enumerable:!0})}if(r.modules)for(let e of Object.keys(r.modules)){let t=r.modules[e];if(t.getters)for(let n of Object.keys(t.getters)){let o=t.getters[n],g=`${e}/${n}`,p=$(()=>{let v=s[e];return o(v)});Object.defineProperty(S,g,{get(){return p.value},enumerable:!0})}}let m={},u=[];if(r.actions)for(let e of Object.keys(r.actions)){let t=r.actions[e];m[e]=function(...n){for(let o of u)o({name:e,args:n});return t.apply(y,n)}}if(r.modules)for(let e of Object.keys(r.modules)){let t=r.modules[e];if(t.actions)for(let n of Object.keys(t.actions)){let o=t.actions[n],g=`${e}/${n}`;m[g]=function(...p){for(let v of u)v({name:g,args:p});return o.apply(y,p)}}}let f=new P,i=!1,l=[];function k(e){f.notify([e,s])}let c=null;function x(){if(c||i)return;let e=h(s);c=j(s,()=>{let t=h(s),n=C(e,t);for(let o in n.added)k({storeId:a,type:"add",key:o,newValue:n.added[o]});for(let o in n.removed)k({storeId:a,type:"delete",key:o,oldValue:n.removed[o]});for(let o in n.changed)k({storeId:a,type:"set",key:o,newValue:n.changed[o].new,oldValue:n.changed[o].old});e=t},{deep:!0}),l.push(c)}function O(){if(!f.hasSubscribers()&&c){c();let e=l.indexOf(c);e!==-1&&l.splice(e,1),c=null}}let y={$id:a,get state(){return s},get getters(){return S},get actions(){return m},$expose(){return{state:s,getters:S}},$reset(){if(i)return;let e=Object.keys(s),t=Object.keys(b);for(let n of t)s[n]=b[n];for(let n of e)t.includes(n)||delete s[n]},$subscribe(e){if(i)return()=>{};let t=f.subscribe(([n,o])=>{e(n,o)});return x(),()=>{t(),O()}},$dispose(){if(!i){for(let e of l)e();l.length=0,c=null,f.clear(),d.delete(a),i=!0}},$patch(e){i||(M(e)?e(s):I(s,e))},use(e){if(i)return()=>{};let t=e.install(y);return()=>{typeof t=="function"&&t()}},$onAction(e){return i?()=>{}:(u.push(e),()=>{let t=u.indexOf(e);t!==-1&&u.splice(t,1)})}};return d.set(a,y),()=>y}function W(){return Array.from(d.keys())}function F(){for(let[a,r]of d)r.$dispose();d.clear()}export{F as clearAllStores,V as createStore,L as getStore,W as getStoreIds};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lytjs/store",
3
- "version": "4.0.5",
3
+ "version": "4.2.0",
4
4
  "description": "Lyt.js 内置状态管理 - 轻量级全局状态管理,支持模块化和插件扩展",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -38,8 +38,8 @@
38
38
  "state-management"
39
39
  ],
40
40
  "dependencies": {
41
- "@lytjs/common": "^4.0.5",
42
- "@lytjs/reactivity": "^4.0.5"
41
+ "@lytjs/common": "^4.2.0",
42
+ "@lytjs/reactivity": "^4.2.0"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=18.0.0"