valtio-define 1.3.3 → 1.4.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 CHANGED
@@ -124,7 +124,7 @@ Save and restore your store state using the `persist` plugin.
124
124
 
125
125
  ### Manual Hydration (SSR Friendly)
126
126
 
127
- To avoid hydration mismatches during Server-Side Rendering, disable automatic hydration and mount it in a `useEffect`.
127
+ To avoid hydration mismatches during Server-Side Rendering, disable automatic hydration and rehydrate it in a `useEffect`.
128
128
 
129
129
  ```tsx
130
130
  // Register with hydrate disabled
@@ -132,7 +132,7 @@ store.use(persist({ hydrate: false }))
132
132
 
133
133
  // In your Client Entry / App Root
134
134
  useEffect(() => {
135
- store.$persist.mount()
135
+ store.$persist.rehydrate()
136
136
  }, [])
137
137
  ```
138
138
 
@@ -224,6 +224,11 @@ valtio.use(myPlugin())
224
224
  // Local
225
225
  const store = defineStore({ /* ... */ })
226
226
  store.use(myPlugin())
227
+
228
+ // Local options
229
+ const store = defineStore({
230
+ use: [myPlugin()],
231
+ })
227
232
  ```
228
233
 
229
234
  ### Creating a Custom Plugin
package/dist/index.mjs CHANGED
@@ -1 +1,152 @@
1
- import{proxy as e,useSnapshot as t}from"valtio";import{batch as n}from"valtio-reactive";import{subscribeKey as r}from"valtio/utils";import{proxy as i,ref as a,subscribe as o}from"valtio/vanilla";const s=e([]);function c(e){s.push(e)}function l(e){let t=typeof e.state==`function`?e.state():e.state,c=e.getters||{},l=e.actions||{},d=i(t),f={},p=i({}),m=new WeakSet,h;for(let e of Object.keys(c))u(d,e,c[e].bind(d),{enumerable:!1}),u(p,e,()=>d[e]);for(let e of Object.keys(l))f[e]=a(l[e].bind(d)),u(d,e,()=>f[e],{enumerable:!1});function g(e){return o(d,t=>e(d,t))}function _(e,t){return r(d,e,e=>t(e),!0)}function v(e){typeof e==`function`?n(()=>e(d)):Object.assign(d,e)}function y(){h?.()}function b(e){C(e)}let x={$subscribe:g,$subscribeKey:_,$patch:v,$state:d,$actions:f,$getters:p,$dispose:y,use:b},S=new Proxy(x,{get(e,t){return t in f?f[t]:t in e?e[t]:d[t]},has(e,t){return t in e||t in f||t in d},set(e,t,n){return t in d?d[t]=n:e[t]=n,!0}});function C(t){m.has(t)||(m.add(t),t({store:S,options:e}))}for(let e of s)C(e);return h=o(s,()=>{for(let e of s)C(e)}),S}function u(e,t,n,r){Object.defineProperty(e,t,{get:n,enumerable:!0,...r})}function d(e,n){return t(e.$state,n)}function f(e,n){return t(e.$getters,n)}function p(e,t,n){let r=d(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 m(e,t){return Object.fromEntries(Object.keys(e.$state).map(n=>[n,p(e,n,t)]))}const h={use:c};export{h as default,l as defineStore,s as plugins,p as storeToState,m as storeToStates,c as use,f as useGetters,d as useStore};
1
+ import { proxy, useSnapshot } from "valtio";
2
+ import { batch } from "valtio-reactive";
3
+ import { subscribeKey } from "valtio/utils";
4
+ import { proxy as proxy$1, ref, subscribe as subscribe$1 } from "valtio/vanilla";
5
+
6
+ //#region src/plugin.ts
7
+ const plugins = proxy([]);
8
+ function use(plugin) {
9
+ plugins.push(plugin);
10
+ }
11
+
12
+ //#endregion
13
+ //#region src/define.ts
14
+ /**
15
+ * @description Define a store
16
+ * @example
17
+ * ```tsx
18
+ * const store = defineStore({
19
+ * state: () => ({ count: 0 }),
20
+ * actions: {
21
+ * increment() {
22
+ * this.count++
23
+ * },
24
+ * },
25
+ * })
26
+ *
27
+ * store.increment()
28
+ * console.log(store.$state.count) // 1
29
+ *
30
+ * function Component() {
31
+ * const store = useStore(store)
32
+ * return (
33
+ * <div>
34
+ * <button onClick={store.increment}>Increment</button>
35
+ * <div>{store.count}</div>
36
+ * </div>
37
+ * )
38
+ * }
39
+ *
40
+ * ```
41
+ */
42
+ function defineStore(options) {
43
+ const state = typeof options.state === "function" ? options.state() : options.state;
44
+ const getters = options.getters || {};
45
+ const actions = options.actions || {};
46
+ const $state = proxy$1(state);
47
+ const $actions = {};
48
+ const $getters = proxy$1({});
49
+ const $plugins = /* @__PURE__ */ new WeakSet();
50
+ let unsub;
51
+ for (const key of Object.keys(getters)) {
52
+ defineProperty($state, key, getters[key].bind($state), { enumerable: false });
53
+ defineProperty($getters, key, () => $state[key]);
54
+ }
55
+ for (const key of Object.keys(actions)) {
56
+ $actions[key] = ref(actions[key].bind($state));
57
+ defineProperty($state, key, () => $actions[key], { enumerable: false });
58
+ }
59
+ function $subscribe(listener) {
60
+ return subscribe$1($state, (ops) => listener($state, ops));
61
+ }
62
+ function $subscribeKey(key, listener) {
63
+ return subscribeKey($state, key, (value) => listener(value), true);
64
+ }
65
+ function $patch(patch) {
66
+ typeof patch === "function" ? batch(() => patch($state)) : Object.assign($state, patch);
67
+ }
68
+ function $dispose() {
69
+ unsub?.();
70
+ }
71
+ function use(plugin) {
72
+ apply(plugin);
73
+ }
74
+ const base = {
75
+ $subscribe,
76
+ $subscribeKey,
77
+ $patch,
78
+ $state,
79
+ $actions,
80
+ $getters,
81
+ $dispose,
82
+ use
83
+ };
84
+ const store = new Proxy(base, {
85
+ get(target, prop) {
86
+ if (prop in $actions) return $actions[prop];
87
+ if (prop in target) return target[prop];
88
+ return $state[prop];
89
+ },
90
+ has(target, prop) {
91
+ return prop in target || prop in $actions || prop in $state;
92
+ },
93
+ set(target, prop, value) {
94
+ prop in $state ? $state[prop] = value : target[prop] = value;
95
+ return true;
96
+ }
97
+ });
98
+ function apply(plugin) {
99
+ if ($plugins.has(plugin)) return;
100
+ $plugins.add(plugin);
101
+ plugin({
102
+ store,
103
+ options
104
+ });
105
+ }
106
+ for (const plugin of plugins) apply(plugin);
107
+ unsub = subscribe$1(plugins, () => {
108
+ for (const plugin of plugins) apply(plugin);
109
+ });
110
+ return store;
111
+ }
112
+ function defineProperty(target, prop, getter, descriptor) {
113
+ Object.defineProperty(target, prop, {
114
+ get: getter,
115
+ enumerable: true,
116
+ ...descriptor
117
+ });
118
+ }
119
+
120
+ //#endregion
121
+ //#region src/hooks.ts
122
+ function useStore(store, options) {
123
+ return useSnapshot(store.$state, options);
124
+ }
125
+ function useGetters(store, options) {
126
+ return useSnapshot(store.$getters, options);
127
+ }
128
+
129
+ //#endregion
130
+ //#region src/utils.ts
131
+ function storeToState(store, key, options) {
132
+ const state = useStore(store, options);
133
+ function set(value) {
134
+ if (typeof value === "function") store.$patch((state) => {
135
+ state[key] = value(state[key]);
136
+ });
137
+ else store.$patch((state) => {
138
+ state[key] = value;
139
+ });
140
+ }
141
+ return [state[key], set];
142
+ }
143
+ function storeToStates(store, options) {
144
+ return Object.fromEntries(Object.keys(store.$state).map((key) => [key, storeToState(store, key, options)]));
145
+ }
146
+
147
+ //#endregion
148
+ //#region src/index.ts
149
+ const defaultExport = { use };
150
+
151
+ //#endregion
152
+ export { defaultExport as default, defineStore, plugins, storeToState, storeToStates, use, useGetters, useStore };
@@ -1 +1,4 @@
1
- import{persist as e}from"./persist/index.mjs";import{signal as t}from"./signal/index.mjs";export{e as persist,t as signal};
1
+ import { persist } from "./persist/index.mjs";
2
+ import { signal } from "./signal/index.mjs";
3
+
4
+ export { persist, signal };
@@ -1 +1,58 @@
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=new Set(Object.keys(c||{})),d=s===!0?{}:s,f=d.key||i(l),p=d.storage??(typeof localStorage<`u`?localStorage:void 0);if(!p?.getItem||!p?.setItem)return;let m=o.store.$persist?.meta??{mounted:!1,hydrated:!1};function h(e){let t=r(e);if(t&&typeof t==`object`){for(let e of Object.keys(t))u.has(e)&&delete t[e];Object.assign(l,t)}m.hydrated=!0}function g(){m.mounted=!0;let e=p.getItem(f);e instanceof Promise?e.then(h):h(e)}function _(){m.unsubscribe?.(),m.unsubscribe=void 0}function v(){_(),m.unsubscribe=e(l,()=>{if(!m.hydrated)return;let e=(d.paths||Object.keys(l)).filter(e=>!u.has(e)).reduce((e,r)=>n(e,r,t(l,r)),{});p.setItem(f,JSON.stringify(e))})}o.store.$persist={mount:g,unmount:_,meta:m},a&&!m.mounted&&g(),v()}}export{a as persist};
1
+ import { subscribe } from "valtio";
2
+ import { get, set } from "@hairy/utils";
3
+ import { destr } from "destr";
4
+ import { generateStructureId } from "structure-id";
5
+
6
+ //#region src/plugins/persist/index.ts
7
+ function persist({ hydrate = true } = {}) {
8
+ return (context) => {
9
+ const { persist, getters } = context.options;
10
+ const { $state } = context.store;
11
+ context.store.$persist?.dehydrate?.();
12
+ if (!persist) return;
13
+ const getterKeys = new Set(Object.keys(getters || {}));
14
+ const options = persist === true ? {} : persist;
15
+ const key = options.key || generateStructureId($state);
16
+ const storage = options.storage ?? (typeof localStorage !== "undefined" ? localStorage : void 0);
17
+ if (!storage?.getItem || !storage?.setItem) return;
18
+ const meta = context.store.$persist?.meta ?? {
19
+ mounted: false,
20
+ hydrated: false
21
+ };
22
+ function initialize(value) {
23
+ const data = destr(value);
24
+ if (data && typeof data === "object") {
25
+ for (const key of Object.keys(data)) getterKeys.has(key) && delete data[key];
26
+ Object.assign($state, data);
27
+ }
28
+ meta.hydrated = true;
29
+ }
30
+ function rehydrate() {
31
+ meta.mounted = true;
32
+ const value = storage.getItem(key);
33
+ value instanceof Promise ? value.then(initialize) : initialize(value);
34
+ }
35
+ function dehydrate() {
36
+ meta.unsubscribe?.();
37
+ meta.unsubscribe = void 0;
38
+ }
39
+ function watch() {
40
+ dehydrate();
41
+ meta.unsubscribe = subscribe($state, () => {
42
+ if (!meta.hydrated) return;
43
+ const statePaths = (options.paths || Object.keys($state)).filter((p) => !getterKeys.has(p)).reduce((acc, p) => set(acc, p, get($state, p)), {});
44
+ storage.setItem(key, JSON.stringify(statePaths));
45
+ });
46
+ }
47
+ context.store.$persist = {
48
+ rehydrate,
49
+ dehydrate,
50
+ meta
51
+ };
52
+ hydrate && !meta.mounted && rehydrate();
53
+ watch();
54
+ };
55
+ }
56
+
57
+ //#endregion
58
+ export { persist };
@@ -19,8 +19,8 @@ interface PersistentMeta {
19
19
  }
20
20
  interface PersistentStore {
21
21
  $persist: {
22
- mount: () => void;
23
- unmount: () => void;
22
+ rehydrate: () => void;
23
+ dehydrate: () => void;
24
24
  meta: PersistentMeta;
25
25
  };
26
26
  }
@@ -1 +1 @@
1
- export{};
1
+ export { };
@@ -1 +1,15 @@
1
- import{$ as e}from"valtio-signal";function t(){return t=>{function n(n){let r=e(t.store.$state);return n?n(r):r}t.store.$signal=n}}export{t as signal};
1
+ import { $ } from "valtio-signal";
2
+
3
+ //#region src/plugins/signal/index.ts
4
+ function signal() {
5
+ return (context) => {
6
+ function $signal(fn) {
7
+ const attached = $(context.store.$state);
8
+ return fn ? fn(attached) : attached;
9
+ }
10
+ context.store.$signal = $signal;
11
+ };
12
+ }
13
+
14
+ //#endregion
15
+ export { signal };
@@ -1 +1,3 @@
1
- import{Fragment as e,jsx as t,jsxDEV as n,jsxs as r}from"./jsx-runtime.mjs";export{e as Fragment,t as jsx,n as jsxDEV,r as jsxs};
1
+ import { Fragment, jsx, jsxDEV, jsxs } from "./jsx-runtime.mjs";
2
+
3
+ export { Fragment, jsx, jsxDEV, jsxs };
@@ -1 +1,3 @@
1
- import{Fragment as e,jsx as t,jsxDEV as n,jsxs as r}from"valtio-signal/jsx-runtime";export{e as Fragment,t as jsx,n as jsxDEV,r as jsxs};
1
+ import { Fragment, jsx, jsxDEV, jsxs } from "valtio-signal/jsx-runtime";
2
+
3
+ export { Fragment, jsx, jsxDEV, jsxs };
@@ -1 +1 @@
1
- export{};
1
+ export { };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "valtio-define",
3
3
  "type": "module",
4
- "version": "1.3.3",
4
+ "version": "1.4.0",
5
5
  "description": "⚡quickly create a fully functional and robust Valtio factory",
6
6
  "author": "Hairyf <wwu710632@gmail.com>",
7
7
  "license": "MIT",