tailwindapi 1.0.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/LICENSE +2 -0
- package/README.md +145 -0
- package/dist/StateManager.d.ts +18 -0
- package/dist/StateManager.d.ts.map +1 -0
- package/dist/StateManager.js +59 -0
- package/dist/StateManager.js.map +1 -0
- package/dist/hooks.d.ts +10 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +63 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utilities.d.ts +7 -0
- package/dist/utilities.d.ts.map +1 -0
- package/dist/utilities.js +59 -0
- package/dist/utilities.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# tailwindAPI
|
|
2
|
+
|
|
3
|
+
State management as simple as CSS classes. No Redux boilerplate.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 **Simple API** - No boilerplate, just create a store and use it
|
|
8
|
+
- 📦 **Lightweight** - ~2KB gzipped
|
|
9
|
+
- âš¡ **TypeScript** - Full type safety out of the box
|
|
10
|
+
- 🎣 **React Hooks** - Built-in hooks for React components
|
|
11
|
+
- 🔄 **Mutations & Actions** - Synchronous and async state updates
|
|
12
|
+
- 💾 **Persistence** - Optional localStorage persistence
|
|
13
|
+
- 🧩 **Composable** - Combine multiple stores easily
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install tailwindapi
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { StateManager, useStateless } from 'tailwindapi';
|
|
25
|
+
|
|
26
|
+
// Create a store
|
|
27
|
+
const counterStore = new StateManager({
|
|
28
|
+
initialState: { count: 0 },
|
|
29
|
+
mutations: {
|
|
30
|
+
INCREMENT: (state, payload) => {
|
|
31
|
+
state.count += payload || 1;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Use in React component
|
|
37
|
+
function Counter() {
|
|
38
|
+
const { state, commit } = useStateless(counterStore);
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div>
|
|
42
|
+
<p>Count: {state.count}</p>
|
|
43
|
+
<button onClick={() => commit('INCREMENT', 1)}>+1</button>
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Documentation
|
|
50
|
+
|
|
51
|
+
### StateManager
|
|
52
|
+
|
|
53
|
+
The core class that manages your application state.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
const store = new StateManager({
|
|
57
|
+
initialState: { count: 0, user: null },
|
|
58
|
+
mutations: {
|
|
59
|
+
INCREMENT: (state, payload) => { state.count += payload || 1; },
|
|
60
|
+
SET_USER: (state, user) => { state.user = user; }
|
|
61
|
+
},
|
|
62
|
+
actions: {
|
|
63
|
+
fetchUser: async (state, userId) => {
|
|
64
|
+
const user = await api.getUser(userId);
|
|
65
|
+
state.user = user;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Hooks
|
|
72
|
+
|
|
73
|
+
#### `useStateless`
|
|
74
|
+
|
|
75
|
+
Basic hook for state management.
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const { state, commit, dispatch, reset } = useStateless(store);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### `useAPI`
|
|
82
|
+
|
|
83
|
+
Hook with built-in loading and error states.
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
const { state, callAPI, isLoading, error } = useAPI(store);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### `useSlice`
|
|
90
|
+
|
|
91
|
+
Subscribe to a single property for performance.
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
const [count, setCount] = useSlice(store, 'count');
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### `useMutate`
|
|
98
|
+
|
|
99
|
+
Simplified hook for mutations only.
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
const { mutate, state } = useMutate(store);
|
|
103
|
+
mutate('INCREMENT', 5);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Utilities
|
|
107
|
+
|
|
108
|
+
#### `withLogger`
|
|
109
|
+
|
|
110
|
+
Add logging to your store for debugging.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const store = withLogger(new StateManager({...}));
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### `createPersistedStore`
|
|
117
|
+
|
|
118
|
+
Create a store that persists to localStorage.
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
const store = createPersistedStore(
|
|
122
|
+
{ initialState: {...}, mutations: {...} },
|
|
123
|
+
'my-app-state'
|
|
124
|
+
);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### `combineStores`
|
|
128
|
+
|
|
129
|
+
Combine multiple stores into one.
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
const rootStore = combineStores({
|
|
133
|
+
user: userStore,
|
|
134
|
+
cart: cartStore
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Examples
|
|
139
|
+
|
|
140
|
+
See [EXAMPLE_USAGE.md](./EXAMPLE_USAGE.md) for complete examples.
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
MIT
|
|
145
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { StateConfig, Listener } from './types';
|
|
2
|
+
export declare class StateManager<T = any> {
|
|
3
|
+
private state;
|
|
4
|
+
private initialState;
|
|
5
|
+
private mutations;
|
|
6
|
+
private actions;
|
|
7
|
+
private listeners;
|
|
8
|
+
constructor(config: StateConfig<T>);
|
|
9
|
+
getState(): T;
|
|
10
|
+
getValue<K extends keyof T>(key: K): T[K];
|
|
11
|
+
commit(mutation: string, payload?: any): void;
|
|
12
|
+
dispatch(action: string, payload?: any): Promise<any>;
|
|
13
|
+
subscribe(listener: Listener<T>): () => void;
|
|
14
|
+
private notify;
|
|
15
|
+
reset(): void;
|
|
16
|
+
setState(updates: Partial<T>): void;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=StateManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StateManager.d.ts","sourceRoot":"","sources":["../src/StateManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEhD,qBAAa,YAAY,CAAC,CAAC,GAAG,GAAG;IAC/B,OAAO,CAAC,KAAK,CAAI;IACjB,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,SAAS,CAAmD;IACpE,OAAO,CAAC,OAAO,CAAmE;IAClF,OAAO,CAAC,SAAS,CAA+B;gBAEpC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAOlC,QAAQ,IAAI,CAAC;IAIb,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAIzC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,GAAU,GAAG,IAAI;IAc7C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,GAAU,GAAG,OAAO,CAAC,GAAG,CAAC;IAcjE,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAO5C,OAAO,CAAC,MAAM;IAId,KAAK,IAAI,IAAI;IAKb,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;CAIpC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export class StateManager {
|
|
2
|
+
constructor(config) {
|
|
3
|
+
this.listeners = new Set();
|
|
4
|
+
this.initialState = JSON.parse(JSON.stringify(config.initialState));
|
|
5
|
+
this.state = JSON.parse(JSON.stringify(config.initialState));
|
|
6
|
+
this.mutations = config.mutations || {};
|
|
7
|
+
this.actions = config.actions || {};
|
|
8
|
+
}
|
|
9
|
+
getState() {
|
|
10
|
+
return this.state;
|
|
11
|
+
}
|
|
12
|
+
getValue(key) {
|
|
13
|
+
return this.state[key];
|
|
14
|
+
}
|
|
15
|
+
commit(mutation, payload = null) {
|
|
16
|
+
if (!this.mutations[mutation]) {
|
|
17
|
+
console.warn(`Mutation "${mutation}" not found`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
this.mutations[mutation](this.state, payload);
|
|
22
|
+
this.notify();
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
console.error(`Error in mutation "${mutation}":`, error);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async dispatch(action, payload = null) {
|
|
29
|
+
if (!this.actions[action]) {
|
|
30
|
+
console.warn(`Action "${action}" not found`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
return await this.actions[action](this.state, payload);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.error(`Error in action "${action}":`, error);
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
subscribe(listener) {
|
|
42
|
+
this.listeners.add(listener);
|
|
43
|
+
return () => {
|
|
44
|
+
this.listeners.delete(listener);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
notify() {
|
|
48
|
+
this.listeners.forEach(listener => listener(this.state));
|
|
49
|
+
}
|
|
50
|
+
reset() {
|
|
51
|
+
this.state = JSON.parse(JSON.stringify(this.initialState));
|
|
52
|
+
this.notify();
|
|
53
|
+
}
|
|
54
|
+
setState(updates) {
|
|
55
|
+
this.state = { ...this.state, ...updates };
|
|
56
|
+
this.notify();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=StateManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StateManager.js","sourceRoot":"","sources":["../src/StateManager.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,YAAY;IAOvB,YAAY,MAAsB;QAF1B,cAAS,GAAqB,IAAI,GAAG,EAAE,CAAC;QAG9C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;QACpE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IACtC,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,QAAQ,CAAoB,GAAM;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,QAAgB,EAAE,UAAe,IAAI;QAC1C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,aAAa,QAAQ,aAAa,CAAC,CAAC;YACjD,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,QAAQ,IAAI,EAAE,KAAK,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,UAAe,IAAI;QAChD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,WAAW,MAAM,aAAa,CAAC,CAAC;YAC7C,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,oBAAoB,MAAM,IAAI,EAAE,KAAK,CAAC,CAAC;YACrD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,SAAS,CAAC,QAAqB;QAC7B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC,CAAC;IACJ,CAAC;IAEO,MAAM;QACZ,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAC3D,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,QAAQ,CAAC,OAAmB;QAC1B,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;CACF"}
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { StateManager } from './StateManager';
|
|
2
|
+
import { UseStatelessReturn, UseAPIReturn } from './types';
|
|
3
|
+
export declare function useStateless<T = any>(store: StateManager<T>): UseStatelessReturn<T>;
|
|
4
|
+
export declare function useAPI<T = any>(store: StateManager<T>): UseAPIReturn<T>;
|
|
5
|
+
export declare function useSlice<T = any, K extends keyof T = keyof T>(store: StateManager<T>, key: K): [T[K], (value: T[K]) => void];
|
|
6
|
+
export declare function useMutate<T = any>(store: StateManager<T>): {
|
|
7
|
+
mutate: (mutation: string, payload?: any) => void;
|
|
8
|
+
state: T;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAY,MAAM,SAAS,CAAC;AAErE,wBAAgB,YAAY,CAAC,CAAC,GAAG,GAAG,EAClC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GACrB,kBAAkB,CAAC,CAAC,CAAC,CA+BvB;AAED,wBAAgB,MAAM,CAAC,CAAC,GAAG,GAAG,EAC5B,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GACrB,YAAY,CAAC,CAAC,CAAC,CAwBjB;AAED,wBAAgB,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,CAAC,EAC3D,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EACtB,GAAG,EAAE,CAAC,GACL,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAgB/B;AAED,wBAAgB,SAAS,CAAC,CAAC,GAAG,GAAG,EAC/B,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GACrB;IAAE,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CASjE"}
|
package/dist/hooks.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
2
|
+
export function useStateless(store) {
|
|
3
|
+
const [state, setState] = useState(store.getState());
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
const unsubscribe = store.subscribe((newState) => {
|
|
6
|
+
setState(newState);
|
|
7
|
+
});
|
|
8
|
+
return unsubscribe;
|
|
9
|
+
}, [store]);
|
|
10
|
+
const dispatch = useCallback((action, payload) => store.dispatch(action, payload), [store]);
|
|
11
|
+
const commit = useCallback((mutation, payload) => store.commit(mutation, payload), [store]);
|
|
12
|
+
const subscribe = useCallback((listener) => store.subscribe(listener), [store]);
|
|
13
|
+
const reset = useCallback(() => {
|
|
14
|
+
store.reset();
|
|
15
|
+
setState(store.getState());
|
|
16
|
+
}, [store]);
|
|
17
|
+
return { state, dispatch, commit, subscribe, reset };
|
|
18
|
+
}
|
|
19
|
+
export function useAPI(store) {
|
|
20
|
+
const { state, dispatch, commit, subscribe, reset } = useStateless(store);
|
|
21
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
22
|
+
const [error, setError] = useState(null);
|
|
23
|
+
const callAPI = useCallback(async (action, payload) => {
|
|
24
|
+
setIsLoading(true);
|
|
25
|
+
setError(null);
|
|
26
|
+
try {
|
|
27
|
+
const result = await dispatch(action, payload);
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
32
|
+
setError(errorMsg);
|
|
33
|
+
throw err;
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
setIsLoading(false);
|
|
37
|
+
}
|
|
38
|
+
}, [dispatch]);
|
|
39
|
+
return { state, dispatch, commit, subscribe, reset, callAPI, isLoading, error };
|
|
40
|
+
}
|
|
41
|
+
export function useSlice(store, key) {
|
|
42
|
+
const [value, setValue] = useState(store.getValue(key));
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
const unsubscribe = store.subscribe((newState) => {
|
|
45
|
+
setValue(newState[key]);
|
|
46
|
+
});
|
|
47
|
+
return unsubscribe;
|
|
48
|
+
}, [store, key]);
|
|
49
|
+
return [
|
|
50
|
+
value,
|
|
51
|
+
(newValue) => {
|
|
52
|
+
store.setState({ [key]: newValue });
|
|
53
|
+
},
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
export function useMutate(store) {
|
|
57
|
+
const { state, commit } = useStateless(store);
|
|
58
|
+
const mutate = useCallback((mutation, payload) => {
|
|
59
|
+
commit(mutation, payload);
|
|
60
|
+
}, [commit]);
|
|
61
|
+
return { mutate, state };
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { StateManager } from './StateManager';
|
|
2
|
+
export { useStateless, useAPI, useSlice, useMutate } from './hooks';
|
|
3
|
+
export { withLogger, createPersistedStore, combineStores } from './utilities';
|
|
4
|
+
export type { StateConfig, Listener, UseStatelessReturn, UseAPIReturn } from './types';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC9E,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface StateConfig<T = any> {
|
|
2
|
+
initialState: T;
|
|
3
|
+
mutations?: Record<string, (state: T, payload: any) => void>;
|
|
4
|
+
actions?: Record<string, (state: T, payload: any) => Promise<void> | void>;
|
|
5
|
+
}
|
|
6
|
+
export type Listener<T = any> = (state: T) => void;
|
|
7
|
+
export interface UseStatelessReturn<T = any> {
|
|
8
|
+
state: T;
|
|
9
|
+
dispatch: (action: string, payload?: any) => Promise<any>;
|
|
10
|
+
commit: (mutation: string, payload?: any) => void;
|
|
11
|
+
subscribe: (listener: Listener<T>) => () => void;
|
|
12
|
+
reset: () => void;
|
|
13
|
+
}
|
|
14
|
+
export interface UseAPIReturn<T = any> extends UseStatelessReturn<T> {
|
|
15
|
+
callAPI: (action: string, payload?: any) => Promise<any>;
|
|
16
|
+
isLoading: boolean;
|
|
17
|
+
error: string | null;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,YAAY,EAAE,CAAC,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;CAC5E;AAED,MAAM,MAAM,QAAQ,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAEnD,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,GAAG;IACzC,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1D,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAClD,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC;IACjD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,GAAG,CAAE,SAAQ,kBAAkB,CAAC,CAAC,CAAC;IAClE,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACzD,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { StateManager } from './StateManager';
|
|
2
|
+
export declare function withLogger<T = any>(store: StateManager<T>): StateManager<T>;
|
|
3
|
+
export declare function createPersistedStore<T>(config: any, storageKey: string): StateManager<T>;
|
|
4
|
+
export declare function combineStores<T extends Record<string, StateManager>>(stores: T): StateManager<{
|
|
5
|
+
[K in keyof T]: ReturnType<T[K]['getState']>;
|
|
6
|
+
}>;
|
|
7
|
+
//# sourceMappingURL=utilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,wBAAgB,UAAU,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAuB3E;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,MAAM,EAAE,GAAG,EACX,UAAU,EAAE,MAAM,GACjB,YAAY,CAAC,CAAC,CAAC,CA0BjB;AAED,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,EAClE,MAAM,EAAE,CAAC,GACR,YAAY,CAAC;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;CAAE,CAAC,CAWhE"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { StateManager } from './StateManager';
|
|
2
|
+
export function withLogger(store) {
|
|
3
|
+
const originalCommit = store.commit.bind(store);
|
|
4
|
+
const originalDispatch = store.dispatch.bind(store);
|
|
5
|
+
store.commit = function (mutation, payload) {
|
|
6
|
+
console.log(`[MUTATION] ${mutation}`, payload);
|
|
7
|
+
originalCommit(mutation, payload);
|
|
8
|
+
console.log('[STATE]', this.getState());
|
|
9
|
+
};
|
|
10
|
+
store.dispatch = async function (action, payload) {
|
|
11
|
+
console.log(`[ACTION] ${action}`, payload);
|
|
12
|
+
try {
|
|
13
|
+
const result = await originalDispatch(action, payload);
|
|
14
|
+
console.log('[STATE]', this.getState());
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
console.error(`[ERROR] ${action}`, error);
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
return store;
|
|
23
|
+
}
|
|
24
|
+
export function createPersistedStore(config, storageKey) {
|
|
25
|
+
let initialState = config.initialState;
|
|
26
|
+
if (typeof window !== 'undefined') {
|
|
27
|
+
const stored = localStorage.getItem(storageKey);
|
|
28
|
+
if (stored) {
|
|
29
|
+
try {
|
|
30
|
+
initialState = JSON.parse(stored);
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
console.warn('Failed to parse stored state');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const store = new StateManager({
|
|
38
|
+
...config,
|
|
39
|
+
initialState,
|
|
40
|
+
});
|
|
41
|
+
store.subscribe((state) => {
|
|
42
|
+
if (typeof window !== 'undefined') {
|
|
43
|
+
localStorage.setItem(storageKey, JSON.stringify(state));
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return store;
|
|
47
|
+
}
|
|
48
|
+
export function combineStores(stores) {
|
|
49
|
+
const initialState = Object.entries(stores).reduce((acc, [key, store]) => {
|
|
50
|
+
acc[key] = store.getState();
|
|
51
|
+
return acc;
|
|
52
|
+
}, {});
|
|
53
|
+
return new StateManager({
|
|
54
|
+
initialState,
|
|
55
|
+
mutations: {},
|
|
56
|
+
actions: {},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=utilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utilities.js","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,UAAU,UAAU,CAAU,KAAsB;IACxD,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,gBAAgB,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEpD,KAAK,CAAC,MAAM,GAAG,UAAS,QAAgB,EAAE,OAAY;QACpD,OAAO,CAAC,GAAG,CAAC,cAAc,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;QAC/C,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEF,KAAK,CAAC,QAAQ,GAAG,KAAK,WAAU,MAAc,EAAE,OAAY;QAC1D,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YACxC,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,WAAW,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC;YAC1C,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,MAAW,EACX,UAAkB;IAElB,IAAI,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;IAEvC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC;gBACH,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACpC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC;QAC7B,GAAG,MAAM;QACT,YAAY;KACb,CAAC,CAAC;IAEH,KAAK,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;QACxB,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,MAAS;IAET,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACvE,GAAG,CAAC,GAAU,CAAC,GAAI,KAAa,CAAC,QAAQ,EAAE,CAAC;QAC5C,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAS,CAAC,CAAC;IAEd,OAAO,IAAI,YAAY,CAAC;QACtB,YAAY;QACZ,SAAS,EAAE,EAAE;QACb,OAAO,EAAE,EAAE;KACZ,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tailwindapi",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "State management as simple as CSS classes. No Redux boilerplate.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"state-management",
|
|
8
|
+
"react",
|
|
9
|
+
"next.js",
|
|
10
|
+
"hooks",
|
|
11
|
+
"typescript"
|
|
12
|
+
],
|
|
13
|
+
"main": "dist/index.js",
|
|
14
|
+
"types": "dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"require": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": ["dist", "README.md", "LICENSE"],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc",
|
|
25
|
+
"watch": "tsc --watch",
|
|
26
|
+
"test": "jest",
|
|
27
|
+
"test:watch": "jest --watch",
|
|
28
|
+
"test:coverage": "jest --coverage",
|
|
29
|
+
"lint": "eslint src/**/*.ts",
|
|
30
|
+
"format": "prettier --write src/**/*.ts",
|
|
31
|
+
"prepublishOnly": "npm run build && npm run test && npm run lint"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"react": ">=17.0.0",
|
|
35
|
+
"react-dom": ">=17.0.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/jest": "^29.0.0",
|
|
39
|
+
"@types/node": "^20.0.0",
|
|
40
|
+
"@types/react": "^18.2.0",
|
|
41
|
+
"@types/react-dom": "^18.2.0",
|
|
42
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
43
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
44
|
+
"eslint": "^8.0.0",
|
|
45
|
+
"jest": "^29.0.0",
|
|
46
|
+
"jest-environment-jsdom": "^29.0.0",
|
|
47
|
+
"prettier": "^3.0.0",
|
|
48
|
+
"react": "^18.2.0",
|
|
49
|
+
"react-dom": "^18.2.0",
|
|
50
|
+
"ts-jest": "^29.0.0",
|
|
51
|
+
"typescript": "^5.0.0"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=16.0.0"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|