Built mode with cache time
This commit is contained in:
commit
c5914a4d18
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Paul Henschel
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
25
context.d.ts
vendored
Normal file
25
context.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
import ReactExports from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import type { StoreApi } from 'zustand';
|
||||
type UseContextStore<S extends StoreApi<unknown>> = {
|
||||
(): ExtractState<S>;
|
||||
<U>(selector: (state: ExtractState<S>) => U, equalityFn?: (a: U, b: U) => boolean): U;
|
||||
};
|
||||
type ExtractState<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? T : never;
|
||||
type WithoutCallSignature<T> = {
|
||||
[K in keyof T]: T[K];
|
||||
};
|
||||
/**
|
||||
* @deprecated Use `createStore` and `useStore` for context usage
|
||||
*/
|
||||
declare function createContext<S extends StoreApi<unknown>>(): {
|
||||
Provider: ({ createStore, children, }: {
|
||||
createStore: () => S;
|
||||
children: ReactNode;
|
||||
}) => ReactExports.FunctionComponentElement<ReactExports.ProviderProps<S | undefined>>;
|
||||
useStore: UseContextStore<S>;
|
||||
useStoreApi: () => WithoutCallSignature<S>;
|
||||
};
|
||||
export default createContext;
|
65
context.js
Normal file
65
context.js
Normal file
@ -0,0 +1,65 @@
|
||||
'use strict';
|
||||
|
||||
var ReactExports = require('react');
|
||||
var traditional = require('zustand/traditional');
|
||||
|
||||
function _extends() {
|
||||
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i];
|
||||
for (var key in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
};
|
||||
return _extends.apply(this, arguments);
|
||||
}
|
||||
|
||||
var createElement = ReactExports.createElement,
|
||||
reactCreateContext = ReactExports.createContext,
|
||||
useContext = ReactExports.useContext,
|
||||
useMemo = ReactExports.useMemo,
|
||||
useRef = ReactExports.useRef;
|
||||
function createContext() {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
console.warn("[DEPRECATED] `context` will be removed in a future version. Instead use `import { createStore, useStore } from 'zustand'`. See: https://github.com/pmndrs/zustand/discussions/1180.");
|
||||
}
|
||||
var ZustandContext = reactCreateContext(undefined);
|
||||
var Provider = function Provider(_ref) {
|
||||
var createStore = _ref.createStore,
|
||||
children = _ref.children;
|
||||
var storeRef = useRef();
|
||||
if (!storeRef.current) {
|
||||
storeRef.current = createStore();
|
||||
}
|
||||
return createElement(ZustandContext.Provider, {
|
||||
value: storeRef.current
|
||||
}, children);
|
||||
};
|
||||
var useContextStore = function useContextStore(selector, equalityFn) {
|
||||
var store = useContext(ZustandContext);
|
||||
if (!store) {
|
||||
throw new Error('Seems like you have not used zustand provider as an ancestor.');
|
||||
}
|
||||
return traditional.useStoreWithEqualityFn(store, selector, equalityFn);
|
||||
};
|
||||
var useStoreApi = function useStoreApi() {
|
||||
var store = useContext(ZustandContext);
|
||||
if (!store) {
|
||||
throw new Error('Seems like you have not used zustand provider as an ancestor.');
|
||||
}
|
||||
return useMemo(function () {
|
||||
return _extends({}, store);
|
||||
}, [store]);
|
||||
};
|
||||
return {
|
||||
Provider: Provider,
|
||||
useStore: useContextStore,
|
||||
useStoreApi: useStoreApi
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = createContext;
|
25
esm/context.d.mts
Normal file
25
esm/context.d.mts
Normal file
@ -0,0 +1,25 @@
|
||||
import ReactExports from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import type { StoreApi } from 'zustand';
|
||||
type UseContextStore<S extends StoreApi<unknown>> = {
|
||||
(): ExtractState<S>;
|
||||
<U>(selector: (state: ExtractState<S>) => U, equalityFn?: (a: U, b: U) => boolean): U;
|
||||
};
|
||||
type ExtractState<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? T : never;
|
||||
type WithoutCallSignature<T> = {
|
||||
[K in keyof T]: T[K];
|
||||
};
|
||||
/**
|
||||
* @deprecated Use `createStore` and `useStore` for context usage
|
||||
*/
|
||||
declare function createContext<S extends StoreApi<unknown>>(): {
|
||||
Provider: ({ createStore, children, }: {
|
||||
createStore: () => S;
|
||||
children: ReactNode;
|
||||
}) => ReactExports.FunctionComponentElement<ReactExports.ProviderProps<S | undefined>>;
|
||||
useStore: UseContextStore<S>;
|
||||
useStoreApi: () => WithoutCallSignature<S>;
|
||||
};
|
||||
export default createContext;
|
25
esm/context.d.ts
vendored
Normal file
25
esm/context.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
import ReactExports from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import type { StoreApi } from 'zustand';
|
||||
type UseContextStore<S extends StoreApi<unknown>> = {
|
||||
(): ExtractState<S>;
|
||||
<U>(selector: (state: ExtractState<S>) => U, equalityFn?: (a: U, b: U) => boolean): U;
|
||||
};
|
||||
type ExtractState<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? T : never;
|
||||
type WithoutCallSignature<T> = {
|
||||
[K in keyof T]: T[K];
|
||||
};
|
||||
/**
|
||||
* @deprecated Use `createStore` and `useStore` for context usage
|
||||
*/
|
||||
declare function createContext<S extends StoreApi<unknown>>(): {
|
||||
Provider: ({ createStore, children, }: {
|
||||
createStore: () => S;
|
||||
children: ReactNode;
|
||||
}) => ReactExports.FunctionComponentElement<ReactExports.ProviderProps<S | undefined>>;
|
||||
useStore: UseContextStore<S>;
|
||||
useStoreApi: () => WithoutCallSignature<S>;
|
||||
};
|
||||
export default createContext;
|
61
esm/context.js
Normal file
61
esm/context.js
Normal file
@ -0,0 +1,61 @@
|
||||
import ReactExports from 'react';
|
||||
import { useStoreWithEqualityFn } from 'zustand/traditional';
|
||||
|
||||
const {
|
||||
createElement,
|
||||
createContext: reactCreateContext,
|
||||
useContext,
|
||||
useMemo,
|
||||
useRef
|
||||
} = ReactExports;
|
||||
function createContext() {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
console.warn(
|
||||
"[DEPRECATED] `context` will be removed in a future version. Instead use `import { createStore, useStore } from 'zustand'`. See: https://github.com/pmndrs/zustand/discussions/1180."
|
||||
);
|
||||
}
|
||||
const ZustandContext = reactCreateContext(void 0);
|
||||
const Provider = ({
|
||||
createStore,
|
||||
children
|
||||
}) => {
|
||||
const storeRef = useRef();
|
||||
if (!storeRef.current) {
|
||||
storeRef.current = createStore();
|
||||
}
|
||||
return createElement(
|
||||
ZustandContext.Provider,
|
||||
{ value: storeRef.current },
|
||||
children
|
||||
);
|
||||
};
|
||||
const useContextStore = (selector, equalityFn) => {
|
||||
const store = useContext(ZustandContext);
|
||||
if (!store) {
|
||||
throw new Error(
|
||||
"Seems like you have not used zustand provider as an ancestor."
|
||||
);
|
||||
}
|
||||
return useStoreWithEqualityFn(
|
||||
store,
|
||||
selector,
|
||||
equalityFn
|
||||
);
|
||||
};
|
||||
const useStoreApi = () => {
|
||||
const store = useContext(ZustandContext);
|
||||
if (!store) {
|
||||
throw new Error(
|
||||
"Seems like you have not used zustand provider as an ancestor."
|
||||
);
|
||||
}
|
||||
return useMemo(() => ({ ...store }), [store]);
|
||||
};
|
||||
return {
|
||||
Provider,
|
||||
useStore: useContextStore,
|
||||
useStoreApi
|
||||
};
|
||||
}
|
||||
|
||||
export { createContext as default };
|
61
esm/context.mjs
Normal file
61
esm/context.mjs
Normal file
@ -0,0 +1,61 @@
|
||||
import ReactExports from 'react';
|
||||
import { useStoreWithEqualityFn } from 'zustand/traditional';
|
||||
|
||||
const {
|
||||
createElement,
|
||||
createContext: reactCreateContext,
|
||||
useContext,
|
||||
useMemo,
|
||||
useRef
|
||||
} = ReactExports;
|
||||
function createContext() {
|
||||
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production") {
|
||||
console.warn(
|
||||
"[DEPRECATED] `context` will be removed in a future version. Instead use `import { createStore, useStore } from 'zustand'`. See: https://github.com/pmndrs/zustand/discussions/1180."
|
||||
);
|
||||
}
|
||||
const ZustandContext = reactCreateContext(void 0);
|
||||
const Provider = ({
|
||||
createStore,
|
||||
children
|
||||
}) => {
|
||||
const storeRef = useRef();
|
||||
if (!storeRef.current) {
|
||||
storeRef.current = createStore();
|
||||
}
|
||||
return createElement(
|
||||
ZustandContext.Provider,
|
||||
{ value: storeRef.current },
|
||||
children
|
||||
);
|
||||
};
|
||||
const useContextStore = (selector, equalityFn) => {
|
||||
const store = useContext(ZustandContext);
|
||||
if (!store) {
|
||||
throw new Error(
|
||||
"Seems like you have not used zustand provider as an ancestor."
|
||||
);
|
||||
}
|
||||
return useStoreWithEqualityFn(
|
||||
store,
|
||||
selector,
|
||||
equalityFn
|
||||
);
|
||||
};
|
||||
const useStoreApi = () => {
|
||||
const store = useContext(ZustandContext);
|
||||
if (!store) {
|
||||
throw new Error(
|
||||
"Seems like you have not used zustand provider as an ancestor."
|
||||
);
|
||||
}
|
||||
return useMemo(() => ({ ...store }), [store]);
|
||||
};
|
||||
return {
|
||||
Provider,
|
||||
useStore: useContextStore,
|
||||
useStoreApi
|
||||
};
|
||||
}
|
||||
|
||||
export { createContext as default };
|
3
esm/index.d.mts
Normal file
3
esm/index.d.mts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './vanilla.mjs';
|
||||
export * from './react.mjs';
|
||||
export { default } from './react.mjs';
|
3
esm/index.d.ts
vendored
Normal file
3
esm/index.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './vanilla';
|
||||
export * from './react';
|
||||
export { default } from './react';
|
48
esm/index.js
Normal file
48
esm/index.js
Normal file
@ -0,0 +1,48 @@
|
||||
import { createStore } from 'zustand/vanilla';
|
||||
export * from 'zustand/vanilla';
|
||||
import ReactExports from 'react';
|
||||
import useSyncExternalStoreExports from 'use-sync-external-store/shim/with-selector.js';
|
||||
|
||||
const { useDebugValue } = ReactExports;
|
||||
const { useSyncExternalStoreWithSelector } = useSyncExternalStoreExports;
|
||||
let didWarnAboutEqualityFn = false;
|
||||
const identity = (arg) => arg;
|
||||
function useStore(api, selector = identity, equalityFn) {
|
||||
if (process.env.NODE_ENV !== "production" && equalityFn && !didWarnAboutEqualityFn) {
|
||||
console.warn(
|
||||
"[DEPRECATED] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`. They can be imported from 'zustand/traditional'. https://github.com/pmndrs/zustand/discussions/1937"
|
||||
);
|
||||
didWarnAboutEqualityFn = true;
|
||||
}
|
||||
const slice = useSyncExternalStoreWithSelector(
|
||||
api.subscribe,
|
||||
api.getState,
|
||||
api.getServerState || api.getInitialState,
|
||||
selector,
|
||||
equalityFn
|
||||
);
|
||||
useDebugValue(slice);
|
||||
return slice;
|
||||
}
|
||||
const createImpl = (createState) => {
|
||||
if (process.env.NODE_ENV !== "production" && typeof createState !== "function") {
|
||||
console.warn(
|
||||
"[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`."
|
||||
);
|
||||
}
|
||||
const api = typeof createState === "function" ? createStore(createState) : createState;
|
||||
const useBoundStore = (selector, equalityFn) => useStore(api, selector, equalityFn);
|
||||
Object.assign(useBoundStore, api);
|
||||
return useBoundStore;
|
||||
};
|
||||
const create = (createState) => createState ? createImpl(createState) : createImpl;
|
||||
var react = (createState) => {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
console.warn(
|
||||
"[DEPRECATED] Default export is deprecated. Instead use `import { create } from 'zustand'`."
|
||||
);
|
||||
}
|
||||
return create(createState);
|
||||
};
|
||||
|
||||
export { create, react as default, useStore };
|
48
esm/index.mjs
Normal file
48
esm/index.mjs
Normal file
@ -0,0 +1,48 @@
|
||||
import { createStore } from 'zustand/vanilla';
|
||||
export * from 'zustand/vanilla';
|
||||
import ReactExports from 'react';
|
||||
import useSyncExternalStoreExports from 'use-sync-external-store/shim/with-selector.js';
|
||||
|
||||
const { useDebugValue } = ReactExports;
|
||||
const { useSyncExternalStoreWithSelector } = useSyncExternalStoreExports;
|
||||
let didWarnAboutEqualityFn = false;
|
||||
const identity = (arg) => arg;
|
||||
function useStore(api, selector = identity, equalityFn) {
|
||||
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && equalityFn && !didWarnAboutEqualityFn) {
|
||||
console.warn(
|
||||
"[DEPRECATED] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`. They can be imported from 'zustand/traditional'. https://github.com/pmndrs/zustand/discussions/1937"
|
||||
);
|
||||
didWarnAboutEqualityFn = true;
|
||||
}
|
||||
const slice = useSyncExternalStoreWithSelector(
|
||||
api.subscribe,
|
||||
api.getState,
|
||||
api.getServerState || api.getInitialState,
|
||||
selector,
|
||||
equalityFn
|
||||
);
|
||||
useDebugValue(slice);
|
||||
return slice;
|
||||
}
|
||||
const createImpl = (createState) => {
|
||||
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && typeof createState !== "function") {
|
||||
console.warn(
|
||||
"[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`."
|
||||
);
|
||||
}
|
||||
const api = typeof createState === "function" ? createStore(createState) : createState;
|
||||
const useBoundStore = (selector, equalityFn) => useStore(api, selector, equalityFn);
|
||||
Object.assign(useBoundStore, api);
|
||||
return useBoundStore;
|
||||
};
|
||||
const create = (createState) => createState ? createImpl(createState) : createImpl;
|
||||
var react = (createState) => {
|
||||
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production") {
|
||||
console.warn(
|
||||
"[DEPRECATED] Default export is deprecated. Instead use `import { create } from 'zustand'`."
|
||||
);
|
||||
}
|
||||
return create(createState);
|
||||
};
|
||||
|
||||
export { create, react as default, useStore };
|
5
esm/middleware.d.mts
Normal file
5
esm/middleware.d.mts
Normal file
@ -0,0 +1,5 @@
|
||||
export * from './middleware/redux.mjs';
|
||||
export * from './middleware/devtools.mjs';
|
||||
export * from './middleware/subscribeWithSelector.mjs';
|
||||
export * from './middleware/combine.mjs';
|
||||
export * from './middleware/persist.mjs';
|
5
esm/middleware.d.ts
vendored
Normal file
5
esm/middleware.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
export * from './middleware/redux';
|
||||
export * from './middleware/devtools';
|
||||
export * from './middleware/subscribeWithSelector';
|
||||
export * from './middleware/combine';
|
||||
export * from './middleware/persist';
|
584
esm/middleware.js
Normal file
584
esm/middleware.js
Normal file
@ -0,0 +1,584 @@
|
||||
const reduxImpl = (reducer, initial) => (set, _get, api) => {
|
||||
api.dispatch = (action) => {
|
||||
set((state) => reducer(state, action), false, action);
|
||||
return action;
|
||||
};
|
||||
api.dispatchFromDevtools = true;
|
||||
return { dispatch: (...a) => api.dispatch(...a), ...initial };
|
||||
};
|
||||
const redux = reduxImpl;
|
||||
|
||||
const trackedConnections = /* @__PURE__ */ new Map();
|
||||
const getTrackedConnectionState = (name) => {
|
||||
const api = trackedConnections.get(name);
|
||||
if (!api)
|
||||
return {};
|
||||
return Object.fromEntries(
|
||||
Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])
|
||||
);
|
||||
};
|
||||
const extractConnectionInformation = (store, extensionConnector, options) => {
|
||||
if (store === void 0) {
|
||||
return {
|
||||
type: "untracked",
|
||||
connection: extensionConnector.connect(options)
|
||||
};
|
||||
}
|
||||
const existingConnection = trackedConnections.get(options.name);
|
||||
if (existingConnection) {
|
||||
return { type: "tracked", store, ...existingConnection };
|
||||
}
|
||||
const newConnection = {
|
||||
connection: extensionConnector.connect(options),
|
||||
stores: {}
|
||||
};
|
||||
trackedConnections.set(options.name, newConnection);
|
||||
return { type: "tracked", store, ...newConnection };
|
||||
};
|
||||
const devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {
|
||||
const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;
|
||||
let extensionConnector;
|
||||
try {
|
||||
extensionConnector = (enabled != null ? enabled : process.env.NODE_ENV !== "production") && window.__REDUX_DEVTOOLS_EXTENSION__;
|
||||
} catch (e) {
|
||||
}
|
||||
if (!extensionConnector) {
|
||||
if (process.env.NODE_ENV !== "production" && enabled) {
|
||||
console.warn(
|
||||
"[zustand devtools middleware] Please install/enable Redux devtools extension"
|
||||
);
|
||||
}
|
||||
return fn(set, get, api);
|
||||
}
|
||||
const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);
|
||||
let isRecording = true;
|
||||
api.setState = (state, replace, nameOrAction) => {
|
||||
const r = set(state, replace);
|
||||
if (!isRecording)
|
||||
return r;
|
||||
const action = nameOrAction === void 0 ? { type: anonymousActionType || "anonymous" } : typeof nameOrAction === "string" ? { type: nameOrAction } : nameOrAction;
|
||||
if (store === void 0) {
|
||||
connection == null ? void 0 : connection.send(action, get());
|
||||
return r;
|
||||
}
|
||||
connection == null ? void 0 : connection.send(
|
||||
{
|
||||
...action,
|
||||
type: `${store}/${action.type}`
|
||||
},
|
||||
{
|
||||
...getTrackedConnectionState(options.name),
|
||||
[store]: api.getState()
|
||||
}
|
||||
);
|
||||
return r;
|
||||
};
|
||||
const setStateFromDevtools = (...a) => {
|
||||
const originalIsRecording = isRecording;
|
||||
isRecording = false;
|
||||
set(...a);
|
||||
isRecording = originalIsRecording;
|
||||
};
|
||||
const initialState = fn(api.setState, get, api);
|
||||
if (connectionInformation.type === "untracked") {
|
||||
connection == null ? void 0 : connection.init(initialState);
|
||||
} else {
|
||||
connectionInformation.stores[connectionInformation.store] = api;
|
||||
connection == null ? void 0 : connection.init(
|
||||
Object.fromEntries(
|
||||
Object.entries(connectionInformation.stores).map(([key, store2]) => [
|
||||
key,
|
||||
key === connectionInformation.store ? initialState : store2.getState()
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
if (api.dispatchFromDevtools && typeof api.dispatch === "function") {
|
||||
let didWarnAboutReservedActionType = false;
|
||||
const originalDispatch = api.dispatch;
|
||||
api.dispatch = (...a) => {
|
||||
if (process.env.NODE_ENV !== "production" && a[0].type === "__setState" && !didWarnAboutReservedActionType) {
|
||||
console.warn(
|
||||
'[zustand devtools middleware] "__setState" action type is reserved to set state from the devtools. Avoid using it.'
|
||||
);
|
||||
didWarnAboutReservedActionType = true;
|
||||
}
|
||||
originalDispatch(...a);
|
||||
};
|
||||
}
|
||||
connection.subscribe((message) => {
|
||||
var _a;
|
||||
switch (message.type) {
|
||||
case "ACTION":
|
||||
if (typeof message.payload !== "string") {
|
||||
console.error(
|
||||
"[zustand devtools middleware] Unsupported action format"
|
||||
);
|
||||
return;
|
||||
}
|
||||
return parseJsonThen(
|
||||
message.payload,
|
||||
(action) => {
|
||||
if (action.type === "__setState") {
|
||||
if (store === void 0) {
|
||||
setStateFromDevtools(action.state);
|
||||
return;
|
||||
}
|
||||
if (Object.keys(action.state).length !== 1) {
|
||||
console.error(
|
||||
`
|
||||
[zustand devtools middleware] Unsupported __setState action format.
|
||||
When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),
|
||||
and value of this only key should be a state object. Example: { "type": "__setState", "state": { "abc123Store": { "foo": "bar" } } }
|
||||
`
|
||||
);
|
||||
}
|
||||
const stateFromDevtools = action.state[store];
|
||||
if (stateFromDevtools === void 0 || stateFromDevtools === null) {
|
||||
return;
|
||||
}
|
||||
if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {
|
||||
setStateFromDevtools(stateFromDevtools);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!api.dispatchFromDevtools)
|
||||
return;
|
||||
if (typeof api.dispatch !== "function")
|
||||
return;
|
||||
api.dispatch(action);
|
||||
}
|
||||
);
|
||||
case "DISPATCH":
|
||||
switch (message.payload.type) {
|
||||
case "RESET":
|
||||
setStateFromDevtools(initialState);
|
||||
if (store === void 0) {
|
||||
return connection == null ? void 0 : connection.init(api.getState());
|
||||
}
|
||||
return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));
|
||||
case "COMMIT":
|
||||
if (store === void 0) {
|
||||
connection == null ? void 0 : connection.init(api.getState());
|
||||
return;
|
||||
}
|
||||
return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));
|
||||
case "ROLLBACK":
|
||||
return parseJsonThen(message.state, (state) => {
|
||||
if (store === void 0) {
|
||||
setStateFromDevtools(state);
|
||||
connection == null ? void 0 : connection.init(api.getState());
|
||||
return;
|
||||
}
|
||||
setStateFromDevtools(state[store]);
|
||||
connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));
|
||||
});
|
||||
case "JUMP_TO_STATE":
|
||||
case "JUMP_TO_ACTION":
|
||||
return parseJsonThen(message.state, (state) => {
|
||||
if (store === void 0) {
|
||||
setStateFromDevtools(state);
|
||||
return;
|
||||
}
|
||||
if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {
|
||||
setStateFromDevtools(state[store]);
|
||||
}
|
||||
});
|
||||
case "IMPORT_STATE": {
|
||||
const { nextLiftedState } = message.payload;
|
||||
const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;
|
||||
if (!lastComputedState)
|
||||
return;
|
||||
if (store === void 0) {
|
||||
setStateFromDevtools(lastComputedState);
|
||||
} else {
|
||||
setStateFromDevtools(lastComputedState[store]);
|
||||
}
|
||||
connection == null ? void 0 : connection.send(
|
||||
null,
|
||||
// FIXME no-any
|
||||
nextLiftedState
|
||||
);
|
||||
return;
|
||||
}
|
||||
case "PAUSE_RECORDING":
|
||||
return isRecording = !isRecording;
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
return initialState;
|
||||
};
|
||||
const devtools = devtoolsImpl;
|
||||
const parseJsonThen = (stringified, f) => {
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(stringified);
|
||||
} catch (e) {
|
||||
console.error(
|
||||
"[zustand devtools middleware] Could not parse the received json",
|
||||
e
|
||||
);
|
||||
}
|
||||
if (parsed !== void 0)
|
||||
f(parsed);
|
||||
};
|
||||
|
||||
const subscribeWithSelectorImpl = (fn) => (set, get, api) => {
|
||||
const origSubscribe = api.subscribe;
|
||||
api.subscribe = (selector, optListener, options) => {
|
||||
let listener = selector;
|
||||
if (optListener) {
|
||||
const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;
|
||||
let currentSlice = selector(api.getState());
|
||||
listener = (state) => {
|
||||
const nextSlice = selector(state);
|
||||
if (!equalityFn(currentSlice, nextSlice)) {
|
||||
const previousSlice = currentSlice;
|
||||
optListener(currentSlice = nextSlice, previousSlice);
|
||||
}
|
||||
};
|
||||
if (options == null ? void 0 : options.fireImmediately) {
|
||||
optListener(currentSlice, currentSlice);
|
||||
}
|
||||
}
|
||||
return origSubscribe(listener);
|
||||
};
|
||||
const initialState = fn(set, get, api);
|
||||
return initialState;
|
||||
};
|
||||
const subscribeWithSelector = subscribeWithSelectorImpl;
|
||||
|
||||
const combine = (initialState, create) => (...a) => Object.assign({}, initialState, create(...a));
|
||||
|
||||
function createJSONStorage(getStorage, options) {
|
||||
let storage;
|
||||
try {
|
||||
storage = getStorage();
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
const persistStorage = {
|
||||
getItem: (name) => {
|
||||
var _a;
|
||||
const parse = (str2) => {
|
||||
if (str2 === null) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parse(str2, options == null ? void 0 : options.reviver);
|
||||
};
|
||||
const str = (_a = storage.getItem(name)) != null ? _a : null;
|
||||
if (str instanceof Promise) {
|
||||
return str.then(parse);
|
||||
}
|
||||
return parse(str);
|
||||
},
|
||||
setItem: (name, newValue) => storage.setItem(
|
||||
name,
|
||||
JSON.stringify(newValue, options == null ? void 0 : options.replacer)
|
||||
),
|
||||
removeItem: (name) => storage.removeItem(name)
|
||||
};
|
||||
return persistStorage;
|
||||
}
|
||||
const toThenable = (fn) => (input) => {
|
||||
try {
|
||||
const result = fn(input);
|
||||
if (result instanceof Promise) {
|
||||
return result;
|
||||
}
|
||||
return {
|
||||
then(onFulfilled) {
|
||||
return toThenable(onFulfilled)(result);
|
||||
},
|
||||
catch(_onRejected) {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
then(_onFulfilled) {
|
||||
return this;
|
||||
},
|
||||
catch(onRejected) {
|
||||
return toThenable(onRejected)(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
const oldImpl = (config, baseOptions) => (set, get, api) => {
|
||||
let options = {
|
||||
getStorage: () => localStorage,
|
||||
serialize: JSON.stringify,
|
||||
deserialize: JSON.parse,
|
||||
partialize: (state) => state,
|
||||
version: 0,
|
||||
merge: (persistedState, currentState) => ({
|
||||
...currentState,
|
||||
...persistedState
|
||||
}),
|
||||
...baseOptions
|
||||
};
|
||||
let hasHydrated = false;
|
||||
const hydrationListeners = /* @__PURE__ */ new Set();
|
||||
const finishHydrationListeners = /* @__PURE__ */ new Set();
|
||||
let storage;
|
||||
try {
|
||||
storage = options.getStorage();
|
||||
} catch (e) {
|
||||
}
|
||||
if (!storage) {
|
||||
return config(
|
||||
(...args) => {
|
||||
console.warn(
|
||||
`[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`
|
||||
);
|
||||
set(...args);
|
||||
},
|
||||
get,
|
||||
api
|
||||
);
|
||||
}
|
||||
const thenableSerialize = toThenable(options.serialize);
|
||||
const setItem = () => {
|
||||
const state = options.partialize({ ...get() });
|
||||
let errorInSync;
|
||||
const thenable = thenableSerialize({ state, version: options.version }).then(
|
||||
(serializedValue) => storage.setItem(options.name, serializedValue)
|
||||
).catch((e) => {
|
||||
errorInSync = e;
|
||||
});
|
||||
if (errorInSync) {
|
||||
throw errorInSync;
|
||||
}
|
||||
return thenable;
|
||||
};
|
||||
const savedSetState = api.setState;
|
||||
api.setState = (state, replace) => {
|
||||
savedSetState(state, replace);
|
||||
void setItem();
|
||||
};
|
||||
const configResult = config(
|
||||
(...args) => {
|
||||
set(...args);
|
||||
void setItem();
|
||||
},
|
||||
get,
|
||||
api
|
||||
);
|
||||
let stateFromStorage;
|
||||
const hydrate = () => {
|
||||
var _a;
|
||||
if (!storage)
|
||||
return;
|
||||
hasHydrated = false;
|
||||
hydrationListeners.forEach((cb) => cb(get()));
|
||||
const postRehydrationCallback = ((_a = options.onRehydrateStorage) == null ? void 0 : _a.call(options, get())) || void 0;
|
||||
return toThenable(storage.getItem.bind(storage))(options.name).then((storageValue) => {
|
||||
if (storageValue) {
|
||||
return options.deserialize(storageValue);
|
||||
}
|
||||
}).then((deserializedStorageValue) => {
|
||||
if (deserializedStorageValue) {
|
||||
if (typeof deserializedStorageValue.version === "number" && deserializedStorageValue.version !== options.version) {
|
||||
if (options.migrate) {
|
||||
return options.migrate(
|
||||
deserializedStorageValue.state,
|
||||
deserializedStorageValue.version
|
||||
);
|
||||
}
|
||||
console.error(
|
||||
`State loaded from storage couldn't be migrated since no migrate function was provided`
|
||||
);
|
||||
} else {
|
||||
return deserializedStorageValue.state;
|
||||
}
|
||||
}
|
||||
}).then((migratedState) => {
|
||||
var _a2;
|
||||
stateFromStorage = options.merge(
|
||||
migratedState,
|
||||
(_a2 = get()) != null ? _a2 : configResult
|
||||
);
|
||||
set(stateFromStorage, true);
|
||||
return setItem();
|
||||
}).then(() => {
|
||||
postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);
|
||||
hasHydrated = true;
|
||||
finishHydrationListeners.forEach((cb) => cb(stateFromStorage));
|
||||
}).catch((e) => {
|
||||
postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);
|
||||
});
|
||||
};
|
||||
api.persist = {
|
||||
setOptions: (newOptions) => {
|
||||
options = {
|
||||
...options,
|
||||
...newOptions
|
||||
};
|
||||
if (newOptions.getStorage) {
|
||||
storage = newOptions.getStorage();
|
||||
}
|
||||
},
|
||||
clearStorage: () => {
|
||||
storage == null ? void 0 : storage.removeItem(options.name);
|
||||
},
|
||||
getOptions: () => options,
|
||||
rehydrate: () => hydrate(),
|
||||
hasHydrated: () => hasHydrated,
|
||||
onHydrate: (cb) => {
|
||||
hydrationListeners.add(cb);
|
||||
return () => {
|
||||
hydrationListeners.delete(cb);
|
||||
};
|
||||
},
|
||||
onFinishHydration: (cb) => {
|
||||
finishHydrationListeners.add(cb);
|
||||
return () => {
|
||||
finishHydrationListeners.delete(cb);
|
||||
};
|
||||
}
|
||||
};
|
||||
hydrate();
|
||||
return stateFromStorage || configResult;
|
||||
};
|
||||
const newImpl = (config, baseOptions) => (set, get, api) => {
|
||||
let options = {
|
||||
storage: createJSONStorage(() => localStorage),
|
||||
partialize: (state) => state,
|
||||
version: 0,
|
||||
merge: (persistedState, currentState) => ({
|
||||
...currentState,
|
||||
...persistedState
|
||||
}),
|
||||
...baseOptions
|
||||
};
|
||||
let hasHydrated = false;
|
||||
const hydrationListeners = /* @__PURE__ */ new Set();
|
||||
const finishHydrationListeners = /* @__PURE__ */ new Set();
|
||||
let storage = options.storage;
|
||||
if (!storage) {
|
||||
return config(
|
||||
(...args) => {
|
||||
console.warn(
|
||||
`[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`
|
||||
);
|
||||
set(...args);
|
||||
},
|
||||
get,
|
||||
api
|
||||
);
|
||||
}
|
||||
const setItem = () => {
|
||||
const state = options.partialize({ ...get() });
|
||||
return storage.setItem(options.name, {
|
||||
state,
|
||||
version: options.version
|
||||
});
|
||||
};
|
||||
const savedSetState = api.setState;
|
||||
api.setState = (state, replace) => {
|
||||
savedSetState(state, replace);
|
||||
void setItem();
|
||||
};
|
||||
const configResult = config(
|
||||
(...args) => {
|
||||
set(...args);
|
||||
void setItem();
|
||||
},
|
||||
get,
|
||||
api
|
||||
);
|
||||
api.getInitialState = () => configResult;
|
||||
let stateFromStorage;
|
||||
const hydrate = () => {
|
||||
var _a, _b;
|
||||
if (!storage)
|
||||
return;
|
||||
hasHydrated = false;
|
||||
hydrationListeners.forEach((cb) => {
|
||||
var _a2;
|
||||
return cb((_a2 = get()) != null ? _a2 : configResult);
|
||||
});
|
||||
const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;
|
||||
return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {
|
||||
if (deserializedStorageValue) {
|
||||
if (typeof deserializedStorageValue.version === "number" && deserializedStorageValue.version !== options.version) {
|
||||
if (options.migrate) {
|
||||
return options.migrate(
|
||||
deserializedStorageValue.state,
|
||||
deserializedStorageValue.version
|
||||
);
|
||||
}
|
||||
console.error(
|
||||
`State loaded from storage couldn't be migrated since no migrate function was provided`
|
||||
);
|
||||
} else {
|
||||
return deserializedStorageValue.state;
|
||||
}
|
||||
}
|
||||
}).then((migratedState) => {
|
||||
var _a2;
|
||||
stateFromStorage = options.merge(
|
||||
migratedState,
|
||||
(_a2 = get()) != null ? _a2 : configResult
|
||||
);
|
||||
set(stateFromStorage, true);
|
||||
return setItem();
|
||||
}).then(() => {
|
||||
postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);
|
||||
stateFromStorage = get();
|
||||
hasHydrated = true;
|
||||
finishHydrationListeners.forEach((cb) => cb(stateFromStorage));
|
||||
}).catch((e) => {
|
||||
postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);
|
||||
});
|
||||
};
|
||||
api.persist = {
|
||||
setOptions: (newOptions) => {
|
||||
options = {
|
||||
...options,
|
||||
...newOptions
|
||||
};
|
||||
if (newOptions.storage) {
|
||||
storage = newOptions.storage;
|
||||
}
|
||||
},
|
||||
clearStorage: () => {
|
||||
storage == null ? void 0 : storage.removeItem(options.name);
|
||||
},
|
||||
getOptions: () => options,
|
||||
rehydrate: () => hydrate(),
|
||||
hasHydrated: () => hasHydrated,
|
||||
onHydrate: (cb) => {
|
||||
hydrationListeners.add(cb);
|
||||
return () => {
|
||||
hydrationListeners.delete(cb);
|
||||
};
|
||||
},
|
||||
onFinishHydration: (cb) => {
|
||||
finishHydrationListeners.add(cb);
|
||||
return () => {
|
||||
finishHydrationListeners.delete(cb);
|
||||
};
|
||||
}
|
||||
};
|
||||
if (!options.skipHydration) {
|
||||
hydrate();
|
||||
}
|
||||
return stateFromStorage || configResult;
|
||||
};
|
||||
const persistImpl = (config, baseOptions) => {
|
||||
if ("getStorage" in baseOptions || "serialize" in baseOptions || "deserialize" in baseOptions) {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
console.warn(
|
||||
"[DEPRECATED] `getStorage`, `serialize` and `deserialize` options are deprecated. Use `storage` option instead."
|
||||
);
|
||||
}
|
||||
return oldImpl(config, baseOptions);
|
||||
}
|
||||
return newImpl(config, baseOptions);
|
||||
};
|
||||
const persist = persistImpl;
|
||||
|
||||
export { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector };
|
584
esm/middleware.mjs
Normal file
584
esm/middleware.mjs
Normal file
@ -0,0 +1,584 @@
|
||||
const reduxImpl = (reducer, initial) => (set, _get, api) => {
|
||||
api.dispatch = (action) => {
|
||||
set((state) => reducer(state, action), false, action);
|
||||
return action;
|
||||
};
|
||||
api.dispatchFromDevtools = true;
|
||||
return { dispatch: (...a) => api.dispatch(...a), ...initial };
|
||||
};
|
||||
const redux = reduxImpl;
|
||||
|
||||
const trackedConnections = /* @__PURE__ */ new Map();
|
||||
const getTrackedConnectionState = (name) => {
|
||||
const api = trackedConnections.get(name);
|
||||
if (!api)
|
||||
return {};
|
||||
return Object.fromEntries(
|
||||
Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])
|
||||
);
|
||||
};
|
||||
const extractConnectionInformation = (store, extensionConnector, options) => {
|
||||
if (store === void 0) {
|
||||
return {
|
||||
type: "untracked",
|
||||
connection: extensionConnector.connect(options)
|
||||
};
|
||||
}
|
||||
const existingConnection = trackedConnections.get(options.name);
|
||||
if (existingConnection) {
|
||||
return { type: "tracked", store, ...existingConnection };
|
||||
}
|
||||
const newConnection = {
|
||||
connection: extensionConnector.connect(options),
|
||||
stores: {}
|
||||
};
|
||||
trackedConnections.set(options.name, newConnection);
|
||||
return { type: "tracked", store, ...newConnection };
|
||||
};
|
||||
const devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {
|
||||
const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;
|
||||
let extensionConnector;
|
||||
try {
|
||||
extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== "production") && window.__REDUX_DEVTOOLS_EXTENSION__;
|
||||
} catch (e) {
|
||||
}
|
||||
if (!extensionConnector) {
|
||||
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && enabled) {
|
||||
console.warn(
|
||||
"[zustand devtools middleware] Please install/enable Redux devtools extension"
|
||||
);
|
||||
}
|
||||
return fn(set, get, api);
|
||||
}
|
||||
const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);
|
||||
let isRecording = true;
|
||||
api.setState = (state, replace, nameOrAction) => {
|
||||
const r = set(state, replace);
|
||||
if (!isRecording)
|
||||
return r;
|
||||
const action = nameOrAction === void 0 ? { type: anonymousActionType || "anonymous" } : typeof nameOrAction === "string" ? { type: nameOrAction } : nameOrAction;
|
||||
if (store === void 0) {
|
||||
connection == null ? void 0 : connection.send(action, get());
|
||||
return r;
|
||||
}
|
||||
connection == null ? void 0 : connection.send(
|
||||
{
|
||||
...action,
|
||||
type: `${store}/${action.type}`
|
||||
},
|
||||
{
|
||||
...getTrackedConnectionState(options.name),
|
||||
[store]: api.getState()
|
||||
}
|
||||
);
|
||||
return r;
|
||||
};
|
||||
const setStateFromDevtools = (...a) => {
|
||||
const originalIsRecording = isRecording;
|
||||
isRecording = false;
|
||||
set(...a);
|
||||
isRecording = originalIsRecording;
|
||||
};
|
||||
const initialState = fn(api.setState, get, api);
|
||||
if (connectionInformation.type === "untracked") {
|
||||
connection == null ? void 0 : connection.init(initialState);
|
||||
} else {
|
||||
connectionInformation.stores[connectionInformation.store] = api;
|
||||
connection == null ? void 0 : connection.init(
|
||||
Object.fromEntries(
|
||||
Object.entries(connectionInformation.stores).map(([key, store2]) => [
|
||||
key,
|
||||
key === connectionInformation.store ? initialState : store2.getState()
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
if (api.dispatchFromDevtools && typeof api.dispatch === "function") {
|
||||
let didWarnAboutReservedActionType = false;
|
||||
const originalDispatch = api.dispatch;
|
||||
api.dispatch = (...a) => {
|
||||
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && a[0].type === "__setState" && !didWarnAboutReservedActionType) {
|
||||
console.warn(
|
||||
'[zustand devtools middleware] "__setState" action type is reserved to set state from the devtools. Avoid using it.'
|
||||
);
|
||||
didWarnAboutReservedActionType = true;
|
||||
}
|
||||
originalDispatch(...a);
|
||||
};
|
||||
}
|
||||
connection.subscribe((message) => {
|
||||
var _a;
|
||||
switch (message.type) {
|
||||
case "ACTION":
|
||||
if (typeof message.payload !== "string") {
|
||||
console.error(
|
||||
"[zustand devtools middleware] Unsupported action format"
|
||||
);
|
||||
return;
|
||||
}
|
||||
return parseJsonThen(
|
||||
message.payload,
|
||||
(action) => {
|
||||
if (action.type === "__setState") {
|
||||
if (store === void 0) {
|
||||
setStateFromDevtools(action.state);
|
||||
return;
|
||||
}
|
||||
if (Object.keys(action.state).length !== 1) {
|
||||
console.error(
|
||||
`
|
||||
[zustand devtools middleware] Unsupported __setState action format.
|
||||
When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),
|
||||
and value of this only key should be a state object. Example: { "type": "__setState", "state": { "abc123Store": { "foo": "bar" } } }
|
||||
`
|
||||
);
|
||||
}
|
||||
const stateFromDevtools = action.state[store];
|
||||
if (stateFromDevtools === void 0 || stateFromDevtools === null) {
|
||||
return;
|
||||
}
|
||||
if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {
|
||||
setStateFromDevtools(stateFromDevtools);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!api.dispatchFromDevtools)
|
||||
return;
|
||||
if (typeof api.dispatch !== "function")
|
||||
return;
|
||||
api.dispatch(action);
|
||||
}
|
||||
);
|
||||
case "DISPATCH":
|
||||
switch (message.payload.type) {
|
||||
case "RESET":
|
||||
setStateFromDevtools(initialState);
|
||||
if (store === void 0) {
|
||||
return connection == null ? void 0 : connection.init(api.getState());
|
||||
}
|
||||
return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));
|
||||
case "COMMIT":
|
||||
if (store === void 0) {
|
||||
connection == null ? void 0 : connection.init(api.getState());
|
||||
return;
|
||||
}
|
||||
return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));
|
||||
case "ROLLBACK":
|
||||
return parseJsonThen(message.state, (state) => {
|
||||
if (store === void 0) {
|
||||
setStateFromDevtools(state);
|
||||
connection == null ? void 0 : connection.init(api.getState());
|
||||
return;
|
||||
}
|
||||
setStateFromDevtools(state[store]);
|
||||
connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));
|
||||
});
|
||||
case "JUMP_TO_STATE":
|
||||
case "JUMP_TO_ACTION":
|
||||
return parseJsonThen(message.state, (state) => {
|
||||
if (store === void 0) {
|
||||
setStateFromDevtools(state);
|
||||
return;
|
||||
}
|
||||
if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {
|
||||
setStateFromDevtools(state[store]);
|
||||
}
|
||||
});
|
||||
case "IMPORT_STATE": {
|
||||
const { nextLiftedState } = message.payload;
|
||||
const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;
|
||||
if (!lastComputedState)
|
||||
return;
|
||||
if (store === void 0) {
|
||||
setStateFromDevtools(lastComputedState);
|
||||
} else {
|
||||
setStateFromDevtools(lastComputedState[store]);
|
||||
}
|
||||
connection == null ? void 0 : connection.send(
|
||||
null,
|
||||
// FIXME no-any
|
||||
nextLiftedState
|
||||
);
|
||||
return;
|
||||
}
|
||||
case "PAUSE_RECORDING":
|
||||
return isRecording = !isRecording;
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
return initialState;
|
||||
};
|
||||
const devtools = devtoolsImpl;
|
||||
const parseJsonThen = (stringified, f) => {
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(stringified);
|
||||
} catch (e) {
|
||||
console.error(
|
||||
"[zustand devtools middleware] Could not parse the received json",
|
||||
e
|
||||
);
|
||||
}
|
||||
if (parsed !== void 0)
|
||||
f(parsed);
|
||||
};
|
||||
|
||||
const subscribeWithSelectorImpl = (fn) => (set, get, api) => {
|
||||
const origSubscribe = api.subscribe;
|
||||
api.subscribe = (selector, optListener, options) => {
|
||||
let listener = selector;
|
||||
if (optListener) {
|
||||
const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;
|
||||
let currentSlice = selector(api.getState());
|
||||
listener = (state) => {
|
||||
const nextSlice = selector(state);
|
||||
if (!equalityFn(currentSlice, nextSlice)) {
|
||||
const previousSlice = currentSlice;
|
||||
optListener(currentSlice = nextSlice, previousSlice);
|
||||
}
|
||||
};
|
||||
if (options == null ? void 0 : options.fireImmediately) {
|
||||
optListener(currentSlice, currentSlice);
|
||||
}
|
||||
}
|
||||
return origSubscribe(listener);
|
||||
};
|
||||
const initialState = fn(set, get, api);
|
||||
return initialState;
|
||||
};
|
||||
const subscribeWithSelector = subscribeWithSelectorImpl;
|
||||
|
||||
const combine = (initialState, create) => (...a) => Object.assign({}, initialState, create(...a));
|
||||
|
||||
function createJSONStorage(getStorage, options) {
|
||||
let storage;
|
||||
try {
|
||||
storage = getStorage();
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
const persistStorage = {
|
||||
getItem: (name) => {
|
||||
var _a;
|
||||
const parse = (str2) => {
|
||||
if (str2 === null) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parse(str2, options == null ? void 0 : options.reviver);
|
||||
};
|
||||
const str = (_a = storage.getItem(name)) != null ? _a : null;
|
||||
if (str instanceof Promise) {
|
||||
return str.then(parse);
|
||||
}
|
||||
return parse(str);
|
||||
},
|
||||
setItem: (name, newValue) => storage.setItem(
|
||||
name,
|
||||
JSON.stringify(newValue, options == null ? void 0 : options.replacer)
|
||||
),
|
||||
removeItem: (name) => storage.removeItem(name)
|
||||
};
|
||||
return persistStorage;
|
||||
}
|
||||
const toThenable = (fn) => (input) => {
|
||||
try {
|
||||
const result = fn(input);
|
||||
if (result instanceof Promise) {
|
||||
return result;
|
||||
}
|
||||
return {
|
||||
then(onFulfilled) {
|
||||
return toThenable(onFulfilled)(result);
|
||||
},
|
||||
catch(_onRejected) {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
then(_onFulfilled) {
|
||||
return this;
|
||||
},
|
||||
catch(onRejected) {
|
||||
return toThenable(onRejected)(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
const oldImpl = (config, baseOptions) => (set, get, api) => {
|
||||
let options = {
|
||||
getStorage: () => localStorage,
|
||||
serialize: JSON.stringify,
|
||||
deserialize: JSON.parse,
|
||||
partialize: (state) => state,
|
||||
version: 0,
|
||||
merge: (persistedState, currentState) => ({
|
||||
...currentState,
|
||||
...persistedState
|
||||
}),
|
||||
...baseOptions
|
||||
};
|
||||
let hasHydrated = false;
|
||||
const hydrationListeners = /* @__PURE__ */ new Set();
|
||||
const finishHydrationListeners = /* @__PURE__ */ new Set();
|
||||
let storage;
|
||||
try {
|
||||
storage = options.getStorage();
|
||||
} catch (e) {
|
||||
}
|
||||
if (!storage) {
|
||||
return config(
|
||||
(...args) => {
|
||||
console.warn(
|
||||
`[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`
|
||||
);
|
||||
set(...args);
|
||||
},
|
||||
get,
|
||||
api
|
||||
);
|
||||
}
|
||||
const thenableSerialize = toThenable(options.serialize);
|
||||
const setItem = () => {
|
||||
const state = options.partialize({ ...get() });
|
||||
let errorInSync;
|
||||
const thenable = thenableSerialize({ state, version: options.version }).then(
|
||||
(serializedValue) => storage.setItem(options.name, serializedValue)
|
||||
).catch((e) => {
|
||||
errorInSync = e;
|
||||
});
|
||||
if (errorInSync) {
|
||||
throw errorInSync;
|
||||
}
|
||||
return thenable;
|
||||
};
|
||||
const savedSetState = api.setState;
|
||||
api.setState = (state, replace) => {
|
||||
savedSetState(state, replace);
|
||||
void setItem();
|
||||
};
|
||||
const configResult = config(
|
||||
(...args) => {
|
||||
set(...args);
|
||||
void setItem();
|
||||
},
|
||||
get,
|
||||
api
|
||||
);
|
||||
let stateFromStorage;
|
||||
const hydrate = () => {
|
||||
var _a;
|
||||
if (!storage)
|
||||
return;
|
||||
hasHydrated = false;
|
||||
hydrationListeners.forEach((cb) => cb(get()));
|
||||
const postRehydrationCallback = ((_a = options.onRehydrateStorage) == null ? void 0 : _a.call(options, get())) || void 0;
|
||||
return toThenable(storage.getItem.bind(storage))(options.name).then((storageValue) => {
|
||||
if (storageValue) {
|
||||
return options.deserialize(storageValue);
|
||||
}
|
||||
}).then((deserializedStorageValue) => {
|
||||
if (deserializedStorageValue) {
|
||||
if (typeof deserializedStorageValue.version === "number" && deserializedStorageValue.version !== options.version) {
|
||||
if (options.migrate) {
|
||||
return options.migrate(
|
||||
deserializedStorageValue.state,
|
||||
deserializedStorageValue.version
|
||||
);
|
||||
}
|
||||
console.error(
|
||||
`State loaded from storage couldn't be migrated since no migrate function was provided`
|
||||
);
|
||||
} else {
|
||||
return deserializedStorageValue.state;
|
||||
}
|
||||
}
|
||||
}).then((migratedState) => {
|
||||
var _a2;
|
||||
stateFromStorage = options.merge(
|
||||
migratedState,
|
||||
(_a2 = get()) != null ? _a2 : configResult
|
||||
);
|
||||
set(stateFromStorage, true);
|
||||
return setItem();
|
||||
}).then(() => {
|
||||
postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);
|
||||
hasHydrated = true;
|
||||
finishHydrationListeners.forEach((cb) => cb(stateFromStorage));
|
||||
}).catch((e) => {
|
||||
postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);
|
||||
});
|
||||
};
|
||||
api.persist = {
|
||||
setOptions: (newOptions) => {
|
||||
options = {
|
||||
...options,
|
||||
...newOptions
|
||||
};
|
||||
if (newOptions.getStorage) {
|
||||
storage = newOptions.getStorage();
|
||||
}
|
||||
},
|
||||
clearStorage: () => {
|
||||
storage == null ? void 0 : storage.removeItem(options.name);
|
||||
},
|
||||
getOptions: () => options,
|
||||
rehydrate: () => hydrate(),
|
||||
hasHydrated: () => hasHydrated,
|
||||
onHydrate: (cb) => {
|
||||
hydrationListeners.add(cb);
|
||||
return () => {
|
||||
hydrationListeners.delete(cb);
|
||||
};
|
||||
},
|
||||
onFinishHydration: (cb) => {
|
||||
finishHydrationListeners.add(cb);
|
||||
return () => {
|
||||
finishHydrationListeners.delete(cb);
|
||||
};
|
||||
}
|
||||
};
|
||||
hydrate();
|
||||
return stateFromStorage || configResult;
|
||||
};
|
||||
const newImpl = (config, baseOptions) => (set, get, api) => {
|
||||
let options = {
|
||||
storage: createJSONStorage(() => localStorage),
|
||||
partialize: (state) => state,
|
||||
version: 0,
|
||||
merge: (persistedState, currentState) => ({
|
||||
...currentState,
|
||||
...persistedState
|
||||
}),
|
||||
...baseOptions
|
||||
};
|
||||
let hasHydrated = false;
|
||||
const hydrationListeners = /* @__PURE__ */ new Set();
|
||||
const finishHydrationListeners = /* @__PURE__ */ new Set();
|
||||
let storage = options.storage;
|
||||
if (!storage) {
|
||||
return config(
|
||||
(...args) => {
|
||||
console.warn(
|
||||
`[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`
|
||||
);
|
||||
set(...args);
|
||||
},
|
||||
get,
|
||||
api
|
||||
);
|
||||
}
|
||||
const setItem = () => {
|
||||
const state = options.partialize({ ...get() });
|
||||
return storage.setItem(options.name, {
|
||||
state,
|
||||
version: options.version
|
||||
});
|
||||
};
|
||||
const savedSetState = api.setState;
|
||||
api.setState = (state, replace) => {
|
||||
savedSetState(state, replace);
|
||||
void setItem();
|
||||
};
|
||||
const configResult = config(
|
||||
(...args) => {
|
||||
set(...args);
|
||||
void setItem();
|
||||
},
|
||||
get,
|
||||
api
|
||||
);
|
||||
api.getInitialState = () => configResult;
|
||||
let stateFromStorage;
|
||||
const hydrate = () => {
|
||||
var _a, _b;
|
||||
if (!storage)
|
||||
return;
|
||||
hasHydrated = false;
|
||||
hydrationListeners.forEach((cb) => {
|
||||
var _a2;
|
||||
return cb((_a2 = get()) != null ? _a2 : configResult);
|
||||
});
|
||||
const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;
|
||||
return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {
|
||||
if (deserializedStorageValue) {
|
||||
if (typeof deserializedStorageValue.version === "number" && deserializedStorageValue.version !== options.version) {
|
||||
if (options.migrate) {
|
||||
return options.migrate(
|
||||
deserializedStorageValue.state,
|
||||
deserializedStorageValue.version
|
||||
);
|
||||
}
|
||||
console.error(
|
||||
`State loaded from storage couldn't be migrated since no migrate function was provided`
|
||||
);
|
||||
} else {
|
||||
return deserializedStorageValue.state;
|
||||
}
|
||||
}
|
||||
}).then((migratedState) => {
|
||||
var _a2;
|
||||
stateFromStorage = options.merge(
|
||||
migratedState,
|
||||
(_a2 = get()) != null ? _a2 : configResult
|
||||
);
|
||||
set(stateFromStorage, true);
|
||||
return setItem();
|
||||
}).then(() => {
|
||||
postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);
|
||||
stateFromStorage = get();
|
||||
hasHydrated = true;
|
||||
finishHydrationListeners.forEach((cb) => cb(stateFromStorage));
|
||||
}).catch((e) => {
|
||||
postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);
|
||||
});
|
||||
};
|
||||
api.persist = {
|
||||
setOptions: (newOptions) => {
|
||||
options = {
|
||||
...options,
|
||||
...newOptions
|
||||
};
|
||||
if (newOptions.storage) {
|
||||
storage = newOptions.storage;
|
||||
}
|
||||
},
|
||||
clearStorage: () => {
|
||||
storage == null ? void 0 : storage.removeItem(options.name);
|
||||
},
|
||||
getOptions: () => options,
|
||||
rehydrate: () => hydrate(),
|
||||
hasHydrated: () => hasHydrated,
|
||||
onHydrate: (cb) => {
|
||||
hydrationListeners.add(cb);
|
||||
return () => {
|
||||
hydrationListeners.delete(cb);
|
||||
};
|
||||
},
|
||||
onFinishHydration: (cb) => {
|
||||
finishHydrationListeners.add(cb);
|
||||
return () => {
|
||||
finishHydrationListeners.delete(cb);
|
||||
};
|
||||
}
|
||||
};
|
||||
if (!options.skipHydration) {
|
||||
hydrate();
|
||||
}
|
||||
return stateFromStorage || configResult;
|
||||
};
|
||||
const persistImpl = (config, baseOptions) => {
|
||||
if ("getStorage" in baseOptions || "serialize" in baseOptions || "deserialize" in baseOptions) {
|
||||
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production") {
|
||||
console.warn(
|
||||
"[DEPRECATED] `getStorage`, `serialize` and `deserialize` options are deprecated. Use `storage` option instead."
|
||||
);
|
||||
}
|
||||
return oldImpl(config, baseOptions);
|
||||
}
|
||||
return newImpl(config, baseOptions);
|
||||
};
|
||||
const persist = persistImpl;
|
||||
|
||||
export { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector };
|
5
esm/middleware/combine.d.mts
Normal file
5
esm/middleware/combine.d.mts
Normal file
@ -0,0 +1,5 @@
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla.mjs';
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type Combine = <T extends object, U extends object, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initialState: T, additionalStateCreator: StateCreator<T, Mps, Mcs, U>) => StateCreator<Write<T, U>, Mps, Mcs>;
|
||||
export declare const combine: Combine;
|
||||
export {};
|
5
esm/middleware/combine.d.ts
vendored
Normal file
5
esm/middleware/combine.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type Combine = <T extends object, U extends object, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initialState: T, additionalStateCreator: StateCreator<T, Mps, Mcs, U>) => StateCreator<Write<T, U>, Mps, Mcs>;
|
||||
export declare const combine: Combine;
|
||||
export {};
|
49
esm/middleware/devtools.d.mts
Normal file
49
esm/middleware/devtools.d.mts
Normal file
@ -0,0 +1,49 @@
|
||||
import type { StateCreator, StoreApi, StoreMutatorIdentifier } from '../vanilla.mjs';
|
||||
type Config = Parameters<(Window extends {
|
||||
__REDUX_DEVTOOLS_EXTENSION__?: infer T;
|
||||
} ? T : {
|
||||
connect: (param: any) => any;
|
||||
})['connect']>[0];
|
||||
declare module '../vanilla.mjs' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/devtools': WithDevtools<S>;
|
||||
}
|
||||
}
|
||||
type Cast<T, U> = T extends U ? T : U;
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type TakeTwo<T> = T extends {
|
||||
length: 0;
|
||||
} ? [undefined, undefined] : T extends {
|
||||
length: 1;
|
||||
} ? [...a0: Cast<T, unknown[]>, a1: undefined] : T extends {
|
||||
length: 0 | 1;
|
||||
} ? [...a0: Cast<T, unknown[]>, a1: undefined] : T extends {
|
||||
length: 2;
|
||||
} ? T : T extends {
|
||||
length: 1 | 2;
|
||||
} ? T : T extends {
|
||||
length: 0 | 1 | 2;
|
||||
} ? T : T extends [infer A0, infer A1, ...unknown[]] ? [A0, A1] : T extends [infer A0, (infer A1)?, ...unknown[]] ? [A0, A1?] : T extends [(infer A0)?, (infer A1)?, ...unknown[]] ? [A0?, A1?] : never;
|
||||
type WithDevtools<S> = Write<S, StoreDevtools<S>>;
|
||||
type StoreDevtools<S> = S extends {
|
||||
setState: (...a: infer Sa) => infer Sr;
|
||||
} ? {
|
||||
setState<A extends string | {
|
||||
type: string;
|
||||
}>(...a: [...a: TakeTwo<Sa>, action?: A]): Sr;
|
||||
} : never;
|
||||
export interface DevtoolsOptions extends Config {
|
||||
name?: string;
|
||||
enabled?: boolean;
|
||||
anonymousActionType?: string;
|
||||
store?: string;
|
||||
}
|
||||
type Devtools = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [...Mps, ['zustand/devtools', never]], Mcs>, devtoolsOptions?: DevtoolsOptions) => StateCreator<T, Mps, [['zustand/devtools', never], ...Mcs]>;
|
||||
declare module '../vanilla.mjs' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/devtools': WithDevtools<S>;
|
||||
}
|
||||
}
|
||||
export type NamedSet<T> = WithDevtools<StoreApi<T>>['setState'];
|
||||
export declare const devtools: Devtools;
|
||||
export {};
|
49
esm/middleware/devtools.d.ts
vendored
Normal file
49
esm/middleware/devtools.d.ts
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
import type { StateCreator, StoreApi, StoreMutatorIdentifier } from '../vanilla';
|
||||
type Config = Parameters<(Window extends {
|
||||
__REDUX_DEVTOOLS_EXTENSION__?: infer T;
|
||||
} ? T : {
|
||||
connect: (param: any) => any;
|
||||
})['connect']>[0];
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/devtools': WithDevtools<S>;
|
||||
}
|
||||
}
|
||||
type Cast<T, U> = T extends U ? T : U;
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type TakeTwo<T> = T extends {
|
||||
length: 0;
|
||||
} ? [undefined, undefined] : T extends {
|
||||
length: 1;
|
||||
} ? [...a0: Cast<T, unknown[]>, a1: undefined] : T extends {
|
||||
length: 0 | 1;
|
||||
} ? [...a0: Cast<T, unknown[]>, a1: undefined] : T extends {
|
||||
length: 2;
|
||||
} ? T : T extends {
|
||||
length: 1 | 2;
|
||||
} ? T : T extends {
|
||||
length: 0 | 1 | 2;
|
||||
} ? T : T extends [infer A0, infer A1, ...unknown[]] ? [A0, A1] : T extends [infer A0, (infer A1)?, ...unknown[]] ? [A0, A1?] : T extends [(infer A0)?, (infer A1)?, ...unknown[]] ? [A0?, A1?] : never;
|
||||
type WithDevtools<S> = Write<S, StoreDevtools<S>>;
|
||||
type StoreDevtools<S> = S extends {
|
||||
setState: (...a: infer Sa) => infer Sr;
|
||||
} ? {
|
||||
setState<A extends string | {
|
||||
type: string;
|
||||
}>(...a: [...a: TakeTwo<Sa>, action?: A]): Sr;
|
||||
} : never;
|
||||
export interface DevtoolsOptions extends Config {
|
||||
name?: string;
|
||||
enabled?: boolean;
|
||||
anonymousActionType?: string;
|
||||
store?: string;
|
||||
}
|
||||
type Devtools = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [...Mps, ['zustand/devtools', never]], Mcs>, devtoolsOptions?: DevtoolsOptions) => StateCreator<T, Mps, [['zustand/devtools', never], ...Mcs]>;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/devtools': WithDevtools<S>;
|
||||
}
|
||||
}
|
||||
export type NamedSet<T> = WithDevtools<StoreApi<T>>['setState'];
|
||||
export declare const devtools: Devtools;
|
||||
export {};
|
25
esm/middleware/immer.d.mts
Normal file
25
esm/middleware/immer.d.mts
Normal file
@ -0,0 +1,25 @@
|
||||
import type { Draft } from 'immer';
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla.mjs';
|
||||
type Immer = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [...Mps, ['zustand/immer', never]], Mcs>) => StateCreator<T, Mps, [['zustand/immer', never], ...Mcs]>;
|
||||
declare module '../vanilla.mjs' {
|
||||
interface StoreMutators<S, A> {
|
||||
['zustand/immer']: WithImmer<S>;
|
||||
}
|
||||
}
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type SkipTwo<T> = T extends {
|
||||
length: 0;
|
||||
} ? [] : T extends {
|
||||
length: 1;
|
||||
} ? [] : T extends {
|
||||
length: 0 | 1;
|
||||
} ? [] : T extends [unknown, unknown, ...infer A] ? A : T extends [unknown, unknown?, ...infer A] ? A : T extends [unknown?, unknown?, ...infer A] ? A : never;
|
||||
type WithImmer<S> = Write<S, StoreImmer<S>>;
|
||||
type StoreImmer<S> = S extends {
|
||||
getState: () => infer T;
|
||||
setState: infer SetState;
|
||||
} ? SetState extends (...a: infer A) => infer Sr ? {
|
||||
setState(nextStateOrUpdater: T | Partial<T> | ((state: Draft<T>) => void), shouldReplace?: boolean | undefined, ...a: SkipTwo<A>): Sr;
|
||||
} : never : never;
|
||||
export declare const immer: Immer;
|
||||
export {};
|
25
esm/middleware/immer.d.ts
vendored
Normal file
25
esm/middleware/immer.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
import type { Draft } from 'immer';
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
type Immer = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [...Mps, ['zustand/immer', never]], Mcs>) => StateCreator<T, Mps, [['zustand/immer', never], ...Mcs]>;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
['zustand/immer']: WithImmer<S>;
|
||||
}
|
||||
}
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type SkipTwo<T> = T extends {
|
||||
length: 0;
|
||||
} ? [] : T extends {
|
||||
length: 1;
|
||||
} ? [] : T extends {
|
||||
length: 0 | 1;
|
||||
} ? [] : T extends [unknown, unknown, ...infer A] ? A : T extends [unknown, unknown?, ...infer A] ? A : T extends [unknown?, unknown?, ...infer A] ? A : never;
|
||||
type WithImmer<S> = Write<S, StoreImmer<S>>;
|
||||
type StoreImmer<S> = S extends {
|
||||
getState: () => infer T;
|
||||
setState: infer SetState;
|
||||
} ? SetState extends (...a: infer A) => infer Sr ? {
|
||||
setState(nextStateOrUpdater: T | Partial<T> | ((state: Draft<T>) => void), shouldReplace?: boolean | undefined, ...a: SkipTwo<A>): Sr;
|
||||
} : never : never;
|
||||
export declare const immer: Immer;
|
||||
export {};
|
12
esm/middleware/immer.js
Normal file
12
esm/middleware/immer.js
Normal file
@ -0,0 +1,12 @@
|
||||
import { produce } from 'immer';
|
||||
|
||||
const immerImpl = (initializer) => (set, get, store) => {
|
||||
store.setState = (updater, replace, ...a) => {
|
||||
const nextState = typeof updater === "function" ? produce(updater) : updater;
|
||||
return set(nextState, replace, ...a);
|
||||
};
|
||||
return initializer(store.setState, get, store);
|
||||
};
|
||||
const immer = immerImpl;
|
||||
|
||||
export { immer };
|
12
esm/middleware/immer.mjs
Normal file
12
esm/middleware/immer.mjs
Normal file
@ -0,0 +1,12 @@
|
||||
import { produce } from 'immer';
|
||||
|
||||
const immerImpl = (initializer) => (set, get, store) => {
|
||||
store.setState = (updater, replace, ...a) => {
|
||||
const nextState = typeof updater === "function" ? produce(updater) : updater;
|
||||
return set(nextState, replace, ...a);
|
||||
};
|
||||
return initializer(store.setState, get, store);
|
||||
};
|
||||
const immer = immerImpl;
|
||||
|
||||
export { immer };
|
119
esm/middleware/persist.d.mts
Normal file
119
esm/middleware/persist.d.mts
Normal file
@ -0,0 +1,119 @@
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla.mjs';
|
||||
export interface StateStorage {
|
||||
getItem: (name: string) => string | null | Promise<string | null>;
|
||||
setItem: (name: string, value: string) => unknown | Promise<unknown>;
|
||||
removeItem: (name: string) => unknown | Promise<unknown>;
|
||||
}
|
||||
export type StorageValue<S> = {
|
||||
state: S;
|
||||
version?: number;
|
||||
};
|
||||
export interface PersistStorage<S> {
|
||||
getItem: (name: string) => StorageValue<S> | null | Promise<StorageValue<S> | null>;
|
||||
setItem: (name: string, value: StorageValue<S>) => unknown | Promise<unknown>;
|
||||
removeItem: (name: string) => unknown | Promise<unknown>;
|
||||
}
|
||||
type JsonStorageOptions = {
|
||||
reviver?: (key: string, value: unknown) => unknown;
|
||||
replacer?: (key: string, value: unknown) => unknown;
|
||||
};
|
||||
export declare function createJSONStorage<S>(getStorage: () => StateStorage, options?: JsonStorageOptions): PersistStorage<S> | undefined;
|
||||
export interface PersistOptions<S, PersistedState = S> {
|
||||
/** Name of the storage (must be unique) */
|
||||
name: string;
|
||||
/**
|
||||
* @deprecated Use `storage` instead.
|
||||
* A function returning a storage.
|
||||
* The storage must fit `window.localStorage`'s api (or an async version of it).
|
||||
* For example the storage could be `AsyncStorage` from React Native.
|
||||
*
|
||||
* @default () => localStorage
|
||||
*/
|
||||
getStorage?: () => StateStorage;
|
||||
/**
|
||||
* @deprecated Use `storage` instead.
|
||||
* Use a custom serializer.
|
||||
* The returned string will be stored in the storage.
|
||||
*
|
||||
* @default JSON.stringify
|
||||
*/
|
||||
serialize?: (state: StorageValue<S>) => string | Promise<string>;
|
||||
/**
|
||||
* @deprecated Use `storage` instead.
|
||||
* Use a custom deserializer.
|
||||
* Must return an object matching StorageValue<S>
|
||||
*
|
||||
* @param str The storage's current value.
|
||||
* @default JSON.parse
|
||||
*/
|
||||
deserialize?: (str: string) => StorageValue<PersistedState> | Promise<StorageValue<PersistedState>>;
|
||||
/**
|
||||
* Use a custom persist storage.
|
||||
*
|
||||
* Combining `createJSONStorage` helps creating a persist storage
|
||||
* with JSON.parse and JSON.stringify.
|
||||
*
|
||||
* @default createJSONStorage(() => localStorage)
|
||||
*/
|
||||
storage?: PersistStorage<PersistedState> | undefined;
|
||||
/**
|
||||
* Filter the persisted value.
|
||||
*
|
||||
* @params state The state's value
|
||||
*/
|
||||
partialize?: (state: S) => PersistedState;
|
||||
/**
|
||||
* A function returning another (optional) function.
|
||||
* The main function will be called before the state rehydration.
|
||||
* The returned function will be called after the state rehydration or when an error occurred.
|
||||
*/
|
||||
onRehydrateStorage?: (state: S) => ((state?: S, error?: unknown) => void) | void;
|
||||
/**
|
||||
* If the stored state's version mismatch the one specified here, the storage will not be used.
|
||||
* This is useful when adding a breaking change to your store.
|
||||
*/
|
||||
version?: number;
|
||||
/**
|
||||
* A function to perform persisted state migration.
|
||||
* This function will be called when persisted state versions mismatch with the one specified here.
|
||||
*/
|
||||
migrate?: (persistedState: unknown, version: number) => PersistedState | Promise<PersistedState>;
|
||||
/**
|
||||
* A function to perform custom hydration merges when combining the stored state with the current one.
|
||||
* By default, this function does a shallow merge.
|
||||
*/
|
||||
merge?: (persistedState: unknown, currentState: S) => S;
|
||||
/**
|
||||
* An optional boolean that will prevent the persist middleware from triggering hydration on initialization,
|
||||
* This allows you to call `rehydrate()` at a specific point in your apps rendering life-cycle.
|
||||
*
|
||||
* This is useful in SSR application.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
skipHydration?: boolean;
|
||||
}
|
||||
type PersistListener<S> = (state: S) => void;
|
||||
type StorePersist<S, Ps> = {
|
||||
persist: {
|
||||
setOptions: (options: Partial<PersistOptions<S, Ps>>) => void;
|
||||
clearStorage: () => void;
|
||||
rehydrate: () => Promise<void> | void;
|
||||
hasHydrated: () => boolean;
|
||||
onHydrate: (fn: PersistListener<S>) => () => void;
|
||||
onFinishHydration: (fn: PersistListener<S>) => () => void;
|
||||
getOptions: () => Partial<PersistOptions<S, Ps>>;
|
||||
};
|
||||
};
|
||||
type Persist = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = [], U = T>(initializer: StateCreator<T, [...Mps, ['zustand/persist', unknown]], Mcs>, options: PersistOptions<T, U>) => StateCreator<T, Mps, [['zustand/persist', U], ...Mcs]>;
|
||||
declare module '../vanilla.mjs' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/persist': WithPersist<S, A>;
|
||||
}
|
||||
}
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type WithPersist<S, A> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? Write<S, StorePersist<T, A>> : never;
|
||||
export declare const persist: Persist;
|
||||
export {};
|
119
esm/middleware/persist.d.ts
vendored
Normal file
119
esm/middleware/persist.d.ts
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
export interface StateStorage {
|
||||
getItem: (name: string) => string | null | Promise<string | null>;
|
||||
setItem: (name: string, value: string) => unknown | Promise<unknown>;
|
||||
removeItem: (name: string) => unknown | Promise<unknown>;
|
||||
}
|
||||
export type StorageValue<S> = {
|
||||
state: S;
|
||||
version?: number;
|
||||
};
|
||||
export interface PersistStorage<S> {
|
||||
getItem: (name: string) => StorageValue<S> | null | Promise<StorageValue<S> | null>;
|
||||
setItem: (name: string, value: StorageValue<S>) => unknown | Promise<unknown>;
|
||||
removeItem: (name: string) => unknown | Promise<unknown>;
|
||||
}
|
||||
type JsonStorageOptions = {
|
||||
reviver?: (key: string, value: unknown) => unknown;
|
||||
replacer?: (key: string, value: unknown) => unknown;
|
||||
};
|
||||
export declare function createJSONStorage<S>(getStorage: () => StateStorage, options?: JsonStorageOptions): PersistStorage<S> | undefined;
|
||||
export interface PersistOptions<S, PersistedState = S> {
|
||||
/** Name of the storage (must be unique) */
|
||||
name: string;
|
||||
/**
|
||||
* @deprecated Use `storage` instead.
|
||||
* A function returning a storage.
|
||||
* The storage must fit `window.localStorage`'s api (or an async version of it).
|
||||
* For example the storage could be `AsyncStorage` from React Native.
|
||||
*
|
||||
* @default () => localStorage
|
||||
*/
|
||||
getStorage?: () => StateStorage;
|
||||
/**
|
||||
* @deprecated Use `storage` instead.
|
||||
* Use a custom serializer.
|
||||
* The returned string will be stored in the storage.
|
||||
*
|
||||
* @default JSON.stringify
|
||||
*/
|
||||
serialize?: (state: StorageValue<S>) => string | Promise<string>;
|
||||
/**
|
||||
* @deprecated Use `storage` instead.
|
||||
* Use a custom deserializer.
|
||||
* Must return an object matching StorageValue<S>
|
||||
*
|
||||
* @param str The storage's current value.
|
||||
* @default JSON.parse
|
||||
*/
|
||||
deserialize?: (str: string) => StorageValue<PersistedState> | Promise<StorageValue<PersistedState>>;
|
||||
/**
|
||||
* Use a custom persist storage.
|
||||
*
|
||||
* Combining `createJSONStorage` helps creating a persist storage
|
||||
* with JSON.parse and JSON.stringify.
|
||||
*
|
||||
* @default createJSONStorage(() => localStorage)
|
||||
*/
|
||||
storage?: PersistStorage<PersistedState> | undefined;
|
||||
/**
|
||||
* Filter the persisted value.
|
||||
*
|
||||
* @params state The state's value
|
||||
*/
|
||||
partialize?: (state: S) => PersistedState;
|
||||
/**
|
||||
* A function returning another (optional) function.
|
||||
* The main function will be called before the state rehydration.
|
||||
* The returned function will be called after the state rehydration or when an error occurred.
|
||||
*/
|
||||
onRehydrateStorage?: (state: S) => ((state?: S, error?: unknown) => void) | void;
|
||||
/**
|
||||
* If the stored state's version mismatch the one specified here, the storage will not be used.
|
||||
* This is useful when adding a breaking change to your store.
|
||||
*/
|
||||
version?: number;
|
||||
/**
|
||||
* A function to perform persisted state migration.
|
||||
* This function will be called when persisted state versions mismatch with the one specified here.
|
||||
*/
|
||||
migrate?: (persistedState: unknown, version: number) => PersistedState | Promise<PersistedState>;
|
||||
/**
|
||||
* A function to perform custom hydration merges when combining the stored state with the current one.
|
||||
* By default, this function does a shallow merge.
|
||||
*/
|
||||
merge?: (persistedState: unknown, currentState: S) => S;
|
||||
/**
|
||||
* An optional boolean that will prevent the persist middleware from triggering hydration on initialization,
|
||||
* This allows you to call `rehydrate()` at a specific point in your apps rendering life-cycle.
|
||||
*
|
||||
* This is useful in SSR application.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
skipHydration?: boolean;
|
||||
}
|
||||
type PersistListener<S> = (state: S) => void;
|
||||
type StorePersist<S, Ps> = {
|
||||
persist: {
|
||||
setOptions: (options: Partial<PersistOptions<S, Ps>>) => void;
|
||||
clearStorage: () => void;
|
||||
rehydrate: () => Promise<void> | void;
|
||||
hasHydrated: () => boolean;
|
||||
onHydrate: (fn: PersistListener<S>) => () => void;
|
||||
onFinishHydration: (fn: PersistListener<S>) => () => void;
|
||||
getOptions: () => Partial<PersistOptions<S, Ps>>;
|
||||
};
|
||||
};
|
||||
type Persist = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = [], U = T>(initializer: StateCreator<T, [...Mps, ['zustand/persist', unknown]], Mcs>, options: PersistOptions<T, U>) => StateCreator<T, Mps, [['zustand/persist', U], ...Mcs]>;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/persist': WithPersist<S, A>;
|
||||
}
|
||||
}
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type WithPersist<S, A> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? Write<S, StorePersist<T, A>> : never;
|
||||
export declare const persist: Persist;
|
||||
export {};
|
21
esm/middleware/redux.d.mts
Normal file
21
esm/middleware/redux.d.mts
Normal file
@ -0,0 +1,21 @@
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla.mjs';
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type Action = {
|
||||
type: string;
|
||||
};
|
||||
type StoreRedux<A> = {
|
||||
dispatch: (a: A) => A;
|
||||
dispatchFromDevtools: true;
|
||||
};
|
||||
type ReduxState<A> = {
|
||||
dispatch: StoreRedux<A>['dispatch'];
|
||||
};
|
||||
type WithRedux<S, A> = Write<S, StoreRedux<A>>;
|
||||
type Redux = <T, A extends Action, Cms extends [StoreMutatorIdentifier, unknown][] = []>(reducer: (state: T, action: A) => T, initialState: T) => StateCreator<Write<T, ReduxState<A>>, Cms, [['zustand/redux', A]]>;
|
||||
declare module '../vanilla.mjs' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/redux': WithRedux<S, A>;
|
||||
}
|
||||
}
|
||||
export declare const redux: Redux;
|
||||
export {};
|
21
esm/middleware/redux.d.ts
vendored
Normal file
21
esm/middleware/redux.d.ts
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type Action = {
|
||||
type: string;
|
||||
};
|
||||
type StoreRedux<A> = {
|
||||
dispatch: (a: A) => A;
|
||||
dispatchFromDevtools: true;
|
||||
};
|
||||
type ReduxState<A> = {
|
||||
dispatch: StoreRedux<A>['dispatch'];
|
||||
};
|
||||
type WithRedux<S, A> = Write<S, StoreRedux<A>>;
|
||||
type Redux = <T, A extends Action, Cms extends [StoreMutatorIdentifier, unknown][] = []>(reducer: (state: T, action: A) => T, initialState: T) => StateCreator<Write<T, ReduxState<A>>, Cms, [['zustand/redux', A]]>;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/redux': WithRedux<S, A>;
|
||||
}
|
||||
}
|
||||
export declare const redux: Redux;
|
||||
export {};
|
25
esm/middleware/subscribeWithSelector.d.mts
Normal file
25
esm/middleware/subscribeWithSelector.d.mts
Normal file
@ -0,0 +1,25 @@
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla.mjs';
|
||||
type SubscribeWithSelector = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [
|
||||
...Mps,
|
||||
['zustand/subscribeWithSelector', never]
|
||||
], Mcs>) => StateCreator<T, Mps, [['zustand/subscribeWithSelector', never], ...Mcs]>;
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type WithSelectorSubscribe<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? Write<S, StoreSubscribeWithSelector<T>> : never;
|
||||
declare module '../vanilla.mjs' {
|
||||
interface StoreMutators<S, A> {
|
||||
['zustand/subscribeWithSelector']: WithSelectorSubscribe<S>;
|
||||
}
|
||||
}
|
||||
type StoreSubscribeWithSelector<T> = {
|
||||
subscribe: {
|
||||
(listener: (selectedState: T, previousSelectedState: T) => void): () => void;
|
||||
<U>(selector: (state: T) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
|
||||
equalityFn?: (a: U, b: U) => boolean;
|
||||
fireImmediately?: boolean;
|
||||
}): () => void;
|
||||
};
|
||||
};
|
||||
export declare const subscribeWithSelector: SubscribeWithSelector;
|
||||
export {};
|
25
esm/middleware/subscribeWithSelector.d.ts
vendored
Normal file
25
esm/middleware/subscribeWithSelector.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
type SubscribeWithSelector = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [
|
||||
...Mps,
|
||||
['zustand/subscribeWithSelector', never]
|
||||
], Mcs>) => StateCreator<T, Mps, [['zustand/subscribeWithSelector', never], ...Mcs]>;
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type WithSelectorSubscribe<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? Write<S, StoreSubscribeWithSelector<T>> : never;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
['zustand/subscribeWithSelector']: WithSelectorSubscribe<S>;
|
||||
}
|
||||
}
|
||||
type StoreSubscribeWithSelector<T> = {
|
||||
subscribe: {
|
||||
(listener: (selectedState: T, previousSelectedState: T) => void): () => void;
|
||||
<U>(selector: (state: T) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
|
||||
equalityFn?: (a: U, b: U) => boolean;
|
||||
fireImmediately?: boolean;
|
||||
}): () => void;
|
||||
};
|
||||
};
|
||||
export declare const subscribeWithSelector: SubscribeWithSelector;
|
||||
export {};
|
38
esm/react.d.mts
Normal file
38
esm/react.d.mts
Normal file
@ -0,0 +1,38 @@
|
||||
import type { Mutate, StateCreator, StoreApi, StoreMutatorIdentifier } from './vanilla.mjs';
|
||||
type ExtractState<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? T : never;
|
||||
type ReadonlyStoreApi<T> = Pick<StoreApi<T>, 'getState' | 'subscribe'>;
|
||||
type WithReact<S extends ReadonlyStoreApi<unknown>> = S & {
|
||||
/** @deprecated please use api.getInitialState() */
|
||||
getServerState?: () => ExtractState<S>;
|
||||
};
|
||||
export declare function useStore<S extends WithReact<StoreApi<unknown>>>(api: S): ExtractState<S>;
|
||||
export declare function useStore<S extends WithReact<StoreApi<unknown>>, U>(api: S, selector: (state: ExtractState<S>) => U): U;
|
||||
/**
|
||||
* @deprecated The usage with three arguments is deprecated. Use `useStoreWithEqualityFn` from 'zustand/traditional'. The usage with one or two arguments is not deprecated.
|
||||
* https://github.com/pmndrs/zustand/discussions/1937
|
||||
*/
|
||||
export declare function useStore<S extends WithReact<StoreApi<unknown>>, U>(api: S, selector: (state: ExtractState<S>) => U, equalityFn: ((a: U, b: U) => boolean) | undefined): U;
|
||||
export type UseBoundStore<S extends WithReact<ReadonlyStoreApi<unknown>>> = {
|
||||
(): ExtractState<S>;
|
||||
<U>(selector: (state: ExtractState<S>) => U): U;
|
||||
/**
|
||||
* @deprecated Use `createWithEqualityFn` from 'zustand/traditional'
|
||||
*/
|
||||
<U>(selector: (state: ExtractState<S>) => U, equalityFn: (a: U, b: U) => boolean): U;
|
||||
} & S;
|
||||
type Create = {
|
||||
<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>): UseBoundStore<Mutate<StoreApi<T>, Mos>>;
|
||||
<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>) => UseBoundStore<Mutate<StoreApi<T>, Mos>>;
|
||||
/**
|
||||
* @deprecated Use `useStore` hook to bind store
|
||||
*/
|
||||
<S extends StoreApi<unknown>>(store: S): UseBoundStore<S>;
|
||||
};
|
||||
export declare const create: Create;
|
||||
/**
|
||||
* @deprecated Use `import { create } from 'zustand'`
|
||||
*/
|
||||
declare const _default: Create;
|
||||
export default _default;
|
38
esm/react.d.ts
vendored
Normal file
38
esm/react.d.ts
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
import type { Mutate, StateCreator, StoreApi, StoreMutatorIdentifier } from './vanilla';
|
||||
type ExtractState<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? T : never;
|
||||
type ReadonlyStoreApi<T> = Pick<StoreApi<T>, 'getState' | 'subscribe'>;
|
||||
type WithReact<S extends ReadonlyStoreApi<unknown>> = S & {
|
||||
/** @deprecated please use api.getInitialState() */
|
||||
getServerState?: () => ExtractState<S>;
|
||||
};
|
||||
export declare function useStore<S extends WithReact<StoreApi<unknown>>>(api: S): ExtractState<S>;
|
||||
export declare function useStore<S extends WithReact<StoreApi<unknown>>, U>(api: S, selector: (state: ExtractState<S>) => U): U;
|
||||
/**
|
||||
* @deprecated The usage with three arguments is deprecated. Use `useStoreWithEqualityFn` from 'zustand/traditional'. The usage with one or two arguments is not deprecated.
|
||||
* https://github.com/pmndrs/zustand/discussions/1937
|
||||
*/
|
||||
export declare function useStore<S extends WithReact<StoreApi<unknown>>, U>(api: S, selector: (state: ExtractState<S>) => U, equalityFn: ((a: U, b: U) => boolean) | undefined): U;
|
||||
export type UseBoundStore<S extends WithReact<ReadonlyStoreApi<unknown>>> = {
|
||||
(): ExtractState<S>;
|
||||
<U>(selector: (state: ExtractState<S>) => U): U;
|
||||
/**
|
||||
* @deprecated Use `createWithEqualityFn` from 'zustand/traditional'
|
||||
*/
|
||||
<U>(selector: (state: ExtractState<S>) => U, equalityFn: (a: U, b: U) => boolean): U;
|
||||
} & S;
|
||||
type Create = {
|
||||
<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>): UseBoundStore<Mutate<StoreApi<T>, Mos>>;
|
||||
<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>) => UseBoundStore<Mutate<StoreApi<T>, Mos>>;
|
||||
/**
|
||||
* @deprecated Use `useStore` hook to bind store
|
||||
*/
|
||||
<S extends StoreApi<unknown>>(store: S): UseBoundStore<S>;
|
||||
};
|
||||
export declare const create: Create;
|
||||
/**
|
||||
* @deprecated Use `import { create } from 'zustand'`
|
||||
*/
|
||||
declare const _default: Create;
|
||||
export default _default;
|
1
esm/react/shallow.d.mts
Normal file
1
esm/react/shallow.d.mts
Normal file
@ -0,0 +1 @@
|
||||
export declare function useShallow<S, U>(selector: (state: S) => U): (state: S) => U;
|
1
esm/react/shallow.d.ts
vendored
Normal file
1
esm/react/shallow.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export declare function useShallow<S, U>(selector: (state: S) => U): (state: S) => U;
|
51
esm/react/shallow.js
Normal file
51
esm/react/shallow.js
Normal file
@ -0,0 +1,51 @@
|
||||
import ReactExports from 'react';
|
||||
|
||||
function shallow(objA, objB) {
|
||||
if (Object.is(objA, objB)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
|
||||
return false;
|
||||
}
|
||||
if (objA instanceof Map && objB instanceof Map) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const [key, value] of objA) {
|
||||
if (!Object.is(value, objB.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (objA instanceof Set && objB instanceof Set) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const value of objA) {
|
||||
if (!objB.has(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const keysA = Object.keys(objA);
|
||||
if (keysA.length !== Object.keys(objB).length) {
|
||||
return false;
|
||||
}
|
||||
for (const keyA of keysA) {
|
||||
if (!Object.prototype.hasOwnProperty.call(objB, keyA) || !Object.is(objA[keyA], objB[keyA])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const { useRef } = ReactExports;
|
||||
function useShallow(selector) {
|
||||
const prev = useRef();
|
||||
return (state) => {
|
||||
const next = selector(state);
|
||||
return shallow(prev.current, next) ? prev.current : prev.current = next;
|
||||
};
|
||||
}
|
||||
|
||||
export { useShallow };
|
51
esm/react/shallow.mjs
Normal file
51
esm/react/shallow.mjs
Normal file
@ -0,0 +1,51 @@
|
||||
import ReactExports from 'react';
|
||||
|
||||
function shallow(objA, objB) {
|
||||
if (Object.is(objA, objB)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
|
||||
return false;
|
||||
}
|
||||
if (objA instanceof Map && objB instanceof Map) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const [key, value] of objA) {
|
||||
if (!Object.is(value, objB.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (objA instanceof Set && objB instanceof Set) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const value of objA) {
|
||||
if (!objB.has(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const keysA = Object.keys(objA);
|
||||
if (keysA.length !== Object.keys(objB).length) {
|
||||
return false;
|
||||
}
|
||||
for (const keyA of keysA) {
|
||||
if (!Object.prototype.hasOwnProperty.call(objB, keyA) || !Object.is(objA[keyA], objB[keyA])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const { useRef } = ReactExports;
|
||||
function useShallow(selector) {
|
||||
const prev = useRef();
|
||||
return (state) => {
|
||||
const next = selector(state);
|
||||
return shallow(prev.current, next) ? prev.current : prev.current = next;
|
||||
};
|
||||
}
|
||||
|
||||
export { useShallow };
|
7
esm/shallow.d.mts
Normal file
7
esm/shallow.d.mts
Normal file
@ -0,0 +1,7 @@
|
||||
import { shallow } from './vanilla/shallow.mjs';
|
||||
/**
|
||||
* @deprecated Use `import { shallow } from 'zustand/shallow'`
|
||||
*/
|
||||
declare const _default: typeof shallow;
|
||||
export default _default;
|
||||
export { shallow };
|
7
esm/shallow.d.ts
vendored
Normal file
7
esm/shallow.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import { shallow } from './vanilla/shallow';
|
||||
/**
|
||||
* @deprecated Use `import { shallow } from 'zustand/shallow'`
|
||||
*/
|
||||
declare const _default: typeof shallow;
|
||||
export default _default;
|
||||
export { shallow };
|
49
esm/shallow.js
Normal file
49
esm/shallow.js
Normal file
@ -0,0 +1,49 @@
|
||||
function shallow$1(objA, objB) {
|
||||
if (Object.is(objA, objB)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
|
||||
return false;
|
||||
}
|
||||
if (objA instanceof Map && objB instanceof Map) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const [key, value] of objA) {
|
||||
if (!Object.is(value, objB.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (objA instanceof Set && objB instanceof Set) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const value of objA) {
|
||||
if (!objB.has(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const keysA = Object.keys(objA);
|
||||
if (keysA.length !== Object.keys(objB).length) {
|
||||
return false;
|
||||
}
|
||||
for (const keyA of keysA) {
|
||||
if (!Object.prototype.hasOwnProperty.call(objB, keyA) || !Object.is(objA[keyA], objB[keyA])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var shallow = (objA, objB) => {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
console.warn(
|
||||
"[DEPRECATED] Default export is deprecated. Instead use `import { shallow } from 'zustand/shallow'`."
|
||||
);
|
||||
}
|
||||
return shallow$1(objA, objB);
|
||||
};
|
||||
|
||||
export { shallow as default, shallow$1 as shallow };
|
49
esm/shallow.mjs
Normal file
49
esm/shallow.mjs
Normal file
@ -0,0 +1,49 @@
|
||||
function shallow$1(objA, objB) {
|
||||
if (Object.is(objA, objB)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
|
||||
return false;
|
||||
}
|
||||
if (objA instanceof Map && objB instanceof Map) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const [key, value] of objA) {
|
||||
if (!Object.is(value, objB.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (objA instanceof Set && objB instanceof Set) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const value of objA) {
|
||||
if (!objB.has(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const keysA = Object.keys(objA);
|
||||
if (keysA.length !== Object.keys(objB).length) {
|
||||
return false;
|
||||
}
|
||||
for (const keyA of keysA) {
|
||||
if (!Object.prototype.hasOwnProperty.call(objB, keyA) || !Object.is(objA[keyA], objB[keyA])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var shallow = (objA, objB) => {
|
||||
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production") {
|
||||
console.warn(
|
||||
"[DEPRECATED] Default export is deprecated. Instead use `import { shallow } from 'zustand/shallow'`."
|
||||
);
|
||||
}
|
||||
return shallow$1(objA, objB);
|
||||
};
|
||||
|
||||
export { shallow as default, shallow$1 as shallow };
|
21
esm/traditional.d.mts
Normal file
21
esm/traditional.d.mts
Normal file
@ -0,0 +1,21 @@
|
||||
import type { Mutate, StateCreator, StoreApi, StoreMutatorIdentifier } from './vanilla.mjs';
|
||||
type ExtractState<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? T : never;
|
||||
type ReadonlyStoreApi<T> = Pick<StoreApi<T>, 'getState' | 'subscribe'>;
|
||||
type WithReact<S extends ReadonlyStoreApi<unknown>> = S & {
|
||||
/** @deprecated please use api.getInitialState() */
|
||||
getServerState?: () => ExtractState<S>;
|
||||
};
|
||||
export declare function useStoreWithEqualityFn<S extends WithReact<StoreApi<unknown>>>(api: S): ExtractState<S>;
|
||||
export declare function useStoreWithEqualityFn<S extends WithReact<StoreApi<unknown>>, U>(api: S, selector: (state: ExtractState<S>) => U, equalityFn?: (a: U, b: U) => boolean): U;
|
||||
export type UseBoundStoreWithEqualityFn<S extends WithReact<ReadonlyStoreApi<unknown>>> = {
|
||||
(): ExtractState<S>;
|
||||
<U>(selector: (state: ExtractState<S>) => U, equalityFn?: (a: U, b: U) => boolean): U;
|
||||
} & S;
|
||||
type CreateWithEqualityFn = {
|
||||
<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>, defaultEqualityFn?: <U>(a: U, b: U) => boolean): UseBoundStoreWithEqualityFn<Mutate<StoreApi<T>, Mos>>;
|
||||
<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>, defaultEqualityFn?: <U>(a: U, b: U) => boolean) => UseBoundStoreWithEqualityFn<Mutate<StoreApi<T>, Mos>>;
|
||||
};
|
||||
export declare const createWithEqualityFn: CreateWithEqualityFn;
|
||||
export {};
|
21
esm/traditional.d.ts
vendored
Normal file
21
esm/traditional.d.ts
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
import type { Mutate, StateCreator, StoreApi, StoreMutatorIdentifier } from './vanilla';
|
||||
type ExtractState<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? T : never;
|
||||
type ReadonlyStoreApi<T> = Pick<StoreApi<T>, 'getState' | 'subscribe'>;
|
||||
type WithReact<S extends ReadonlyStoreApi<unknown>> = S & {
|
||||
/** @deprecated please use api.getInitialState() */
|
||||
getServerState?: () => ExtractState<S>;
|
||||
};
|
||||
export declare function useStoreWithEqualityFn<S extends WithReact<StoreApi<unknown>>>(api: S): ExtractState<S>;
|
||||
export declare function useStoreWithEqualityFn<S extends WithReact<StoreApi<unknown>>, U>(api: S, selector: (state: ExtractState<S>) => U, equalityFn?: (a: U, b: U) => boolean): U;
|
||||
export type UseBoundStoreWithEqualityFn<S extends WithReact<ReadonlyStoreApi<unknown>>> = {
|
||||
(): ExtractState<S>;
|
||||
<U>(selector: (state: ExtractState<S>) => U, equalityFn?: (a: U, b: U) => boolean): U;
|
||||
} & S;
|
||||
type CreateWithEqualityFn = {
|
||||
<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>, defaultEqualityFn?: <U>(a: U, b: U) => boolean): UseBoundStoreWithEqualityFn<Mutate<StoreApi<T>, Mos>>;
|
||||
<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>, defaultEqualityFn?: <U>(a: U, b: U) => boolean) => UseBoundStoreWithEqualityFn<Mutate<StoreApi<T>, Mos>>;
|
||||
};
|
||||
export declare const createWithEqualityFn: CreateWithEqualityFn;
|
||||
export {};
|
27
esm/traditional.js
Normal file
27
esm/traditional.js
Normal file
@ -0,0 +1,27 @@
|
||||
import ReactExports from 'react';
|
||||
import useSyncExternalStoreExports from 'use-sync-external-store/shim/with-selector.js';
|
||||
import { createStore } from 'zustand/vanilla';
|
||||
|
||||
const { useDebugValue } = ReactExports;
|
||||
const { useSyncExternalStoreWithSelector } = useSyncExternalStoreExports;
|
||||
const identity = (arg) => arg;
|
||||
function useStoreWithEqualityFn(api, selector = identity, equalityFn) {
|
||||
const slice = useSyncExternalStoreWithSelector(
|
||||
api.subscribe,
|
||||
api.getState,
|
||||
api.getServerState || api.getInitialState,
|
||||
selector,
|
||||
equalityFn
|
||||
);
|
||||
useDebugValue(slice);
|
||||
return slice;
|
||||
}
|
||||
const createWithEqualityFnImpl = (createState, defaultEqualityFn) => {
|
||||
const api = createStore(createState);
|
||||
const useBoundStoreWithEqualityFn = (selector, equalityFn = defaultEqualityFn) => useStoreWithEqualityFn(api, selector, equalityFn);
|
||||
Object.assign(useBoundStoreWithEqualityFn, api);
|
||||
return useBoundStoreWithEqualityFn;
|
||||
};
|
||||
const createWithEqualityFn = (createState, defaultEqualityFn) => createState ? createWithEqualityFnImpl(createState, defaultEqualityFn) : createWithEqualityFnImpl;
|
||||
|
||||
export { createWithEqualityFn, useStoreWithEqualityFn };
|
27
esm/traditional.mjs
Normal file
27
esm/traditional.mjs
Normal file
@ -0,0 +1,27 @@
|
||||
import ReactExports from 'react';
|
||||
import useSyncExternalStoreExports from 'use-sync-external-store/shim/with-selector.js';
|
||||
import { createStore } from 'zustand/vanilla';
|
||||
|
||||
const { useDebugValue } = ReactExports;
|
||||
const { useSyncExternalStoreWithSelector } = useSyncExternalStoreExports;
|
||||
const identity = (arg) => arg;
|
||||
function useStoreWithEqualityFn(api, selector = identity, equalityFn) {
|
||||
const slice = useSyncExternalStoreWithSelector(
|
||||
api.subscribe,
|
||||
api.getState,
|
||||
api.getServerState || api.getInitialState,
|
||||
selector,
|
||||
equalityFn
|
||||
);
|
||||
useDebugValue(slice);
|
||||
return slice;
|
||||
}
|
||||
const createWithEqualityFnImpl = (createState, defaultEqualityFn) => {
|
||||
const api = createStore(createState);
|
||||
const useBoundStoreWithEqualityFn = (selector, equalityFn = defaultEqualityFn) => useStoreWithEqualityFn(api, selector, equalityFn);
|
||||
Object.assign(useBoundStoreWithEqualityFn, api);
|
||||
return useBoundStoreWithEqualityFn;
|
||||
};
|
||||
const createWithEqualityFn = (createState, defaultEqualityFn) => createState ? createWithEqualityFnImpl(createState, defaultEqualityFn) : createWithEqualityFnImpl;
|
||||
|
||||
export { createWithEqualityFn, useStoreWithEqualityFn };
|
85
esm/vanilla.d.mts
Normal file
85
esm/vanilla.d.mts
Normal file
@ -0,0 +1,85 @@
|
||||
type SetStateInternal<T> = {
|
||||
_(partial: T | Partial<T> | {
|
||||
_(state: T): T | Partial<T>;
|
||||
}['_'], replace?: boolean | undefined): void;
|
||||
}['_'];
|
||||
export interface StoreApi<T> {
|
||||
setState: SetStateInternal<T>;
|
||||
getState: () => T;
|
||||
getInitialState: () => T;
|
||||
subscribe: (listener: (state: T, prevState: T) => void) => () => void;
|
||||
/**
|
||||
* @deprecated Use `unsubscribe` returned by `subscribe`
|
||||
*/
|
||||
destroy: () => void;
|
||||
}
|
||||
type Get<T, K, F> = K extends keyof T ? T[K] : F;
|
||||
export type Mutate<S, Ms> = number extends Ms['length' & keyof Ms] ? S : Ms extends [] ? S : Ms extends [[infer Mi, infer Ma], ...infer Mrs] ? Mutate<StoreMutators<S, Ma>[Mi & StoreMutatorIdentifier], Mrs> : never;
|
||||
export type StateCreator<T, Mis extends [StoreMutatorIdentifier, unknown][] = [], Mos extends [StoreMutatorIdentifier, unknown][] = [], U = T> = ((setState: Get<Mutate<StoreApi<T>, Mis>, 'setState', never>, getState: Get<Mutate<StoreApi<T>, Mis>, 'getState', never>, store: Mutate<StoreApi<T>, Mis>) => U) & {
|
||||
$$storeMutators?: Mos;
|
||||
};
|
||||
export interface StoreMutators<S, A> {
|
||||
}
|
||||
export type StoreMutatorIdentifier = keyof StoreMutators<unknown, unknown>;
|
||||
type CreateStore = {
|
||||
<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>): Mutate<StoreApi<T>, Mos>;
|
||||
<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>) => Mutate<StoreApi<T>, Mos>;
|
||||
};
|
||||
type Configs = {
|
||||
cacheTime?: number;
|
||||
};
|
||||
type CreateStoreImpl = <T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>, configs?: Configs) => Mutate<StoreApi<T>, Mos>;
|
||||
export declare const createStore: CreateStoreImpl;
|
||||
/**
|
||||
* @deprecated Use `import { createStore } from 'zustand/vanilla'`
|
||||
*/
|
||||
declare const _default: CreateStore;
|
||||
export default _default;
|
||||
/**
|
||||
* @deprecated Use `unknown` instead of `State`
|
||||
*/
|
||||
export type State = unknown;
|
||||
/**
|
||||
* @deprecated Use `Partial<T> | ((s: T) => Partial<T>)` instead of `PartialState<T>`
|
||||
*/
|
||||
export type PartialState<T extends State> = Partial<T> | ((state: T) => Partial<T>);
|
||||
/**
|
||||
* @deprecated Use `(s: T) => U` instead of `StateSelector<T, U>`
|
||||
*/
|
||||
export type StateSelector<T extends State, U> = (state: T) => U;
|
||||
/**
|
||||
* @deprecated Use `(a: T, b: T) => boolean` instead of `EqualityChecker<T>`
|
||||
*/
|
||||
export type EqualityChecker<T> = (state: T, newState: T) => boolean;
|
||||
/**
|
||||
* @deprecated Use `(state: T, previousState: T) => void` instead of `StateListener<T>`
|
||||
*/
|
||||
export type StateListener<T> = (state: T, previousState: T) => void;
|
||||
/**
|
||||
* @deprecated Use `(slice: T, previousSlice: T) => void` instead of `StateSliceListener<T>`.
|
||||
*/
|
||||
export type StateSliceListener<T> = (slice: T, previousSlice: T) => void;
|
||||
/**
|
||||
* @deprecated Use `(listener: (state: T) => void) => void` instead of `Subscribe<T>`.
|
||||
*/
|
||||
export type Subscribe<T extends State> = {
|
||||
(listener: (state: T, previousState: T) => void): () => void;
|
||||
};
|
||||
/**
|
||||
* @deprecated You might be looking for `StateCreator`, if not then
|
||||
* use `StoreApi<T>['setState']` instead of `SetState<T>`.
|
||||
*/
|
||||
export type SetState<T extends State> = {
|
||||
_(partial: T | Partial<T> | {
|
||||
_(state: T): T | Partial<T>;
|
||||
}['_'], replace?: boolean | undefined): void;
|
||||
}['_'];
|
||||
/**
|
||||
* @deprecated You might be looking for `StateCreator`, if not then
|
||||
* use `StoreApi<T>['getState']` instead of `GetState<T>`.
|
||||
*/
|
||||
export type GetState<T extends State> = () => T;
|
||||
/**
|
||||
* @deprecated Use `StoreApi<T>['destroy']` instead of `Destroy`.
|
||||
*/
|
||||
export type Destroy = () => void;
|
85
esm/vanilla.d.ts
vendored
Normal file
85
esm/vanilla.d.ts
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
type SetStateInternal<T> = {
|
||||
_(partial: T | Partial<T> | {
|
||||
_(state: T): T | Partial<T>;
|
||||
}['_'], replace?: boolean | undefined): void;
|
||||
}['_'];
|
||||
export interface StoreApi<T> {
|
||||
setState: SetStateInternal<T>;
|
||||
getState: () => T;
|
||||
getInitialState: () => T;
|
||||
subscribe: (listener: (state: T, prevState: T) => void) => () => void;
|
||||
/**
|
||||
* @deprecated Use `unsubscribe` returned by `subscribe`
|
||||
*/
|
||||
destroy: () => void;
|
||||
}
|
||||
type Get<T, K, F> = K extends keyof T ? T[K] : F;
|
||||
export type Mutate<S, Ms> = number extends Ms['length' & keyof Ms] ? S : Ms extends [] ? S : Ms extends [[infer Mi, infer Ma], ...infer Mrs] ? Mutate<StoreMutators<S, Ma>[Mi & StoreMutatorIdentifier], Mrs> : never;
|
||||
export type StateCreator<T, Mis extends [StoreMutatorIdentifier, unknown][] = [], Mos extends [StoreMutatorIdentifier, unknown][] = [], U = T> = ((setState: Get<Mutate<StoreApi<T>, Mis>, 'setState', never>, getState: Get<Mutate<StoreApi<T>, Mis>, 'getState', never>, store: Mutate<StoreApi<T>, Mis>) => U) & {
|
||||
$$storeMutators?: Mos;
|
||||
};
|
||||
export interface StoreMutators<S, A> {
|
||||
}
|
||||
export type StoreMutatorIdentifier = keyof StoreMutators<unknown, unknown>;
|
||||
type CreateStore = {
|
||||
<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>): Mutate<StoreApi<T>, Mos>;
|
||||
<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>) => Mutate<StoreApi<T>, Mos>;
|
||||
};
|
||||
type Configs = {
|
||||
cacheTime?: number;
|
||||
};
|
||||
type CreateStoreImpl = <T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>, configs?: Configs) => Mutate<StoreApi<T>, Mos>;
|
||||
export declare const createStore: CreateStoreImpl;
|
||||
/**
|
||||
* @deprecated Use `import { createStore } from 'zustand/vanilla'`
|
||||
*/
|
||||
declare const _default: CreateStore;
|
||||
export default _default;
|
||||
/**
|
||||
* @deprecated Use `unknown` instead of `State`
|
||||
*/
|
||||
export type State = unknown;
|
||||
/**
|
||||
* @deprecated Use `Partial<T> | ((s: T) => Partial<T>)` instead of `PartialState<T>`
|
||||
*/
|
||||
export type PartialState<T extends State> = Partial<T> | ((state: T) => Partial<T>);
|
||||
/**
|
||||
* @deprecated Use `(s: T) => U` instead of `StateSelector<T, U>`
|
||||
*/
|
||||
export type StateSelector<T extends State, U> = (state: T) => U;
|
||||
/**
|
||||
* @deprecated Use `(a: T, b: T) => boolean` instead of `EqualityChecker<T>`
|
||||
*/
|
||||
export type EqualityChecker<T> = (state: T, newState: T) => boolean;
|
||||
/**
|
||||
* @deprecated Use `(state: T, previousState: T) => void` instead of `StateListener<T>`
|
||||
*/
|
||||
export type StateListener<T> = (state: T, previousState: T) => void;
|
||||
/**
|
||||
* @deprecated Use `(slice: T, previousSlice: T) => void` instead of `StateSliceListener<T>`.
|
||||
*/
|
||||
export type StateSliceListener<T> = (slice: T, previousSlice: T) => void;
|
||||
/**
|
||||
* @deprecated Use `(listener: (state: T) => void) => void` instead of `Subscribe<T>`.
|
||||
*/
|
||||
export type Subscribe<T extends State> = {
|
||||
(listener: (state: T, previousState: T) => void): () => void;
|
||||
};
|
||||
/**
|
||||
* @deprecated You might be looking for `StateCreator`, if not then
|
||||
* use `StoreApi<T>['setState']` instead of `SetState<T>`.
|
||||
*/
|
||||
export type SetState<T extends State> = {
|
||||
_(partial: T | Partial<T> | {
|
||||
_(state: T): T | Partial<T>;
|
||||
}['_'], replace?: boolean | undefined): void;
|
||||
}['_'];
|
||||
/**
|
||||
* @deprecated You might be looking for `StateCreator`, if not then
|
||||
* use `StoreApi<T>['getState']` instead of `GetState<T>`.
|
||||
*/
|
||||
export type GetState<T extends State> = () => T;
|
||||
/**
|
||||
* @deprecated Use `StoreApi<T>['destroy']` instead of `Destroy`.
|
||||
*/
|
||||
export type Destroy = () => void;
|
58
esm/vanilla.js
Normal file
58
esm/vanilla.js
Normal file
@ -0,0 +1,58 @@
|
||||
const createStoreImpl = (createState, configs) => {
|
||||
let timeout;
|
||||
let state;
|
||||
const listeners = /* @__PURE__ */ new Set();
|
||||
const setState = (partial, replace) => {
|
||||
const nextState = typeof partial === "function" ? partial(state) : partial;
|
||||
if (!Object.is(nextState, state)) {
|
||||
const previousState = state;
|
||||
state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
|
||||
listeners.forEach((listener) => listener(state, previousState));
|
||||
}
|
||||
};
|
||||
const getState = () => state;
|
||||
const getInitialState = () => initialState;
|
||||
const resetBasedOnCachTime = () => {
|
||||
if (!(configs == null ? void 0 : configs.cacheTime))
|
||||
return;
|
||||
if (timeout)
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => {
|
||||
state = createState(setState, getState, api);
|
||||
}, configs == null ? void 0 : configs.cacheTime);
|
||||
};
|
||||
const subscribe = (listener) => {
|
||||
listeners.add(listener);
|
||||
if (timeout)
|
||||
clearTimeout(timeout);
|
||||
return () => {
|
||||
const responseDelete = listeners.delete(listener);
|
||||
if (!listeners.size) {
|
||||
resetBasedOnCachTime();
|
||||
}
|
||||
return responseDelete;
|
||||
};
|
||||
};
|
||||
const destroy = () => {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
console.warn(
|
||||
"[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."
|
||||
);
|
||||
}
|
||||
listeners.clear();
|
||||
};
|
||||
const api = { setState, getState, getInitialState, subscribe, destroy };
|
||||
const initialState = state = createState(setState, getState, api);
|
||||
return api;
|
||||
};
|
||||
const createStore = createStoreImpl;
|
||||
var vanilla = (createState) => {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
console.warn(
|
||||
"[DEPRECATED] Default export is deprecated. Instead use import { createStore } from 'zustand/vanilla'."
|
||||
);
|
||||
}
|
||||
return createStore(createState);
|
||||
};
|
||||
|
||||
export { createStore, vanilla as default };
|
58
esm/vanilla.mjs
Normal file
58
esm/vanilla.mjs
Normal file
@ -0,0 +1,58 @@
|
||||
const createStoreImpl = (createState, configs) => {
|
||||
let timeout;
|
||||
let state;
|
||||
const listeners = /* @__PURE__ */ new Set();
|
||||
const setState = (partial, replace) => {
|
||||
const nextState = typeof partial === "function" ? partial(state) : partial;
|
||||
if (!Object.is(nextState, state)) {
|
||||
const previousState = state;
|
||||
state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
|
||||
listeners.forEach((listener) => listener(state, previousState));
|
||||
}
|
||||
};
|
||||
const getState = () => state;
|
||||
const getInitialState = () => initialState;
|
||||
const resetBasedOnCachTime = () => {
|
||||
if (!(configs == null ? void 0 : configs.cacheTime))
|
||||
return;
|
||||
if (timeout)
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => {
|
||||
state = createState(setState, getState, api);
|
||||
}, configs == null ? void 0 : configs.cacheTime);
|
||||
};
|
||||
const subscribe = (listener) => {
|
||||
listeners.add(listener);
|
||||
if (timeout)
|
||||
clearTimeout(timeout);
|
||||
return () => {
|
||||
const responseDelete = listeners.delete(listener);
|
||||
if (!listeners.size) {
|
||||
resetBasedOnCachTime();
|
||||
}
|
||||
return responseDelete;
|
||||
};
|
||||
};
|
||||
const destroy = () => {
|
||||
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production") {
|
||||
console.warn(
|
||||
"[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."
|
||||
);
|
||||
}
|
||||
listeners.clear();
|
||||
};
|
||||
const api = { setState, getState, getInitialState, subscribe, destroy };
|
||||
const initialState = state = createState(setState, getState, api);
|
||||
return api;
|
||||
};
|
||||
const createStore = createStoreImpl;
|
||||
var vanilla = (createState) => {
|
||||
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production") {
|
||||
console.warn(
|
||||
"[DEPRECATED] Default export is deprecated. Instead use import { createStore } from 'zustand/vanilla'."
|
||||
);
|
||||
}
|
||||
return createStore(createState);
|
||||
};
|
||||
|
||||
export { createStore, vanilla as default };
|
1
esm/vanilla/shallow.d.mts
Normal file
1
esm/vanilla/shallow.d.mts
Normal file
@ -0,0 +1 @@
|
||||
export declare function shallow<T>(objA: T, objB: T): boolean;
|
1
esm/vanilla/shallow.d.ts
vendored
Normal file
1
esm/vanilla/shallow.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export declare function shallow<T>(objA: T, objB: T): boolean;
|
40
esm/vanilla/shallow.js
Normal file
40
esm/vanilla/shallow.js
Normal file
@ -0,0 +1,40 @@
|
||||
function shallow(objA, objB) {
|
||||
if (Object.is(objA, objB)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
|
||||
return false;
|
||||
}
|
||||
if (objA instanceof Map && objB instanceof Map) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const [key, value] of objA) {
|
||||
if (!Object.is(value, objB.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (objA instanceof Set && objB instanceof Set) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const value of objA) {
|
||||
if (!objB.has(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const keysA = Object.keys(objA);
|
||||
if (keysA.length !== Object.keys(objB).length) {
|
||||
return false;
|
||||
}
|
||||
for (const keyA of keysA) {
|
||||
if (!Object.prototype.hasOwnProperty.call(objB, keyA) || !Object.is(objA[keyA], objB[keyA])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export { shallow };
|
40
esm/vanilla/shallow.mjs
Normal file
40
esm/vanilla/shallow.mjs
Normal file
@ -0,0 +1,40 @@
|
||||
function shallow(objA, objB) {
|
||||
if (Object.is(objA, objB)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
|
||||
return false;
|
||||
}
|
||||
if (objA instanceof Map && objB instanceof Map) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const [key, value] of objA) {
|
||||
if (!Object.is(value, objB.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (objA instanceof Set && objB instanceof Set) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const value of objA) {
|
||||
if (!objB.has(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const keysA = Object.keys(objA);
|
||||
if (keysA.length !== Object.keys(objB).length) {
|
||||
return false;
|
||||
}
|
||||
for (const keyA of keysA) {
|
||||
if (!Object.prototype.hasOwnProperty.call(objB, keyA) || !Object.is(objA[keyA], objB[keyA])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export { shallow };
|
3
index.d.ts
vendored
Normal file
3
index.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './vanilla';
|
||||
export * from './react';
|
||||
export { default } from './react';
|
60
index.js
Normal file
60
index.js
Normal file
@ -0,0 +1,60 @@
|
||||
'use strict';
|
||||
|
||||
var vanilla = require('zustand/vanilla');
|
||||
var ReactExports = require('react');
|
||||
var useSyncExternalStoreExports = require('use-sync-external-store/shim/with-selector');
|
||||
|
||||
var useDebugValue = ReactExports.useDebugValue;
|
||||
var useSyncExternalStoreWithSelector = useSyncExternalStoreExports.useSyncExternalStoreWithSelector;
|
||||
var didWarnAboutEqualityFn = false;
|
||||
var identity = function identity(arg) {
|
||||
return arg;
|
||||
};
|
||||
function useStore(api, selector, equalityFn) {
|
||||
if (selector === void 0) {
|
||||
selector = identity;
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production' && equalityFn && !didWarnAboutEqualityFn) {
|
||||
console.warn("[DEPRECATED] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`. They can be imported from 'zustand/traditional'. https://github.com/pmndrs/zustand/discussions/1937");
|
||||
didWarnAboutEqualityFn = true;
|
||||
}
|
||||
var slice = useSyncExternalStoreWithSelector(api.subscribe, api.getState, api.getServerState || api.getInitialState, selector, equalityFn);
|
||||
useDebugValue(slice);
|
||||
return slice;
|
||||
}
|
||||
var createImpl = function createImpl(createState) {
|
||||
if (process.env.NODE_ENV !== 'production' && typeof createState !== 'function') {
|
||||
console.warn("[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`.");
|
||||
}
|
||||
var api = typeof createState === 'function' ? vanilla.createStore(createState) : createState;
|
||||
var useBoundStore = function useBoundStore(selector, equalityFn) {
|
||||
return useStore(api, selector, equalityFn);
|
||||
};
|
||||
Object.assign(useBoundStore, api);
|
||||
return useBoundStore;
|
||||
};
|
||||
var create = function create(createState) {
|
||||
return createState ? createImpl(createState) : createImpl;
|
||||
};
|
||||
var react = (function (createState) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
console.warn("[DEPRECATED] Default export is deprecated. Instead use `import { create } from 'zustand'`.");
|
||||
}
|
||||
return create(createState);
|
||||
});
|
||||
|
||||
exports.create = create;
|
||||
exports.default = react;
|
||||
exports.useStore = useStore;
|
||||
Object.keys(vanilla).forEach(function (k) {
|
||||
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
||||
enumerable: true,
|
||||
get: function () { return vanilla[k]; }
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = react;
|
||||
module.exports.create = create;
|
||||
module.exports.useStore = useStore;
|
||||
module.exports.createStore = vanilla.createStore;
|
||||
exports.default = module.exports;
|
5
middleware.d.ts
vendored
Normal file
5
middleware.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
export * from './middleware/redux';
|
||||
export * from './middleware/devtools';
|
||||
export * from './middleware/subscribeWithSelector';
|
||||
export * from './middleware/combine';
|
||||
export * from './middleware/persist';
|
612
middleware.js
Normal file
612
middleware.js
Normal file
@ -0,0 +1,612 @@
|
||||
'use strict';
|
||||
|
||||
function _extends() {
|
||||
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i];
|
||||
for (var key in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
};
|
||||
return _extends.apply(this, arguments);
|
||||
}
|
||||
function _objectWithoutPropertiesLoose(source, excluded) {
|
||||
if (source == null) return {};
|
||||
var target = {};
|
||||
var sourceKeys = Object.keys(source);
|
||||
var key, i;
|
||||
for (i = 0; i < sourceKeys.length; i++) {
|
||||
key = sourceKeys[i];
|
||||
if (excluded.indexOf(key) >= 0) continue;
|
||||
target[key] = source[key];
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
var reduxImpl = function reduxImpl(reducer, initial) {
|
||||
return function (set, _get, api) {
|
||||
api.dispatch = function (action) {
|
||||
set(function (state) {
|
||||
return reducer(state, action);
|
||||
}, false, action);
|
||||
return action;
|
||||
};
|
||||
api.dispatchFromDevtools = true;
|
||||
return _extends({
|
||||
dispatch: function dispatch() {
|
||||
var _ref;
|
||||
return (_ref = api).dispatch.apply(_ref, arguments);
|
||||
}
|
||||
}, initial);
|
||||
};
|
||||
};
|
||||
var redux = reduxImpl;
|
||||
|
||||
var _excluded = ["enabled", "anonymousActionType", "store"],
|
||||
_excluded2 = ["connection"];
|
||||
var trackedConnections = new Map();
|
||||
var getTrackedConnectionState = function getTrackedConnectionState(name) {
|
||||
var api = trackedConnections.get(name);
|
||||
if (!api) return {};
|
||||
return Object.fromEntries(Object.entries(api.stores).map(function (_ref) {
|
||||
var key = _ref[0],
|
||||
api = _ref[1];
|
||||
return [key, api.getState()];
|
||||
}));
|
||||
};
|
||||
var extractConnectionInformation = function extractConnectionInformation(store, extensionConnector, options) {
|
||||
if (store === undefined) {
|
||||
return {
|
||||
type: 'untracked',
|
||||
connection: extensionConnector.connect(options)
|
||||
};
|
||||
}
|
||||
var existingConnection = trackedConnections.get(options.name);
|
||||
if (existingConnection) {
|
||||
return _extends({
|
||||
type: 'tracked',
|
||||
store: store
|
||||
}, existingConnection);
|
||||
}
|
||||
var newConnection = {
|
||||
connection: extensionConnector.connect(options),
|
||||
stores: {}
|
||||
};
|
||||
trackedConnections.set(options.name, newConnection);
|
||||
return _extends({
|
||||
type: 'tracked',
|
||||
store: store
|
||||
}, newConnection);
|
||||
};
|
||||
var devtoolsImpl = function devtoolsImpl(fn, devtoolsOptions) {
|
||||
if (devtoolsOptions === void 0) {
|
||||
devtoolsOptions = {};
|
||||
}
|
||||
return function (set, get, api) {
|
||||
var _devtoolsOptions = devtoolsOptions,
|
||||
enabled = _devtoolsOptions.enabled,
|
||||
anonymousActionType = _devtoolsOptions.anonymousActionType,
|
||||
store = _devtoolsOptions.store,
|
||||
options = _objectWithoutPropertiesLoose(_devtoolsOptions, _excluded);
|
||||
var extensionConnector;
|
||||
try {
|
||||
extensionConnector = (enabled != null ? enabled : process.env.NODE_ENV !== 'production') && window.__REDUX_DEVTOOLS_EXTENSION__;
|
||||
} catch (e) {}
|
||||
if (!extensionConnector) {
|
||||
if (process.env.NODE_ENV !== 'production' && enabled) {
|
||||
console.warn('[zustand devtools middleware] Please install/enable Redux devtools extension');
|
||||
}
|
||||
return fn(set, get, api);
|
||||
}
|
||||
var _extractConnectionInf = extractConnectionInformation(store, extensionConnector, options),
|
||||
connection = _extractConnectionInf.connection,
|
||||
connectionInformation = _objectWithoutPropertiesLoose(_extractConnectionInf, _excluded2);
|
||||
var isRecording = true;
|
||||
api.setState = function (state, replace, nameOrAction) {
|
||||
var _extends2;
|
||||
var r = set(state, replace);
|
||||
if (!isRecording) return r;
|
||||
var action = nameOrAction === undefined ? {
|
||||
type: anonymousActionType || 'anonymous'
|
||||
} : typeof nameOrAction === 'string' ? {
|
||||
type: nameOrAction
|
||||
} : nameOrAction;
|
||||
if (store === undefined) {
|
||||
connection == null || connection.send(action, get());
|
||||
return r;
|
||||
}
|
||||
connection == null || connection.send(_extends({}, action, {
|
||||
type: store + "/" + action.type
|
||||
}), _extends({}, getTrackedConnectionState(options.name), (_extends2 = {}, _extends2[store] = api.getState(), _extends2)));
|
||||
return r;
|
||||
};
|
||||
var setStateFromDevtools = function setStateFromDevtools() {
|
||||
var originalIsRecording = isRecording;
|
||||
isRecording = false;
|
||||
set.apply(void 0, arguments);
|
||||
isRecording = originalIsRecording;
|
||||
};
|
||||
var initialState = fn(api.setState, get, api);
|
||||
if (connectionInformation.type === 'untracked') {
|
||||
connection == null || connection.init(initialState);
|
||||
} else {
|
||||
connectionInformation.stores[connectionInformation.store] = api;
|
||||
connection == null || connection.init(Object.fromEntries(Object.entries(connectionInformation.stores).map(function (_ref2) {
|
||||
var key = _ref2[0],
|
||||
store = _ref2[1];
|
||||
return [key, key === connectionInformation.store ? initialState : store.getState()];
|
||||
})));
|
||||
}
|
||||
if (api.dispatchFromDevtools && typeof api.dispatch === 'function') {
|
||||
var didWarnAboutReservedActionType = false;
|
||||
var originalDispatch = api.dispatch;
|
||||
api.dispatch = function () {
|
||||
for (var _len = arguments.length, a = new Array(_len), _key = 0; _key < _len; _key++) {
|
||||
a[_key] = arguments[_key];
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production' && a[0].type === '__setState' && !didWarnAboutReservedActionType) {
|
||||
console.warn('[zustand devtools middleware] "__setState" action type is reserved ' + 'to set state from the devtools. Avoid using it.');
|
||||
didWarnAboutReservedActionType = true;
|
||||
}
|
||||
originalDispatch.apply(void 0, a);
|
||||
};
|
||||
}
|
||||
connection.subscribe(function (message) {
|
||||
switch (message.type) {
|
||||
case 'ACTION':
|
||||
if (typeof message.payload !== 'string') {
|
||||
console.error('[zustand devtools middleware] Unsupported action format');
|
||||
return;
|
||||
}
|
||||
return parseJsonThen(message.payload, function (action) {
|
||||
if (action.type === '__setState') {
|
||||
if (store === undefined) {
|
||||
setStateFromDevtools(action.state);
|
||||
return;
|
||||
}
|
||||
if (Object.keys(action.state).length !== 1) {
|
||||
console.error("\n [zustand devtools middleware] Unsupported __setState action format. \n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n ");
|
||||
}
|
||||
var stateFromDevtools = action.state[store];
|
||||
if (stateFromDevtools === undefined || stateFromDevtools === null) {
|
||||
return;
|
||||
}
|
||||
if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {
|
||||
setStateFromDevtools(stateFromDevtools);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!api.dispatchFromDevtools) return;
|
||||
if (typeof api.dispatch !== 'function') return;
|
||||
api.dispatch(action);
|
||||
});
|
||||
case 'DISPATCH':
|
||||
switch (message.payload.type) {
|
||||
case 'RESET':
|
||||
setStateFromDevtools(initialState);
|
||||
if (store === undefined) {
|
||||
return connection == null ? void 0 : connection.init(api.getState());
|
||||
}
|
||||
return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));
|
||||
case 'COMMIT':
|
||||
if (store === undefined) {
|
||||
connection == null || connection.init(api.getState());
|
||||
return;
|
||||
}
|
||||
return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));
|
||||
case 'ROLLBACK':
|
||||
return parseJsonThen(message.state, function (state) {
|
||||
if (store === undefined) {
|
||||
setStateFromDevtools(state);
|
||||
connection == null || connection.init(api.getState());
|
||||
return;
|
||||
}
|
||||
setStateFromDevtools(state[store]);
|
||||
connection == null || connection.init(getTrackedConnectionState(options.name));
|
||||
});
|
||||
case 'JUMP_TO_STATE':
|
||||
case 'JUMP_TO_ACTION':
|
||||
return parseJsonThen(message.state, function (state) {
|
||||
if (store === undefined) {
|
||||
setStateFromDevtools(state);
|
||||
return;
|
||||
}
|
||||
if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {
|
||||
setStateFromDevtools(state[store]);
|
||||
}
|
||||
});
|
||||
case 'IMPORT_STATE':
|
||||
{
|
||||
var _nextLiftedState$comp;
|
||||
var nextLiftedState = message.payload.nextLiftedState;
|
||||
var lastComputedState = (_nextLiftedState$comp = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _nextLiftedState$comp.state;
|
||||
if (!lastComputedState) return;
|
||||
if (store === undefined) {
|
||||
setStateFromDevtools(lastComputedState);
|
||||
} else {
|
||||
setStateFromDevtools(lastComputedState[store]);
|
||||
}
|
||||
connection == null || connection.send(null, nextLiftedState);
|
||||
return;
|
||||
}
|
||||
case 'PAUSE_RECORDING':
|
||||
return isRecording = !isRecording;
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
return initialState;
|
||||
};
|
||||
};
|
||||
var devtools = devtoolsImpl;
|
||||
var parseJsonThen = function parseJsonThen(stringified, f) {
|
||||
var parsed;
|
||||
try {
|
||||
parsed = JSON.parse(stringified);
|
||||
} catch (e) {
|
||||
console.error('[zustand devtools middleware] Could not parse the received json', e);
|
||||
}
|
||||
if (parsed !== undefined) f(parsed);
|
||||
};
|
||||
|
||||
var subscribeWithSelectorImpl = function subscribeWithSelectorImpl(fn) {
|
||||
return function (set, get, api) {
|
||||
var origSubscribe = api.subscribe;
|
||||
api.subscribe = function (selector, optListener, options) {
|
||||
var listener = selector;
|
||||
if (optListener) {
|
||||
var equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;
|
||||
var currentSlice = selector(api.getState());
|
||||
listener = function listener(state) {
|
||||
var nextSlice = selector(state);
|
||||
if (!equalityFn(currentSlice, nextSlice)) {
|
||||
var previousSlice = currentSlice;
|
||||
optListener(currentSlice = nextSlice, previousSlice);
|
||||
}
|
||||
};
|
||||
if (options != null && options.fireImmediately) {
|
||||
optListener(currentSlice, currentSlice);
|
||||
}
|
||||
}
|
||||
return origSubscribe(listener);
|
||||
};
|
||||
var initialState = fn(set, get, api);
|
||||
return initialState;
|
||||
};
|
||||
};
|
||||
var subscribeWithSelector = subscribeWithSelectorImpl;
|
||||
|
||||
var combine = function combine(initialState, create) {
|
||||
return function () {
|
||||
return Object.assign({}, initialState, create.apply(void 0, arguments));
|
||||
};
|
||||
};
|
||||
|
||||
function createJSONStorage(getStorage, options) {
|
||||
var storage;
|
||||
try {
|
||||
storage = getStorage();
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
var persistStorage = {
|
||||
getItem: function getItem(name) {
|
||||
var _getItem;
|
||||
var parse = function parse(str) {
|
||||
if (str === null) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parse(str, options == null ? void 0 : options.reviver);
|
||||
};
|
||||
var str = (_getItem = storage.getItem(name)) != null ? _getItem : null;
|
||||
if (str instanceof Promise) {
|
||||
return str.then(parse);
|
||||
}
|
||||
return parse(str);
|
||||
},
|
||||
setItem: function setItem(name, newValue) {
|
||||
return storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer));
|
||||
},
|
||||
removeItem: function removeItem(name) {
|
||||
return storage.removeItem(name);
|
||||
}
|
||||
};
|
||||
return persistStorage;
|
||||
}
|
||||
var toThenable = function toThenable(fn) {
|
||||
return function (input) {
|
||||
try {
|
||||
var result = fn(input);
|
||||
if (result instanceof Promise) {
|
||||
return result;
|
||||
}
|
||||
return {
|
||||
then: function then(onFulfilled) {
|
||||
return toThenable(onFulfilled)(result);
|
||||
},
|
||||
catch: function _catch(_onRejected) {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
then: function then(_onFulfilled) {
|
||||
return this;
|
||||
},
|
||||
catch: function _catch(onRejected) {
|
||||
return toThenable(onRejected)(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
var oldImpl = function oldImpl(config, baseOptions) {
|
||||
return function (set, get, api) {
|
||||
var options = _extends({
|
||||
getStorage: function getStorage() {
|
||||
return localStorage;
|
||||
},
|
||||
serialize: JSON.stringify,
|
||||
deserialize: JSON.parse,
|
||||
partialize: function partialize(state) {
|
||||
return state;
|
||||
},
|
||||
version: 0,
|
||||
merge: function merge(persistedState, currentState) {
|
||||
return _extends({}, currentState, persistedState);
|
||||
}
|
||||
}, baseOptions);
|
||||
var _hasHydrated = false;
|
||||
var hydrationListeners = new Set();
|
||||
var finishHydrationListeners = new Set();
|
||||
var storage;
|
||||
try {
|
||||
storage = options.getStorage();
|
||||
} catch (e) {}
|
||||
if (!storage) {
|
||||
return config(function () {
|
||||
console.warn("[zustand persist middleware] Unable to update item '" + options.name + "', the given storage is currently unavailable.");
|
||||
set.apply(void 0, arguments);
|
||||
}, get, api);
|
||||
}
|
||||
var thenableSerialize = toThenable(options.serialize);
|
||||
var setItem = function setItem() {
|
||||
var state = options.partialize(_extends({}, get()));
|
||||
var errorInSync;
|
||||
var thenable = thenableSerialize({
|
||||
state: state,
|
||||
version: options.version
|
||||
}).then(function (serializedValue) {
|
||||
return storage.setItem(options.name, serializedValue);
|
||||
}).catch(function (e) {
|
||||
errorInSync = e;
|
||||
});
|
||||
if (errorInSync) {
|
||||
throw errorInSync;
|
||||
}
|
||||
return thenable;
|
||||
};
|
||||
var savedSetState = api.setState;
|
||||
api.setState = function (state, replace) {
|
||||
savedSetState(state, replace);
|
||||
void setItem();
|
||||
};
|
||||
var configResult = config(function () {
|
||||
set.apply(void 0, arguments);
|
||||
void setItem();
|
||||
}, get, api);
|
||||
var stateFromStorage;
|
||||
var hydrate = function hydrate() {
|
||||
if (!storage) return;
|
||||
_hasHydrated = false;
|
||||
hydrationListeners.forEach(function (cb) {
|
||||
return cb(get());
|
||||
});
|
||||
var postRehydrationCallback = (options.onRehydrateStorage == null ? void 0 : options.onRehydrateStorage(get())) || undefined;
|
||||
return toThenable(storage.getItem.bind(storage))(options.name).then(function (storageValue) {
|
||||
if (storageValue) {
|
||||
return options.deserialize(storageValue);
|
||||
}
|
||||
}).then(function (deserializedStorageValue) {
|
||||
if (deserializedStorageValue) {
|
||||
if (typeof deserializedStorageValue.version === 'number' && deserializedStorageValue.version !== options.version) {
|
||||
if (options.migrate) {
|
||||
return options.migrate(deserializedStorageValue.state, deserializedStorageValue.version);
|
||||
}
|
||||
console.error("State loaded from storage couldn't be migrated since no migrate function was provided");
|
||||
} else {
|
||||
return deserializedStorageValue.state;
|
||||
}
|
||||
}
|
||||
}).then(function (migratedState) {
|
||||
var _get;
|
||||
stateFromStorage = options.merge(migratedState, (_get = get()) != null ? _get : configResult);
|
||||
set(stateFromStorage, true);
|
||||
return setItem();
|
||||
}).then(function () {
|
||||
postRehydrationCallback == null || postRehydrationCallback(stateFromStorage, undefined);
|
||||
_hasHydrated = true;
|
||||
finishHydrationListeners.forEach(function (cb) {
|
||||
return cb(stateFromStorage);
|
||||
});
|
||||
}).catch(function (e) {
|
||||
postRehydrationCallback == null || postRehydrationCallback(undefined, e);
|
||||
});
|
||||
};
|
||||
api.persist = {
|
||||
setOptions: function setOptions(newOptions) {
|
||||
options = _extends({}, options, newOptions);
|
||||
if (newOptions.getStorage) {
|
||||
storage = newOptions.getStorage();
|
||||
}
|
||||
},
|
||||
clearStorage: function clearStorage() {
|
||||
var _storage;
|
||||
(_storage = storage) == null || _storage.removeItem(options.name);
|
||||
},
|
||||
getOptions: function getOptions() {
|
||||
return options;
|
||||
},
|
||||
rehydrate: function rehydrate() {
|
||||
return hydrate();
|
||||
},
|
||||
hasHydrated: function hasHydrated() {
|
||||
return _hasHydrated;
|
||||
},
|
||||
onHydrate: function onHydrate(cb) {
|
||||
hydrationListeners.add(cb);
|
||||
return function () {
|
||||
hydrationListeners.delete(cb);
|
||||
};
|
||||
},
|
||||
onFinishHydration: function onFinishHydration(cb) {
|
||||
finishHydrationListeners.add(cb);
|
||||
return function () {
|
||||
finishHydrationListeners.delete(cb);
|
||||
};
|
||||
}
|
||||
};
|
||||
hydrate();
|
||||
return stateFromStorage || configResult;
|
||||
};
|
||||
};
|
||||
var newImpl = function newImpl(config, baseOptions) {
|
||||
return function (set, get, api) {
|
||||
var options = _extends({
|
||||
storage: createJSONStorage(function () {
|
||||
return localStorage;
|
||||
}),
|
||||
partialize: function partialize(state) {
|
||||
return state;
|
||||
},
|
||||
version: 0,
|
||||
merge: function merge(persistedState, currentState) {
|
||||
return _extends({}, currentState, persistedState);
|
||||
}
|
||||
}, baseOptions);
|
||||
var _hasHydrated2 = false;
|
||||
var hydrationListeners = new Set();
|
||||
var finishHydrationListeners = new Set();
|
||||
var storage = options.storage;
|
||||
if (!storage) {
|
||||
return config(function () {
|
||||
console.warn("[zustand persist middleware] Unable to update item '" + options.name + "', the given storage is currently unavailable.");
|
||||
set.apply(void 0, arguments);
|
||||
}, get, api);
|
||||
}
|
||||
var setItem = function setItem() {
|
||||
var state = options.partialize(_extends({}, get()));
|
||||
return storage.setItem(options.name, {
|
||||
state: state,
|
||||
version: options.version
|
||||
});
|
||||
};
|
||||
var savedSetState = api.setState;
|
||||
api.setState = function (state, replace) {
|
||||
savedSetState(state, replace);
|
||||
void setItem();
|
||||
};
|
||||
var configResult = config(function () {
|
||||
set.apply(void 0, arguments);
|
||||
void setItem();
|
||||
}, get, api);
|
||||
api.getInitialState = function () {
|
||||
return configResult;
|
||||
};
|
||||
var stateFromStorage;
|
||||
var hydrate = function hydrate() {
|
||||
var _get3;
|
||||
if (!storage) return;
|
||||
_hasHydrated2 = false;
|
||||
hydrationListeners.forEach(function (cb) {
|
||||
var _get2;
|
||||
return cb((_get2 = get()) != null ? _get2 : configResult);
|
||||
});
|
||||
var postRehydrationCallback = (options.onRehydrateStorage == null ? void 0 : options.onRehydrateStorage((_get3 = get()) != null ? _get3 : configResult)) || undefined;
|
||||
return toThenable(storage.getItem.bind(storage))(options.name).then(function (deserializedStorageValue) {
|
||||
if (deserializedStorageValue) {
|
||||
if (typeof deserializedStorageValue.version === 'number' && deserializedStorageValue.version !== options.version) {
|
||||
if (options.migrate) {
|
||||
return options.migrate(deserializedStorageValue.state, deserializedStorageValue.version);
|
||||
}
|
||||
console.error("State loaded from storage couldn't be migrated since no migrate function was provided");
|
||||
} else {
|
||||
return deserializedStorageValue.state;
|
||||
}
|
||||
}
|
||||
}).then(function (migratedState) {
|
||||
var _get4;
|
||||
stateFromStorage = options.merge(migratedState, (_get4 = get()) != null ? _get4 : configResult);
|
||||
set(stateFromStorage, true);
|
||||
return setItem();
|
||||
}).then(function () {
|
||||
postRehydrationCallback == null || postRehydrationCallback(stateFromStorage, undefined);
|
||||
stateFromStorage = get();
|
||||
_hasHydrated2 = true;
|
||||
finishHydrationListeners.forEach(function (cb) {
|
||||
return cb(stateFromStorage);
|
||||
});
|
||||
}).catch(function (e) {
|
||||
postRehydrationCallback == null || postRehydrationCallback(undefined, e);
|
||||
});
|
||||
};
|
||||
api.persist = {
|
||||
setOptions: function setOptions(newOptions) {
|
||||
options = _extends({}, options, newOptions);
|
||||
if (newOptions.storage) {
|
||||
storage = newOptions.storage;
|
||||
}
|
||||
},
|
||||
clearStorage: function clearStorage() {
|
||||
var _storage2;
|
||||
(_storage2 = storage) == null || _storage2.removeItem(options.name);
|
||||
},
|
||||
getOptions: function getOptions() {
|
||||
return options;
|
||||
},
|
||||
rehydrate: function rehydrate() {
|
||||
return hydrate();
|
||||
},
|
||||
hasHydrated: function hasHydrated() {
|
||||
return _hasHydrated2;
|
||||
},
|
||||
onHydrate: function onHydrate(cb) {
|
||||
hydrationListeners.add(cb);
|
||||
return function () {
|
||||
hydrationListeners.delete(cb);
|
||||
};
|
||||
},
|
||||
onFinishHydration: function onFinishHydration(cb) {
|
||||
finishHydrationListeners.add(cb);
|
||||
return function () {
|
||||
finishHydrationListeners.delete(cb);
|
||||
};
|
||||
}
|
||||
};
|
||||
if (!options.skipHydration) {
|
||||
hydrate();
|
||||
}
|
||||
return stateFromStorage || configResult;
|
||||
};
|
||||
};
|
||||
var persistImpl = function persistImpl(config, baseOptions) {
|
||||
if ('getStorage' in baseOptions || 'serialize' in baseOptions || 'deserialize' in baseOptions) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
console.warn('[DEPRECATED] `getStorage`, `serialize` and `deserialize` options are deprecated. Use `storage` option instead.');
|
||||
}
|
||||
return oldImpl(config, baseOptions);
|
||||
}
|
||||
return newImpl(config, baseOptions);
|
||||
};
|
||||
var persist = persistImpl;
|
||||
|
||||
exports.combine = combine;
|
||||
exports.createJSONStorage = createJSONStorage;
|
||||
exports.devtools = devtools;
|
||||
exports.persist = persist;
|
||||
exports.redux = redux;
|
||||
exports.subscribeWithSelector = subscribeWithSelector;
|
5
middleware/combine.d.ts
vendored
Normal file
5
middleware/combine.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type Combine = <T extends object, U extends object, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initialState: T, additionalStateCreator: StateCreator<T, Mps, Mcs, U>) => StateCreator<Write<T, U>, Mps, Mcs>;
|
||||
export declare const combine: Combine;
|
||||
export {};
|
49
middleware/devtools.d.ts
vendored
Normal file
49
middleware/devtools.d.ts
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
import type { StateCreator, StoreApi, StoreMutatorIdentifier } from '../vanilla';
|
||||
type Config = Parameters<(Window extends {
|
||||
__REDUX_DEVTOOLS_EXTENSION__?: infer T;
|
||||
} ? T : {
|
||||
connect: (param: any) => any;
|
||||
})['connect']>[0];
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/devtools': WithDevtools<S>;
|
||||
}
|
||||
}
|
||||
type Cast<T, U> = T extends U ? T : U;
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type TakeTwo<T> = T extends {
|
||||
length: 0;
|
||||
} ? [undefined, undefined] : T extends {
|
||||
length: 1;
|
||||
} ? [...a0: Cast<T, unknown[]>, a1: undefined] : T extends {
|
||||
length: 0 | 1;
|
||||
} ? [...a0: Cast<T, unknown[]>, a1: undefined] : T extends {
|
||||
length: 2;
|
||||
} ? T : T extends {
|
||||
length: 1 | 2;
|
||||
} ? T : T extends {
|
||||
length: 0 | 1 | 2;
|
||||
} ? T : T extends [infer A0, infer A1, ...unknown[]] ? [A0, A1] : T extends [infer A0, (infer A1)?, ...unknown[]] ? [A0, A1?] : T extends [(infer A0)?, (infer A1)?, ...unknown[]] ? [A0?, A1?] : never;
|
||||
type WithDevtools<S> = Write<S, StoreDevtools<S>>;
|
||||
type StoreDevtools<S> = S extends {
|
||||
setState: (...a: infer Sa) => infer Sr;
|
||||
} ? {
|
||||
setState<A extends string | {
|
||||
type: string;
|
||||
}>(...a: [...a: TakeTwo<Sa>, action?: A]): Sr;
|
||||
} : never;
|
||||
export interface DevtoolsOptions extends Config {
|
||||
name?: string;
|
||||
enabled?: boolean;
|
||||
anonymousActionType?: string;
|
||||
store?: string;
|
||||
}
|
||||
type Devtools = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [...Mps, ['zustand/devtools', never]], Mcs>, devtoolsOptions?: DevtoolsOptions) => StateCreator<T, Mps, [['zustand/devtools', never], ...Mcs]>;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/devtools': WithDevtools<S>;
|
||||
}
|
||||
}
|
||||
export type NamedSet<T> = WithDevtools<StoreApi<T>>['setState'];
|
||||
export declare const devtools: Devtools;
|
||||
export {};
|
25
middleware/immer.d.ts
vendored
Normal file
25
middleware/immer.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
import type { Draft } from 'immer';
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
type Immer = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [...Mps, ['zustand/immer', never]], Mcs>) => StateCreator<T, Mps, [['zustand/immer', never], ...Mcs]>;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
['zustand/immer']: WithImmer<S>;
|
||||
}
|
||||
}
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type SkipTwo<T> = T extends {
|
||||
length: 0;
|
||||
} ? [] : T extends {
|
||||
length: 1;
|
||||
} ? [] : T extends {
|
||||
length: 0 | 1;
|
||||
} ? [] : T extends [unknown, unknown, ...infer A] ? A : T extends [unknown, unknown?, ...infer A] ? A : T extends [unknown?, unknown?, ...infer A] ? A : never;
|
||||
type WithImmer<S> = Write<S, StoreImmer<S>>;
|
||||
type StoreImmer<S> = S extends {
|
||||
getState: () => infer T;
|
||||
setState: infer SetState;
|
||||
} ? SetState extends (...a: infer A) => infer Sr ? {
|
||||
setState(nextStateOrUpdater: T | Partial<T> | ((state: Draft<T>) => void), shouldReplace?: boolean | undefined, ...a: SkipTwo<A>): Sr;
|
||||
} : never : never;
|
||||
export declare const immer: Immer;
|
||||
export {};
|
19
middleware/immer.js
Normal file
19
middleware/immer.js
Normal file
@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
var immer$1 = require('immer');
|
||||
|
||||
var immerImpl = function immerImpl(initializer) {
|
||||
return function (set, get, store) {
|
||||
store.setState = function (updater, replace) {
|
||||
var nextState = typeof updater === 'function' ? immer$1.produce(updater) : updater;
|
||||
for (var _len = arguments.length, a = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
||||
a[_key - 2] = arguments[_key];
|
||||
}
|
||||
return set.apply(void 0, [nextState, replace].concat(a));
|
||||
};
|
||||
return initializer(store.setState, get, store);
|
||||
};
|
||||
};
|
||||
var immer = immerImpl;
|
||||
|
||||
exports.immer = immer;
|
119
middleware/persist.d.ts
vendored
Normal file
119
middleware/persist.d.ts
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
export interface StateStorage {
|
||||
getItem: (name: string) => string | null | Promise<string | null>;
|
||||
setItem: (name: string, value: string) => unknown | Promise<unknown>;
|
||||
removeItem: (name: string) => unknown | Promise<unknown>;
|
||||
}
|
||||
export type StorageValue<S> = {
|
||||
state: S;
|
||||
version?: number;
|
||||
};
|
||||
export interface PersistStorage<S> {
|
||||
getItem: (name: string) => StorageValue<S> | null | Promise<StorageValue<S> | null>;
|
||||
setItem: (name: string, value: StorageValue<S>) => unknown | Promise<unknown>;
|
||||
removeItem: (name: string) => unknown | Promise<unknown>;
|
||||
}
|
||||
type JsonStorageOptions = {
|
||||
reviver?: (key: string, value: unknown) => unknown;
|
||||
replacer?: (key: string, value: unknown) => unknown;
|
||||
};
|
||||
export declare function createJSONStorage<S>(getStorage: () => StateStorage, options?: JsonStorageOptions): PersistStorage<S> | undefined;
|
||||
export interface PersistOptions<S, PersistedState = S> {
|
||||
/** Name of the storage (must be unique) */
|
||||
name: string;
|
||||
/**
|
||||
* @deprecated Use `storage` instead.
|
||||
* A function returning a storage.
|
||||
* The storage must fit `window.localStorage`'s api (or an async version of it).
|
||||
* For example the storage could be `AsyncStorage` from React Native.
|
||||
*
|
||||
* @default () => localStorage
|
||||
*/
|
||||
getStorage?: () => StateStorage;
|
||||
/**
|
||||
* @deprecated Use `storage` instead.
|
||||
* Use a custom serializer.
|
||||
* The returned string will be stored in the storage.
|
||||
*
|
||||
* @default JSON.stringify
|
||||
*/
|
||||
serialize?: (state: StorageValue<S>) => string | Promise<string>;
|
||||
/**
|
||||
* @deprecated Use `storage` instead.
|
||||
* Use a custom deserializer.
|
||||
* Must return an object matching StorageValue<S>
|
||||
*
|
||||
* @param str The storage's current value.
|
||||
* @default JSON.parse
|
||||
*/
|
||||
deserialize?: (str: string) => StorageValue<PersistedState> | Promise<StorageValue<PersistedState>>;
|
||||
/**
|
||||
* Use a custom persist storage.
|
||||
*
|
||||
* Combining `createJSONStorage` helps creating a persist storage
|
||||
* with JSON.parse and JSON.stringify.
|
||||
*
|
||||
* @default createJSONStorage(() => localStorage)
|
||||
*/
|
||||
storage?: PersistStorage<PersistedState> | undefined;
|
||||
/**
|
||||
* Filter the persisted value.
|
||||
*
|
||||
* @params state The state's value
|
||||
*/
|
||||
partialize?: (state: S) => PersistedState;
|
||||
/**
|
||||
* A function returning another (optional) function.
|
||||
* The main function will be called before the state rehydration.
|
||||
* The returned function will be called after the state rehydration or when an error occurred.
|
||||
*/
|
||||
onRehydrateStorage?: (state: S) => ((state?: S, error?: unknown) => void) | void;
|
||||
/**
|
||||
* If the stored state's version mismatch the one specified here, the storage will not be used.
|
||||
* This is useful when adding a breaking change to your store.
|
||||
*/
|
||||
version?: number;
|
||||
/**
|
||||
* A function to perform persisted state migration.
|
||||
* This function will be called when persisted state versions mismatch with the one specified here.
|
||||
*/
|
||||
migrate?: (persistedState: unknown, version: number) => PersistedState | Promise<PersistedState>;
|
||||
/**
|
||||
* A function to perform custom hydration merges when combining the stored state with the current one.
|
||||
* By default, this function does a shallow merge.
|
||||
*/
|
||||
merge?: (persistedState: unknown, currentState: S) => S;
|
||||
/**
|
||||
* An optional boolean that will prevent the persist middleware from triggering hydration on initialization,
|
||||
* This allows you to call `rehydrate()` at a specific point in your apps rendering life-cycle.
|
||||
*
|
||||
* This is useful in SSR application.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
skipHydration?: boolean;
|
||||
}
|
||||
type PersistListener<S> = (state: S) => void;
|
||||
type StorePersist<S, Ps> = {
|
||||
persist: {
|
||||
setOptions: (options: Partial<PersistOptions<S, Ps>>) => void;
|
||||
clearStorage: () => void;
|
||||
rehydrate: () => Promise<void> | void;
|
||||
hasHydrated: () => boolean;
|
||||
onHydrate: (fn: PersistListener<S>) => () => void;
|
||||
onFinishHydration: (fn: PersistListener<S>) => () => void;
|
||||
getOptions: () => Partial<PersistOptions<S, Ps>>;
|
||||
};
|
||||
};
|
||||
type Persist = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = [], U = T>(initializer: StateCreator<T, [...Mps, ['zustand/persist', unknown]], Mcs>, options: PersistOptions<T, U>) => StateCreator<T, Mps, [['zustand/persist', U], ...Mcs]>;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/persist': WithPersist<S, A>;
|
||||
}
|
||||
}
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type WithPersist<S, A> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? Write<S, StorePersist<T, A>> : never;
|
||||
export declare const persist: Persist;
|
||||
export {};
|
21
middleware/redux.d.ts
vendored
Normal file
21
middleware/redux.d.ts
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type Action = {
|
||||
type: string;
|
||||
};
|
||||
type StoreRedux<A> = {
|
||||
dispatch: (a: A) => A;
|
||||
dispatchFromDevtools: true;
|
||||
};
|
||||
type ReduxState<A> = {
|
||||
dispatch: StoreRedux<A>['dispatch'];
|
||||
};
|
||||
type WithRedux<S, A> = Write<S, StoreRedux<A>>;
|
||||
type Redux = <T, A extends Action, Cms extends [StoreMutatorIdentifier, unknown][] = []>(reducer: (state: T, action: A) => T, initialState: T) => StateCreator<Write<T, ReduxState<A>>, Cms, [['zustand/redux', A]]>;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/redux': WithRedux<S, A>;
|
||||
}
|
||||
}
|
||||
export declare const redux: Redux;
|
||||
export {};
|
25
middleware/subscribeWithSelector.d.ts
vendored
Normal file
25
middleware/subscribeWithSelector.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
type SubscribeWithSelector = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [
|
||||
...Mps,
|
||||
['zustand/subscribeWithSelector', never]
|
||||
], Mcs>) => StateCreator<T, Mps, [['zustand/subscribeWithSelector', never], ...Mcs]>;
|
||||
type Write<T, U> = Omit<T, keyof U> & U;
|
||||
type WithSelectorSubscribe<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? Write<S, StoreSubscribeWithSelector<T>> : never;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
['zustand/subscribeWithSelector']: WithSelectorSubscribe<S>;
|
||||
}
|
||||
}
|
||||
type StoreSubscribeWithSelector<T> = {
|
||||
subscribe: {
|
||||
(listener: (selectedState: T, previousSelectedState: T) => void): () => void;
|
||||
<U>(selector: (state: T) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
|
||||
equalityFn?: (a: U, b: U) => boolean;
|
||||
fireImmediately?: boolean;
|
||||
}): () => void;
|
||||
};
|
||||
};
|
||||
export declare const subscribeWithSelector: SubscribeWithSelector;
|
||||
export {};
|
196
package.json
Normal file
196
package.json
Normal file
@ -0,0 +1,196 @@
|
||||
{
|
||||
"name": "zustand",
|
||||
"private": false,
|
||||
"version": "4.5.2",
|
||||
"description": "🐻 Bear necessities for state management in React",
|
||||
"main": "./index.js",
|
||||
"types": "./index.d.ts",
|
||||
"typesVersions": {
|
||||
"<4.0": {
|
||||
"esm/*": [
|
||||
"ts3.4/*"
|
||||
],
|
||||
"*": [
|
||||
"ts3.4/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"**"
|
||||
],
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./esm/index.d.mts",
|
||||
"default": "./esm/index.mjs"
|
||||
},
|
||||
"module": {
|
||||
"types": "./esm/index.d.ts",
|
||||
"default": "./esm/index.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./index.d.ts",
|
||||
"default": "./index.js"
|
||||
}
|
||||
},
|
||||
"./vanilla": {
|
||||
"import": {
|
||||
"types": "./esm/vanilla.d.mts",
|
||||
"default": "./esm/vanilla.mjs"
|
||||
},
|
||||
"module": {
|
||||
"types": "./esm/vanilla.d.ts",
|
||||
"default": "./esm/vanilla.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./vanilla.d.ts",
|
||||
"default": "./vanilla.js"
|
||||
}
|
||||
},
|
||||
"./middleware": {
|
||||
"import": {
|
||||
"types": "./esm/middleware.d.mts",
|
||||
"default": "./esm/middleware.mjs"
|
||||
},
|
||||
"module": {
|
||||
"types": "./esm/middleware.d.ts",
|
||||
"default": "./esm/middleware.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./middleware.d.ts",
|
||||
"default": "./middleware.js"
|
||||
}
|
||||
},
|
||||
"./middleware/immer": {
|
||||
"import": {
|
||||
"types": "./esm/middleware/immer.d.mts",
|
||||
"default": "./esm/middleware/immer.mjs"
|
||||
},
|
||||
"module": {
|
||||
"types": "./esm/middleware/immer.d.ts",
|
||||
"default": "./esm/middleware/immer.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./middleware/immer.d.ts",
|
||||
"default": "./middleware/immer.js"
|
||||
}
|
||||
},
|
||||
"./shallow": {
|
||||
"import": {
|
||||
"types": "./esm/shallow.d.mts",
|
||||
"default": "./esm/shallow.mjs"
|
||||
},
|
||||
"module": {
|
||||
"types": "./esm/shallow.d.ts",
|
||||
"default": "./esm/shallow.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./shallow.d.ts",
|
||||
"default": "./shallow.js"
|
||||
}
|
||||
},
|
||||
"./vanilla/shallow": {
|
||||
"import": {
|
||||
"types": "./esm/vanilla/shallow.d.mts",
|
||||
"default": "./esm/vanilla/shallow.mjs"
|
||||
},
|
||||
"module": {
|
||||
"types": "./esm/vanilla/shallow.d.ts",
|
||||
"default": "./esm/vanilla/shallow.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./vanilla/shallow.d.ts",
|
||||
"default": "./vanilla/shallow.js"
|
||||
}
|
||||
},
|
||||
"./react/shallow": {
|
||||
"import": {
|
||||
"types": "./esm/react/shallow.d.mts",
|
||||
"default": "./esm/react/shallow.mjs"
|
||||
},
|
||||
"module": {
|
||||
"types": "./esm/react/shallow.d.ts",
|
||||
"default": "./esm/react/shallow.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./react/shallow.d.ts",
|
||||
"default": "./react/shallow.js"
|
||||
}
|
||||
},
|
||||
"./traditional": {
|
||||
"import": {
|
||||
"types": "./esm/traditional.d.mts",
|
||||
"default": "./esm/traditional.mjs"
|
||||
},
|
||||
"module": {
|
||||
"types": "./esm/traditional.d.ts",
|
||||
"default": "./esm/traditional.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./traditional.d.ts",
|
||||
"default": "./traditional.js"
|
||||
}
|
||||
},
|
||||
"./context": {
|
||||
"import": {
|
||||
"types": "./esm/context.d.mts",
|
||||
"default": "./esm/context.mjs"
|
||||
},
|
||||
"module": {
|
||||
"types": "./esm/context.d.ts",
|
||||
"default": "./esm/context.js"
|
||||
},
|
||||
"default": {
|
||||
"types": "./context.d.ts",
|
||||
"default": "./context.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sideEffects": false,
|
||||
"engines": {
|
||||
"node": ">=12.7.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/pmndrs/zustand.git"
|
||||
},
|
||||
"keywords": [
|
||||
"react",
|
||||
"state",
|
||||
"manager",
|
||||
"management",
|
||||
"redux",
|
||||
"store"
|
||||
],
|
||||
"author": "Paul Henschel",
|
||||
"contributors": [
|
||||
"Jeremy Holcomb (https://github.com/JeremyRH)",
|
||||
"Daishi Kato (https://github.com/dai-shi)"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/pmndrs/zustand/issues"
|
||||
},
|
||||
"homepage": "https://github.com/pmndrs/zustand",
|
||||
"dependencies": {
|
||||
"use-sync-external-store": "1.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": ">=16.8",
|
||||
"immer": ">=9.0.6",
|
||||
"react": ">=16.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"immer": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"packageManager": "yarn@1.22.21+sha256.dbed5b7e10c552ba0e1a545c948d5473bc6c5a28ce22a8fd27e493e3e5eb6370"
|
||||
}
|
38
react.d.ts
vendored
Normal file
38
react.d.ts
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
import type { Mutate, StateCreator, StoreApi, StoreMutatorIdentifier } from './vanilla';
|
||||
type ExtractState<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? T : never;
|
||||
type ReadonlyStoreApi<T> = Pick<StoreApi<T>, 'getState' | 'subscribe'>;
|
||||
type WithReact<S extends ReadonlyStoreApi<unknown>> = S & {
|
||||
/** @deprecated please use api.getInitialState() */
|
||||
getServerState?: () => ExtractState<S>;
|
||||
};
|
||||
export declare function useStore<S extends WithReact<StoreApi<unknown>>>(api: S): ExtractState<S>;
|
||||
export declare function useStore<S extends WithReact<StoreApi<unknown>>, U>(api: S, selector: (state: ExtractState<S>) => U): U;
|
||||
/**
|
||||
* @deprecated The usage with three arguments is deprecated. Use `useStoreWithEqualityFn` from 'zustand/traditional'. The usage with one or two arguments is not deprecated.
|
||||
* https://github.com/pmndrs/zustand/discussions/1937
|
||||
*/
|
||||
export declare function useStore<S extends WithReact<StoreApi<unknown>>, U>(api: S, selector: (state: ExtractState<S>) => U, equalityFn: ((a: U, b: U) => boolean) | undefined): U;
|
||||
export type UseBoundStore<S extends WithReact<ReadonlyStoreApi<unknown>>> = {
|
||||
(): ExtractState<S>;
|
||||
<U>(selector: (state: ExtractState<S>) => U): U;
|
||||
/**
|
||||
* @deprecated Use `createWithEqualityFn` from 'zustand/traditional'
|
||||
*/
|
||||
<U>(selector: (state: ExtractState<S>) => U, equalityFn: (a: U, b: U) => boolean): U;
|
||||
} & S;
|
||||
type Create = {
|
||||
<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>): UseBoundStore<Mutate<StoreApi<T>, Mos>>;
|
||||
<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>) => UseBoundStore<Mutate<StoreApi<T>, Mos>>;
|
||||
/**
|
||||
* @deprecated Use `useStore` hook to bind store
|
||||
*/
|
||||
<S extends StoreApi<unknown>>(store: S): UseBoundStore<S>;
|
||||
};
|
||||
export declare const create: Create;
|
||||
/**
|
||||
* @deprecated Use `import { create } from 'zustand'`
|
||||
*/
|
||||
declare const _default: Create;
|
||||
export default _default;
|
1
react/shallow.d.ts
vendored
Normal file
1
react/shallow.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export declare function useShallow<S, U>(selector: (state: S) => U): (state: S) => U;
|
88
react/shallow.js
Normal file
88
react/shallow.js
Normal file
@ -0,0 +1,88 @@
|
||||
'use strict';
|
||||
|
||||
var ReactExports = require('react');
|
||||
|
||||
function _unsupportedIterableToArray(o, minLen) {
|
||||
if (!o) return;
|
||||
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
||||
var n = Object.prototype.toString.call(o).slice(8, -1);
|
||||
if (n === "Object" && o.constructor) n = o.constructor.name;
|
||||
if (n === "Map" || n === "Set") return Array.from(o);
|
||||
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
||||
}
|
||||
function _arrayLikeToArray(arr, len) {
|
||||
if (len == null || len > arr.length) len = arr.length;
|
||||
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
||||
return arr2;
|
||||
}
|
||||
function _createForOfIteratorHelperLoose(o, allowArrayLike) {
|
||||
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
|
||||
if (it) return (it = it.call(o)).next.bind(it);
|
||||
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
|
||||
if (it) o = it;
|
||||
var i = 0;
|
||||
return function () {
|
||||
if (i >= o.length) return {
|
||||
done: true
|
||||
};
|
||||
return {
|
||||
done: false,
|
||||
value: o[i++]
|
||||
};
|
||||
};
|
||||
}
|
||||
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
||||
}
|
||||
|
||||
function shallow(objA, objB) {
|
||||
if (Object.is(objA, objB)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
|
||||
return false;
|
||||
}
|
||||
if (objA instanceof Map && objB instanceof Map) {
|
||||
if (objA.size !== objB.size) return false;
|
||||
for (var _iterator = _createForOfIteratorHelperLoose(objA), _step; !(_step = _iterator()).done;) {
|
||||
var _step$value = _step.value,
|
||||
key = _step$value[0],
|
||||
value = _step$value[1];
|
||||
if (!Object.is(value, objB.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (objA instanceof Set && objB instanceof Set) {
|
||||
if (objA.size !== objB.size) return false;
|
||||
for (var _iterator2 = _createForOfIteratorHelperLoose(objA), _step2; !(_step2 = _iterator2()).done;) {
|
||||
var _value = _step2.value;
|
||||
if (!objB.has(_value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
var keysA = Object.keys(objA);
|
||||
if (keysA.length !== Object.keys(objB).length) {
|
||||
return false;
|
||||
}
|
||||
for (var _i = 0, _keysA = keysA; _i < _keysA.length; _i++) {
|
||||
var keyA = _keysA[_i];
|
||||
if (!Object.prototype.hasOwnProperty.call(objB, keyA) || !Object.is(objA[keyA], objB[keyA])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var useRef = ReactExports.useRef;
|
||||
function useShallow(selector) {
|
||||
var prev = useRef();
|
||||
return function (state) {
|
||||
var next = selector(state);
|
||||
return shallow(prev.current, next) ? prev.current : prev.current = next;
|
||||
};
|
||||
}
|
||||
|
||||
exports.useShallow = useShallow;
|
505
readme.md
Normal file
505
readme.md
Normal file
@ -0,0 +1,505 @@
|
||||
<p align="center">
|
||||
<img src="bear.jpg" />
|
||||
</p>
|
||||
|
||||
[](https://github.com/pmndrs/zustand/actions?query=workflow%3ALint)
|
||||
[](https://bundlephobia.com/result?p=zustand)
|
||||
[](https://www.npmjs.com/package/zustand)
|
||||
[](https://www.npmjs.com/package/zustand)
|
||||
[](https://discord.gg/poimandres)
|
||||
|
||||
A small, fast and scalable bearbones state-management solution using simplified flux principles. Has a comfy API based on hooks, isn't boilerplatey or opinionated.
|
||||
|
||||
Don't disregard it because it's cute. It has quite the claws, lots of time was spent dealing with common pitfalls, like the dreaded [zombie child problem](https://react-redux.js.org/api/hooks#stale-props-and-zombie-children), [react concurrency](https://github.com/bvaughn/rfcs/blob/useMutableSource/text/0000-use-mutable-source.md), and [context loss](https://github.com/facebook/react/issues/13332) between mixed renderers. It may be the one state-manager in the React space that gets all of these right.
|
||||
|
||||
You can try a live demo [here](https://githubbox.com/pmndrs/zustand/tree/main/examples/demo).
|
||||
|
||||
```bash
|
||||
npm install zustand # or yarn add zustand or pnpm add zustand
|
||||
```
|
||||
|
||||
:warning: This readme is written for JavaScript users. If you are a TypeScript user, be sure to check out our [TypeScript Usage section](#typescript-usage).
|
||||
|
||||
## First create a store
|
||||
|
||||
Your store is a hook! You can put anything in it: primitives, objects, functions. State has to be updated immutably and the `set` function [merges state](./docs/guides/immutable-state-and-merging.md) to help it.
|
||||
|
||||
```jsx
|
||||
import { create } from 'zustand'
|
||||
|
||||
const useBearStore = create((set) => ({
|
||||
bears: 0,
|
||||
increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
|
||||
removeAllBears: () => set({ bears: 0 }),
|
||||
}))
|
||||
```
|
||||
|
||||
## Then bind your components, and that's it!
|
||||
|
||||
Use the hook anywhere, no providers are needed. Select your state and the component will re-render on changes.
|
||||
|
||||
```jsx
|
||||
function BearCounter() {
|
||||
const bears = useBearStore((state) => state.bears)
|
||||
return <h1>{bears} around here ...</h1>
|
||||
}
|
||||
|
||||
function Controls() {
|
||||
const increasePopulation = useBearStore((state) => state.increasePopulation)
|
||||
return <button onClick={increasePopulation}>one up</button>
|
||||
}
|
||||
```
|
||||
|
||||
### Why zustand over redux?
|
||||
|
||||
- Simple and un-opinionated
|
||||
- Makes hooks the primary means of consuming state
|
||||
- Doesn't wrap your app in context providers
|
||||
- [Can inform components transiently (without causing render)](#transient-updates-for-often-occurring-state-changes)
|
||||
|
||||
### Why zustand over context?
|
||||
|
||||
- Less boilerplate
|
||||
- Renders components only on changes
|
||||
- Centralized, action-based state management
|
||||
|
||||
---
|
||||
|
||||
# Recipes
|
||||
|
||||
## Fetching everything
|
||||
|
||||
You can, but bear in mind that it will cause the component to update on every state change!
|
||||
|
||||
```jsx
|
||||
const state = useBearStore()
|
||||
```
|
||||
|
||||
## Selecting multiple state slices
|
||||
|
||||
It detects changes with strict-equality (old === new) by default, this is efficient for atomic state picks.
|
||||
|
||||
```jsx
|
||||
const nuts = useBearStore((state) => state.nuts)
|
||||
const honey = useBearStore((state) => state.honey)
|
||||
```
|
||||
|
||||
If you want to construct a single object with multiple state-picks inside, similar to redux's mapStateToProps, you can use [useShallow](./docs/guides/prevent-rerenders-with-use-shallow.md) to prevent unnecessary rerenders when the selector output does not change according to shallow equal.
|
||||
|
||||
```jsx
|
||||
import { create } from 'zustand'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
|
||||
const useBearStore = create((set) => ({
|
||||
bears: 0,
|
||||
increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
|
||||
removeAllBears: () => set({ bears: 0 }),
|
||||
}))
|
||||
|
||||
// Object pick, re-renders the component when either state.nuts or state.honey change
|
||||
const { nuts, honey } = useBearStore(
|
||||
useShallow((state) => ({ nuts: state.nuts, honey: state.honey })),
|
||||
)
|
||||
|
||||
// Array pick, re-renders the component when either state.nuts or state.honey change
|
||||
const [nuts, honey] = useBearStore(
|
||||
useShallow((state) => [state.nuts, state.honey]),
|
||||
)
|
||||
|
||||
// Mapped picks, re-renders the component when state.treats changes in order, count or keys
|
||||
const treats = useBearStore(useShallow((state) => Object.keys(state.treats)))
|
||||
```
|
||||
|
||||
For more control over re-rendering, you may provide any custom equality function.
|
||||
|
||||
```jsx
|
||||
const treats = useBearStore(
|
||||
(state) => state.treats,
|
||||
(oldTreats, newTreats) => compare(oldTreats, newTreats),
|
||||
)
|
||||
```
|
||||
|
||||
## Overwriting state
|
||||
|
||||
The `set` function has a second argument, `false` by default. Instead of merging, it will replace the state model. Be careful not to wipe out parts you rely on, like actions.
|
||||
|
||||
```jsx
|
||||
import omit from 'lodash-es/omit'
|
||||
|
||||
const useFishStore = create((set) => ({
|
||||
salmon: 1,
|
||||
tuna: 2,
|
||||
deleteEverything: () => set({}, true), // clears the entire store, actions included
|
||||
deleteTuna: () => set((state) => omit(state, ['tuna']), true),
|
||||
}))
|
||||
```
|
||||
|
||||
## Async actions
|
||||
|
||||
Just call `set` when you're ready, zustand doesn't care if your actions are async or not.
|
||||
|
||||
```jsx
|
||||
const useFishStore = create((set) => ({
|
||||
fishies: {},
|
||||
fetch: async (pond) => {
|
||||
const response = await fetch(pond)
|
||||
set({ fishies: await response.json() })
|
||||
},
|
||||
}))
|
||||
```
|
||||
|
||||
## Read from state in actions
|
||||
|
||||
`set` allows fn-updates `set(state => result)`, but you still have access to state outside of it through `get`.
|
||||
|
||||
```jsx
|
||||
const useSoundStore = create((set, get) => ({
|
||||
sound: 'grunt',
|
||||
action: () => {
|
||||
const sound = get().sound
|
||||
...
|
||||
```
|
||||
|
||||
## Reading/writing state and reacting to changes outside of components
|
||||
|
||||
Sometimes you need to access state in a non-reactive way or act upon the store. For these cases, the resulting hook has utility functions attached to its prototype.
|
||||
|
||||
:warning: This technique is not recommended for adding state in [React Server Components](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md) (typically in Next.js 13 and above). It can lead to unexpected bugs and privacy issues for your users. For more details, see [#2200](https://github.com/pmndrs/zustand/discussions/2200).
|
||||
|
||||
```jsx
|
||||
const useDogStore = create(() => ({ paw: true, snout: true, fur: true }))
|
||||
|
||||
// Getting non-reactive fresh state
|
||||
const paw = useDogStore.getState().paw
|
||||
// Listening to all changes, fires synchronously on every change
|
||||
const unsub1 = useDogStore.subscribe(console.log)
|
||||
// Updating state, will trigger listeners
|
||||
useDogStore.setState({ paw: false })
|
||||
// Unsubscribe listeners
|
||||
unsub1()
|
||||
|
||||
// You can of course use the hook as you always would
|
||||
function Component() {
|
||||
const paw = useDogStore((state) => state.paw)
|
||||
...
|
||||
```
|
||||
|
||||
### Using subscribe with selector
|
||||
|
||||
If you need to subscribe with a selector,
|
||||
`subscribeWithSelector` middleware will help.
|
||||
|
||||
With this middleware `subscribe` accepts an additional signature:
|
||||
|
||||
```ts
|
||||
subscribe(selector, callback, options?: { equalityFn, fireImmediately }): Unsubscribe
|
||||
```
|
||||
|
||||
```js
|
||||
import { subscribeWithSelector } from 'zustand/middleware'
|
||||
const useDogStore = create(
|
||||
subscribeWithSelector(() => ({ paw: true, snout: true, fur: true })),
|
||||
)
|
||||
|
||||
// Listening to selected changes, in this case when "paw" changes
|
||||
const unsub2 = useDogStore.subscribe((state) => state.paw, console.log)
|
||||
// Subscribe also exposes the previous value
|
||||
const unsub3 = useDogStore.subscribe(
|
||||
(state) => state.paw,
|
||||
(paw, previousPaw) => console.log(paw, previousPaw),
|
||||
)
|
||||
// Subscribe also supports an optional equality function
|
||||
const unsub4 = useDogStore.subscribe(
|
||||
(state) => [state.paw, state.fur],
|
||||
console.log,
|
||||
{ equalityFn: shallow },
|
||||
)
|
||||
// Subscribe and fire immediately
|
||||
const unsub5 = useDogStore.subscribe((state) => state.paw, console.log, {
|
||||
fireImmediately: true,
|
||||
})
|
||||
```
|
||||
|
||||
## Using zustand without React
|
||||
|
||||
Zustand core can be imported and used without the React dependency. The only difference is that the create function does not return a hook, but the API utilities.
|
||||
|
||||
```jsx
|
||||
import { createStore } from 'zustand/vanilla'
|
||||
|
||||
const store = createStore((set) => ...)
|
||||
const { getState, setState, subscribe, getInitialState } = store
|
||||
|
||||
export default store
|
||||
```
|
||||
|
||||
You can use a vanilla store with `useStore` hook available since v4.
|
||||
|
||||
```jsx
|
||||
import { useStore } from 'zustand'
|
||||
import { vanillaStore } from './vanillaStore'
|
||||
|
||||
const useBoundStore = (selector) => useStore(vanillaStore, selector)
|
||||
```
|
||||
|
||||
:warning: Note that middlewares that modify `set` or `get` are not applied to `getState` and `setState`.
|
||||
|
||||
## Transient updates (for often occurring state-changes)
|
||||
|
||||
The subscribe function allows components to bind to a state-portion without forcing re-render on changes. Best combine it with useEffect for automatic unsubscribe on unmount. This can make a [drastic](https://codesandbox.io/s/peaceful-johnson-txtws) performance impact when you are allowed to mutate the view directly.
|
||||
|
||||
```jsx
|
||||
const useScratchStore = create((set) => ({ scratches: 0, ... }))
|
||||
|
||||
const Component = () => {
|
||||
// Fetch initial state
|
||||
const scratchRef = useRef(useScratchStore.getState().scratches)
|
||||
// Connect to the store on mount, disconnect on unmount, catch state-changes in a reference
|
||||
useEffect(() => useScratchStore.subscribe(
|
||||
state => (scratchRef.current = state.scratches)
|
||||
), [])
|
||||
...
|
||||
```
|
||||
|
||||
## Sick of reducers and changing nested states? Use Immer!
|
||||
|
||||
Reducing nested structures is tiresome. Have you tried [immer](https://github.com/mweststrate/immer)?
|
||||
|
||||
```jsx
|
||||
import { produce } from 'immer'
|
||||
|
||||
const useLushStore = create((set) => ({
|
||||
lush: { forest: { contains: { a: 'bear' } } },
|
||||
clearForest: () =>
|
||||
set(
|
||||
produce((state) => {
|
||||
state.lush.forest.contains = null
|
||||
}),
|
||||
),
|
||||
}))
|
||||
|
||||
const clearForest = useLushStore((state) => state.clearForest)
|
||||
clearForest()
|
||||
```
|
||||
|
||||
[Alternatively, there are some other solutions.](./docs/guides/updating-state.md#with-immer)
|
||||
|
||||
## Persist middleware
|
||||
|
||||
You can persist your store's data using any kind of storage.
|
||||
|
||||
```jsx
|
||||
import { create } from 'zustand'
|
||||
import { persist, createJSONStorage } from 'zustand/middleware'
|
||||
|
||||
const useFishStore = create(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
fishes: 0,
|
||||
addAFish: () => set({ fishes: get().fishes + 1 }),
|
||||
}),
|
||||
{
|
||||
name: 'food-storage', // name of the item in the storage (must be unique)
|
||||
storage: createJSONStorage(() => sessionStorage), // (optional) by default, 'localStorage' is used
|
||||
},
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
[See the full documentation for this middleware.](./docs/integrations/persisting-store-data.md)
|
||||
|
||||
## Immer middleware
|
||||
|
||||
Immer is available as middleware too.
|
||||
|
||||
```jsx
|
||||
import { create } from 'zustand'
|
||||
import { immer } from 'zustand/middleware/immer'
|
||||
|
||||
const useBeeStore = create(
|
||||
immer((set) => ({
|
||||
bees: 0,
|
||||
addBees: (by) =>
|
||||
set((state) => {
|
||||
state.bees += by
|
||||
}),
|
||||
})),
|
||||
)
|
||||
```
|
||||
|
||||
## Can't live without redux-like reducers and action types?
|
||||
|
||||
```jsx
|
||||
const types = { increase: 'INCREASE', decrease: 'DECREASE' }
|
||||
|
||||
const reducer = (state, { type, by = 1 }) => {
|
||||
switch (type) {
|
||||
case types.increase:
|
||||
return { grumpiness: state.grumpiness + by }
|
||||
case types.decrease:
|
||||
return { grumpiness: state.grumpiness - by }
|
||||
}
|
||||
}
|
||||
|
||||
const useGrumpyStore = create((set) => ({
|
||||
grumpiness: 0,
|
||||
dispatch: (args) => set((state) => reducer(state, args)),
|
||||
}))
|
||||
|
||||
const dispatch = useGrumpyStore((state) => state.dispatch)
|
||||
dispatch({ type: types.increase, by: 2 })
|
||||
```
|
||||
|
||||
Or, just use our redux-middleware. It wires up your main-reducer, sets the initial state, and adds a dispatch function to the state itself and the vanilla API.
|
||||
|
||||
```jsx
|
||||
import { redux } from 'zustand/middleware'
|
||||
|
||||
const useGrumpyStore = create(redux(reducer, initialState))
|
||||
```
|
||||
|
||||
## Redux devtools
|
||||
|
||||
```jsx
|
||||
import { devtools } from 'zustand/middleware'
|
||||
|
||||
// Usage with a plain action store, it will log actions as "setState"
|
||||
const usePlainStore = create(devtools((set) => ...))
|
||||
// Usage with a redux store, it will log full action types
|
||||
const useReduxStore = create(devtools(redux(reducer, initialState)))
|
||||
```
|
||||
|
||||
One redux devtools connection for multiple stores
|
||||
|
||||
```jsx
|
||||
import { devtools } from 'zustand/middleware'
|
||||
|
||||
// Usage with a plain action store, it will log actions as "setState"
|
||||
const usePlainStore1 = create(devtools((set) => ..., { name, store: storeName1 }))
|
||||
const usePlainStore2 = create(devtools((set) => ..., { name, store: storeName2 }))
|
||||
// Usage with a redux store, it will log full action types
|
||||
const useReduxStore = create(devtools(redux(reducer, initialState)), , { name, store: storeName3 })
|
||||
const useReduxStore = create(devtools(redux(reducer, initialState)), , { name, store: storeName4 })
|
||||
```
|
||||
|
||||
Assigning different connection names will separate stores in redux devtools. This also helps group different stores into separate redux devtools connections.
|
||||
|
||||
devtools takes the store function as its first argument, optionally you can name the store or configure [serialize](https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Arguments.md#serialize) options with a second argument.
|
||||
|
||||
Name store: `devtools(..., {name: "MyStore"})`, which will create a separate instance named "MyStore" in the devtools.
|
||||
|
||||
Serialize options: `devtools(..., { serialize: { options: true } })`.
|
||||
|
||||
#### Logging Actions
|
||||
|
||||
devtools will only log actions from each separated store unlike in a typical _combined reducers_ redux store. See an approach to combining stores https://github.com/pmndrs/zustand/issues/163
|
||||
|
||||
You can log a specific action type for each `set` function by passing a third parameter:
|
||||
|
||||
```jsx
|
||||
const useBearStore = create(devtools((set) => ({
|
||||
...
|
||||
eatFish: () => set(
|
||||
(prev) => ({ fishes: prev.fishes > 1 ? prev.fishes - 1 : 0 }),
|
||||
false,
|
||||
'bear/eatFish'
|
||||
),
|
||||
...
|
||||
```
|
||||
|
||||
You can also log the action's type along with its payload:
|
||||
|
||||
```jsx
|
||||
...
|
||||
addFishes: (count) => set(
|
||||
(prev) => ({ fishes: prev.fishes + count }),
|
||||
false,
|
||||
{ type: 'bear/addFishes', count, }
|
||||
),
|
||||
...
|
||||
```
|
||||
|
||||
If an action type is not provided, it is defaulted to "anonymous". You can customize this default value by providing an `anonymousActionType` parameter:
|
||||
|
||||
```jsx
|
||||
devtools(..., { anonymousActionType: 'unknown', ... })
|
||||
```
|
||||
|
||||
If you wish to disable devtools (on production for instance). You can customize this setting by providing the `enabled` parameter:
|
||||
|
||||
```jsx
|
||||
devtools(..., { enabled: false, ... })
|
||||
```
|
||||
|
||||
## React context
|
||||
|
||||
The store created with `create` doesn't require context providers. In some cases, you may want to use contexts for dependency injection or if you want to initialize your store with props from a component. Because the normal store is a hook, passing it as a normal context value may violate the rules of hooks.
|
||||
|
||||
The recommended method available since v4 is to use the vanilla store.
|
||||
|
||||
```jsx
|
||||
import { createContext, useContext } from 'react'
|
||||
import { createStore, useStore } from 'zustand'
|
||||
|
||||
const store = createStore(...) // vanilla store without hooks
|
||||
|
||||
const StoreContext = createContext()
|
||||
|
||||
const App = () => (
|
||||
<StoreContext.Provider value={store}>
|
||||
...
|
||||
</StoreContext.Provider>
|
||||
)
|
||||
|
||||
const Component = () => {
|
||||
const store = useContext(StoreContext)
|
||||
const slice = useStore(store, selector)
|
||||
...
|
||||
```
|
||||
|
||||
## TypeScript Usage
|
||||
|
||||
Basic typescript usage doesn't require anything special except for writing `create<State>()(...)` instead of `create(...)`...
|
||||
|
||||
```ts
|
||||
import { create } from 'zustand'
|
||||
import { devtools, persist } from 'zustand/middleware'
|
||||
import type {} from '@redux-devtools/extension' // required for devtools typing
|
||||
|
||||
interface BearState {
|
||||
bears: number
|
||||
increase: (by: number) => void
|
||||
}
|
||||
|
||||
const useBearStore = create<BearState>()(
|
||||
devtools(
|
||||
persist(
|
||||
(set) => ({
|
||||
bears: 0,
|
||||
increase: (by) => set((state) => ({ bears: state.bears + by })),
|
||||
}),
|
||||
{
|
||||
name: 'bear-storage',
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
A more complete TypeScript guide is [here](docs/guides/typescript.md).
|
||||
|
||||
## Best practices
|
||||
|
||||
- You may wonder how to organize your code for better maintenance: [Splitting the store into separate slices](./docs/guides/slices-pattern.md).
|
||||
- Recommended usage for this unopinionated library: [Flux inspired practice](./docs/guides/flux-inspired-practice.md).
|
||||
- [Calling actions outside a React event handler in pre-React 18](./docs/guides/event-handler-in-pre-react-18.md).
|
||||
- [Testing](./docs/guides/testing.md)
|
||||
- For more, have a look [in the docs folder](./docs/)
|
||||
|
||||
## Third-Party Libraries
|
||||
|
||||
Some users may want to extend Zustand's feature set which can be done using third-party libraries made by the community. For information regarding third-party libraries with Zustand, visit [the doc](./docs/integrations/third-party-libraries.md).
|
||||
|
||||
## Comparison with other libraries
|
||||
|
||||
- [Difference between zustand and other state management libraries for React](https://docs.pmnd.rs/zustand/getting-started/comparison)
|
7
shallow.d.ts
vendored
Normal file
7
shallow.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import { shallow } from './vanilla/shallow';
|
||||
/**
|
||||
* @deprecated Use `import { shallow } from 'zustand/shallow'`
|
||||
*/
|
||||
declare const _default: typeof shallow;
|
||||
export default _default;
|
||||
export { shallow };
|
89
shallow.js
Normal file
89
shallow.js
Normal file
@ -0,0 +1,89 @@
|
||||
'use strict';
|
||||
|
||||
function _unsupportedIterableToArray(o, minLen) {
|
||||
if (!o) return;
|
||||
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
||||
var n = Object.prototype.toString.call(o).slice(8, -1);
|
||||
if (n === "Object" && o.constructor) n = o.constructor.name;
|
||||
if (n === "Map" || n === "Set") return Array.from(o);
|
||||
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
||||
}
|
||||
function _arrayLikeToArray(arr, len) {
|
||||
if (len == null || len > arr.length) len = arr.length;
|
||||
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
||||
return arr2;
|
||||
}
|
||||
function _createForOfIteratorHelperLoose(o, allowArrayLike) {
|
||||
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
|
||||
if (it) return (it = it.call(o)).next.bind(it);
|
||||
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
|
||||
if (it) o = it;
|
||||
var i = 0;
|
||||
return function () {
|
||||
if (i >= o.length) return {
|
||||
done: true
|
||||
};
|
||||
return {
|
||||
done: false,
|
||||
value: o[i++]
|
||||
};
|
||||
};
|
||||
}
|
||||
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
||||
}
|
||||
|
||||
function shallow$1(objA, objB) {
|
||||
if (Object.is(objA, objB)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
|
||||
return false;
|
||||
}
|
||||
if (objA instanceof Map && objB instanceof Map) {
|
||||
if (objA.size !== objB.size) return false;
|
||||
for (var _iterator = _createForOfIteratorHelperLoose(objA), _step; !(_step = _iterator()).done;) {
|
||||
var _step$value = _step.value,
|
||||
key = _step$value[0],
|
||||
value = _step$value[1];
|
||||
if (!Object.is(value, objB.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (objA instanceof Set && objB instanceof Set) {
|
||||
if (objA.size !== objB.size) return false;
|
||||
for (var _iterator2 = _createForOfIteratorHelperLoose(objA), _step2; !(_step2 = _iterator2()).done;) {
|
||||
var _value = _step2.value;
|
||||
if (!objB.has(_value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
var keysA = Object.keys(objA);
|
||||
if (keysA.length !== Object.keys(objB).length) {
|
||||
return false;
|
||||
}
|
||||
for (var _i = 0, _keysA = keysA; _i < _keysA.length; _i++) {
|
||||
var keyA = _keysA[_i];
|
||||
if (!Object.prototype.hasOwnProperty.call(objB, keyA) || !Object.is(objA[keyA], objB[keyA])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var shallow = (function (objA, objB) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
console.warn("[DEPRECATED] Default export is deprecated. Instead use `import { shallow } from 'zustand/shallow'`.");
|
||||
}
|
||||
return shallow$1(objA, objB);
|
||||
});
|
||||
|
||||
exports.default = shallow;
|
||||
exports.shallow = shallow$1;
|
||||
|
||||
module.exports = shallow;
|
||||
module.exports.shallow = shallow$1;
|
||||
exports.default = module.exports;
|
73
system/context.development.js
Normal file
73
system/context.development.js
Normal file
@ -0,0 +1,73 @@
|
||||
System.register(['react', 'zustand/traditional'], (function (exports) {
|
||||
'use strict';
|
||||
var ReactExports, useStoreWithEqualityFn;
|
||||
return {
|
||||
setters: [function (module) {
|
||||
ReactExports = module.default;
|
||||
}, function (module) {
|
||||
useStoreWithEqualityFn = module.useStoreWithEqualityFn;
|
||||
}],
|
||||
execute: (function () {
|
||||
|
||||
exports("default", createContext);
|
||||
|
||||
const {
|
||||
createElement,
|
||||
createContext: reactCreateContext,
|
||||
useContext,
|
||||
useMemo,
|
||||
useRef
|
||||
} = ReactExports;
|
||||
function createContext() {
|
||||
{
|
||||
console.warn(
|
||||
"[DEPRECATED] `context` will be removed in a future version. Instead use `import { createStore, useStore } from 'zustand'`. See: https://github.com/pmndrs/zustand/discussions/1180."
|
||||
);
|
||||
}
|
||||
const ZustandContext = reactCreateContext(void 0);
|
||||
const Provider = ({
|
||||
createStore,
|
||||
children
|
||||
}) => {
|
||||
const storeRef = useRef();
|
||||
if (!storeRef.current) {
|
||||
storeRef.current = createStore();
|
||||
}
|
||||
return createElement(
|
||||
ZustandContext.Provider,
|
||||
{ value: storeRef.current },
|
||||
children
|
||||
);
|
||||
};
|
||||
const useContextStore = (selector, equalityFn) => {
|
||||
const store = useContext(ZustandContext);
|
||||
if (!store) {
|
||||
throw new Error(
|
||||
"Seems like you have not used zustand provider as an ancestor."
|
||||
);
|
||||
}
|
||||
return useStoreWithEqualityFn(
|
||||
store,
|
||||
selector,
|
||||
equalityFn
|
||||
);
|
||||
};
|
||||
const useStoreApi = () => {
|
||||
const store = useContext(ZustandContext);
|
||||
if (!store) {
|
||||
throw new Error(
|
||||
"Seems like you have not used zustand provider as an ancestor."
|
||||
);
|
||||
}
|
||||
return useMemo(() => ({ ...store }), [store]);
|
||||
};
|
||||
return {
|
||||
Provider,
|
||||
useStore: useContextStore,
|
||||
useStoreApi
|
||||
};
|
||||
}
|
||||
|
||||
})
|
||||
};
|
||||
}));
|
1
system/context.production.js
Normal file
1
system/context.production.js
Normal file
@ -0,0 +1 @@
|
||||
System.register(["react","zustand/traditional"],function(a){"use strict";var o,s;return{setters:[function(r){o=r.default},function(r){s=r.useStoreWithEqualityFn}],execute:function(){a("default",l);const{createElement:r,createContext:c,useContext:i,useMemo:d,useRef:f}=o;function l(){const n=c(void 0);return{Provider:({createStore:e,children:u})=>{const t=f();return t.current||(t.current=e()),r(n.Provider,{value:t.current},u)},useStore:(e,u)=>{const t=i(n);if(!t)throw new Error("Seems like you have not used zustand provider as an ancestor.");return s(t,e,u)},useStoreApi:()=>{const e=i(n);if(!e)throw new Error("Seems like you have not used zustand provider as an ancestor.");return d(()=>({...e}),[e])}}}}}});
|
71
system/index.development.js
Normal file
71
system/index.development.js
Normal file
@ -0,0 +1,71 @@
|
||||
System.register(['zustand/vanilla', 'react', 'use-sync-external-store/shim/with-selector'], (function (exports) {
|
||||
'use strict';
|
||||
var _starExcludes = {
|
||||
__proto__: null,
|
||||
create: 1,
|
||||
default: 1,
|
||||
useStore: 1
|
||||
};
|
||||
var createStore, ReactExports, useSyncExternalStoreExports;
|
||||
return {
|
||||
setters: [function (module) {
|
||||
createStore = module.createStore;
|
||||
var setter = { __proto__: null };
|
||||
for (var name in module) {
|
||||
if (!_starExcludes[name]) setter[name] = module[name];
|
||||
}
|
||||
exports(setter);
|
||||
}, function (module) {
|
||||
ReactExports = module.default;
|
||||
}, function (module) {
|
||||
useSyncExternalStoreExports = module.default;
|
||||
}],
|
||||
execute: (function () {
|
||||
|
||||
exports("useStore", useStore);
|
||||
|
||||
const { useDebugValue } = ReactExports;
|
||||
const { useSyncExternalStoreWithSelector } = useSyncExternalStoreExports;
|
||||
let didWarnAboutEqualityFn = false;
|
||||
const identity = (arg) => arg;
|
||||
function useStore(api, selector = identity, equalityFn) {
|
||||
if (equalityFn && !didWarnAboutEqualityFn) {
|
||||
console.warn(
|
||||
"[DEPRECATED] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`. They can be imported from 'zustand/traditional'. https://github.com/pmndrs/zustand/discussions/1937"
|
||||
);
|
||||
didWarnAboutEqualityFn = true;
|
||||
}
|
||||
const slice = useSyncExternalStoreWithSelector(
|
||||
api.subscribe,
|
||||
api.getState,
|
||||
api.getServerState || api.getInitialState,
|
||||
selector,
|
||||
equalityFn
|
||||
);
|
||||
useDebugValue(slice);
|
||||
return slice;
|
||||
}
|
||||
const createImpl = (createState) => {
|
||||
if (typeof createState !== "function") {
|
||||
console.warn(
|
||||
"[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`."
|
||||
);
|
||||
}
|
||||
const api = typeof createState === "function" ? createStore(createState) : createState;
|
||||
const useBoundStore = (selector, equalityFn) => useStore(api, selector, equalityFn);
|
||||
Object.assign(useBoundStore, api);
|
||||
return useBoundStore;
|
||||
};
|
||||
const create = exports("create", (createState) => createState ? createImpl(createState) : createImpl);
|
||||
var react = exports("default", (createState) => {
|
||||
{
|
||||
console.warn(
|
||||
"[DEPRECATED] Default export is deprecated. Instead use `import { create } from 'zustand'`."
|
||||
);
|
||||
}
|
||||
return create(createState);
|
||||
});
|
||||
|
||||
})
|
||||
};
|
||||
}));
|
1
system/index.production.js
Normal file
1
system/index.production.js
Normal file
@ -0,0 +1 @@
|
||||
System.register(["zustand/vanilla","react","use-sync-external-store/shim/with-selector"],function(n){"use strict";var _={__proto__:null,create:1,default:1,useStore:1},o,i,l;return{setters:[function(t){o=t.createStore;var c={__proto__:null};for(var r in t)_[r]||(c[r]=t[r]);n(c)},function(t){i=t.default},function(t){l=t.default}],execute:function(){n("useStore",f);const{useDebugValue:t}=i,{useSyncExternalStoreWithSelector:c}=l,r=e=>e;function f(e,s=r,u){const a=c(e.subscribe,e.getState,e.getServerState||e.getInitialState,s,u);return t(a),a}const S=e=>{const s=typeof e=="function"?o(e):e,u=(a,g)=>f(s,a,g);return Object.assign(u,s),u},v=n("create",e=>e?S(e):S);var d=n("default",e=>v(e))}}});
|
593
system/middleware.development.js
Normal file
593
system/middleware.development.js
Normal file
@ -0,0 +1,593 @@
|
||||
System.register([], (function (exports) {
|
||||
'use strict';
|
||||
return {
|
||||
execute: (function () {
|
||||
|
||||
exports("createJSONStorage", createJSONStorage);
|
||||
|
||||
const reduxImpl = (reducer, initial) => (set, _get, api) => {
|
||||
api.dispatch = (action) => {
|
||||
set((state) => reducer(state, action), false, action);
|
||||
return action;
|
||||
};
|
||||
api.dispatchFromDevtools = true;
|
||||
return { dispatch: (...a) => api.dispatch(...a), ...initial };
|
||||
};
|
||||
const redux = exports("redux", reduxImpl);
|
||||
|
||||
const trackedConnections = /* @__PURE__ */ new Map();
|
||||
const getTrackedConnectionState = (name) => {
|
||||
const api = trackedConnections.get(name);
|
||||
if (!api)
|
||||
return {};
|
||||
return Object.fromEntries(
|
||||
Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])
|
||||
);
|
||||
};
|
||||
const extractConnectionInformation = (store, extensionConnector, options) => {
|
||||
if (store === void 0) {
|
||||
return {
|
||||
type: "untracked",
|
||||
connection: extensionConnector.connect(options)
|
||||
};
|
||||
}
|
||||
const existingConnection = trackedConnections.get(options.name);
|
||||
if (existingConnection) {
|
||||
return { type: "tracked", store, ...existingConnection };
|
||||
}
|
||||
const newConnection = {
|
||||
connection: extensionConnector.connect(options),
|
||||
stores: {}
|
||||
};
|
||||
trackedConnections.set(options.name, newConnection);
|
||||
return { type: "tracked", store, ...newConnection };
|
||||
};
|
||||
const devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {
|
||||
const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;
|
||||
let extensionConnector;
|
||||
try {
|
||||
extensionConnector = (enabled != null ? enabled : true) && window.__REDUX_DEVTOOLS_EXTENSION__;
|
||||
} catch (e) {
|
||||
}
|
||||
if (!extensionConnector) {
|
||||
if (enabled) {
|
||||
console.warn(
|
||||
"[zustand devtools middleware] Please install/enable Redux devtools extension"
|
||||
);
|
||||
}
|
||||
return fn(set, get, api);
|
||||
}
|
||||
const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);
|
||||
let isRecording = true;
|
||||
api.setState = (state, replace, nameOrAction) => {
|
||||
const r = set(state, replace);
|
||||
if (!isRecording)
|
||||
return r;
|
||||
const action = nameOrAction === void 0 ? { type: anonymousActionType || "anonymous" } : typeof nameOrAction === "string" ? { type: nameOrAction } : nameOrAction;
|
||||
if (store === void 0) {
|
||||
connection == null ? void 0 : connection.send(action, get());
|
||||
return r;
|
||||
}
|
||||
connection == null ? void 0 : connection.send(
|
||||
{
|
||||
...action,
|
||||
type: `${store}/${action.type}`
|
||||
},
|
||||
{
|
||||
...getTrackedConnectionState(options.name),
|
||||
[store]: api.getState()
|
||||
}
|
||||
);
|
||||
return r;
|
||||
};
|
||||
const setStateFromDevtools = (...a) => {
|
||||
const originalIsRecording = isRecording;
|
||||
isRecording = false;
|
||||
set(...a);
|
||||
isRecording = originalIsRecording;
|
||||
};
|
||||
const initialState = fn(api.setState, get, api);
|
||||
if (connectionInformation.type === "untracked") {
|
||||
connection == null ? void 0 : connection.init(initialState);
|
||||
} else {
|
||||
connectionInformation.stores[connectionInformation.store] = api;
|
||||
connection == null ? void 0 : connection.init(
|
||||
Object.fromEntries(
|
||||
Object.entries(connectionInformation.stores).map(([key, store2]) => [
|
||||
key,
|
||||
key === connectionInformation.store ? initialState : store2.getState()
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
if (api.dispatchFromDevtools && typeof api.dispatch === "function") {
|
||||
let didWarnAboutReservedActionType = false;
|
||||
const originalDispatch = api.dispatch;
|
||||
api.dispatch = (...a) => {
|
||||
if (a[0].type === "__setState" && !didWarnAboutReservedActionType) {
|
||||
console.warn(
|
||||
'[zustand devtools middleware] "__setState" action type is reserved to set state from the devtools. Avoid using it.'
|
||||
);
|
||||
didWarnAboutReservedActionType = true;
|
||||
}
|
||||
originalDispatch(...a);
|
||||
};
|
||||
}
|
||||
connection.subscribe((message) => {
|
||||
var _a;
|
||||
switch (message.type) {
|
||||
case "ACTION":
|
||||
if (typeof message.payload !== "string") {
|
||||
console.error(
|
||||
"[zustand devtools middleware] Unsupported action format"
|
||||
);
|
||||
return;
|
||||
}
|
||||
return parseJsonThen(
|
||||
message.payload,
|
||||
(action) => {
|
||||
if (action.type === "__setState") {
|
||||
if (store === void 0) {
|
||||
setStateFromDevtools(action.state);
|
||||
return;
|
||||
}
|
||||
if (Object.keys(action.state).length !== 1) {
|
||||
console.error(
|
||||
`
|
||||
[zustand devtools middleware] Unsupported __setState action format.
|
||||
When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),
|
||||
and value of this only key should be a state object. Example: { "type": "__setState", "state": { "abc123Store": { "foo": "bar" } } }
|
||||
`
|
||||
);
|
||||
}
|
||||
const stateFromDevtools = action.state[store];
|
||||
if (stateFromDevtools === void 0 || stateFromDevtools === null) {
|
||||
return;
|
||||
}
|
||||
if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {
|
||||
setStateFromDevtools(stateFromDevtools);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!api.dispatchFromDevtools)
|
||||
return;
|
||||
if (typeof api.dispatch !== "function")
|
||||
return;
|
||||
api.dispatch(action);
|
||||
}
|
||||
);
|
||||
case "DISPATCH":
|
||||
switch (message.payload.type) {
|
||||
case "RESET":
|
||||
setStateFromDevtools(initialState);
|
||||
if (store === void 0) {
|
||||
return connection == null ? void 0 : connection.init(api.getState());
|
||||
}
|
||||
return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));
|
||||
case "COMMIT":
|
||||
if (store === void 0) {
|
||||
connection == null ? void 0 : connection.init(api.getState());
|
||||
return;
|
||||
}
|
||||
return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));
|
||||
case "ROLLBACK":
|
||||
return parseJsonThen(message.state, (state) => {
|
||||
if (store === void 0) {
|
||||
setStateFromDevtools(state);
|
||||
connection == null ? void 0 : connection.init(api.getState());
|
||||
return;
|
||||
}
|
||||
setStateFromDevtools(state[store]);
|
||||
connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));
|
||||
});
|
||||
case "JUMP_TO_STATE":
|
||||
case "JUMP_TO_ACTION":
|
||||
return parseJsonThen(message.state, (state) => {
|
||||
if (store === void 0) {
|
||||
setStateFromDevtools(state);
|
||||
return;
|
||||
}
|
||||
if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {
|
||||
setStateFromDevtools(state[store]);
|
||||
}
|
||||
});
|
||||
case "IMPORT_STATE": {
|
||||
const { nextLiftedState } = message.payload;
|
||||
const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;
|
||||
if (!lastComputedState)
|
||||
return;
|
||||
if (store === void 0) {
|
||||
setStateFromDevtools(lastComputedState);
|
||||
} else {
|
||||
setStateFromDevtools(lastComputedState[store]);
|
||||
}
|
||||
connection == null ? void 0 : connection.send(
|
||||
null,
|
||||
// FIXME no-any
|
||||
nextLiftedState
|
||||
);
|
||||
return;
|
||||
}
|
||||
case "PAUSE_RECORDING":
|
||||
return isRecording = !isRecording;
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
return initialState;
|
||||
};
|
||||
const devtools = exports("devtools", devtoolsImpl);
|
||||
const parseJsonThen = (stringified, f) => {
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(stringified);
|
||||
} catch (e) {
|
||||
console.error(
|
||||
"[zustand devtools middleware] Could not parse the received json",
|
||||
e
|
||||
);
|
||||
}
|
||||
if (parsed !== void 0)
|
||||
f(parsed);
|
||||
};
|
||||
|
||||
const subscribeWithSelectorImpl = (fn) => (set, get, api) => {
|
||||
const origSubscribe = api.subscribe;
|
||||
api.subscribe = (selector, optListener, options) => {
|
||||
let listener = selector;
|
||||
if (optListener) {
|
||||
const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;
|
||||
let currentSlice = selector(api.getState());
|
||||
listener = (state) => {
|
||||
const nextSlice = selector(state);
|
||||
if (!equalityFn(currentSlice, nextSlice)) {
|
||||
const previousSlice = currentSlice;
|
||||
optListener(currentSlice = nextSlice, previousSlice);
|
||||
}
|
||||
};
|
||||
if (options == null ? void 0 : options.fireImmediately) {
|
||||
optListener(currentSlice, currentSlice);
|
||||
}
|
||||
}
|
||||
return origSubscribe(listener);
|
||||
};
|
||||
const initialState = fn(set, get, api);
|
||||
return initialState;
|
||||
};
|
||||
const subscribeWithSelector = exports("subscribeWithSelector", subscribeWithSelectorImpl);
|
||||
|
||||
const combine = exports("combine", (initialState, create) => (...a) => Object.assign({}, initialState, create(...a)));
|
||||
|
||||
function createJSONStorage(getStorage, options) {
|
||||
let storage;
|
||||
try {
|
||||
storage = getStorage();
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
const persistStorage = {
|
||||
getItem: (name) => {
|
||||
var _a;
|
||||
const parse = (str2) => {
|
||||
if (str2 === null) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parse(str2, options == null ? void 0 : options.reviver);
|
||||
};
|
||||
const str = (_a = storage.getItem(name)) != null ? _a : null;
|
||||
if (str instanceof Promise) {
|
||||
return str.then(parse);
|
||||
}
|
||||
return parse(str);
|
||||
},
|
||||
setItem: (name, newValue) => storage.setItem(
|
||||
name,
|
||||
JSON.stringify(newValue, options == null ? void 0 : options.replacer)
|
||||
),
|
||||
removeItem: (name) => storage.removeItem(name)
|
||||
};
|
||||
return persistStorage;
|
||||
}
|
||||
const toThenable = (fn) => (input) => {
|
||||
try {
|
||||
const result = fn(input);
|
||||
if (result instanceof Promise) {
|
||||
return result;
|
||||
}
|
||||
return {
|
||||
then(onFulfilled) {
|
||||
return toThenable(onFulfilled)(result);
|
||||
},
|
||||
catch(_onRejected) {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
then(_onFulfilled) {
|
||||
return this;
|
||||
},
|
||||
catch(onRejected) {
|
||||
return toThenable(onRejected)(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
const oldImpl = (config, baseOptions) => (set, get, api) => {
|
||||
let options = {
|
||||
getStorage: () => localStorage,
|
||||
serialize: JSON.stringify,
|
||||
deserialize: JSON.parse,
|
||||
partialize: (state) => state,
|
||||
version: 0,
|
||||
merge: (persistedState, currentState) => ({
|
||||
...currentState,
|
||||
...persistedState
|
||||
}),
|
||||
...baseOptions
|
||||
};
|
||||
let hasHydrated = false;
|
||||
const hydrationListeners = /* @__PURE__ */ new Set();
|
||||
const finishHydrationListeners = /* @__PURE__ */ new Set();
|
||||
let storage;
|
||||
try {
|
||||
storage = options.getStorage();
|
||||
} catch (e) {
|
||||
}
|
||||
if (!storage) {
|
||||
return config(
|
||||
(...args) => {
|
||||
console.warn(
|
||||
`[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`
|
||||
);
|
||||
set(...args);
|
||||
},
|
||||
get,
|
||||
api
|
||||
);
|
||||
}
|
||||
const thenableSerialize = toThenable(options.serialize);
|
||||
const setItem = () => {
|
||||
const state = options.partialize({ ...get() });
|
||||
let errorInSync;
|
||||
const thenable = thenableSerialize({ state, version: options.version }).then(
|
||||
(serializedValue) => storage.setItem(options.name, serializedValue)
|
||||
).catch((e) => {
|
||||
errorInSync = e;
|
||||
});
|
||||
if (errorInSync) {
|
||||
throw errorInSync;
|
||||
}
|
||||
return thenable;
|
||||
};
|
||||
const savedSetState = api.setState;
|
||||
api.setState = (state, replace) => {
|
||||
savedSetState(state, replace);
|
||||
void setItem();
|
||||
};
|
||||
const configResult = config(
|
||||
(...args) => {
|
||||
set(...args);
|
||||
void setItem();
|
||||
},
|
||||
get,
|
||||
api
|
||||
);
|
||||
let stateFromStorage;
|
||||
const hydrate = () => {
|
||||
var _a;
|
||||
if (!storage)
|
||||
return;
|
||||
hasHydrated = false;
|
||||
hydrationListeners.forEach((cb) => cb(get()));
|
||||
const postRehydrationCallback = ((_a = options.onRehydrateStorage) == null ? void 0 : _a.call(options, get())) || void 0;
|
||||
return toThenable(storage.getItem.bind(storage))(options.name).then((storageValue) => {
|
||||
if (storageValue) {
|
||||
return options.deserialize(storageValue);
|
||||
}
|
||||
}).then((deserializedStorageValue) => {
|
||||
if (deserializedStorageValue) {
|
||||
if (typeof deserializedStorageValue.version === "number" && deserializedStorageValue.version !== options.version) {
|
||||
if (options.migrate) {
|
||||
return options.migrate(
|
||||
deserializedStorageValue.state,
|
||||
deserializedStorageValue.version
|
||||
);
|
||||
}
|
||||
console.error(
|
||||
`State loaded from storage couldn't be migrated since no migrate function was provided`
|
||||
);
|
||||
} else {
|
||||
return deserializedStorageValue.state;
|
||||
}
|
||||
}
|
||||
}).then((migratedState) => {
|
||||
var _a2;
|
||||
stateFromStorage = options.merge(
|
||||
migratedState,
|
||||
(_a2 = get()) != null ? _a2 : configResult
|
||||
);
|
||||
set(stateFromStorage, true);
|
||||
return setItem();
|
||||
}).then(() => {
|
||||
postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);
|
||||
hasHydrated = true;
|
||||
finishHydrationListeners.forEach((cb) => cb(stateFromStorage));
|
||||
}).catch((e) => {
|
||||
postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);
|
||||
});
|
||||
};
|
||||
api.persist = {
|
||||
setOptions: (newOptions) => {
|
||||
options = {
|
||||
...options,
|
||||
...newOptions
|
||||
};
|
||||
if (newOptions.getStorage) {
|
||||
storage = newOptions.getStorage();
|
||||
}
|
||||
},
|
||||
clearStorage: () => {
|
||||
storage == null ? void 0 : storage.removeItem(options.name);
|
||||
},
|
||||
getOptions: () => options,
|
||||
rehydrate: () => hydrate(),
|
||||
hasHydrated: () => hasHydrated,
|
||||
onHydrate: (cb) => {
|
||||
hydrationListeners.add(cb);
|
||||
return () => {
|
||||
hydrationListeners.delete(cb);
|
||||
};
|
||||
},
|
||||
onFinishHydration: (cb) => {
|
||||
finishHydrationListeners.add(cb);
|
||||
return () => {
|
||||
finishHydrationListeners.delete(cb);
|
||||
};
|
||||
}
|
||||
};
|
||||
hydrate();
|
||||
return stateFromStorage || configResult;
|
||||
};
|
||||
const newImpl = (config, baseOptions) => (set, get, api) => {
|
||||
let options = {
|
||||
storage: createJSONStorage(() => localStorage),
|
||||
partialize: (state) => state,
|
||||
version: 0,
|
||||
merge: (persistedState, currentState) => ({
|
||||
...currentState,
|
||||
...persistedState
|
||||
}),
|
||||
...baseOptions
|
||||
};
|
||||
let hasHydrated = false;
|
||||
const hydrationListeners = /* @__PURE__ */ new Set();
|
||||
const finishHydrationListeners = /* @__PURE__ */ new Set();
|
||||
let storage = options.storage;
|
||||
if (!storage) {
|
||||
return config(
|
||||
(...args) => {
|
||||
console.warn(
|
||||
`[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`
|
||||
);
|
||||
set(...args);
|
||||
},
|
||||
get,
|
||||
api
|
||||
);
|
||||
}
|
||||
const setItem = () => {
|
||||
const state = options.partialize({ ...get() });
|
||||
return storage.setItem(options.name, {
|
||||
state,
|
||||
version: options.version
|
||||
});
|
||||
};
|
||||
const savedSetState = api.setState;
|
||||
api.setState = (state, replace) => {
|
||||
savedSetState(state, replace);
|
||||
void setItem();
|
||||
};
|
||||
const configResult = config(
|
||||
(...args) => {
|
||||
set(...args);
|
||||
void setItem();
|
||||
},
|
||||
get,
|
||||
api
|
||||
);
|
||||
api.getInitialState = () => configResult;
|
||||
let stateFromStorage;
|
||||
const hydrate = () => {
|
||||
var _a, _b;
|
||||
if (!storage)
|
||||
return;
|
||||
hasHydrated = false;
|
||||
hydrationListeners.forEach((cb) => {
|
||||
var _a2;
|
||||
return cb((_a2 = get()) != null ? _a2 : configResult);
|
||||
});
|
||||
const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;
|
||||
return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {
|
||||
if (deserializedStorageValue) {
|
||||
if (typeof deserializedStorageValue.version === "number" && deserializedStorageValue.version !== options.version) {
|
||||
if (options.migrate) {
|
||||
return options.migrate(
|
||||
deserializedStorageValue.state,
|
||||
deserializedStorageValue.version
|
||||
);
|
||||
}
|
||||
console.error(
|
||||
`State loaded from storage couldn't be migrated since no migrate function was provided`
|
||||
);
|
||||
} else {
|
||||
return deserializedStorageValue.state;
|
||||
}
|
||||
}
|
||||
}).then((migratedState) => {
|
||||
var _a2;
|
||||
stateFromStorage = options.merge(
|
||||
migratedState,
|
||||
(_a2 = get()) != null ? _a2 : configResult
|
||||
);
|
||||
set(stateFromStorage, true);
|
||||
return setItem();
|
||||
}).then(() => {
|
||||
postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);
|
||||
stateFromStorage = get();
|
||||
hasHydrated = true;
|
||||
finishHydrationListeners.forEach((cb) => cb(stateFromStorage));
|
||||
}).catch((e) => {
|
||||
postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);
|
||||
});
|
||||
};
|
||||
api.persist = {
|
||||
setOptions: (newOptions) => {
|
||||
options = {
|
||||
...options,
|
||||
...newOptions
|
||||
};
|
||||
if (newOptions.storage) {
|
||||
storage = newOptions.storage;
|
||||
}
|
||||
},
|
||||
clearStorage: () => {
|
||||
storage == null ? void 0 : storage.removeItem(options.name);
|
||||
},
|
||||
getOptions: () => options,
|
||||
rehydrate: () => hydrate(),
|
||||
hasHydrated: () => hasHydrated,
|
||||
onHydrate: (cb) => {
|
||||
hydrationListeners.add(cb);
|
||||
return () => {
|
||||
hydrationListeners.delete(cb);
|
||||
};
|
||||
},
|
||||
onFinishHydration: (cb) => {
|
||||
finishHydrationListeners.add(cb);
|
||||
return () => {
|
||||
finishHydrationListeners.delete(cb);
|
||||
};
|
||||
}
|
||||
};
|
||||
if (!options.skipHydration) {
|
||||
hydrate();
|
||||
}
|
||||
return stateFromStorage || configResult;
|
||||
};
|
||||
const persistImpl = (config, baseOptions) => {
|
||||
if ("getStorage" in baseOptions || "serialize" in baseOptions || "deserialize" in baseOptions) {
|
||||
{
|
||||
console.warn(
|
||||
"[DEPRECATED] `getStorage`, `serialize` and `deserialize` options are deprecated. Use `storage` option instead."
|
||||
);
|
||||
}
|
||||
return oldImpl(config, baseOptions);
|
||||
}
|
||||
return newImpl(config, baseOptions);
|
||||
};
|
||||
const persist = exports("persist", persistImpl);
|
||||
|
||||
})
|
||||
};
|
||||
}));
|
5
system/middleware.production.js
Normal file
5
system/middleware.production.js
Normal file
File diff suppressed because one or more lines are too long
21
system/middleware/immer.development.js
Normal file
21
system/middleware/immer.development.js
Normal file
@ -0,0 +1,21 @@
|
||||
System.register(['immer'], (function (exports) {
|
||||
'use strict';
|
||||
var produce;
|
||||
return {
|
||||
setters: [function (module) {
|
||||
produce = module.produce;
|
||||
}],
|
||||
execute: (function () {
|
||||
|
||||
const immerImpl = (initializer) => (set, get, store) => {
|
||||
store.setState = (updater, replace, ...a) => {
|
||||
const nextState = typeof updater === "function" ? produce(updater) : updater;
|
||||
return set(nextState, replace, ...a);
|
||||
};
|
||||
return initializer(store.setState, get, store);
|
||||
};
|
||||
const immer = exports("immer", immerImpl);
|
||||
|
||||
})
|
||||
};
|
||||
}));
|
1
system/middleware/immer.production.js
Normal file
1
system/middleware/immer.production.js
Normal file
@ -0,0 +1 @@
|
||||
System.register(["immer"],function(c){"use strict";var r;return{setters:[function(n){r=n.produce}],execute:function(){const S=c("immer",s=>(o,u,t)=>(t.setState=(e,i,...m)=>{const f=typeof e=="function"?r(e):e;return o(f,i,...m)},s(t.setState,u,t)))}}});
|
62
system/react/shallow.development.js
Normal file
62
system/react/shallow.development.js
Normal file
@ -0,0 +1,62 @@
|
||||
System.register(['react'], (function (exports) {
|
||||
'use strict';
|
||||
var ReactExports;
|
||||
return {
|
||||
setters: [function (module) {
|
||||
ReactExports = module.default;
|
||||
}],
|
||||
execute: (function () {
|
||||
|
||||
exports("useShallow", useShallow);
|
||||
|
||||
function shallow(objA, objB) {
|
||||
if (Object.is(objA, objB)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
|
||||
return false;
|
||||
}
|
||||
if (objA instanceof Map && objB instanceof Map) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const [key, value] of objA) {
|
||||
if (!Object.is(value, objB.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (objA instanceof Set && objB instanceof Set) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const value of objA) {
|
||||
if (!objB.has(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const keysA = Object.keys(objA);
|
||||
if (keysA.length !== Object.keys(objB).length) {
|
||||
return false;
|
||||
}
|
||||
for (const keyA of keysA) {
|
||||
if (!Object.prototype.hasOwnProperty.call(objB, keyA) || !Object.is(objA[keyA], objB[keyA])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const { useRef } = ReactExports;
|
||||
function useShallow(selector) {
|
||||
const prev = useRef();
|
||||
return (state) => {
|
||||
const next = selector(state);
|
||||
return shallow(prev.current, next) ? prev.current : prev.current = next;
|
||||
};
|
||||
}
|
||||
|
||||
})
|
||||
};
|
||||
}));
|
1
system/react/shallow.production.js
Normal file
1
system/react/shallow.production.js
Normal file
@ -0,0 +1 @@
|
||||
System.register(["react"],function(o){"use strict";var c;return{setters:[function(s){c=s.default}],execute:function(){o("useShallow",u);function s(r,t){if(Object.is(r,t))return!0;if(typeof r!="object"||r===null||typeof t!="object"||t===null)return!1;if(r instanceof Map&&t instanceof Map){if(r.size!==t.size)return!1;for(const[e,i]of r)if(!Object.is(i,t.get(e)))return!1;return!0}if(r instanceof Set&&t instanceof Set){if(r.size!==t.size)return!1;for(const e of r)if(!t.has(e))return!1;return!0}const n=Object.keys(r);if(n.length!==Object.keys(t).length)return!1;for(const e of n)if(!Object.prototype.hasOwnProperty.call(t,e)||!Object.is(r[e],t[e]))return!1;return!0}const{useRef:f}=c;function u(r){const t=f();return n=>{const e=r(n);return s(t.current,e)?t.current:t.current=e}}}}});
|
58
system/shallow.development.js
Normal file
58
system/shallow.development.js
Normal file
@ -0,0 +1,58 @@
|
||||
System.register([], (function (exports) {
|
||||
'use strict';
|
||||
return {
|
||||
execute: (function () {
|
||||
|
||||
exports("shallow", shallow$1);
|
||||
|
||||
function shallow$1(objA, objB) {
|
||||
if (Object.is(objA, objB)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
|
||||
return false;
|
||||
}
|
||||
if (objA instanceof Map && objB instanceof Map) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const [key, value] of objA) {
|
||||
if (!Object.is(value, objB.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (objA instanceof Set && objB instanceof Set) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const value of objA) {
|
||||
if (!objB.has(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const keysA = Object.keys(objA);
|
||||
if (keysA.length !== Object.keys(objB).length) {
|
||||
return false;
|
||||
}
|
||||
for (const keyA of keysA) {
|
||||
if (!Object.prototype.hasOwnProperty.call(objB, keyA) || !Object.is(objA[keyA], objB[keyA])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var shallow = exports("default", (objA, objB) => {
|
||||
{
|
||||
console.warn(
|
||||
"[DEPRECATED] Default export is deprecated. Instead use `import { shallow } from 'zustand/shallow'`."
|
||||
);
|
||||
}
|
||||
return shallow$1(objA, objB);
|
||||
});
|
||||
|
||||
})
|
||||
};
|
||||
}));
|
1
system/shallow.production.js
Normal file
1
system/shallow.production.js
Normal file
@ -0,0 +1 @@
|
||||
System.register([],function(n){"use strict";return{execute:function(){n("shallow",f);function f(t,r){if(Object.is(t,r))return!0;if(typeof t!="object"||t===null||typeof r!="object"||r===null)return!1;if(t instanceof Map&&r instanceof Map){if(t.size!==r.size)return!1;for(const[e,o]of t)if(!Object.is(o,r.get(e)))return!1;return!0}if(t instanceof Set&&r instanceof Set){if(t.size!==r.size)return!1;for(const e of t)if(!r.has(e))return!1;return!0}const i=Object.keys(t);if(i.length!==Object.keys(r).length)return!1;for(const e of i)if(!Object.prototype.hasOwnProperty.call(r,e)||!Object.is(t[e],r[e]))return!1;return!0}var s=n("default",(t,r)=>f(t,r))}}});
|
40
system/traditional.development.js
Normal file
40
system/traditional.development.js
Normal file
@ -0,0 +1,40 @@
|
||||
System.register(['react', 'use-sync-external-store/shim/with-selector', 'zustand/vanilla'], (function (exports) {
|
||||
'use strict';
|
||||
var ReactExports, useSyncExternalStoreExports, createStore;
|
||||
return {
|
||||
setters: [function (module) {
|
||||
ReactExports = module.default;
|
||||
}, function (module) {
|
||||
useSyncExternalStoreExports = module.default;
|
||||
}, function (module) {
|
||||
createStore = module.createStore;
|
||||
}],
|
||||
execute: (function () {
|
||||
|
||||
exports("useStoreWithEqualityFn", useStoreWithEqualityFn);
|
||||
|
||||
const { useDebugValue } = ReactExports;
|
||||
const { useSyncExternalStoreWithSelector } = useSyncExternalStoreExports;
|
||||
const identity = (arg) => arg;
|
||||
function useStoreWithEqualityFn(api, selector = identity, equalityFn) {
|
||||
const slice = useSyncExternalStoreWithSelector(
|
||||
api.subscribe,
|
||||
api.getState,
|
||||
api.getServerState || api.getInitialState,
|
||||
selector,
|
||||
equalityFn
|
||||
);
|
||||
useDebugValue(slice);
|
||||
return slice;
|
||||
}
|
||||
const createWithEqualityFnImpl = (createState, defaultEqualityFn) => {
|
||||
const api = createStore(createState);
|
||||
const useBoundStoreWithEqualityFn = (selector, equalityFn = defaultEqualityFn) => useStoreWithEqualityFn(api, selector, equalityFn);
|
||||
Object.assign(useBoundStoreWithEqualityFn, api);
|
||||
return useBoundStoreWithEqualityFn;
|
||||
};
|
||||
const createWithEqualityFn = exports("createWithEqualityFn", (createState, defaultEqualityFn) => createState ? createWithEqualityFnImpl(createState, defaultEqualityFn) : createWithEqualityFnImpl);
|
||||
|
||||
})
|
||||
};
|
||||
}));
|
1
system/traditional.production.js
Normal file
1
system/traditional.production.js
Normal file
@ -0,0 +1 @@
|
||||
System.register(["react","use-sync-external-store/shim/with-selector","zustand/vanilla"],function(a){"use strict";var c,i,s;return{setters:[function(e){c=e.default},function(e){i=e.default},function(e){s=e.createStore}],execute:function(){a("useStoreWithEqualityFn",o);const{useDebugValue:e}=c,{useSyncExternalStoreWithSelector:S}=i,f=t=>t;function o(t,n=f,u){const r=S(t.subscribe,t.getState,t.getServerState||t.getInitialState,n,u);return e(r),r}const l=(t,n)=>{const u=s(t),r=(y,h=n)=>o(u,y,h);return Object.assign(r,u),r},g=a("createWithEqualityFn",(t,n)=>t?l(t,n):l)}}});
|
65
system/vanilla.development.js
Normal file
65
system/vanilla.development.js
Normal file
@ -0,0 +1,65 @@
|
||||
System.register([], (function (exports) {
|
||||
'use strict';
|
||||
return {
|
||||
execute: (function () {
|
||||
|
||||
const createStoreImpl = (createState, configs) => {
|
||||
let timeout;
|
||||
let state;
|
||||
const listeners = /* @__PURE__ */ new Set();
|
||||
const setState = (partial, replace) => {
|
||||
const nextState = typeof partial === "function" ? partial(state) : partial;
|
||||
if (!Object.is(nextState, state)) {
|
||||
const previousState = state;
|
||||
state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
|
||||
listeners.forEach((listener) => listener(state, previousState));
|
||||
}
|
||||
};
|
||||
const getState = () => state;
|
||||
const getInitialState = () => initialState;
|
||||
const resetBasedOnCachTime = () => {
|
||||
if (!(configs == null ? void 0 : configs.cacheTime))
|
||||
return;
|
||||
if (timeout)
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => {
|
||||
state = createState(setState, getState, api);
|
||||
}, configs == null ? void 0 : configs.cacheTime);
|
||||
};
|
||||
const subscribe = (listener) => {
|
||||
listeners.add(listener);
|
||||
if (timeout)
|
||||
clearTimeout(timeout);
|
||||
return () => {
|
||||
const responseDelete = listeners.delete(listener);
|
||||
if (!listeners.size) {
|
||||
resetBasedOnCachTime();
|
||||
}
|
||||
return responseDelete;
|
||||
};
|
||||
};
|
||||
const destroy = () => {
|
||||
{
|
||||
console.warn(
|
||||
"[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."
|
||||
);
|
||||
}
|
||||
listeners.clear();
|
||||
};
|
||||
const api = { setState, getState, getInitialState, subscribe, destroy };
|
||||
const initialState = state = createState(setState, getState, api);
|
||||
return api;
|
||||
};
|
||||
const createStore = exports("createStore", createStoreImpl);
|
||||
var vanilla = exports("default", (createState) => {
|
||||
{
|
||||
console.warn(
|
||||
"[DEPRECATED] Default export is deprecated. Instead use import { createStore } from 'zustand/vanilla'."
|
||||
);
|
||||
}
|
||||
return createStore(createState);
|
||||
});
|
||||
|
||||
})
|
||||
};
|
||||
}));
|
1
system/vanilla.production.js
Normal file
1
system/vanilla.production.js
Normal file
@ -0,0 +1 @@
|
||||
System.register([],function(f){"use strict";return{execute:function(){const S=f("createStore",(a,i)=>{let c,t;const n=new Set,u=(e,l)=>{const o=typeof e=="function"?e(t):e;if(!Object.is(o,t)){const T=t;t=(l!=null?l:typeof o!="object"||o===null)?o:Object.assign({},t,o),n.forEach(b=>b(t,T))}},s=()=>t,d=()=>y,m=()=>{i!=null&&i.cacheTime&&(c&&clearTimeout(c),c=setTimeout(()=>{t=a(u,s,r)},i==null?void 0:i.cacheTime))},r={setState:u,getState:s,getInitialState:d,subscribe:e=>(n.add(e),c&&clearTimeout(c),()=>{const l=n.delete(e);return n.size||m(),l}),destroy:()=>{n.clear()}},y=t=a(u,s,r);return r});var h=f("default",a=>S(a))}}});
|
49
system/vanilla/shallow.development.js
Normal file
49
system/vanilla/shallow.development.js
Normal file
@ -0,0 +1,49 @@
|
||||
System.register([], (function (exports) {
|
||||
'use strict';
|
||||
return {
|
||||
execute: (function () {
|
||||
|
||||
exports("shallow", shallow);
|
||||
|
||||
function shallow(objA, objB) {
|
||||
if (Object.is(objA, objB)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
|
||||
return false;
|
||||
}
|
||||
if (objA instanceof Map && objB instanceof Map) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const [key, value] of objA) {
|
||||
if (!Object.is(value, objB.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (objA instanceof Set && objB instanceof Set) {
|
||||
if (objA.size !== objB.size)
|
||||
return false;
|
||||
for (const value of objA) {
|
||||
if (!objB.has(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const keysA = Object.keys(objA);
|
||||
if (keysA.length !== Object.keys(objB).length) {
|
||||
return false;
|
||||
}
|
||||
for (const keyA of keysA) {
|
||||
if (!Object.prototype.hasOwnProperty.call(objB, keyA) || !Object.is(objA[keyA], objB[keyA])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
})
|
||||
};
|
||||
}));
|
1
system/vanilla/shallow.production.js
Normal file
1
system/vanilla/shallow.production.js
Normal file
@ -0,0 +1 @@
|
||||
System.register([],function(f){"use strict";return{execute:function(){f("shallow",i);function i(t,r){if(Object.is(t,r))return!0;if(typeof t!="object"||t===null||typeof r!="object"||r===null)return!1;if(t instanceof Map&&r instanceof Map){if(t.size!==r.size)return!1;for(const[e,o]of t)if(!Object.is(o,r.get(e)))return!1;return!0}if(t instanceof Set&&r instanceof Set){if(t.size!==r.size)return!1;for(const e of t)if(!r.has(e))return!1;return!0}const n=Object.keys(t);if(n.length!==Object.keys(r).length)return!1;for(const e of n)if(!Object.prototype.hasOwnProperty.call(r,e)||!Object.is(t[e],r[e]))return!1;return!0}}}});
|
21
traditional.d.ts
vendored
Normal file
21
traditional.d.ts
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
import type { Mutate, StateCreator, StoreApi, StoreMutatorIdentifier } from './vanilla';
|
||||
type ExtractState<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? T : never;
|
||||
type ReadonlyStoreApi<T> = Pick<StoreApi<T>, 'getState' | 'subscribe'>;
|
||||
type WithReact<S extends ReadonlyStoreApi<unknown>> = S & {
|
||||
/** @deprecated please use api.getInitialState() */
|
||||
getServerState?: () => ExtractState<S>;
|
||||
};
|
||||
export declare function useStoreWithEqualityFn<S extends WithReact<StoreApi<unknown>>>(api: S): ExtractState<S>;
|
||||
export declare function useStoreWithEqualityFn<S extends WithReact<StoreApi<unknown>>, U>(api: S, selector: (state: ExtractState<S>) => U, equalityFn?: (a: U, b: U) => boolean): U;
|
||||
export type UseBoundStoreWithEqualityFn<S extends WithReact<ReadonlyStoreApi<unknown>>> = {
|
||||
(): ExtractState<S>;
|
||||
<U>(selector: (state: ExtractState<S>) => U, equalityFn?: (a: U, b: U) => boolean): U;
|
||||
} & S;
|
||||
type CreateWithEqualityFn = {
|
||||
<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>, defaultEqualityFn?: <U>(a: U, b: U) => boolean): UseBoundStoreWithEqualityFn<Mutate<StoreApi<T>, Mos>>;
|
||||
<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>, defaultEqualityFn?: <U>(a: U, b: U) => boolean) => UseBoundStoreWithEqualityFn<Mutate<StoreApi<T>, Mos>>;
|
||||
};
|
||||
export declare const createWithEqualityFn: CreateWithEqualityFn;
|
||||
export {};
|
36
traditional.js
Normal file
36
traditional.js
Normal file
@ -0,0 +1,36 @@
|
||||
'use strict';
|
||||
|
||||
var ReactExports = require('react');
|
||||
var useSyncExternalStoreExports = require('use-sync-external-store/shim/with-selector');
|
||||
var vanilla = require('zustand/vanilla');
|
||||
|
||||
var useDebugValue = ReactExports.useDebugValue;
|
||||
var useSyncExternalStoreWithSelector = useSyncExternalStoreExports.useSyncExternalStoreWithSelector;
|
||||
var identity = function identity(arg) {
|
||||
return arg;
|
||||
};
|
||||
function useStoreWithEqualityFn(api, selector, equalityFn) {
|
||||
if (selector === void 0) {
|
||||
selector = identity;
|
||||
}
|
||||
var slice = useSyncExternalStoreWithSelector(api.subscribe, api.getState, api.getServerState || api.getInitialState, selector, equalityFn);
|
||||
useDebugValue(slice);
|
||||
return slice;
|
||||
}
|
||||
var createWithEqualityFnImpl = function createWithEqualityFnImpl(createState, defaultEqualityFn) {
|
||||
var api = vanilla.createStore(createState);
|
||||
var useBoundStoreWithEqualityFn = function useBoundStoreWithEqualityFn(selector, equalityFn) {
|
||||
if (equalityFn === void 0) {
|
||||
equalityFn = defaultEqualityFn;
|
||||
}
|
||||
return useStoreWithEqualityFn(api, selector, equalityFn);
|
||||
};
|
||||
Object.assign(useBoundStoreWithEqualityFn, api);
|
||||
return useBoundStoreWithEqualityFn;
|
||||
};
|
||||
var createWithEqualityFn = function createWithEqualityFn(createState, defaultEqualityFn) {
|
||||
return createState ? createWithEqualityFnImpl(createState, defaultEqualityFn) : createWithEqualityFnImpl;
|
||||
};
|
||||
|
||||
exports.createWithEqualityFn = createWithEqualityFn;
|
||||
exports.useStoreWithEqualityFn = useStoreWithEqualityFn;
|
25
ts3.4/context.d.ts
vendored
Normal file
25
ts3.4/context.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
import ReactExports from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
import { StoreApi } from 'zustand';
|
||||
type UseContextStore<S extends StoreApi<unknown>> = {
|
||||
(): ExtractState<S>;
|
||||
<U>(selector: (state: ExtractState<S>) => U, equalityFn?: (a: U, b: U) => boolean): U;
|
||||
};
|
||||
type ExtractState<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? T : never;
|
||||
type WithoutCallSignature<T> = {
|
||||
[K in keyof T]: T[K];
|
||||
};
|
||||
/**
|
||||
* @deprecated Use `createStore` and `useStore` for context usage
|
||||
*/
|
||||
declare function createContext<S extends StoreApi<unknown>>(): {
|
||||
Provider: ({ createStore, children, }: {
|
||||
createStore: () => S;
|
||||
children: ReactNode;
|
||||
}) => ReactExports.FunctionComponentElement<ReactExports.ProviderProps<S | undefined>>;
|
||||
useStore: UseContextStore<S>;
|
||||
useStoreApi: () => WithoutCallSignature<S>;
|
||||
};
|
||||
export default createContext;
|
25
ts3.4/esm/context.d.ts
vendored
Normal file
25
ts3.4/esm/context.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
import ReactExports from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
import { StoreApi } from 'zustand';
|
||||
type UseContextStore<S extends StoreApi<unknown>> = {
|
||||
(): ExtractState<S>;
|
||||
<U>(selector: (state: ExtractState<S>) => U, equalityFn?: (a: U, b: U) => boolean): U;
|
||||
};
|
||||
type ExtractState<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? T : never;
|
||||
type WithoutCallSignature<T> = {
|
||||
[K in keyof T]: T[K];
|
||||
};
|
||||
/**
|
||||
* @deprecated Use `createStore` and `useStore` for context usage
|
||||
*/
|
||||
declare function createContext<S extends StoreApi<unknown>>(): {
|
||||
Provider: ({ createStore, children, }: {
|
||||
createStore: () => S;
|
||||
children: ReactNode;
|
||||
}) => ReactExports.FunctionComponentElement<ReactExports.ProviderProps<S | undefined>>;
|
||||
useStore: UseContextStore<S>;
|
||||
useStoreApi: () => WithoutCallSignature<S>;
|
||||
};
|
||||
export default createContext;
|
3
ts3.4/esm/index.d.ts
vendored
Normal file
3
ts3.4/esm/index.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './vanilla';
|
||||
export * from './react';
|
||||
export { default } from './react';
|
5
ts3.4/esm/middleware.d.ts
vendored
Normal file
5
ts3.4/esm/middleware.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
export * from './middleware/redux';
|
||||
export * from './middleware/devtools';
|
||||
export * from './middleware/subscribeWithSelector';
|
||||
export * from './middleware/combine';
|
||||
export * from './middleware/persist';
|
13
ts3.4/esm/middleware/combine.d.ts
vendored
Normal file
13
ts3.4/esm/middleware/combine.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
import { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
type Write<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
|
||||
type Combine = <T extends object, U extends object, Mps extends [
|
||||
StoreMutatorIdentifier,
|
||||
unknown
|
||||
][] = [
|
||||
], Mcs extends [
|
||||
StoreMutatorIdentifier,
|
||||
unknown
|
||||
][] = [
|
||||
]>(initialState: T, additionalStateCreator: StateCreator<T, Mps, Mcs, U>) => StateCreator<Write<T, U>, Mps, Mcs>;
|
||||
export declare const combine: Combine;
|
||||
export {};
|
102
ts3.4/esm/middleware/devtools.d.ts
vendored
Normal file
102
ts3.4/esm/middleware/devtools.d.ts
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
import { StateCreator, StoreApi, StoreMutatorIdentifier } from '../vanilla';
|
||||
type Config = Parameters<(Window extends {
|
||||
__REDUX_DEVTOOLS_EXTENSION__?: infer T;
|
||||
} ? T : {
|
||||
connect: (param: any) => any;
|
||||
})['connect']>[0];
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/devtools': WithDevtools<S>;
|
||||
}
|
||||
}
|
||||
type Cast<T, U> = T extends U ? T : U;
|
||||
type Write<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
|
||||
type TakeTwo<T> = T extends {
|
||||
length: 0;
|
||||
} ? [
|
||||
undefined,
|
||||
undefined
|
||||
] : T extends {
|
||||
length: 1;
|
||||
} ? [
|
||||
/*a0*/ ...Cast<T, unknown[]>,
|
||||
/*a1*/ undefined
|
||||
] : T extends {
|
||||
length: 0 | 1;
|
||||
} ? [
|
||||
/*a0*/ ...Cast<T, unknown[]>,
|
||||
/*a1*/ undefined
|
||||
] : T extends {
|
||||
length: 2;
|
||||
} ? T : T extends {
|
||||
length: 1 | 2;
|
||||
} ? T : T extends {
|
||||
length: 0 | 1 | 2;
|
||||
} ? T : T extends [
|
||||
infer A0,
|
||||
infer A1,
|
||||
...unknown[]
|
||||
] ? [
|
||||
A0,
|
||||
A1
|
||||
] : T extends [
|
||||
infer A0,
|
||||
(infer A1)?,
|
||||
...unknown[]
|
||||
] ? [
|
||||
A0,
|
||||
A1?
|
||||
] : T extends [
|
||||
(infer A0)?,
|
||||
(infer A1)?,
|
||||
...unknown[]
|
||||
] ? [
|
||||
A0?,
|
||||
A1?
|
||||
] : never;
|
||||
type WithDevtools<S> = Write<S, StoreDevtools<S>>;
|
||||
type StoreDevtools<S> = S extends {
|
||||
setState: (...a: infer Sa) => infer Sr;
|
||||
} ? {
|
||||
setState<A extends string | {
|
||||
type: string;
|
||||
}>(...a: [
|
||||
/*a*/ ...TakeTwo<Sa>,
|
||||
/*action*/ A
|
||||
]): Sr;
|
||||
} : never;
|
||||
export interface DevtoolsOptions extends Config {
|
||||
name?: string;
|
||||
enabled?: boolean;
|
||||
anonymousActionType?: string;
|
||||
store?: string;
|
||||
}
|
||||
type Devtools = <T, Mps extends [
|
||||
StoreMutatorIdentifier,
|
||||
unknown
|
||||
][] = [
|
||||
], Mcs extends [
|
||||
StoreMutatorIdentifier,
|
||||
unknown
|
||||
][] = [
|
||||
]>(initializer: StateCreator<T, [
|
||||
...Mps,
|
||||
[
|
||||
'zustand/devtools',
|
||||
never
|
||||
]
|
||||
], Mcs>, devtoolsOptions?: DevtoolsOptions) => StateCreator<T, Mps, [
|
||||
[
|
||||
'zustand/devtools',
|
||||
never
|
||||
],
|
||||
...Mcs
|
||||
]>;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/devtools': WithDevtools<S>;
|
||||
}
|
||||
}
|
||||
export type NamedSet<T> = WithDevtools<StoreApi<T>>['setState'];
|
||||
export declare const devtools: Devtools;
|
||||
export {};
|
60
ts3.4/esm/middleware/immer.d.ts
vendored
Normal file
60
ts3.4/esm/middleware/immer.d.ts
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
import { Draft } from 'immer';
|
||||
import { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
type Immer = <T, Mps extends [
|
||||
StoreMutatorIdentifier,
|
||||
unknown
|
||||
][] = [
|
||||
], Mcs extends [
|
||||
StoreMutatorIdentifier,
|
||||
unknown
|
||||
][] = [
|
||||
]>(initializer: StateCreator<T, [
|
||||
...Mps,
|
||||
[
|
||||
'zustand/immer',
|
||||
never
|
||||
]
|
||||
], Mcs>) => StateCreator<T, Mps, [
|
||||
[
|
||||
'zustand/immer',
|
||||
never
|
||||
],
|
||||
...Mcs
|
||||
]>;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
['zustand/immer']: WithImmer<S>;
|
||||
}
|
||||
}
|
||||
type Write<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
|
||||
type SkipTwo<T> = T extends {
|
||||
length: 0;
|
||||
} ? [
|
||||
] : T extends {
|
||||
length: 1;
|
||||
} ? [
|
||||
] : T extends {
|
||||
length: 0 | 1;
|
||||
} ? [
|
||||
] : T extends [
|
||||
unknown,
|
||||
unknown,
|
||||
...infer A
|
||||
] ? A : T extends [
|
||||
unknown,
|
||||
unknown?,
|
||||
...infer A
|
||||
] ? A : T extends [
|
||||
unknown?,
|
||||
unknown?,
|
||||
...infer A
|
||||
] ? A : never;
|
||||
type WithImmer<S> = Write<S, StoreImmer<S>>;
|
||||
type StoreImmer<S> = S extends {
|
||||
getState: () => infer T;
|
||||
setState: infer SetState;
|
||||
} ? SetState extends (...a: infer A) => infer Sr ? {
|
||||
setState(nextStateOrUpdater: T | Partial<T> | ((state: Draft<T>) => void), shouldReplace?: boolean | undefined, ...a: SkipTwo<A>): Sr;
|
||||
} : never : never;
|
||||
export declare const immer: Immer;
|
||||
export {};
|
139
ts3.4/esm/middleware/persist.d.ts
vendored
Normal file
139
ts3.4/esm/middleware/persist.d.ts
vendored
Normal file
@ -0,0 +1,139 @@
|
||||
import { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
export interface StateStorage {
|
||||
getItem: (name: string) => string | null | Promise<string | null>;
|
||||
setItem: (name: string, value: string) => unknown | Promise<unknown>;
|
||||
removeItem: (name: string) => unknown | Promise<unknown>;
|
||||
}
|
||||
export type StorageValue<S> = {
|
||||
state: S;
|
||||
version?: number;
|
||||
};
|
||||
export interface PersistStorage<S> {
|
||||
getItem: (name: string) => StorageValue<S> | null | Promise<StorageValue<S> | null>;
|
||||
setItem: (name: string, value: StorageValue<S>) => unknown | Promise<unknown>;
|
||||
removeItem: (name: string) => unknown | Promise<unknown>;
|
||||
}
|
||||
type JsonStorageOptions = {
|
||||
reviver?: (key: string, value: unknown) => unknown;
|
||||
replacer?: (key: string, value: unknown) => unknown;
|
||||
};
|
||||
export declare function createJSONStorage<S>(getStorage: () => StateStorage, options?: JsonStorageOptions): PersistStorage<S> | undefined;
|
||||
export interface PersistOptions<S, PersistedState = S> {
|
||||
/** Name of the storage (must be unique) */
|
||||
name: string;
|
||||
/**
|
||||
* @deprecated Use `storage` instead.
|
||||
* A function returning a storage.
|
||||
* The storage must fit `window.localStorage`'s api (or an async version of it).
|
||||
* For example the storage could be `AsyncStorage` from React Native.
|
||||
*
|
||||
* @default () => localStorage
|
||||
*/
|
||||
getStorage?: () => StateStorage;
|
||||
/**
|
||||
* @deprecated Use `storage` instead.
|
||||
* Use a custom serializer.
|
||||
* The returned string will be stored in the storage.
|
||||
*
|
||||
* @default JSON.stringify
|
||||
*/
|
||||
serialize?: (state: StorageValue<S>) => string | Promise<string>;
|
||||
/**
|
||||
* @deprecated Use `storage` instead.
|
||||
* Use a custom deserializer.
|
||||
* Must return an object matching StorageValue<S>
|
||||
*
|
||||
* @param str The storage's current value.
|
||||
* @default JSON.parse
|
||||
*/
|
||||
deserialize?: (str: string) => StorageValue<PersistedState> | Promise<StorageValue<PersistedState>>;
|
||||
/**
|
||||
* Use a custom persist storage.
|
||||
*
|
||||
* Combining `createJSONStorage` helps creating a persist storage
|
||||
* with JSON.parse and JSON.stringify.
|
||||
*
|
||||
* @default createJSONStorage(() => localStorage)
|
||||
*/
|
||||
storage?: PersistStorage<PersistedState> | undefined;
|
||||
/**
|
||||
* Filter the persisted value.
|
||||
*
|
||||
* @params state The state's value
|
||||
*/
|
||||
partialize?: (state: S) => PersistedState;
|
||||
/**
|
||||
* A function returning another (optional) function.
|
||||
* The main function will be called before the state rehydration.
|
||||
* The returned function will be called after the state rehydration or when an error occurred.
|
||||
*/
|
||||
onRehydrateStorage?: (state: S) => ((state?: S, error?: unknown) => void) | void;
|
||||
/**
|
||||
* If the stored state's version mismatch the one specified here, the storage will not be used.
|
||||
* This is useful when adding a breaking change to your store.
|
||||
*/
|
||||
version?: number;
|
||||
/**
|
||||
* A function to perform persisted state migration.
|
||||
* This function will be called when persisted state versions mismatch with the one specified here.
|
||||
*/
|
||||
migrate?: (persistedState: unknown, version: number) => PersistedState | Promise<PersistedState>;
|
||||
/**
|
||||
* A function to perform custom hydration merges when combining the stored state with the current one.
|
||||
* By default, this function does a shallow merge.
|
||||
*/
|
||||
merge?: (persistedState: unknown, currentState: S) => S;
|
||||
/**
|
||||
* An optional boolean that will prevent the persist middleware from triggering hydration on initialization,
|
||||
* This allows you to call `rehydrate()` at a specific point in your apps rendering life-cycle.
|
||||
*
|
||||
* This is useful in SSR application.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
skipHydration?: boolean;
|
||||
}
|
||||
type PersistListener<S> = (state: S) => void;
|
||||
type StorePersist<S, Ps> = {
|
||||
persist: {
|
||||
setOptions: (options: Partial<PersistOptions<S, Ps>>) => void;
|
||||
clearStorage: () => void;
|
||||
rehydrate: () => Promise<void> | void;
|
||||
hasHydrated: () => boolean;
|
||||
onHydrate: (fn: PersistListener<S>) => () => void;
|
||||
onFinishHydration: (fn: PersistListener<S>) => () => void;
|
||||
getOptions: () => Partial<PersistOptions<S, Ps>>;
|
||||
};
|
||||
};
|
||||
type Persist = <T, Mps extends [
|
||||
StoreMutatorIdentifier,
|
||||
unknown
|
||||
][] = [
|
||||
], Mcs extends [
|
||||
StoreMutatorIdentifier,
|
||||
unknown
|
||||
][] = [
|
||||
], U = T>(initializer: StateCreator<T, [
|
||||
...Mps,
|
||||
[
|
||||
'zustand/persist',
|
||||
unknown
|
||||
]
|
||||
], Mcs>, options: PersistOptions<T, U>) => StateCreator<T, Mps, [
|
||||
[
|
||||
'zustand/persist',
|
||||
U
|
||||
],
|
||||
...Mcs
|
||||
]>;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/persist': WithPersist<S, A>;
|
||||
}
|
||||
}
|
||||
type Write<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
|
||||
type WithPersist<S, A> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? Write<S, StorePersist<T, A>> : never;
|
||||
export declare const persist: Persist;
|
||||
export {};
|
30
ts3.4/esm/middleware/redux.d.ts
vendored
Normal file
30
ts3.4/esm/middleware/redux.d.ts
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
import { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
type Write<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
|
||||
type Action = {
|
||||
type: string;
|
||||
};
|
||||
type StoreRedux<A> = {
|
||||
dispatch: (a: A) => A;
|
||||
dispatchFromDevtools: true;
|
||||
};
|
||||
type ReduxState<A> = {
|
||||
dispatch: StoreRedux<A>['dispatch'];
|
||||
};
|
||||
type WithRedux<S, A> = Write<S, StoreRedux<A>>;
|
||||
type Redux = <T, A extends Action, Cms extends [
|
||||
StoreMutatorIdentifier,
|
||||
unknown
|
||||
][] = [
|
||||
]>(reducer: (state: T, action: A) => T, initialState: T) => StateCreator<Write<T, ReduxState<A>>, Cms, [
|
||||
[
|
||||
'zustand/redux',
|
||||
A
|
||||
]
|
||||
]>;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
'zustand/redux': WithRedux<S, A>;
|
||||
}
|
||||
}
|
||||
export declare const redux: Redux;
|
||||
export {};
|
42
ts3.4/esm/middleware/subscribeWithSelector.d.ts
vendored
Normal file
42
ts3.4/esm/middleware/subscribeWithSelector.d.ts
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
import { StateCreator, StoreMutatorIdentifier } from '../vanilla';
|
||||
type SubscribeWithSelector = <T, Mps extends [
|
||||
StoreMutatorIdentifier,
|
||||
unknown
|
||||
][] = [
|
||||
], Mcs extends [
|
||||
StoreMutatorIdentifier,
|
||||
unknown
|
||||
][] = [
|
||||
]>(initializer: StateCreator<T, [
|
||||
...Mps,
|
||||
[
|
||||
'zustand/subscribeWithSelector',
|
||||
never
|
||||
]
|
||||
], Mcs>) => StateCreator<T, Mps, [
|
||||
[
|
||||
'zustand/subscribeWithSelector',
|
||||
never
|
||||
],
|
||||
...Mcs
|
||||
]>;
|
||||
type Write<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
|
||||
type WithSelectorSubscribe<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? Write<S, StoreSubscribeWithSelector<T>> : never;
|
||||
declare module '../vanilla' {
|
||||
interface StoreMutators<S, A> {
|
||||
['zustand/subscribeWithSelector']: WithSelectorSubscribe<S>;
|
||||
}
|
||||
}
|
||||
type StoreSubscribeWithSelector<T> = {
|
||||
subscribe: {
|
||||
(listener: (selectedState: T, previousSelectedState: T) => void): () => void;
|
||||
<U>(selector: (state: T) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
|
||||
equalityFn?: (a: U, b: U) => boolean;
|
||||
fireImmediately?: boolean;
|
||||
}): () => void;
|
||||
};
|
||||
};
|
||||
export declare const subscribeWithSelector: SubscribeWithSelector;
|
||||
export {};
|
48
ts3.4/esm/react.d.ts
vendored
Normal file
48
ts3.4/esm/react.d.ts
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
import { Mutate, StateCreator, StoreApi, StoreMutatorIdentifier } from './vanilla';
|
||||
type ExtractState<S> = S extends {
|
||||
getState: () => infer T;
|
||||
} ? T : never;
|
||||
type ReadonlyStoreApi<T> = Pick<StoreApi<T>, 'getState' | 'subscribe'>;
|
||||
type WithReact<S extends ReadonlyStoreApi<unknown>> = S & {
|
||||
/** @deprecated please use api.getInitialState() */
|
||||
getServerState?: () => ExtractState<S>;
|
||||
};
|
||||
export declare function useStore<S extends WithReact<StoreApi<unknown>>>(api: S): ExtractState<S>;
|
||||
export declare function useStore<S extends WithReact<StoreApi<unknown>>, U>(api: S, selector: (state: ExtractState<S>) => U): U;
|
||||
/**
|
||||
* @deprecated The usage with three arguments is deprecated. Use `useStoreWithEqualityFn` from 'zustand/traditional'. The usage with one or two arguments is not deprecated.
|
||||
* https://github.com/pmndrs/zustand/discussions/1937
|
||||
*/
|
||||
export declare function useStore<S extends WithReact<StoreApi<unknown>>, U>(api: S, selector: (state: ExtractState<S>) => U, equalityFn: ((a: U, b: U) => boolean) | undefined): U;
|
||||
export type UseBoundStore<S extends WithReact<ReadonlyStoreApi<unknown>>> = {
|
||||
(): ExtractState<S>;
|
||||
<U>(selector: (state: ExtractState<S>) => U): U;
|
||||
/**
|
||||
* @deprecated Use `createWithEqualityFn` from 'zustand/traditional'
|
||||
*/
|
||||
<U>(selector: (state: ExtractState<S>) => U, equalityFn: (a: U, b: U) => boolean): U;
|
||||
} & S;
|
||||
type Create = {
|
||||
<T, Mos extends [
|
||||
StoreMutatorIdentifier,
|
||||
unknown
|
||||
][] = [
|
||||
]>(initializer: StateCreator<T, [
|
||||
], Mos>): UseBoundStore<Mutate<StoreApi<T>, Mos>>;
|
||||
<T>(): <Mos extends [
|
||||
StoreMutatorIdentifier,
|
||||
unknown
|
||||
][] = [
|
||||
]>(initializer: StateCreator<T, [
|
||||
], Mos>) => UseBoundStore<Mutate<StoreApi<T>, Mos>>;
|
||||
/**
|
||||
* @deprecated Use `useStore` hook to bind store
|
||||
*/
|
||||
<S extends StoreApi<unknown>>(store: S): UseBoundStore<S>;
|
||||
};
|
||||
export declare const create: Create;
|
||||
/**
|
||||
* @deprecated Use `import { create } from 'zustand'`
|
||||
*/
|
||||
declare const _default: Create;
|
||||
export default _default;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user