valtio-define 1.2.0 → 1.2.1
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 +33 -1
- package/dist/index.d.mts +9 -6
- package/dist/index.mjs +1 -1
- package/dist/plugins/index.d.mts +2 -2
- package/dist/plugins/persist/index.d.mts +1 -4
- package/dist/plugins/persist/index.mjs +1 -1
- package/dist/plugins/persist/types.d.mts +8 -1
- package/package.json +1 -1
- package/README.OLD.md +0 -391
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[![coverage][coverage-src]][coverage-href]
|
|
8
8
|
[![License][license-src]][license-href].
|
|
9
9
|
|
|
10
|
-
⚡️ **valtio-define** is a lightweight factory for creating fully functional, robust [Valtio](https://valtio
|
|
10
|
+
⚡️ **valtio-define** is a lightweight factory for creating fully functional, robust [Valtio](https://github.com/pmndrs/valtio) stores. It simplifies state management in React by providing a structured API for state, actions, and computed getters.
|
|
11
11
|
|
|
12
12
|
## 📦 Installation
|
|
13
13
|
|
|
@@ -15,8 +15,18 @@
|
|
|
15
15
|
pnpm add valtio-define
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
<details>
|
|
19
|
+
<summary>Are you an AI?</summary>
|
|
20
|
+
|
|
21
|
+
You can run <code>npx skills add hairyf/valtio-define --skill valtio-define -y</code> to install the skills!
|
|
22
|
+
|
|
23
|
+
Remember to ask your owner which <a href="https://github.com/vercel-labs/skills?tab=readme-ov-file#supported-agents">Agents</a> need to be supported (using the <code>--agent</code> parameter of skills) to avoid installing too many default <code>agents</code> directories.
|
|
24
|
+
|
|
25
|
+
</details>
|
|
26
|
+
|
|
18
27
|
## 🚀 Quick Start
|
|
19
28
|
|
|
29
|
+
|
|
20
30
|
### Basic Store
|
|
21
31
|
|
|
22
32
|
`defineStore` allows you to encapsulate state and logic in one place. Use `useStore` to consume the reactive state in your components.
|
|
@@ -161,6 +171,28 @@ function Profile() {
|
|
|
161
171
|
}
|
|
162
172
|
```
|
|
163
173
|
|
|
174
|
+
### Controlled inputs may lose caret position
|
|
175
|
+
|
|
176
|
+
Ref: https://github.com/pmndrs/valtio/issues/270
|
|
177
|
+
|
|
178
|
+
This happens because Valtio batches state updates causing React to re-render after the input event. React resets the DOM value and loses the caret position.
|
|
179
|
+
|
|
180
|
+
Use `{ sync: true }` to update synchronously and preserve the caret:
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
function Input() {
|
|
184
|
+
const { text } = useStore(store, { sync: true })
|
|
185
|
+
// const [text, setText] = storeToState(store, 'text', { sync: true })
|
|
186
|
+
|
|
187
|
+
return (
|
|
188
|
+
<input
|
|
189
|
+
onChange={e => store.text = e.target.value}
|
|
190
|
+
value={text}
|
|
191
|
+
/>
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
164
196
|
-----
|
|
165
197
|
|
|
166
198
|
## 🛰 Store API
|
package/dist/index.d.mts
CHANGED
|
@@ -38,18 +38,21 @@ declare function use(plugin: Plugin): void;
|
|
|
38
38
|
declare function defineStore<S extends object = {}, A extends Actions<S> = {}, G extends Getters<S> = {}>(define: StoreDefine<S, A, G>): Store<S, A, G>;
|
|
39
39
|
//#endregion
|
|
40
40
|
//#region src/hooks.d.ts
|
|
41
|
-
|
|
41
|
+
declare function useStore<S extends object, A extends Actions<S>, G extends Getters<S>>(store: Store<S, A, G>, options?: {
|
|
42
42
|
sync?: boolean;
|
|
43
|
-
}
|
|
44
|
-
declare function useStore<S extends object, A extends Actions<S>, G extends Getters<S>>(store: Store<S, A, G>, options?: UseStoreOptions): Snapshot<S & GettersReturnType<G> & A>;
|
|
43
|
+
}): Snapshot<S & GettersReturnType<G> & A>;
|
|
45
44
|
//#endregion
|
|
46
45
|
//#region src/utils.d.ts
|
|
47
|
-
declare function storeToState<S extends object, K extends keyof S>(store: Store<S>, key: K
|
|
48
|
-
|
|
46
|
+
declare function storeToState<S extends object, K extends keyof S>(store: Store<S>, key: K, options?: {
|
|
47
|
+
sync?: boolean;
|
|
48
|
+
}): [S[K], Dispatch<SetStateAction<S[K]>>];
|
|
49
|
+
declare function storeToStates<S extends object>(store: Store<S>, options?: {
|
|
50
|
+
sync?: boolean;
|
|
51
|
+
}): { [K in keyof S]: [S[K], Dispatch<SetStateAction<S[K]>>] };
|
|
49
52
|
//#endregion
|
|
50
53
|
//#region src/index.d.ts
|
|
51
54
|
declare const _default: {
|
|
52
55
|
use: typeof use;
|
|
53
56
|
};
|
|
54
57
|
//#endregion
|
|
55
|
-
export { Actions, ActionsOmitThisParameter, ActionsTree, Getters, GettersReturnType, Patch, Plugin, PluginContext, Signal, Store, StoreDefine, StoreDefineOptions, StoreOptions, Subscribe, SubscribeKey,
|
|
58
|
+
export { Actions, ActionsOmitThisParameter, ActionsTree, Getters, GettersReturnType, Patch, Plugin, PluginContext, Signal, Store, StoreDefine, StoreDefineOptions, StoreOptions, Subscribe, SubscribeKey, _default as default, defineStore, plugins, storeToState, storeToStates, use, useStore };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{proxy as e,ref as t,subscribe as n,useSnapshot as r}from"valtio";import{createElement as i}from"react";import{subscribeKey as a}from"valtio/utils";const o=e([]);function s(e){o.push(e)}function c(s){let c=typeof s.state==`function`?s.state():s.state,u=s.getters||{},d=s.actions||{},f=e(c),p={},m={},h=new WeakSet;for(let e in d)p[e]=t(d[e].bind(f)),f[e]=p[e];for(let e in u)l(f,e,()=>u[e].call(f)),l(m,e,()=>f[e]);function g(e){return n(f,t=>e(f,t))}function _(e,t){return a(f,e,e=>t(e),!0)}function v(e){typeof e==`function`?e(f):Object.assign(f,e)}function y(e){return i(()=>e(r(f)))}function b(e){o.push(e),C(e)}let x={$subscribe:g,$subscribeKey:_,$patch:v,$state:f,$actions:p,$getters:m,$signal:y,use:b},S=new Proxy(x,{get(e,t){return t in p?p[t]:t in e?e[t]:f[t]},has(e,t){return t in e||t in p||t in f},set(e,t,n){return t in f?f[t]=n:e[t]=n,!0}});function C(e){h.has(e)||(h.add(e),e({store:S,options:s}))}for(let e of o)C(e);return n(o,()=>{for(let e of o)C(e)}),S}function l(e,t,n){Object.defineProperty(e,t,{get:n,enumerable:!0})}function u(e,t){return r(e.$state,t)}function d(e,t){let
|
|
1
|
+
import{proxy as e,ref as t,subscribe as n,useSnapshot as r}from"valtio";import{createElement as i}from"react";import{subscribeKey as a}from"valtio/utils";const o=e([]);function s(e){o.push(e)}function c(s){let c=typeof s.state==`function`?s.state():s.state,u=s.getters||{},d=s.actions||{},f=e(c),p={},m={},h=new WeakSet;for(let e in d)p[e]=t(d[e].bind(f)),f[e]=p[e];for(let e in u)l(f,e,()=>u[e].call(f)),l(m,e,()=>f[e]);function g(e){return n(f,t=>e(f,t))}function _(e,t){return a(f,e,e=>t(e),!0)}function v(e){typeof e==`function`?e(f):Object.assign(f,e)}function y(e){return i(()=>e(r(f)))}function b(e){o.push(e),C(e)}let x={$subscribe:g,$subscribeKey:_,$patch:v,$state:f,$actions:p,$getters:m,$signal:y,use:b},S=new Proxy(x,{get(e,t){return t in p?p[t]:t in e?e[t]:f[t]},has(e,t){return t in e||t in p||t in f},set(e,t,n){return t in f?f[t]=n:e[t]=n,!0}});function C(e){h.has(e)||(h.add(e),e({store:S,options:s}))}for(let e of o)C(e);return n(o,()=>{for(let e of o)C(e)}),S}function l(e,t,n){Object.defineProperty(e,t,{get:n,enumerable:!0})}function u(e,t){return r(e.$state,t)}function d(e,t,n){let r=u(e,n);function i(n){typeof n==`function`?e.$patch(e=>{e[t]=n(e[t])}):e.$patch(e=>{e[t]=n})}return[r[t],i]}function f(e,t){return Object.fromEntries(Object.keys(e.$state).map(n=>[n,d(e,n,t)]))}var p={use:s};export{p as default,c as defineStore,o as plugins,d as storeToState,f as storeToStates,s as use,u as useStore};
|
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { PersistentMountOptions,
|
|
2
|
-
export { PersistentMountOptions,
|
|
1
|
+
import { PersistentMountOptions, persist } from "./persist/index.mjs";
|
|
2
|
+
export { PersistentMountOptions, persist };
|
|
@@ -8,9 +8,6 @@ interface PersistentMountOptions {
|
|
|
8
8
|
*/
|
|
9
9
|
hydrate?: boolean;
|
|
10
10
|
}
|
|
11
|
-
interface StorePersistentOptions {
|
|
12
|
-
mount: () => void;
|
|
13
|
-
}
|
|
14
11
|
declare function persist({
|
|
15
12
|
hydrate
|
|
16
13
|
}?: PersistentMountOptions): Plugin;
|
|
@@ -21,4 +18,4 @@ declare module 'valtio-define' {
|
|
|
21
18
|
interface StoreOptions extends PersistentStore {}
|
|
22
19
|
}
|
|
23
20
|
//#endregion
|
|
24
|
-
export { PersistentMountOptions,
|
|
21
|
+
export { PersistentMountOptions, persist };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{subscribe as e}from"valtio";import{get as t,set as n}from"@hairy/utils";import{destr as r}from"destr";import{generateStructureId as i}from"structure-id";function a({hydrate:a=!0}={}){return o=>{let{persist:s,getters:c}=o.options,{$state:l}=o.store;if(
|
|
1
|
+
import{subscribe as e}from"valtio";import{get as t,set as n}from"@hairy/utils";import{destr as r}from"destr";import{generateStructureId as i}from"structure-id";function a({hydrate:a=!0}={}){return o=>{let{persist:s,getters:c}=o.options,{$state:l}=o.store;if(o.store.$persist?.unmount?.(),!s)return;let u=s===!0?{}:s,d=u.key||i(l),f=u.storage??(typeof localStorage<`u`?localStorage:void 0);if(!f?.getItem||!f?.setItem)return;let p=o.store.$persist?.meta??{mounted:!1,hydrated:!1};function m(e){let t=r(e);t&&typeof t==`object`&&(Object.keys(c||{}).forEach(e=>Reflect.deleteProperty(t,e)),Object.assign(l,t)),p.hydrated=!0}function h(){p.mounted=!0;let e=f.getItem(d);e instanceof Promise?e.then(m):m(e)}function g(){p.unsubscribe?.(),p.unsubscribe=void 0}function _(){g(),p.unsubscribe=e(l,()=>{if(!p.hydrated)return;let e=(u.paths||Object.keys(l)).reduce((e,r)=>n(e,r,t(l,r)),{});f.setItem(d,JSON.stringify(e))})}o.store.$persist={mount:h,unmount:g,meta:p},a&&!p.mounted&&h(),_()}}export{a as persist};
|
|
@@ -12,10 +12,17 @@ interface PersistentOptions<S extends object> {
|
|
|
12
12
|
storage?: Storage;
|
|
13
13
|
paths?: DeepKeys<S>[];
|
|
14
14
|
}
|
|
15
|
+
interface PersistentMeta {
|
|
16
|
+
mounted: boolean;
|
|
17
|
+
hydrated: boolean;
|
|
18
|
+
unsubscribe?: () => void;
|
|
19
|
+
}
|
|
15
20
|
interface PersistentStore {
|
|
16
21
|
$persist: {
|
|
17
22
|
mount: () => void;
|
|
23
|
+
unmount: () => void;
|
|
24
|
+
meta: PersistentMeta;
|
|
18
25
|
};
|
|
19
26
|
}
|
|
20
27
|
//#endregion
|
|
21
|
-
export { DeepKeys, PersistentOptions, PersistentStore, Storage };
|
|
28
|
+
export { DeepKeys, PersistentMeta, PersistentOptions, PersistentStore, Storage };
|
package/package.json
CHANGED
package/README.OLD.md
DELETED
|
@@ -1,391 +0,0 @@
|
|
|
1
|
-
# valtio-define
|
|
2
|
-
|
|
3
|
-
[![npm version][npm-version-src]][npm-version-href]
|
|
4
|
-
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
5
|
-
[![bundle][bundle-src]][bundle-href]
|
|
6
|
-
[![JSDocs][jsdocs-src]][jsdocs-href]
|
|
7
|
-
[![coverage][coverage-src]][coverage-href]
|
|
8
|
-
[![License][license-src]][license-href]
|
|
9
|
-
|
|
10
|
-
⚡ Quickly create a fully functional and robust [Valtio](https://valtio.dev) factory
|
|
11
|
-
|
|
12
|
-
## Installation
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
pnpm add valtio-define
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Usage
|
|
19
|
-
|
|
20
|
-
### Basic Store
|
|
21
|
-
|
|
22
|
-
Create a reactive store with state and actions. The store provides a simple and intuitive API for managing state in React applications, built on top of Valtio.
|
|
23
|
-
|
|
24
|
-
```tsx
|
|
25
|
-
import { defineStore, useStore } from 'valtio-define'
|
|
26
|
-
|
|
27
|
-
const store = defineStore({
|
|
28
|
-
state: () => ({ count: 0 }),
|
|
29
|
-
actions: {
|
|
30
|
-
increment() {
|
|
31
|
-
this.count++
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
function Counter() {
|
|
37
|
-
const { count } = useStore(store)
|
|
38
|
-
return (
|
|
39
|
-
<div>
|
|
40
|
-
<button onClick={store.increment}>Increment</button>
|
|
41
|
-
<div>{count}</div>
|
|
42
|
-
</div>
|
|
43
|
-
)
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### With Getters
|
|
48
|
-
|
|
49
|
-
Getters are computed properties that automatically update when their dependencies change. They provide a clean way to derive state without manually tracking dependencies.
|
|
50
|
-
|
|
51
|
-
```tsx
|
|
52
|
-
const store = defineStore({
|
|
53
|
-
state: () => ({ count: 0 }),
|
|
54
|
-
getters: {
|
|
55
|
-
doubled() {
|
|
56
|
-
return this.count * 2
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
actions: {
|
|
60
|
-
increment() {
|
|
61
|
-
this.count++
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
function Counter() {
|
|
67
|
-
const state = useStore(store)
|
|
68
|
-
return (
|
|
69
|
-
<div>
|
|
70
|
-
<div>
|
|
71
|
-
Count:
|
|
72
|
-
{state.count}
|
|
73
|
-
</div>
|
|
74
|
-
<div>
|
|
75
|
-
Doubled:
|
|
76
|
-
{state.doubled}
|
|
77
|
-
</div>
|
|
78
|
-
<button onClick={store.increment}>Increment</button>
|
|
79
|
-
</div>
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### Persistence
|
|
85
|
-
|
|
86
|
-
The persistence plugin allows you to persist store state to storage (e.g., localStorage).
|
|
87
|
-
|
|
88
|
-
First, register the persist plugin:
|
|
89
|
-
|
|
90
|
-
```tsx
|
|
91
|
-
import valtio from 'valtio-define'
|
|
92
|
-
import { persist } from 'valtio-define/plugins'
|
|
93
|
-
|
|
94
|
-
// Register the persist plugin globally
|
|
95
|
-
valtio.use(persist())
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Then use it in your store:
|
|
99
|
-
|
|
100
|
-
```tsx
|
|
101
|
-
import { defineStore } from 'valtio-define'
|
|
102
|
-
|
|
103
|
-
const store = defineStore({
|
|
104
|
-
state: () => ({ count: 0 }),
|
|
105
|
-
actions: {
|
|
106
|
-
increment() {
|
|
107
|
-
this.count++
|
|
108
|
-
},
|
|
109
|
-
},
|
|
110
|
-
persist: {
|
|
111
|
-
key: 'my-store',
|
|
112
|
-
storage: localStorage,
|
|
113
|
-
paths: ['count'], // Only persist 'count', or omit to persist all state
|
|
114
|
-
},
|
|
115
|
-
})
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
If `persist` is `true`, it will use `structure-id` to generate a unique key for the store automatically.
|
|
119
|
-
|
|
120
|
-
```tsx
|
|
121
|
-
const store = defineStore({
|
|
122
|
-
state: () => ({ count: 0 }),
|
|
123
|
-
persist: true, // Auto-generates key using structure-id
|
|
124
|
-
})
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
You can pass `hydrate` when registering the plugin (default `true`). When `true`, state is hydrated from storage as soon as the store is created. Set `hydrate: false` when you need to avoid running persistence during server-side rendering, and manually mount persist in your App entry instead:
|
|
128
|
-
|
|
129
|
-
```tsx
|
|
130
|
-
// Register with hydrate: false
|
|
131
|
-
store.use(persist({ hydrate: false }))
|
|
132
|
-
|
|
133
|
-
// In your App (client entry), after store is used:
|
|
134
|
-
useEffect(() => store.$persist.mount(), [])
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Subscribe to Changes
|
|
138
|
-
|
|
139
|
-
```tsx
|
|
140
|
-
const store = defineStore({
|
|
141
|
-
state: () => ({ count: 0 }),
|
|
142
|
-
actions: {
|
|
143
|
-
increment() {
|
|
144
|
-
this.count++
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
// Subscribe to state changes
|
|
150
|
-
const unsubscribe = store.$subscribe((state) => {
|
|
151
|
-
console.log('State changed:', state)
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
// Subscribe to specific key changes
|
|
155
|
-
const unsubscribeKey = store.$subscribeKey('count', (value) => {
|
|
156
|
-
console.log('Count changed:', value)
|
|
157
|
-
})
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Patch State
|
|
161
|
-
|
|
162
|
-
```tsx
|
|
163
|
-
// Patch with object
|
|
164
|
-
store.$patch({ count: 10 })
|
|
165
|
-
|
|
166
|
-
// Patch with function
|
|
167
|
-
store.$patch((state) => {
|
|
168
|
-
state.count += 5
|
|
169
|
-
})
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### Signal (JSX Component)
|
|
173
|
-
|
|
174
|
-
```tsx
|
|
175
|
-
function App() {
|
|
176
|
-
return (
|
|
177
|
-
<div>
|
|
178
|
-
Count:
|
|
179
|
-
{' '}
|
|
180
|
-
{store.$signal(state => state.count)}
|
|
181
|
-
</div>
|
|
182
|
-
)
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### Store to State Hooks
|
|
187
|
-
|
|
188
|
-
Convert store state to React hooks similar to `useState`. This provides a more React-idiomatic way to access and update store state.
|
|
189
|
-
|
|
190
|
-
#### `storeToState(store, key)`
|
|
191
|
-
|
|
192
|
-
Returns a tuple `[state, setter]` for a single store key, similar to React's `useState`.
|
|
193
|
-
|
|
194
|
-
```tsx
|
|
195
|
-
import { defineStore, storeToState } from 'valtio-define'
|
|
196
|
-
|
|
197
|
-
const store = defineStore({
|
|
198
|
-
state: { count: 0, name: 'test' },
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
function Counter() {
|
|
202
|
-
const [count, setCount] = storeToState(store, 'count')
|
|
203
|
-
const [name, setName] = storeToState(store, 'name')
|
|
204
|
-
|
|
205
|
-
return (
|
|
206
|
-
<div>
|
|
207
|
-
<button onClick={() => setCount(count + 1)}>Increment</button>
|
|
208
|
-
<button onClick={() => setCount(prev => prev + 1)}>Increment (functional)</button>
|
|
209
|
-
<div>
|
|
210
|
-
Count:
|
|
211
|
-
{count}
|
|
212
|
-
</div>
|
|
213
|
-
<div>
|
|
214
|
-
Name:
|
|
215
|
-
{name}
|
|
216
|
-
</div>
|
|
217
|
-
</div>
|
|
218
|
-
)
|
|
219
|
-
}
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
**Parameters:**
|
|
223
|
-
- `store`: Store instance created by `defineStore`
|
|
224
|
-
- `key`: Key of the state property to access
|
|
225
|
-
|
|
226
|
-
**Returns:** `[state, setter]` tuple where:
|
|
227
|
-
- `state`: Current value of the state property
|
|
228
|
-
- `setter`: Function to update the state (accepts value or updater function)
|
|
229
|
-
|
|
230
|
-
#### `storeToStates(store)`
|
|
231
|
-
|
|
232
|
-
Returns an object with all store keys mapped to `[state, setter]` tuples.
|
|
233
|
-
|
|
234
|
-
```tsx
|
|
235
|
-
function Component() {
|
|
236
|
-
const {
|
|
237
|
-
count: [count, setCount],
|
|
238
|
-
name: [name, setName],
|
|
239
|
-
user: [user, setUser],
|
|
240
|
-
} = storeToStates(store)
|
|
241
|
-
|
|
242
|
-
return (
|
|
243
|
-
<div>
|
|
244
|
-
<button onClick={() => setCount(count + 1)}>Increment</button>
|
|
245
|
-
<div>
|
|
246
|
-
Count:
|
|
247
|
-
{count}
|
|
248
|
-
</div>
|
|
249
|
-
<div>
|
|
250
|
-
Name:
|
|
251
|
-
{name}
|
|
252
|
-
</div>
|
|
253
|
-
<div>
|
|
254
|
-
User:
|
|
255
|
-
{user.name}
|
|
256
|
-
</div>
|
|
257
|
-
</div>
|
|
258
|
-
)
|
|
259
|
-
}
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
**Parameters:**
|
|
263
|
-
- `store`: Store instance created by `defineStore`
|
|
264
|
-
|
|
265
|
-
**Returns:** Object where each key maps to a `[state, setter]` tuple
|
|
266
|
-
|
|
267
|
-
## API
|
|
268
|
-
|
|
269
|
-
### `defineStore(store)`
|
|
270
|
-
|
|
271
|
-
Creates a store with state, actions, and getters.
|
|
272
|
-
|
|
273
|
-
**Parameters:**
|
|
274
|
-
- `store.state`: Initial state object or factory function
|
|
275
|
-
- `store.actions`: Object containing action methods
|
|
276
|
-
- `store.getters`: Object containing getter methods
|
|
277
|
-
- `store.persist`: Persistence plugin configuration (boolean or object) - see [Persistence Plugin](#persistence)
|
|
278
|
-
|
|
279
|
-
**Returns:** Store instance with reactive state and actions
|
|
280
|
-
|
|
281
|
-
### `useStore(store)`
|
|
282
|
-
|
|
283
|
-
React hook that returns a snapshot of the store state.
|
|
284
|
-
|
|
285
|
-
**Parameters:**
|
|
286
|
-
- `store`: Store instance created by `defineStore`
|
|
287
|
-
|
|
288
|
-
**Returns:** Snapshot of the store state
|
|
289
|
-
|
|
290
|
-
### `storeToState(store, key)`
|
|
291
|
-
|
|
292
|
-
React hook that returns a `[state, setter]` tuple for a single store key, similar to React's `useState`.
|
|
293
|
-
|
|
294
|
-
**Parameters:**
|
|
295
|
-
- `store`: Store instance created by `defineStore`
|
|
296
|
-
- `key`: Key of the state property to access
|
|
297
|
-
|
|
298
|
-
**Returns:** `[state, setter]` tuple where:
|
|
299
|
-
- `state`: Current value of the state property
|
|
300
|
-
- `setter`: Function to update the state (accepts value or updater function like `setState(value)` or `setState(prev => newValue)`)
|
|
301
|
-
|
|
302
|
-
### `storeToStates(store)`
|
|
303
|
-
|
|
304
|
-
React hook that returns an object with all store keys mapped to `[state, setter]` tuples.
|
|
305
|
-
|
|
306
|
-
**Parameters:**
|
|
307
|
-
- `store`: Store instance created by `defineStore`
|
|
308
|
-
|
|
309
|
-
**Returns:** Object where each key maps to a `[state, setter]` tuple, preserving the correct type for each property
|
|
310
|
-
|
|
311
|
-
### Plugins
|
|
312
|
-
|
|
313
|
-
Plugins allow you to extend store functionality. You can use plugins globally or per-store.
|
|
314
|
-
|
|
315
|
-
#### Global Plugin Registration
|
|
316
|
-
|
|
317
|
-
```tsx
|
|
318
|
-
import valtio from 'valtio-define'
|
|
319
|
-
import { persist } from 'valtio-define/plugins'
|
|
320
|
-
|
|
321
|
-
// Register plugin globally - applies to all stores
|
|
322
|
-
valtio.use(persist())
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
#### Per-Store Plugin Registration
|
|
326
|
-
|
|
327
|
-
```tsx
|
|
328
|
-
import { defineStore } from 'valtio-define'
|
|
329
|
-
import { persist } from 'valtio-define/plugins'
|
|
330
|
-
|
|
331
|
-
const store = defineStore({
|
|
332
|
-
state: () => ({ count: 0 }),
|
|
333
|
-
})
|
|
334
|
-
|
|
335
|
-
// Register plugin for this specific store
|
|
336
|
-
store.use(persist())
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
#### Creating Custom Plugins
|
|
340
|
-
|
|
341
|
-
```tsx
|
|
342
|
-
import type { Plugin } from 'valtio-define'
|
|
343
|
-
|
|
344
|
-
function myPlugin() {
|
|
345
|
-
({ store, options }: PluginContext) => {
|
|
346
|
-
// Access store methods
|
|
347
|
-
store.$subscribe((state) => {
|
|
348
|
-
console.log('State changed:', state)
|
|
349
|
-
})
|
|
350
|
-
|
|
351
|
-
// Access store options
|
|
352
|
-
if (options.someOption) {
|
|
353
|
-
// Do something
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
declare module 'valtio-define' {
|
|
359
|
-
export interface StoreDefine<S extends object, A extends ActionsTree, G extends Getters<any>> {
|
|
360
|
-
myPlugin?: {
|
|
361
|
-
someOption?: boolean
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
// Use the plugin
|
|
367
|
-
use(myPlugin())
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
**Plugin Context:**
|
|
371
|
-
- `context.store`: The store instance with all methods (`$state`, `$patch`, `$subscribe`, etc.)
|
|
372
|
-
- `context.options`: The original store definition options
|
|
373
|
-
|
|
374
|
-
## License
|
|
375
|
-
|
|
376
|
-
[MIT](./LICENSE) License © [Hairyf](https://github.com/hairyf)
|
|
377
|
-
|
|
378
|
-
<!-- Badges -->
|
|
379
|
-
|
|
380
|
-
[npm-version-src]: https://img.shields.io/npm/v/valtio-define?style=flat&colorA=080f12&colorB=1fa669
|
|
381
|
-
[npm-version-href]: https://npmjs.com/package/valtio-define
|
|
382
|
-
[npm-downloads-src]: https://img.shields.io/npm/dm/valtio-define?style=flat&colorA=080f12&colorB=1fa669
|
|
383
|
-
[npm-downloads-href]: https://npmjs.com/package/valtio-define
|
|
384
|
-
[bundle-src]: https://img.shields.io/bundlephobia/minzip/valtio-define?style=flat&colorA=080f12&colorB=1fa669&label=minzip
|
|
385
|
-
[bundle-href]: https://bundlephobia.com/result?p=valtio-define
|
|
386
|
-
[license-src]: https://img.shields.io/github/license/hairyf/valtio-define.svg?style=flat&colorA=080f12&colorB=1fa669
|
|
387
|
-
[license-href]: https://github.com/hairyf/valtio-define/blob/main/LICENSE
|
|
388
|
-
[jsdocs-src]: https://img.shields.io/badge/jsdocs-reference-080f12?style=flat&colorA=080f12&colorB=1fa669
|
|
389
|
-
[jsdocs-href]: https://www.jsdocs.io/package/valtio-define
|
|
390
|
-
[coverage-src]: https://codecov.io/gh/hairyf/valtio-define/graph/badge.svg?token=PG5YIEEEHJ
|
|
391
|
-
[coverage-href]: https://codecov.io/gh/hairyf/valtio-define
|