zustand-lite 0.4.0 → 0.4.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 +2 -2
- package/dist/index.cjs +283 -3
- package/dist/index.d.cts +58 -37
- package/dist/index.d.ts +58 -37
- package/dist/index.js +244 -3
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -48,7 +48,6 @@ Thanks to **zustand‑lite**, you can move faster without sacrificing clarity or
|
|
|
48
48
|
- 🧩 **Optional middlewares**: Seamlessly add devtools and persist middleware layers.
|
|
49
49
|
- 🌱 **Chainable API**: create the store in a few simple composable steps.
|
|
50
50
|
- 👁 **Redux devtools labeling**: Built-in clear, traceable action labeling useful for debugging.
|
|
51
|
-
- 🧼 **No dependencies, only Zustand**: Keeps bundle size small and performance high.
|
|
52
51
|
|
|
53
52
|
---
|
|
54
53
|
|
|
@@ -371,7 +370,8 @@ You can enable the most useful middlewares:
|
|
|
371
370
|
- createPlugin function that will automatically infer types from the usage without the need of
|
|
372
371
|
specifying types yourself, avoiding repetitiveness.
|
|
373
372
|
- Ability to specify equality function for extended getters. It's possible now, but requires to
|
|
374
|
-
import hook from 'zustand' package, which is suboptimal **(available from version 3.0.0 with
|
|
373
|
+
import hook from 'zustand' package, which is suboptimal **(available from version 3.0.0 with
|
|
374
|
+
use() function or deep auto-generated selectors. Still no possible for custom getters)**.
|
|
375
375
|
|
|
376
376
|
|
|
377
377
|
## 🧱 Built With
|
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,283 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
createStore: () => createStore,
|
|
34
|
+
reset: () => reset,
|
|
35
|
+
setGlobalConfig: () => setGlobalConfig
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(index_exports);
|
|
38
|
+
|
|
39
|
+
// src/lib/createStore.ts
|
|
40
|
+
var import_middleware = require("zustand/middleware");
|
|
41
|
+
var import_vanilla = require("zustand/vanilla");
|
|
42
|
+
|
|
43
|
+
// src/lib/extendGetters.ts
|
|
44
|
+
var import_shallow2 = require("zustand/shallow");
|
|
45
|
+
var import_traditional2 = require("zustand/traditional");
|
|
46
|
+
|
|
47
|
+
// src/lib/generateGetFn.ts
|
|
48
|
+
function generateGetFn(lib) {
|
|
49
|
+
return () => lib.getState();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/lib/generateUseFn.ts
|
|
53
|
+
var import_shallow = require("zustand/shallow");
|
|
54
|
+
var import_traditional = require("zustand/traditional");
|
|
55
|
+
function generateUseFn(lib) {
|
|
56
|
+
return (selector, equality = import_shallow.shallow) => {
|
|
57
|
+
return (0, import_traditional.useStoreWithEqualityFn)(lib, selector, equality);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/lib/extendGetters.ts
|
|
62
|
+
function extendGetters(builder, store, lib) {
|
|
63
|
+
const methods = builder({ get: store.get });
|
|
64
|
+
const getters = {};
|
|
65
|
+
Object.keys(methods).forEach((key) => {
|
|
66
|
+
getters[key] = (...args) => (0, import_traditional2.useStoreWithEqualityFn)(lib, () => methods[key](...args), import_shallow2.shallow);
|
|
67
|
+
});
|
|
68
|
+
store.use = Object.assign(generateUseFn(lib), store.use, getters);
|
|
69
|
+
store.get = Object.assign(generateGetFn(lib), store.get, methods);
|
|
70
|
+
return store;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// src/lib/generateSetFn.ts
|
|
74
|
+
function generateSetFn(lib, hasDevtools) {
|
|
75
|
+
return (updater, replace, name) => {
|
|
76
|
+
lib.setState(
|
|
77
|
+
updater,
|
|
78
|
+
replace,
|
|
79
|
+
// @ts-ignore Additional parameter will have no effect even if devtools are disabled.
|
|
80
|
+
hasDevtools ? { type: name ?? "setState", payload: updater } : void 0
|
|
81
|
+
);
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// src/lib/extendSetters.ts
|
|
86
|
+
function extendSetters(builder, store, lib, hasDevtools) {
|
|
87
|
+
const setters = generateSetFn(lib, hasDevtools);
|
|
88
|
+
const baseSet = Object.entries(builder(store)).reduce(
|
|
89
|
+
(acc, [name, func]) => {
|
|
90
|
+
acc[name] = function _zustandLiteInferName_(...args) {
|
|
91
|
+
return func(...args);
|
|
92
|
+
};
|
|
93
|
+
return acc;
|
|
94
|
+
},
|
|
95
|
+
{}
|
|
96
|
+
);
|
|
97
|
+
store.set = Object.assign(setters, store.set, baseSet);
|
|
98
|
+
return store;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/lib/generateApi.ts
|
|
102
|
+
function generateApi(lib) {
|
|
103
|
+
return {
|
|
104
|
+
getInitialState: lib.getInitialState,
|
|
105
|
+
getState: lib.getState,
|
|
106
|
+
persist: augmentPersist(lib),
|
|
107
|
+
setState: lib.setState,
|
|
108
|
+
subscribe: lib.subscribe
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function augmentPersist(lib) {
|
|
112
|
+
if ("persist" in lib) {
|
|
113
|
+
const augmented = lib.persist;
|
|
114
|
+
augmented.read = () => {
|
|
115
|
+
try {
|
|
116
|
+
return JSON.parse(localStorage?.getItem(augmented.name) ?? "")?.state;
|
|
117
|
+
} catch {
|
|
118
|
+
return void 0;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
return augmented;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// src/lib/generateGet.ts
|
|
126
|
+
function generateGet(lib) {
|
|
127
|
+
return generateGetFn(lib);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/lib/generateSet.ts
|
|
131
|
+
var import_error_stack_parser = __toESM(require("error-stack-parser"), 1);
|
|
132
|
+
function getSetterName() {
|
|
133
|
+
const stack = import_error_stack_parser.default.parse(new Error());
|
|
134
|
+
return stack[3].functionName?.includes("_zustandLiteInferName_") ? stack[2].functionName : null;
|
|
135
|
+
}
|
|
136
|
+
function generateSet(lib, hasDevtools) {
|
|
137
|
+
const setters = generateSetFn(lib, hasDevtools);
|
|
138
|
+
Object.keys(lib.getState()).forEach((key) => {
|
|
139
|
+
setters[key] = (value) => {
|
|
140
|
+
if (lib.getState()[key] === value) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
lib.setState(
|
|
144
|
+
(state) => ({ ...state, [key]: value }),
|
|
145
|
+
false,
|
|
146
|
+
// @ts-ignore Additional parameter will have no effect even if devtools are disabled.
|
|
147
|
+
hasDevtools ? { type: getSetterName() ?? key, payload: { [key]: value } } : void 0
|
|
148
|
+
);
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
return setters;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// src/lib/generateUseStep.ts
|
|
155
|
+
var import_shallow3 = require("zustand/shallow");
|
|
156
|
+
var import_traditional3 = require("zustand/traditional");
|
|
157
|
+
function generateUseStep(state, getters, path, lib) {
|
|
158
|
+
if (typeof state === "object" && state !== null) {
|
|
159
|
+
Object.keys(state).forEach((key) => {
|
|
160
|
+
const newPath = [...path, key];
|
|
161
|
+
Object.defineProperty(getters, key, {
|
|
162
|
+
value: (equalityFn = import_shallow3.shallow) => {
|
|
163
|
+
return (0, import_traditional3.useStoreWithEqualityFn)(
|
|
164
|
+
lib,
|
|
165
|
+
(state2) => getFromPath(state2, newPath),
|
|
166
|
+
equalityFn
|
|
167
|
+
);
|
|
168
|
+
},
|
|
169
|
+
writable: true,
|
|
170
|
+
configurable: true,
|
|
171
|
+
enumerable: true
|
|
172
|
+
});
|
|
173
|
+
generateUseStep(state[key], getters[key], newPath, lib);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function getFromPath(state, path) {
|
|
178
|
+
let data = state;
|
|
179
|
+
for (const key of path) {
|
|
180
|
+
data = data[key];
|
|
181
|
+
if (!data) {
|
|
182
|
+
return data;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return data;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// src/lib/generateUse.ts
|
|
189
|
+
function generateUse(lib) {
|
|
190
|
+
const getters = generateUseFn(lib);
|
|
191
|
+
generateUseStep(lib.getState(), getters, [], lib);
|
|
192
|
+
return getters;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// src/lib/restrictState.ts
|
|
196
|
+
function restrictState(privateState, mergedState, store, lib) {
|
|
197
|
+
return {
|
|
198
|
+
api: store.api,
|
|
199
|
+
set: store.set,
|
|
200
|
+
use: privateState ? (() => {
|
|
201
|
+
const getters = Object.keys(store.use).reduce(
|
|
202
|
+
(acc, key) => mergedState[key] && privateState.includes(key) ? acc : { ...acc, [key]: store.use[key] },
|
|
203
|
+
{}
|
|
204
|
+
);
|
|
205
|
+
return Object.assign(generateUseFn(lib), getters);
|
|
206
|
+
})() : store.use,
|
|
207
|
+
get: privateState ? (() => {
|
|
208
|
+
const getFn = () => Object.entries(store.get()).reduce(
|
|
209
|
+
(acc, [key, val]) => mergedState[key] && privateState.includes(key) ? acc : { ...acc, [key]: val },
|
|
210
|
+
{}
|
|
211
|
+
);
|
|
212
|
+
return Object.assign(getFn, store.get);
|
|
213
|
+
})() : store.get
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// src/lib/createStore.ts
|
|
218
|
+
var config = { appName: "zustand-lite", devtools: false };
|
|
219
|
+
function setGlobalConfig(newConfig) {
|
|
220
|
+
config = { ...config, ...newConfig };
|
|
221
|
+
}
|
|
222
|
+
function createStore(initialState, options) {
|
|
223
|
+
const { name = "zustand-lite", plugins = [], middlewares = {} } = options ?? {};
|
|
224
|
+
let mergedState = initialState;
|
|
225
|
+
plugins.forEach((plugin) => {
|
|
226
|
+
if (plugin.creates) {
|
|
227
|
+
mergedState = { ...mergedState, ...plugin.creates() };
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
let initializer = () => mergedState;
|
|
231
|
+
if (middlewares.devtools || config.devtools) {
|
|
232
|
+
initializer = (0, import_middleware.devtools)(
|
|
233
|
+
initializer,
|
|
234
|
+
middlewares.devtools === true || config.devtools && !middlewares.devtools ? { name: config.appName, store: name } : { name: config.appName, store: name, ...middlewares.devtools }
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
if (middlewares.persist) {
|
|
238
|
+
initializer = (0, import_middleware.persist)(
|
|
239
|
+
initializer,
|
|
240
|
+
middlewares.persist === true ? { name: `${config.appName.replace(/\s/, "-")}.${name}` } : { name: `${config.appName.replace(/\s/, "-")}.${name}`, ...middlewares.persist }
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
const storeLib = (0, import_vanilla.createStore)(initializer);
|
|
244
|
+
const storeApi = {
|
|
245
|
+
api: generateApi(storeLib),
|
|
246
|
+
get: generateGet(storeLib),
|
|
247
|
+
use: generateUse(storeLib),
|
|
248
|
+
set: generateSet(storeLib, !!middlewares.devtools),
|
|
249
|
+
extendGetters(builder) {
|
|
250
|
+
return extendGetters(builder, this, storeLib);
|
|
251
|
+
},
|
|
252
|
+
extendSetters(builder) {
|
|
253
|
+
return extendSetters(builder, this, storeLib, !!middlewares.devtools);
|
|
254
|
+
},
|
|
255
|
+
restrictState(publicState = []) {
|
|
256
|
+
return restrictState(publicState, mergedState, this, storeLib);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
let result = storeApi;
|
|
260
|
+
plugins.forEach((plugin) => {
|
|
261
|
+
if (plugin.extends) {
|
|
262
|
+
result = plugin.extends(storeApi);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// src/plugins/reset.ts
|
|
269
|
+
var reset = {
|
|
270
|
+
extends: (store) => {
|
|
271
|
+
return store.extendSetters(({ api, set }) => ({
|
|
272
|
+
reset: () => {
|
|
273
|
+
set(api.getInitialState?.() ?? {}, true);
|
|
274
|
+
}
|
|
275
|
+
}));
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
279
|
+
0 && (module.exports = {
|
|
280
|
+
createStore,
|
|
281
|
+
reset,
|
|
282
|
+
setGlobalConfig
|
|
283
|
+
});
|
package/dist/index.d.cts
CHANGED
|
@@ -5,69 +5,90 @@ type State = Record<string | symbol, unknown>;
|
|
|
5
5
|
type Empty = Record<string, never>;
|
|
6
6
|
type Default = Record<string | symbol, any>;
|
|
7
7
|
type EqualityChecker<S> = (state: S, newState: S) => boolean;
|
|
8
|
-
type
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
type Override<T, U> = Omit<T, keyof U> & U;
|
|
9
|
+
type OverrideGet<T, U, S extends Record<string, any>> = Override<T, U> & GetRecordBase<S>;
|
|
10
|
+
type OverrideSet<T, U, S extends Record<string, any>> = Override<T, U> & SetRecordBase<S>;
|
|
11
|
+
type OverrideUse<T, U, S extends Record<string, any>> = Override<T, U> & UseRecordBase<S>;
|
|
12
|
+
type StoreApiEncapsulated<S extends State = Empty, Getters = Default, Setters = Default, ExtraMW = {}> = {
|
|
13
|
+
api: StoreApi$1<S> & ExtraMW;
|
|
14
|
+
get: OverrideGet<GetRecord<S>, Getters, S>;
|
|
15
|
+
set: OverrideSet<SetRecord<S>, Setters, S>;
|
|
16
|
+
use: OverrideUse<UseRecord<S>, Getters, S>;
|
|
13
17
|
};
|
|
14
|
-
type StoreApi<S extends State = Empty, Getters = Default, Setters = Default> = {
|
|
15
|
-
api: Omit<StoreApi$1<S>, 'setState' | 'getState'
|
|
16
|
-
get: GetRecord<S
|
|
17
|
-
set: SetRecord<S
|
|
18
|
-
use: UseRecord<S
|
|
19
|
-
extendGetters<Builder extends GettersBuilder<S, Getters>>(builder: Builder): StoreApi<S, Getters
|
|
20
|
-
extendSetters<Builder extends SettersBuilder<S, Getters, Setters>>(builder: Builder): StoreApi<S, Getters, Setters
|
|
21
|
-
restrictState(): StoreApiEncapsulated<S, Getters, Setters>;
|
|
22
|
-
restrictState<Key extends keyof S>(publicState: Key[]): StoreApiEncapsulated<Omit<S, Key>, Getters, Setters>;
|
|
18
|
+
type StoreApi<S extends State = Empty, Getters = Default, Setters = Default, ExtraMW = {}> = {
|
|
19
|
+
api: Omit<StoreApi$1<S>, 'setState' | 'getState'> & ExtraMW;
|
|
20
|
+
get: OverrideGet<GetRecord<S>, Getters, S>;
|
|
21
|
+
set: OverrideSet<SetRecord<S>, Setters, S>;
|
|
22
|
+
use: OverrideUse<UseRecord<S>, Getters, S>;
|
|
23
|
+
extendGetters<Builder extends GettersBuilder<S, Getters>>(builder: Builder): StoreApi<S, OverrideGet<Getters, ReturnType<Builder>, S>, Setters, ExtraMW>;
|
|
24
|
+
extendSetters<Builder extends SettersBuilder<S, Getters, Setters>>(builder: Builder): StoreApi<S, Getters, OverrideSet<Setters, ReturnType<Builder>, S>, ExtraMW>;
|
|
25
|
+
restrictState(): StoreApiEncapsulated<S, Getters, Setters, ExtraMW>;
|
|
26
|
+
restrictState<Key extends keyof S>(publicState: Key[]): StoreApiEncapsulated<Omit<S, Key>, Getters, Setters, ExtraMW>;
|
|
23
27
|
};
|
|
24
28
|
type GettersBuilder<S extends State, Getters = Default> = (args: {
|
|
25
|
-
get: GetRecord<S
|
|
29
|
+
get: OverrideGet<GetRecord<S>, Getters, S>;
|
|
26
30
|
}) => Record<string, (...args: any[]) => any>;
|
|
27
31
|
type SettersBuilder<S extends State, Getters = Default, Setters = Default> = (args: {
|
|
28
32
|
api: Omit<StoreApi$1<S>, 'setState' | 'getState'>;
|
|
29
|
-
get: GetRecord<S
|
|
30
|
-
set: SetRecord<S
|
|
33
|
+
get: OverrideGet<GetRecord<S>, Getters, S>;
|
|
34
|
+
set: OverrideSet<SetRecord<S>, Setters, S>;
|
|
31
35
|
}) => Record<string, (...args: any[]) => void>;
|
|
32
|
-
type
|
|
33
|
-
type
|
|
36
|
+
type GetRecordBase<S extends Record<string, any>> = () => S;
|
|
37
|
+
type GetRecord<S extends Record<string, any>> = GetRecordBase<S>;
|
|
38
|
+
type SetRecordBase<S extends Record<string, any>> = StoreApi$1<S>['setState'];
|
|
39
|
+
type SetRecord<S extends Record<string, any>> = SetRecordBase<S> & {
|
|
34
40
|
[K in keyof S]-?: (value: S[K]) => void;
|
|
35
41
|
};
|
|
36
|
-
type
|
|
42
|
+
type UseRecordBase<S> = <R>(selector: (state: S) => R, equality?: EqualityChecker<R>) => R;
|
|
43
|
+
type UseRecord<S> = UseRecordDeep<S> & UseRecordBase<S>;
|
|
37
44
|
type UseRecordDeep<S> = {
|
|
38
45
|
[K in keyof S]-?: S[K] extends Record<string, any> ? IsOptional<S, K> extends false ? ((equalityFn?: EqualityChecker<S[K]>) => S[K]) & UseRecordDeep<S[K]> : never : (equalityFn?: EqualityChecker<S[K]>) => S[K];
|
|
39
46
|
};
|
|
40
47
|
type IsOptional<S, K extends keyof S> = undefined extends S[K] ? {} extends Pick<S, K> ? true : false : false;
|
|
41
|
-
type StoreApiPlugin<NewApiData extends State, NewGetters, NewSetters> = {
|
|
48
|
+
type StoreApiPlugin<NewApiData extends State, NewGetters, NewSetters, NewExtraMW = Default> = {
|
|
42
49
|
creates?: () => NewApiData;
|
|
43
|
-
extends?: (store: StoreApi<NewApiData, NewGetters, NewSetters>) => StoreApi<NewApiData, NewGetters, NewSetters>;
|
|
50
|
+
extends?: (store: StoreApi<NewApiData, NewGetters, NewSetters, NewExtraMW>) => StoreApi<NewApiData, NewGetters, NewSetters, NewExtraMW>;
|
|
44
51
|
};
|
|
45
|
-
type StoreApiPluginList = StoreApiPlugin<any, any, any>[];
|
|
52
|
+
type StoreApiPluginList = StoreApiPlugin<any, any, any, any>[];
|
|
46
53
|
type AugmentedApiData<S, Plugins extends StoreApiPluginList> = S & UnionToIntersection<ExtractPluginTypes<Plugins, 'create'>[number]>;
|
|
47
54
|
type AugmentedGetters<Plugins extends StoreApiPluginList> = UnionToIntersection<ExtractPluginTypes<Plugins, 'extend'>[number]['getters']>;
|
|
48
55
|
type AugmentedSetters<Plugins extends StoreApiPluginList> = UnionToIntersection<ExtractPluginTypes<Plugins, 'extend'>[number]['setters']>;
|
|
56
|
+
type UnionToIntersection<S> = (S extends any ? (k: S) => void : never) extends (k: infer I) => void ? I : never;
|
|
49
57
|
type ExtractPluginTypes<Plugins extends StoreApiPluginList, Key extends 'create' | 'extend'> = {
|
|
50
58
|
[K in keyof Plugins]: Plugins[K] extends StoreApiPlugin<infer S, infer G, infer A> ? Key extends 'create' ? S : Key extends 'extend' ? {
|
|
51
59
|
getters: G;
|
|
52
60
|
setters: A;
|
|
53
61
|
} : never : never;
|
|
54
62
|
};
|
|
55
|
-
type
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
type MWConfiguration = {
|
|
64
|
+
devtools?: true | Omit<DevtoolsOptions, 'store'>;
|
|
65
|
+
persist?: true | Omit<PersistOptions<any>, 'name'>;
|
|
66
|
+
};
|
|
67
|
+
type StorePersist<S> = {
|
|
68
|
+
persist: {
|
|
69
|
+
clearStorage: () => void;
|
|
70
|
+
getOptions: () => Partial<PersistOptions<S, S>>;
|
|
71
|
+
hasHydrated: () => boolean;
|
|
72
|
+
onFinishHydration: (fn: (state: S) => void) => () => void;
|
|
73
|
+
onHydrate: (fn: (state: S) => void) => () => void;
|
|
74
|
+
read: () => S | undefined;
|
|
75
|
+
rehydrate: () => Promise<void> | void;
|
|
76
|
+
setOptions: (options: Partial<PersistOptions<S, S>>) => void;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
type GlobalConfig = {
|
|
80
|
+
appName: string;
|
|
81
|
+
devtools: boolean;
|
|
82
|
+
};
|
|
62
83
|
|
|
63
|
-
declare function
|
|
84
|
+
declare function setGlobalConfig(newConfig: Partial<GlobalConfig>): void;
|
|
85
|
+
declare function createStore<S extends State, Plugins extends StoreApiPluginList = [], ExtraMW extends MWConfiguration = {}>(initialState: S, options?: {
|
|
64
86
|
name?: string;
|
|
65
87
|
plugins?: [...Plugins];
|
|
66
|
-
middlewares?:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}): Plugins extends [] ? StoreApi<S> : StoreApi<AugmentedApiData<S, Plugins>, AugmentedGetters<Plugins>, AugmentedSetters<Plugins>>;
|
|
88
|
+
middlewares?: ExtraMW;
|
|
89
|
+
}): StoreApi<Plugins extends [] ? S : AugmentedApiData<S, Plugins>, Plugins extends [] ? Default : AugmentedGetters<Plugins>, Plugins extends [] ? Default : AugmentedSetters<Plugins>, ExtraMW extends {
|
|
90
|
+
persist: any;
|
|
91
|
+
} ? StorePersist<S> : {}>;
|
|
71
92
|
|
|
72
93
|
type PluginResetSetters = {
|
|
73
94
|
reset: () => void;
|
|
@@ -77,4 +98,4 @@ type PluginResetSetters = {
|
|
|
77
98
|
*/
|
|
78
99
|
declare const reset: StoreApiPlugin<{}, {}, PluginResetSetters>;
|
|
79
100
|
|
|
80
|
-
export { type StoreApiPlugin, createStore, reset };
|
|
101
|
+
export { type StoreApiPlugin, createStore, reset, setGlobalConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -5,69 +5,90 @@ type State = Record<string | symbol, unknown>;
|
|
|
5
5
|
type Empty = Record<string, never>;
|
|
6
6
|
type Default = Record<string | symbol, any>;
|
|
7
7
|
type EqualityChecker<S> = (state: S, newState: S) => boolean;
|
|
8
|
-
type
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
type Override<T, U> = Omit<T, keyof U> & U;
|
|
9
|
+
type OverrideGet<T, U, S extends Record<string, any>> = Override<T, U> & GetRecordBase<S>;
|
|
10
|
+
type OverrideSet<T, U, S extends Record<string, any>> = Override<T, U> & SetRecordBase<S>;
|
|
11
|
+
type OverrideUse<T, U, S extends Record<string, any>> = Override<T, U> & UseRecordBase<S>;
|
|
12
|
+
type StoreApiEncapsulated<S extends State = Empty, Getters = Default, Setters = Default, ExtraMW = {}> = {
|
|
13
|
+
api: StoreApi$1<S> & ExtraMW;
|
|
14
|
+
get: OverrideGet<GetRecord<S>, Getters, S>;
|
|
15
|
+
set: OverrideSet<SetRecord<S>, Setters, S>;
|
|
16
|
+
use: OverrideUse<UseRecord<S>, Getters, S>;
|
|
13
17
|
};
|
|
14
|
-
type StoreApi<S extends State = Empty, Getters = Default, Setters = Default> = {
|
|
15
|
-
api: Omit<StoreApi$1<S>, 'setState' | 'getState'
|
|
16
|
-
get: GetRecord<S
|
|
17
|
-
set: SetRecord<S
|
|
18
|
-
use: UseRecord<S
|
|
19
|
-
extendGetters<Builder extends GettersBuilder<S, Getters>>(builder: Builder): StoreApi<S, Getters
|
|
20
|
-
extendSetters<Builder extends SettersBuilder<S, Getters, Setters>>(builder: Builder): StoreApi<S, Getters, Setters
|
|
21
|
-
restrictState(): StoreApiEncapsulated<S, Getters, Setters>;
|
|
22
|
-
restrictState<Key extends keyof S>(publicState: Key[]): StoreApiEncapsulated<Omit<S, Key>, Getters, Setters>;
|
|
18
|
+
type StoreApi<S extends State = Empty, Getters = Default, Setters = Default, ExtraMW = {}> = {
|
|
19
|
+
api: Omit<StoreApi$1<S>, 'setState' | 'getState'> & ExtraMW;
|
|
20
|
+
get: OverrideGet<GetRecord<S>, Getters, S>;
|
|
21
|
+
set: OverrideSet<SetRecord<S>, Setters, S>;
|
|
22
|
+
use: OverrideUse<UseRecord<S>, Getters, S>;
|
|
23
|
+
extendGetters<Builder extends GettersBuilder<S, Getters>>(builder: Builder): StoreApi<S, OverrideGet<Getters, ReturnType<Builder>, S>, Setters, ExtraMW>;
|
|
24
|
+
extendSetters<Builder extends SettersBuilder<S, Getters, Setters>>(builder: Builder): StoreApi<S, Getters, OverrideSet<Setters, ReturnType<Builder>, S>, ExtraMW>;
|
|
25
|
+
restrictState(): StoreApiEncapsulated<S, Getters, Setters, ExtraMW>;
|
|
26
|
+
restrictState<Key extends keyof S>(publicState: Key[]): StoreApiEncapsulated<Omit<S, Key>, Getters, Setters, ExtraMW>;
|
|
23
27
|
};
|
|
24
28
|
type GettersBuilder<S extends State, Getters = Default> = (args: {
|
|
25
|
-
get: GetRecord<S
|
|
29
|
+
get: OverrideGet<GetRecord<S>, Getters, S>;
|
|
26
30
|
}) => Record<string, (...args: any[]) => any>;
|
|
27
31
|
type SettersBuilder<S extends State, Getters = Default, Setters = Default> = (args: {
|
|
28
32
|
api: Omit<StoreApi$1<S>, 'setState' | 'getState'>;
|
|
29
|
-
get: GetRecord<S
|
|
30
|
-
set: SetRecord<S
|
|
33
|
+
get: OverrideGet<GetRecord<S>, Getters, S>;
|
|
34
|
+
set: OverrideSet<SetRecord<S>, Setters, S>;
|
|
31
35
|
}) => Record<string, (...args: any[]) => void>;
|
|
32
|
-
type
|
|
33
|
-
type
|
|
36
|
+
type GetRecordBase<S extends Record<string, any>> = () => S;
|
|
37
|
+
type GetRecord<S extends Record<string, any>> = GetRecordBase<S>;
|
|
38
|
+
type SetRecordBase<S extends Record<string, any>> = StoreApi$1<S>['setState'];
|
|
39
|
+
type SetRecord<S extends Record<string, any>> = SetRecordBase<S> & {
|
|
34
40
|
[K in keyof S]-?: (value: S[K]) => void;
|
|
35
41
|
};
|
|
36
|
-
type
|
|
42
|
+
type UseRecordBase<S> = <R>(selector: (state: S) => R, equality?: EqualityChecker<R>) => R;
|
|
43
|
+
type UseRecord<S> = UseRecordDeep<S> & UseRecordBase<S>;
|
|
37
44
|
type UseRecordDeep<S> = {
|
|
38
45
|
[K in keyof S]-?: S[K] extends Record<string, any> ? IsOptional<S, K> extends false ? ((equalityFn?: EqualityChecker<S[K]>) => S[K]) & UseRecordDeep<S[K]> : never : (equalityFn?: EqualityChecker<S[K]>) => S[K];
|
|
39
46
|
};
|
|
40
47
|
type IsOptional<S, K extends keyof S> = undefined extends S[K] ? {} extends Pick<S, K> ? true : false : false;
|
|
41
|
-
type StoreApiPlugin<NewApiData extends State, NewGetters, NewSetters> = {
|
|
48
|
+
type StoreApiPlugin<NewApiData extends State, NewGetters, NewSetters, NewExtraMW = Default> = {
|
|
42
49
|
creates?: () => NewApiData;
|
|
43
|
-
extends?: (store: StoreApi<NewApiData, NewGetters, NewSetters>) => StoreApi<NewApiData, NewGetters, NewSetters>;
|
|
50
|
+
extends?: (store: StoreApi<NewApiData, NewGetters, NewSetters, NewExtraMW>) => StoreApi<NewApiData, NewGetters, NewSetters, NewExtraMW>;
|
|
44
51
|
};
|
|
45
|
-
type StoreApiPluginList = StoreApiPlugin<any, any, any>[];
|
|
52
|
+
type StoreApiPluginList = StoreApiPlugin<any, any, any, any>[];
|
|
46
53
|
type AugmentedApiData<S, Plugins extends StoreApiPluginList> = S & UnionToIntersection<ExtractPluginTypes<Plugins, 'create'>[number]>;
|
|
47
54
|
type AugmentedGetters<Plugins extends StoreApiPluginList> = UnionToIntersection<ExtractPluginTypes<Plugins, 'extend'>[number]['getters']>;
|
|
48
55
|
type AugmentedSetters<Plugins extends StoreApiPluginList> = UnionToIntersection<ExtractPluginTypes<Plugins, 'extend'>[number]['setters']>;
|
|
56
|
+
type UnionToIntersection<S> = (S extends any ? (k: S) => void : never) extends (k: infer I) => void ? I : never;
|
|
49
57
|
type ExtractPluginTypes<Plugins extends StoreApiPluginList, Key extends 'create' | 'extend'> = {
|
|
50
58
|
[K in keyof Plugins]: Plugins[K] extends StoreApiPlugin<infer S, infer G, infer A> ? Key extends 'create' ? S : Key extends 'extend' ? {
|
|
51
59
|
getters: G;
|
|
52
60
|
setters: A;
|
|
53
61
|
} : never : never;
|
|
54
62
|
};
|
|
55
|
-
type
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
type MWConfiguration = {
|
|
64
|
+
devtools?: true | Omit<DevtoolsOptions, 'store'>;
|
|
65
|
+
persist?: true | Omit<PersistOptions<any>, 'name'>;
|
|
66
|
+
};
|
|
67
|
+
type StorePersist<S> = {
|
|
68
|
+
persist: {
|
|
69
|
+
clearStorage: () => void;
|
|
70
|
+
getOptions: () => Partial<PersistOptions<S, S>>;
|
|
71
|
+
hasHydrated: () => boolean;
|
|
72
|
+
onFinishHydration: (fn: (state: S) => void) => () => void;
|
|
73
|
+
onHydrate: (fn: (state: S) => void) => () => void;
|
|
74
|
+
read: () => S | undefined;
|
|
75
|
+
rehydrate: () => Promise<void> | void;
|
|
76
|
+
setOptions: (options: Partial<PersistOptions<S, S>>) => void;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
type GlobalConfig = {
|
|
80
|
+
appName: string;
|
|
81
|
+
devtools: boolean;
|
|
82
|
+
};
|
|
62
83
|
|
|
63
|
-
declare function
|
|
84
|
+
declare function setGlobalConfig(newConfig: Partial<GlobalConfig>): void;
|
|
85
|
+
declare function createStore<S extends State, Plugins extends StoreApiPluginList = [], ExtraMW extends MWConfiguration = {}>(initialState: S, options?: {
|
|
64
86
|
name?: string;
|
|
65
87
|
plugins?: [...Plugins];
|
|
66
|
-
middlewares?:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}): Plugins extends [] ? StoreApi<S> : StoreApi<AugmentedApiData<S, Plugins>, AugmentedGetters<Plugins>, AugmentedSetters<Plugins>>;
|
|
88
|
+
middlewares?: ExtraMW;
|
|
89
|
+
}): StoreApi<Plugins extends [] ? S : AugmentedApiData<S, Plugins>, Plugins extends [] ? Default : AugmentedGetters<Plugins>, Plugins extends [] ? Default : AugmentedSetters<Plugins>, ExtraMW extends {
|
|
90
|
+
persist: any;
|
|
91
|
+
} ? StorePersist<S> : {}>;
|
|
71
92
|
|
|
72
93
|
type PluginResetSetters = {
|
|
73
94
|
reset: () => void;
|
|
@@ -77,4 +98,4 @@ type PluginResetSetters = {
|
|
|
77
98
|
*/
|
|
78
99
|
declare const reset: StoreApiPlugin<{}, {}, PluginResetSetters>;
|
|
79
100
|
|
|
80
|
-
export { type StoreApiPlugin, createStore, reset };
|
|
101
|
+
export { type StoreApiPlugin, createStore, reset, setGlobalConfig };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,244 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// src/lib/createStore.ts
|
|
2
|
+
import { devtools, persist } from "zustand/middleware";
|
|
3
|
+
import { createStore as createVanillaStore } from "zustand/vanilla";
|
|
4
|
+
|
|
5
|
+
// src/lib/extendGetters.ts
|
|
6
|
+
import { shallow as shallow2 } from "zustand/shallow";
|
|
7
|
+
import { useStoreWithEqualityFn as useStoreWithEqualityFn2 } from "zustand/traditional";
|
|
8
|
+
|
|
9
|
+
// src/lib/generateGetFn.ts
|
|
10
|
+
function generateGetFn(lib) {
|
|
11
|
+
return () => lib.getState();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// src/lib/generateUseFn.ts
|
|
15
|
+
import { shallow } from "zustand/shallow";
|
|
16
|
+
import { useStoreWithEqualityFn } from "zustand/traditional";
|
|
17
|
+
function generateUseFn(lib) {
|
|
18
|
+
return (selector, equality = shallow) => {
|
|
19
|
+
return useStoreWithEqualityFn(lib, selector, equality);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/lib/extendGetters.ts
|
|
24
|
+
function extendGetters(builder, store, lib) {
|
|
25
|
+
const methods = builder({ get: store.get });
|
|
26
|
+
const getters = {};
|
|
27
|
+
Object.keys(methods).forEach((key) => {
|
|
28
|
+
getters[key] = (...args) => useStoreWithEqualityFn2(lib, () => methods[key](...args), shallow2);
|
|
29
|
+
});
|
|
30
|
+
store.use = Object.assign(generateUseFn(lib), store.use, getters);
|
|
31
|
+
store.get = Object.assign(generateGetFn(lib), store.get, methods);
|
|
32
|
+
return store;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/lib/generateSetFn.ts
|
|
36
|
+
function generateSetFn(lib, hasDevtools) {
|
|
37
|
+
return (updater, replace, name) => {
|
|
38
|
+
lib.setState(
|
|
39
|
+
updater,
|
|
40
|
+
replace,
|
|
41
|
+
// @ts-ignore Additional parameter will have no effect even if devtools are disabled.
|
|
42
|
+
hasDevtools ? { type: name ?? "setState", payload: updater } : void 0
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/lib/extendSetters.ts
|
|
48
|
+
function extendSetters(builder, store, lib, hasDevtools) {
|
|
49
|
+
const setters = generateSetFn(lib, hasDevtools);
|
|
50
|
+
const baseSet = Object.entries(builder(store)).reduce(
|
|
51
|
+
(acc, [name, func]) => {
|
|
52
|
+
acc[name] = function _zustandLiteInferName_(...args) {
|
|
53
|
+
return func(...args);
|
|
54
|
+
};
|
|
55
|
+
return acc;
|
|
56
|
+
},
|
|
57
|
+
{}
|
|
58
|
+
);
|
|
59
|
+
store.set = Object.assign(setters, store.set, baseSet);
|
|
60
|
+
return store;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/lib/generateApi.ts
|
|
64
|
+
function generateApi(lib) {
|
|
65
|
+
return {
|
|
66
|
+
getInitialState: lib.getInitialState,
|
|
67
|
+
getState: lib.getState,
|
|
68
|
+
persist: augmentPersist(lib),
|
|
69
|
+
setState: lib.setState,
|
|
70
|
+
subscribe: lib.subscribe
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function augmentPersist(lib) {
|
|
74
|
+
if ("persist" in lib) {
|
|
75
|
+
const augmented = lib.persist;
|
|
76
|
+
augmented.read = () => {
|
|
77
|
+
try {
|
|
78
|
+
return JSON.parse(localStorage?.getItem(augmented.name) ?? "")?.state;
|
|
79
|
+
} catch {
|
|
80
|
+
return void 0;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
return augmented;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// src/lib/generateGet.ts
|
|
88
|
+
function generateGet(lib) {
|
|
89
|
+
return generateGetFn(lib);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/lib/generateSet.ts
|
|
93
|
+
import ErrorStackParser from "error-stack-parser";
|
|
94
|
+
function getSetterName() {
|
|
95
|
+
const stack = ErrorStackParser.parse(new Error());
|
|
96
|
+
return stack[3].functionName?.includes("_zustandLiteInferName_") ? stack[2].functionName : null;
|
|
97
|
+
}
|
|
98
|
+
function generateSet(lib, hasDevtools) {
|
|
99
|
+
const setters = generateSetFn(lib, hasDevtools);
|
|
100
|
+
Object.keys(lib.getState()).forEach((key) => {
|
|
101
|
+
setters[key] = (value) => {
|
|
102
|
+
if (lib.getState()[key] === value) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
lib.setState(
|
|
106
|
+
(state) => ({ ...state, [key]: value }),
|
|
107
|
+
false,
|
|
108
|
+
// @ts-ignore Additional parameter will have no effect even if devtools are disabled.
|
|
109
|
+
hasDevtools ? { type: getSetterName() ?? key, payload: { [key]: value } } : void 0
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
return setters;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/lib/generateUseStep.ts
|
|
117
|
+
import { shallow as shallow3 } from "zustand/shallow";
|
|
118
|
+
import { useStoreWithEqualityFn as useStoreWithEqualityFn3 } from "zustand/traditional";
|
|
119
|
+
function generateUseStep(state, getters, path, lib) {
|
|
120
|
+
if (typeof state === "object" && state !== null) {
|
|
121
|
+
Object.keys(state).forEach((key) => {
|
|
122
|
+
const newPath = [...path, key];
|
|
123
|
+
Object.defineProperty(getters, key, {
|
|
124
|
+
value: (equalityFn = shallow3) => {
|
|
125
|
+
return useStoreWithEqualityFn3(
|
|
126
|
+
lib,
|
|
127
|
+
(state2) => getFromPath(state2, newPath),
|
|
128
|
+
equalityFn
|
|
129
|
+
);
|
|
130
|
+
},
|
|
131
|
+
writable: true,
|
|
132
|
+
configurable: true,
|
|
133
|
+
enumerable: true
|
|
134
|
+
});
|
|
135
|
+
generateUseStep(state[key], getters[key], newPath, lib);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function getFromPath(state, path) {
|
|
140
|
+
let data = state;
|
|
141
|
+
for (const key of path) {
|
|
142
|
+
data = data[key];
|
|
143
|
+
if (!data) {
|
|
144
|
+
return data;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return data;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/lib/generateUse.ts
|
|
151
|
+
function generateUse(lib) {
|
|
152
|
+
const getters = generateUseFn(lib);
|
|
153
|
+
generateUseStep(lib.getState(), getters, [], lib);
|
|
154
|
+
return getters;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// src/lib/restrictState.ts
|
|
158
|
+
function restrictState(privateState, mergedState, store, lib) {
|
|
159
|
+
return {
|
|
160
|
+
api: store.api,
|
|
161
|
+
set: store.set,
|
|
162
|
+
use: privateState ? (() => {
|
|
163
|
+
const getters = Object.keys(store.use).reduce(
|
|
164
|
+
(acc, key) => mergedState[key] && privateState.includes(key) ? acc : { ...acc, [key]: store.use[key] },
|
|
165
|
+
{}
|
|
166
|
+
);
|
|
167
|
+
return Object.assign(generateUseFn(lib), getters);
|
|
168
|
+
})() : store.use,
|
|
169
|
+
get: privateState ? (() => {
|
|
170
|
+
const getFn = () => Object.entries(store.get()).reduce(
|
|
171
|
+
(acc, [key, val]) => mergedState[key] && privateState.includes(key) ? acc : { ...acc, [key]: val },
|
|
172
|
+
{}
|
|
173
|
+
);
|
|
174
|
+
return Object.assign(getFn, store.get);
|
|
175
|
+
})() : store.get
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// src/lib/createStore.ts
|
|
180
|
+
var config = { appName: "zustand-lite", devtools: false };
|
|
181
|
+
function setGlobalConfig(newConfig) {
|
|
182
|
+
config = { ...config, ...newConfig };
|
|
183
|
+
}
|
|
184
|
+
function createStore(initialState, options) {
|
|
185
|
+
const { name = "zustand-lite", plugins = [], middlewares = {} } = options ?? {};
|
|
186
|
+
let mergedState = initialState;
|
|
187
|
+
plugins.forEach((plugin) => {
|
|
188
|
+
if (plugin.creates) {
|
|
189
|
+
mergedState = { ...mergedState, ...plugin.creates() };
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
let initializer = () => mergedState;
|
|
193
|
+
if (middlewares.devtools || config.devtools) {
|
|
194
|
+
initializer = devtools(
|
|
195
|
+
initializer,
|
|
196
|
+
middlewares.devtools === true || config.devtools && !middlewares.devtools ? { name: config.appName, store: name } : { name: config.appName, store: name, ...middlewares.devtools }
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
if (middlewares.persist) {
|
|
200
|
+
initializer = persist(
|
|
201
|
+
initializer,
|
|
202
|
+
middlewares.persist === true ? { name: `${config.appName.replace(/\s/, "-")}.${name}` } : { name: `${config.appName.replace(/\s/, "-")}.${name}`, ...middlewares.persist }
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
const storeLib = createVanillaStore(initializer);
|
|
206
|
+
const storeApi = {
|
|
207
|
+
api: generateApi(storeLib),
|
|
208
|
+
get: generateGet(storeLib),
|
|
209
|
+
use: generateUse(storeLib),
|
|
210
|
+
set: generateSet(storeLib, !!middlewares.devtools),
|
|
211
|
+
extendGetters(builder) {
|
|
212
|
+
return extendGetters(builder, this, storeLib);
|
|
213
|
+
},
|
|
214
|
+
extendSetters(builder) {
|
|
215
|
+
return extendSetters(builder, this, storeLib, !!middlewares.devtools);
|
|
216
|
+
},
|
|
217
|
+
restrictState(publicState = []) {
|
|
218
|
+
return restrictState(publicState, mergedState, this, storeLib);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
let result = storeApi;
|
|
222
|
+
plugins.forEach((plugin) => {
|
|
223
|
+
if (plugin.extends) {
|
|
224
|
+
result = plugin.extends(storeApi);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
return result;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// src/plugins/reset.ts
|
|
231
|
+
var reset = {
|
|
232
|
+
extends: (store) => {
|
|
233
|
+
return store.extendSetters(({ api, set }) => ({
|
|
234
|
+
reset: () => {
|
|
235
|
+
set(api.getInitialState?.() ?? {}, true);
|
|
236
|
+
}
|
|
237
|
+
}));
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
export {
|
|
241
|
+
createStore,
|
|
242
|
+
reset,
|
|
243
|
+
setGlobalConfig
|
|
244
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zustand-lite",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Zustand Lite builds upon zustand, by auto-generating selectors and simplifying API even more.",
|
|
5
5
|
"author": "Piotr Siatkowski <p.siatkowski@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
"test": "jest"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"zustand": "5.0.5"
|
|
45
|
+
"zustand": "5.0.5",
|
|
46
|
+
"error-stack-parser": "2.1.4"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@testing-library/jest-dom": "^6.6.3",
|