valtio-define 0.1.0 → 0.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/LICENSE.md CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025-PRESENT Hairyf <wwu710632@gmail.com>
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025-PRESENT Hairyf <wwu710632@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,253 +1,253 @@
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
- [![License][license-src]][license-href]
8
-
9
- ⚡ Quickly create a fully functional and robust Valtio factory
10
-
11
- ## Installation
12
-
13
- ```bash
14
- npm install valtio-define
15
- ```
16
-
17
- ## Usage
18
-
19
- ### Basic Store
20
-
21
- ```tsx
22
- import { defineStore, useStore } from 'valtio-define'
23
-
24
- const store = defineStore({
25
- state: () => ({ count: 0 }),
26
- actions: {
27
- increment() {
28
- this.count++
29
- },
30
- },
31
- })
32
-
33
- function Counter() {
34
- const state = useStore(store)
35
- return (
36
- <div>
37
- <button onClick={store.increment}>Increment</button>
38
- <div>{state.count}</div>
39
- </div>
40
- )
41
- }
42
- ```
43
-
44
- ### With Getters
45
-
46
- ```tsx
47
- const store = defineStore({
48
- state: () => ({ count: 0 }),
49
- getters: {
50
- doubled() {
51
- return this.count * 2
52
- },
53
- },
54
- actions: {
55
- increment() {
56
- this.count++
57
- },
58
- },
59
- })
60
-
61
- function Counter() {
62
- const state = useStore(store)
63
- return (
64
- <div>
65
- <div>
66
- Count:
67
- {state.count}
68
- </div>
69
- <div>
70
- Doubled:
71
- {state.doubled}
72
- </div>
73
- <button onClick={store.increment}>Increment</button>
74
- </div>
75
- )
76
- }
77
- ```
78
-
79
- ### Async Actions with Status
80
-
81
- ```tsx
82
- import { defineStore, useStatus, useStore } from 'valtio-define'
83
-
84
- const store = defineStore({
85
- state: () => ({ data: null }),
86
- actions: {
87
- async fetchData() {
88
- const response = await fetch('/api/data')
89
- this.data = await response.json()
90
- },
91
- },
92
- })
93
-
94
- function DataComponent() {
95
- const state = useStore(store)
96
- const status = useStatus(store)
97
-
98
- return (
99
- <div>
100
- {status.loading && <div> Store all actions are loading...</div>}
101
- {status.finished && <div> Store all actions are finished...</div>}
102
- {status.error && <div> Store all actions are error...</div>}
103
-
104
- {status.fetchData.finished && <div> Data fetched successfully...</div>}
105
- {status.fetchData.error && (
106
- <div>
107
- {' '}
108
- Error fetching data:
109
- {status.fetchData.error.message}
110
- </div>
111
- )}
112
- {state.data && <div>{JSON.stringify(state.data)}</div>}
113
- <button onClick={store.fetchData}>Fetch Data</button>
114
- </div>
115
- )
116
- }
117
- ```
118
-
119
- ### Persistence
120
-
121
- ```tsx
122
- const store = defineStore(
123
- {
124
- state: () => ({ count: 0 }),
125
- actions: {
126
- increment() {
127
- this.count++
128
- },
129
- },
130
- },
131
- {
132
- persist: true // or { key: 'my-store', storage: localStorage, paths: ['count'] }
133
- }
134
- )
135
- ```
136
-
137
- If the persist is a boolean value, it will use `structure-id` to generate a unique key for the store.
138
-
139
- ### Subscribe to Changes
140
-
141
- ```tsx
142
- const store = defineStore({
143
- state: () => ({ count: 0 }),
144
- actions: {
145
- increment() {
146
- this.count++
147
- },
148
- },
149
- })
150
-
151
- // Subscribe to state changes
152
- const unsubscribe = store.$subscribe((state) => {
153
- console.log('State changed:', state)
154
- })
155
-
156
- // Subscribe to status changes
157
- const unsubscribeStatus = store.$subscribe.status((status) => {
158
- console.log('Status changed:', status)
159
- })
160
- ```
161
-
162
- ### Patch State
163
-
164
- ```tsx
165
- // Patch with object
166
- store.$patch({ count: 10 })
167
-
168
- // Patch with function
169
- store.$patch((state) => {
170
- state.count += 5
171
- })
172
- ```
173
-
174
- ### Signal (JSX Component)
175
-
176
- ```tsx
177
- function App() {
178
- return (
179
- <div>
180
- {store.$signal(state => (
181
- <div>
182
- Count:
183
- {state.count}
184
- </div>
185
- ))}
186
- {store.$signal.status(status => (
187
- status.loading && <div>Loading...</div>
188
- ))}
189
- </div>
190
- )
191
- }
192
- ```
193
-
194
- ## API
195
-
196
- ### `defineStore(store, options?)`
197
-
198
- Creates a store with state, actions, and getters.
199
-
200
- **Parameters:**
201
- - `store.state`: Initial state object or factory function
202
- - `store.actions`: Object containing action methods
203
- - `store.getters`: Object containing getter methods
204
- - `options.persist`: Persistence configuration (boolean or object)
205
-
206
- **Returns:** Store instance with reactive state and actions
207
-
208
- ### `useStore(store)`
209
-
210
- React hook that returns a snapshot of the store state.
211
-
212
- **Parameters:**
213
- - `store`: Store instance created by `defineStore`
214
-
215
- **Returns:** Snapshot of the store state
216
-
217
- ### `useStatus(store)`
218
-
219
- React hook that returns the status of all actions.
220
-
221
- **Parameters:**
222
- - `store`: Store instance created by `defineStore`
223
-
224
- **Returns:** Status object with loading, finished, and error states
225
-
226
- ### `proxyWithPersistent(initialObject, options?)`
227
-
228
- Creates a persistent proxy state.
229
-
230
- **Parameters:**
231
- - `initialObject`: Initial state object
232
- - `options.key`: Storage key (auto-generated if not provided)
233
- - `options.storage`: Storage instance (defaults to localStorage)
234
- - `options.paths`: Array of paths to persist (defaults to all)
235
-
236
- **Returns:** Persistent proxy state
237
-
238
- ## License
239
-
240
- [MIT](./LICENSE) License © [Hairyf](https://github.com/hairyf)
241
-
242
- <!-- Badges -->
243
-
244
- [npm-version-src]: https://img.shields.io/npm/v/valtio-define?style=flat&colorA=080f12&colorB=1fa669
245
- [npm-version-href]: https://npmjs.com/package/valtio-define
246
- [npm-downloads-src]: https://img.shields.io/npm/dm/valtio-define?style=flat&colorA=080f12&colorB=1fa669
247
- [npm-downloads-href]: https://npmjs.com/package/valtio-define
248
- [bundle-src]: https://img.shields.io/bundlephobia/minzip/valtio-define?style=flat&colorA=080f12&colorB=1fa669&label=minzip
249
- [bundle-href]: https://bundlephobia.com/result?p=valtio-define
250
- [license-src]: https://img.shields.io/github/license/hairyf/valtio-define.svg?style=flat&colorA=080f12&colorB=1fa669
251
- [license-href]: https://github.com/hairyf/valtio-define/blob/main/LICENSE
252
- [jsdocs-src]: https://img.shields.io/badge/jsdocs-reference-080f12?style=flat&colorA=080f12&colorB=1fa669
253
- [jsdocs-href]: https://www.jsdocs.io/package/valtio-define
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
+ [![License][license-src]][license-href]
8
+
9
+ ⚡ Quickly create a fully functional and robust Valtio factory
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install valtio-define
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ### Basic Store
20
+
21
+ ```tsx
22
+ import { defineStore, useStore } from 'valtio-define'
23
+
24
+ const store = defineStore({
25
+ state: () => ({ count: 0 }),
26
+ actions: {
27
+ increment() {
28
+ this.count++
29
+ },
30
+ },
31
+ })
32
+
33
+ function Counter() {
34
+ const state = useStore(store)
35
+ return (
36
+ <div>
37
+ <button onClick={store.increment}>Increment</button>
38
+ <div>{state.count}</div>
39
+ </div>
40
+ )
41
+ }
42
+ ```
43
+
44
+ ### With Getters
45
+
46
+ ```tsx
47
+ const store = defineStore({
48
+ state: () => ({ count: 0 }),
49
+ getters: {
50
+ doubled() {
51
+ return this.count * 2
52
+ },
53
+ },
54
+ actions: {
55
+ increment() {
56
+ this.count++
57
+ },
58
+ },
59
+ })
60
+
61
+ function Counter() {
62
+ const state = useStore(store)
63
+ return (
64
+ <div>
65
+ <div>
66
+ Count:
67
+ {state.count}
68
+ </div>
69
+ <div>
70
+ Doubled:
71
+ {state.doubled}
72
+ </div>
73
+ <button onClick={store.increment}>Increment</button>
74
+ </div>
75
+ )
76
+ }
77
+ ```
78
+
79
+ ### Async Actions with Status
80
+
81
+ ```tsx
82
+ import { defineStore, useStatus, useStore } from 'valtio-define'
83
+
84
+ const store = defineStore({
85
+ state: () => ({ data: null }),
86
+ actions: {
87
+ async fetchData() {
88
+ const response = await fetch('/api/data')
89
+ this.data = await response.json()
90
+ },
91
+ },
92
+ })
93
+
94
+ function DataComponent() {
95
+ const state = useStore(store)
96
+ const status = useStatus(store)
97
+
98
+ return (
99
+ <div>
100
+ {status.loading && <div> Store all actions are loading...</div>}
101
+ {status.finished && <div> Store all actions are finished...</div>}
102
+ {status.error && <div> Store all actions are error...</div>}
103
+
104
+ {status.fetchData.finished && <div> Data fetched successfully...</div>}
105
+ {status.fetchData.error && (
106
+ <div>
107
+ {' '}
108
+ Error fetching data:
109
+ {status.fetchData.error.message}
110
+ </div>
111
+ )}
112
+ {state.data && <div>{JSON.stringify(state.data)}</div>}
113
+ <button onClick={store.fetchData}>Fetch Data</button>
114
+ </div>
115
+ )
116
+ }
117
+ ```
118
+
119
+ ### Persistence
120
+
121
+ ```tsx
122
+ const store = defineStore(
123
+ {
124
+ state: () => ({ count: 0 }),
125
+ actions: {
126
+ increment() {
127
+ this.count++
128
+ },
129
+ },
130
+ },
131
+ {
132
+ persist: true // or { key: 'my-store', storage: localStorage, paths: ['count'] }
133
+ }
134
+ )
135
+ ```
136
+
137
+ If the persist is a boolean value, it will use `structure-id` to generate a unique key for the store.
138
+
139
+ ### Subscribe to Changes
140
+
141
+ ```tsx
142
+ const store = defineStore({
143
+ state: () => ({ count: 0 }),
144
+ actions: {
145
+ increment() {
146
+ this.count++
147
+ },
148
+ },
149
+ })
150
+
151
+ // Subscribe to state changes
152
+ const unsubscribe = store.$subscribe((state) => {
153
+ console.log('State changed:', state)
154
+ })
155
+
156
+ // Subscribe to status changes
157
+ const unsubscribeStatus = store.$subscribe.status((status) => {
158
+ console.log('Status changed:', status)
159
+ })
160
+ ```
161
+
162
+ ### Patch State
163
+
164
+ ```tsx
165
+ // Patch with object
166
+ store.$patch({ count: 10 })
167
+
168
+ // Patch with function
169
+ store.$patch((state) => {
170
+ state.count += 5
171
+ })
172
+ ```
173
+
174
+ ### Signal (JSX Component)
175
+
176
+ ```tsx
177
+ function App() {
178
+ return (
179
+ <div>
180
+ {store.$signal(state => (
181
+ <div>
182
+ Count:
183
+ {state.count}
184
+ </div>
185
+ ))}
186
+ {store.$signal.status(status => (
187
+ status.loading && <div>Loading...</div>
188
+ ))}
189
+ </div>
190
+ )
191
+ }
192
+ ```
193
+
194
+ ## API
195
+
196
+ ### `defineStore(store, options?)`
197
+
198
+ Creates a store with state, actions, and getters.
199
+
200
+ **Parameters:**
201
+ - `store.state`: Initial state object or factory function
202
+ - `store.actions`: Object containing action methods
203
+ - `store.getters`: Object containing getter methods
204
+ - `options.persist`: Persistence configuration (boolean or object)
205
+
206
+ **Returns:** Store instance with reactive state and actions
207
+
208
+ ### `useStore(store)`
209
+
210
+ React hook that returns a snapshot of the store state.
211
+
212
+ **Parameters:**
213
+ - `store`: Store instance created by `defineStore`
214
+
215
+ **Returns:** Snapshot of the store state
216
+
217
+ ### `useStatus(store)`
218
+
219
+ React hook that returns the status of all actions.
220
+
221
+ **Parameters:**
222
+ - `store`: Store instance created by `defineStore`
223
+
224
+ **Returns:** Status object with loading, finished, and error states
225
+
226
+ ### `proxyWithPersistent(initialObject, options?)`
227
+
228
+ Creates a persistent proxy state.
229
+
230
+ **Parameters:**
231
+ - `initialObject`: Initial state object
232
+ - `options.key`: Storage key (auto-generated if not provided)
233
+ - `options.storage`: Storage instance (defaults to localStorage)
234
+ - `options.paths`: Array of paths to persist (defaults to all)
235
+
236
+ **Returns:** Persistent proxy state
237
+
238
+ ## License
239
+
240
+ [MIT](./LICENSE) License © [Hairyf](https://github.com/hairyf)
241
+
242
+ <!-- Badges -->
243
+
244
+ [npm-version-src]: https://img.shields.io/npm/v/valtio-define?style=flat&colorA=080f12&colorB=1fa669
245
+ [npm-version-href]: https://npmjs.com/package/valtio-define
246
+ [npm-downloads-src]: https://img.shields.io/npm/dm/valtio-define?style=flat&colorA=080f12&colorB=1fa669
247
+ [npm-downloads-href]: https://npmjs.com/package/valtio-define
248
+ [bundle-src]: https://img.shields.io/bundlephobia/minzip/valtio-define?style=flat&colorA=080f12&colorB=1fa669&label=minzip
249
+ [bundle-href]: https://bundlephobia.com/result?p=valtio-define
250
+ [license-src]: https://img.shields.io/github/license/hairyf/valtio-define.svg?style=flat&colorA=080f12&colorB=1fa669
251
+ [license-href]: https://github.com/hairyf/valtio-define/blob/main/LICENSE
252
+ [jsdocs-src]: https://img.shields.io/badge/jsdocs-reference-080f12?style=flat&colorA=080f12&colorB=1fa669
253
+ [jsdocs-href]: https://www.jsdocs.io/package/valtio-define
package/dist/index.d.mts CHANGED
@@ -7,7 +7,7 @@ type ActionsOmitThisParameter<A extends Actions<any>> = { [K in keyof A]: (...ar
7
7
  interface Status {
8
8
  finished: boolean;
9
9
  loading: boolean;
10
- error: Error | null;
10
+ error?: Error;
11
11
  }
12
12
  type ActionsStatus<A extends Actions<any>> = Status & { [K in keyof A]: Status };
13
13
  type GettersReturnType<G extends Getters<any>> = { [K in keyof G]: ReturnType<G[K]> };
@@ -74,7 +74,7 @@ interface PersistentOptions {
74
74
  *
75
75
  * ```
76
76
  */
77
- declare function defineStore<S extends object, A extends Actions<S>, G extends Getters<S>>(store: StoreDefine<S, A, G>, options?: StoreOptions): Store<S, A, G>;
77
+ declare function defineStore<S extends object, A extends Actions<S>, G extends Getters<S>>(store: StoreDefine<S, A, G> & StoreOptions): Store<S, A, G>;
78
78
  //#endregion
79
79
  //#region src/persistent.d.ts
80
80
  declare function proxyWithPersistent<T extends object>(initialObject: T, options?: PersistentOptions): T;
@@ -83,6 +83,6 @@ declare function proxyWithPersistent<T extends object>(initialObject: T, options
83
83
  declare function useStatus<S extends object, A extends Actions<S>, G extends Getters<S>>(store: Store<S, A, G>): Snapshot<ActionsStatus<A>>;
84
84
  //#endregion
85
85
  //#region src/use-store.d.ts
86
- declare function useStore<S extends object, A extends Actions<S>, G extends Getters<S>>(store: Store<S, A, G>): Snapshot<S & GettersReturnType<G>>;
86
+ declare function useStore<S extends object, A extends Actions<S>, G extends Getters<S>>(store: Store<S, A, G>): Snapshot<S & GettersReturnType<G> & A>;
87
87
  //#endregion
88
88
  export { defineStore, proxyWithPersistent, useStatus, useStore };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createElement } from "react";
2
- import { proxy, subscribe, useSnapshot } from "valtio";
2
+ import { proxy, ref, subscribe, useSnapshot } from "valtio";
3
3
  import { jsonTryParse } from "@hairy/utils";
4
4
  import { generateStructureId } from "structure-id";
5
5
 
@@ -14,6 +14,7 @@ function track(action, status) {
14
14
  };
15
15
  const fulfilled = (value) => {
16
16
  status.finished = true;
17
+ if (status.error) delete status.error;
17
18
  done();
18
19
  return value;
19
20
  };
@@ -87,16 +88,16 @@ function proxyWithPersistent(initialObject, options = {}) {
87
88
  *
88
89
  * ```
89
90
  */
90
- function defineStore(store, options = {}) {
91
+ function defineStore(store) {
91
92
  const state = typeof store.state === "function" ? store.state() : store.state;
92
93
  const getters = store.getters || {};
93
94
  const actions = store.actions || {};
94
95
  const status = {};
95
96
  status.finished = false;
96
97
  status.loading = false;
97
- status.error = null;
98
+ status.error = void 0;
98
99
  const $status = proxy(status);
99
- const $state = options.persist ? proxyWithPersistent(state, options.persist === true ? {} : options.persist) : proxy(state);
100
+ const $state = store.persist ? proxyWithPersistent(state, store.persist === true ? {} : store.persist) : proxy(state);
100
101
  const $actions = {};
101
102
  const $getters = {};
102
103
  setupActions($state, actions, $actions, $status);
@@ -134,10 +135,13 @@ function setupActions($state, actions, $actions, $status) {
134
135
  $status[key] = {
135
136
  finished: false,
136
137
  loading: false,
137
- error: null
138
+ error: void 0
138
139
  };
139
140
  $actions[key] = track(actions[key].bind($state), $status[key]);
140
- Object.defineProperty($state, key, { get: () => $actions[key] });
141
+ Object.defineProperty($state, key, {
142
+ get: () => ref($actions[key]),
143
+ enumerable: false
144
+ });
141
145
  }
142
146
  }
143
147
  function setupGetters(state, $state, getters, $getters) {
@@ -162,7 +166,9 @@ function setupStatus($actions, $status) {
162
166
  enumerable: true
163
167
  });
164
168
  Object.defineProperty($status, "error", {
165
- get: () => Object.keys($actions).find((key) => $status[key].error),
169
+ get: () => {
170
+ return $status[Object.keys($actions).find((key) => $status[key].error) || ""]?.error;
171
+ },
166
172
  enumerable: true
167
173
  });
168
174
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "valtio-define",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.2.0",
5
5
  "description": "⚡quickly create a fully functional and robust Valtio factory",
6
6
  "author": "Hairyf <wwu710632@gmail.com>",
7
7
  "license": "MIT",
@@ -13,13 +13,15 @@
13
13
  "bugs": "https://github.com/hairyf/valtio-define/issues",
14
14
  "keywords": [],
15
15
  "sideEffects": false,
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
16
19
  "exports": {
17
20
  ".": "./dist/index.mjs",
18
21
  "./package.json": "./package.json"
19
22
  },
20
23
  "main": "./dist/index.mjs",
21
24
  "module": "./dist/index.mjs",
22
- "types": "./dist/index.d.mts",
23
25
  "files": [
24
26
  "dist"
25
27
  ],
@@ -58,6 +60,7 @@
58
60
  "lint-staged": {
59
61
  "*": "eslint --fix"
60
62
  },
63
+ "types": "./dist/index.d.mts",
61
64
  "scripts": {
62
65
  "build": "tsdown",
63
66
  "dev": "tsdown --watch",