pl-fe: Replace immer with mutative
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
7ca17884f8
commit
cc858d4f0f
10 changed files with 133 additions and 108 deletions
|
@ -87,7 +87,6 @@
|
|||
"fuzzysort": "^3.0.2",
|
||||
"graphemesplit": "^2.4.4",
|
||||
"html-react-parser": "^5.1.16",
|
||||
"immer": "^10.1.1",
|
||||
"immutable": "^4.3.7",
|
||||
"intersection-observer": "^0.12.2",
|
||||
"intl-messageformat": "^10.5.14",
|
||||
|
@ -100,6 +99,7 @@
|
|||
"lodash": "^4.17.21",
|
||||
"mini-css-extract-plugin": "^2.9.1",
|
||||
"multiselect-react-dropdown": "^2.0.25",
|
||||
"mutative": "^1.0.11",
|
||||
"path-browserify": "^1.0.1",
|
||||
"pl-api": "^0.1.9",
|
||||
"postcss": "^8.4.47",
|
||||
|
@ -142,7 +142,8 @@
|
|||
"vite-plugin-html": "^3.2.2",
|
||||
"vite-plugin-require": "^1.2.14",
|
||||
"vite-plugin-static-copy": "^1.0.6",
|
||||
"zustand": "^5.0.0-rc.2"
|
||||
"zustand": "^5.0.0-rc.2",
|
||||
"zustand-mutative": "^1.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@formatjs/cli": "^6.2.12",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { produce, enableMapSet } from 'immer';
|
||||
import { create, type Immutable } from 'mutative';
|
||||
|
||||
import {
|
||||
ENTITIES_IMPORT,
|
||||
|
@ -17,12 +17,10 @@ import { createCache, createList, updateStore, updateList } from './utils';
|
|||
import type { DeleteEntitiesOpts } from './actions';
|
||||
import type { EntitiesTransaction, Entity, EntityCache, EntityListState, ImportPosition } from './types';
|
||||
|
||||
enableMapSet();
|
||||
|
||||
/** Entity reducer state. */
|
||||
interface State {
|
||||
type State = Immutable<{
|
||||
[entityType: string]: EntityCache | undefined;
|
||||
}
|
||||
}>;
|
||||
|
||||
/** Import entities into the cache. */
|
||||
const importEntities = (
|
||||
|
@ -33,7 +31,7 @@ const importEntities = (
|
|||
pos?: ImportPosition,
|
||||
newState?: EntityListState,
|
||||
overwrite = false,
|
||||
): State => produce(state, draft => {
|
||||
): State => create(state, draft => {
|
||||
const cache = draft[entityType] ?? createCache();
|
||||
cache.store = updateStore(cache.store, entities);
|
||||
|
||||
|
@ -54,14 +52,16 @@ const importEntities = (
|
|||
}
|
||||
|
||||
draft[entityType] = cache;
|
||||
});
|
||||
|
||||
return draft;
|
||||
}, { enableAutoFreeze: true });
|
||||
|
||||
const deleteEntities = (
|
||||
state: State,
|
||||
entityType: string,
|
||||
ids: Iterable<string>,
|
||||
opts: DeleteEntitiesOpts,
|
||||
) => produce(state, draft => {
|
||||
) => create(state, draft => {
|
||||
const cache = draft[entityType] ?? createCache();
|
||||
|
||||
for (const id of ids) {
|
||||
|
@ -88,7 +88,7 @@ const dismissEntities = (
|
|||
entityType: string,
|
||||
ids: Iterable<string>,
|
||||
listKey: string,
|
||||
) => produce(state, draft => {
|
||||
) => create(state, draft => {
|
||||
const cache = draft[entityType] ?? createCache();
|
||||
const list = cache.lists[listKey];
|
||||
|
||||
|
@ -110,7 +110,7 @@ const incrementEntities = (
|
|||
entityType: string,
|
||||
listKey: string,
|
||||
diff: number,
|
||||
) => produce(state, draft => {
|
||||
) => create(state, draft => {
|
||||
const cache = draft[entityType] ?? createCache();
|
||||
const list = cache.lists[listKey];
|
||||
|
||||
|
@ -126,7 +126,7 @@ const setFetching = (
|
|||
listKey: string | undefined,
|
||||
isFetching: boolean,
|
||||
error?: any,
|
||||
) => produce(state, draft => {
|
||||
) => create(state, draft => {
|
||||
const cache = draft[entityType] ?? createCache();
|
||||
|
||||
if (typeof listKey === 'string') {
|
||||
|
@ -139,13 +139,13 @@ const setFetching = (
|
|||
draft[entityType] = cache;
|
||||
});
|
||||
|
||||
const invalidateEntityList = (state: State, entityType: string, listKey: string) => produce(state, draft => {
|
||||
const invalidateEntityList = (state: State, entityType: string, listKey: string) => create(state, draft => {
|
||||
const cache = draft[entityType] ?? createCache();
|
||||
const list = cache.lists[listKey] ?? createList();
|
||||
list.state.invalid = true;
|
||||
});
|
||||
|
||||
const doTransaction = (state: State, transaction: EntitiesTransaction) => produce(state, draft => {
|
||||
const doTransaction = (state: State, transaction: EntitiesTransaction) => create(state, draft => {
|
||||
for (const [entityType, changes] of Object.entries(transaction)) {
|
||||
const cache = draft[entityType] ?? createCache();
|
||||
for (const [id, change] of Object.entries(changes)) {
|
||||
|
|
|
@ -39,9 +39,9 @@ const UserIndex: React.FC = () => {
|
|||
updateQuery();
|
||||
}, []);
|
||||
|
||||
const hasMore = items.count() < total && !!next;
|
||||
const hasMore = items.length < total && !!next;
|
||||
|
||||
const showLoading = isLoading && items.isEmpty();
|
||||
const showLoading = isLoading && !items.length;
|
||||
|
||||
return (
|
||||
<Column label={intl.formatMessage(messages.heading)}>
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
* Accounts Meta: private user data only the owner should see.
|
||||
* @module pl-fe/reducers/accounts_meta
|
||||
*/
|
||||
|
||||
import { produce } from 'immer';
|
||||
import { create, type Immutable } from 'mutative';
|
||||
|
||||
import { VERIFY_CREDENTIALS_SUCCESS, AUTH_ACCOUNT_REMEMBER_SUCCESS, type AuthAction } from 'pl-fe/actions/auth';
|
||||
import { ME_FETCH_SUCCESS, ME_PATCH_SUCCESS, type MeAction } from 'pl-fe/actions/me';
|
||||
|
@ -15,17 +14,17 @@ interface AccountMeta {
|
|||
source: Account['__meta']['source'];
|
||||
}
|
||||
|
||||
type State = Record<string, AccountMeta | undefined>;
|
||||
type State = Immutable<Record<string, AccountMeta | undefined>>;
|
||||
|
||||
const importAccount = (state: State, account: CredentialAccount): State =>
|
||||
produce(state, draft => {
|
||||
create(state, draft => {
|
||||
const existing = draft[account.id];
|
||||
|
||||
draft[account.id] = {
|
||||
pleroma: account.__meta.pleroma ?? existing?.pleroma,
|
||||
source: account.__meta.source ?? existing?.source,
|
||||
};
|
||||
});
|
||||
}, { enableAutoFreeze: true });
|
||||
|
||||
const accounts_meta = (state: Readonly<State> = {}, action: AuthAction | MeAction): State => {
|
||||
switch (action.type) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { OrderedSet as ImmutableOrderedSet, Record as ImmutableRecord } from 'immutable';
|
||||
import { create } from 'mutative';
|
||||
|
||||
import {
|
||||
ADMIN_USER_INDEX_EXPAND_FAIL,
|
||||
|
@ -10,58 +10,74 @@ import {
|
|||
ADMIN_USER_INDEX_QUERY_SET,
|
||||
} from 'pl-fe/actions/admin';
|
||||
|
||||
import type { AnyAction } from '@reduxjs/toolkit';
|
||||
import type { AdminAccount, AdminGetAccountsParams, PaginatedResponse } from 'pl-api';
|
||||
import type { APIEntity } from 'pl-fe/types/entities';
|
||||
import type { AnyAction } from 'redux';
|
||||
|
||||
const ReducerRecord = ImmutableRecord({
|
||||
type State = {
|
||||
isLoading: boolean;
|
||||
loaded: boolean;
|
||||
items: Array<string>;
|
||||
total: number;
|
||||
page: number;
|
||||
query: string;
|
||||
next: (() => Promise<PaginatedResponse<AdminAccount>>) | null;
|
||||
params: AdminGetAccountsParams | null;
|
||||
}
|
||||
|
||||
const initialState: State = {
|
||||
isLoading: false,
|
||||
loaded: false,
|
||||
items: ImmutableOrderedSet<string>(),
|
||||
items: [],
|
||||
total: Infinity,
|
||||
page: -1,
|
||||
query: '',
|
||||
next: null as (() => Promise<PaginatedResponse<AdminAccount>>) | null,
|
||||
params: null as AdminGetAccountsParams | null,
|
||||
});
|
||||
next: null,
|
||||
params: null,
|
||||
};
|
||||
|
||||
type State = ReturnType<typeof ReducerRecord>;
|
||||
|
||||
const admin_user_index = (state: State = ReducerRecord(), action: AnyAction): State => {
|
||||
const admin_user_index = (state: State = initialState, action: AnyAction): State => {
|
||||
switch (action.type) {
|
||||
case ADMIN_USER_INDEX_QUERY_SET:
|
||||
return state.set('query', action.query);
|
||||
return create(state, draft => {
|
||||
draft.query = action.query;
|
||||
});
|
||||
case ADMIN_USER_INDEX_FETCH_REQUEST:
|
||||
return state
|
||||
.set('isLoading', true)
|
||||
.set('loaded', true)
|
||||
.set('items', ImmutableOrderedSet())
|
||||
.set('total', action.total)
|
||||
.set('page', 0)
|
||||
.set('next', null);
|
||||
return create(state, draft => {
|
||||
draft.isLoading = true;
|
||||
draft.loaded = true;
|
||||
draft.items = [];
|
||||
draft.total = action.total;
|
||||
draft.page = 0;
|
||||
draft.next = null;
|
||||
});
|
||||
case ADMIN_USER_INDEX_FETCH_SUCCESS:
|
||||
return state
|
||||
.set('isLoading', false)
|
||||
.set('loaded', true)
|
||||
.set('items', ImmutableOrderedSet(action.users.map((user: APIEntity) => user.id)))
|
||||
.set('total', action.total)
|
||||
.set('page', 1)
|
||||
.set('next', action.next);
|
||||
return create(state, draft => {
|
||||
draft.isLoading = false;
|
||||
draft.loaded = true;
|
||||
draft.items = action.users.map((user: APIEntity) => user.id);
|
||||
draft.total = action.total;
|
||||
draft.page = 1;
|
||||
draft.next = action.next;
|
||||
});
|
||||
case ADMIN_USER_INDEX_FETCH_FAIL:
|
||||
case ADMIN_USER_INDEX_EXPAND_FAIL:
|
||||
return state
|
||||
.set('isLoading', false);
|
||||
return create(state, draft => {
|
||||
draft.isLoading = false;
|
||||
});
|
||||
case ADMIN_USER_INDEX_EXPAND_REQUEST:
|
||||
return state
|
||||
.set('isLoading', true);
|
||||
return create(state, draft => {
|
||||
draft.isLoading = true;
|
||||
});
|
||||
case ADMIN_USER_INDEX_EXPAND_SUCCESS:
|
||||
return state
|
||||
.set('isLoading', false)
|
||||
.set('loaded', true)
|
||||
.set('items', state.items.union(action.users.map((user: APIEntity) => user.id)))
|
||||
.set('total', action.total)
|
||||
.set('page', 1)
|
||||
.set('next', action.next);
|
||||
return create(state, draft => {
|
||||
draft.isLoading = false;
|
||||
draft.loaded = true;
|
||||
draft.items = [...new Set(draft.items.concat(action.users.map((user: APIEntity) => user.id)))];
|
||||
draft.total = action.total;
|
||||
draft.page = 1;
|
||||
draft.next = action.next;
|
||||
});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { produce } from 'immer';
|
||||
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
|
||||
import { create } from 'mutative';
|
||||
import { type Instance, instanceSchema } from 'pl-api';
|
||||
import * as v from 'valibot';
|
||||
|
||||
|
@ -11,9 +11,11 @@ import ConfigDB from 'pl-fe/utils/config-db';
|
|||
|
||||
import type { AnyAction } from 'redux';
|
||||
|
||||
const initialState: Instance = v.parse(instanceSchema, {});
|
||||
const initialState: State = v.parse(instanceSchema, {});
|
||||
|
||||
const preloadImport = (state: Instance, action: Record<string, any>, path: string) => {
|
||||
type State = Instance;
|
||||
|
||||
const preloadImport = (state: State, action: Record<string, any>, path: string) => {
|
||||
const instance = action.data[path];
|
||||
return instance ? v.parse(instanceSchema, instance) : state;
|
||||
};
|
||||
|
@ -25,32 +27,30 @@ const getConfigValue = (instanceConfig: ImmutableMap<string, any>, key: string)
|
|||
return v ? v.getIn(['tuple', 1]) : undefined;
|
||||
};
|
||||
|
||||
const importConfigs = (state: Instance, configs: ImmutableList<any>) => {
|
||||
const importConfigs = (state: State, configs: ImmutableList<any>) => {
|
||||
// FIXME: This is pretty hacked together. Need to make a cleaner map.
|
||||
const config = ConfigDB.find(configs, ':pleroma', ':instance');
|
||||
const simplePolicy = ConfigDB.toSimplePolicy(configs);
|
||||
|
||||
if (!config && !simplePolicy) return state;
|
||||
|
||||
return produce(state, (draft) => {
|
||||
if (config) {
|
||||
const value = config.get('value', ImmutableList());
|
||||
const registrationsOpen = getConfigValue(value, ':registrations_open') as boolean | undefined;
|
||||
const approvalRequired = getConfigValue(value, ':account_approval_required') as boolean | undefined;
|
||||
if (config) {
|
||||
const value = config.get('value', ImmutableList());
|
||||
const registrationsOpen = getConfigValue(value, ':registrations_open') as boolean | undefined;
|
||||
const approvalRequired = getConfigValue(value, ':account_approval_required') as boolean | undefined;
|
||||
|
||||
draft.registrations = {
|
||||
enabled: registrationsOpen ?? draft.registrations.enabled,
|
||||
approval_required: approvalRequired ?? draft.registrations.approval_required,
|
||||
};
|
||||
}
|
||||
state.registrations = {
|
||||
enabled: registrationsOpen ?? state.registrations.enabled,
|
||||
approval_required: approvalRequired ?? state.registrations.approval_required,
|
||||
};
|
||||
}
|
||||
|
||||
if (simplePolicy) {
|
||||
draft.pleroma.metadata.federation.mrf_simple = simplePolicy;
|
||||
}
|
||||
});
|
||||
if (simplePolicy) {
|
||||
state.pleroma.metadata.federation.mrf_simple = simplePolicy;
|
||||
}
|
||||
};
|
||||
|
||||
const handleAuthFetch = (state: Instance) => {
|
||||
const handleAuthFetch = (state: State) => {
|
||||
// Authenticated fetch is enabled, so make the instance appear censored
|
||||
return {
|
||||
...state,
|
||||
|
@ -78,7 +78,7 @@ const persistInstance = (instance: { domain: string }, host: string | null = get
|
|||
}
|
||||
};
|
||||
|
||||
const handleInstanceFetchFail = (state: Instance, error: Record<string, any>) => {
|
||||
const handleInstanceFetchFail = (state: State, error: Record<string, any>) => {
|
||||
if (error.response?.status === 401) {
|
||||
return handleAuthFetch(state);
|
||||
} else {
|
||||
|
@ -86,10 +86,10 @@ const handleInstanceFetchFail = (state: Instance, error: Record<string, any>) =>
|
|||
}
|
||||
};
|
||||
|
||||
const instance = (state = initialState, action: AnyAction | InstanceAction | PreloadAction): Instance => {
|
||||
const instance = (state = initialState, action: AnyAction | InstanceAction | PreloadAction): State => {
|
||||
switch (action.type) {
|
||||
case PLEROMA_PRELOAD_IMPORT:
|
||||
return preloadImport(state, action, '/api/v1/instance');
|
||||
return create(state, (draft) => preloadImport(draft, action, '/api/v1/instance'));
|
||||
case INSTANCE_FETCH_SUCCESS:
|
||||
persistInstance(action.instance);
|
||||
return action.instance;
|
||||
|
@ -97,10 +97,9 @@ const instance = (state = initialState, action: AnyAction | InstanceAction | Pre
|
|||
return handleInstanceFetchFail(state, action.error);
|
||||
case ADMIN_CONFIG_UPDATE_REQUEST:
|
||||
case ADMIN_CONFIG_UPDATE_SUCCESS:
|
||||
return importConfigs(state, ImmutableList(fromJS(action.configs)));
|
||||
return create(state, (draft) => importConfigs(draft, ImmutableList(fromJS(action.configs))));
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export { instance as default };
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import { configureStore, Tuple } from '@reduxjs/toolkit';
|
||||
import { configureStore, Tuple, type AnyAction } from '@reduxjs/toolkit';
|
||||
import { thunk, type ThunkDispatch } from 'redux-thunk';
|
||||
|
||||
import errorsMiddleware from './middleware/errors';
|
||||
import soundsMiddleware from './middleware/sounds';
|
||||
import appReducer from './reducers';
|
||||
|
||||
import type { AnyAction } from 'redux';
|
||||
|
||||
const store = configureStore({
|
||||
reducer: appReducer,
|
||||
middleware: () => new Tuple(
|
||||
|
@ -17,6 +15,8 @@ const store = configureStore({
|
|||
devTools: true,
|
||||
});
|
||||
|
||||
(window as any).store = store;
|
||||
|
||||
type Store = typeof store;
|
||||
|
||||
// Infer the `RootState` and `AppDispatch` types from the store itself
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { produce } from 'immer';
|
||||
import { create } from 'zustand';
|
||||
import { mutative } from 'zustand-mutative';
|
||||
|
||||
import type { ICryptoAddress } from 'pl-fe/features/crypto-donate/components/crypto-address';
|
||||
import type { ModalType } from 'pl-fe/features/ui/components/modal-root';
|
||||
|
@ -86,12 +86,12 @@ type State = {
|
|||
closeModal: (modalType?: ModalType) => void;
|
||||
};
|
||||
|
||||
const useModalsStore = create<State>((set) => ({
|
||||
const useModalsStore = create<State>()(mutative((set) => ({
|
||||
modals: [],
|
||||
openModal: (...[modalType, modalProps]) => set(produce((state: State) => {
|
||||
openModal: (...[modalType, modalProps]) => set((state: State) => {
|
||||
state.modals.push({ modalType, modalProps });
|
||||
})),
|
||||
closeModal: (modalType) => set(produce((state: State) => {
|
||||
}),
|
||||
closeModal: (modalType) => set((state: State) => {
|
||||
if (state.modals.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ const useModalsStore = create<State>((set) => ({
|
|||
} else if (state.modals.some((modal) => modalType === modal.modalType)) {
|
||||
state.modals = state.modals.slice(0, state.modals.findLastIndex((modal) => modalType === modal.modalType));
|
||||
}
|
||||
})),
|
||||
}));
|
||||
}),
|
||||
}), { enableAutoFreeze: true }));
|
||||
|
||||
export { useModalsStore };
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { produce } from 'immer';
|
||||
import * as v from 'valibot';
|
||||
import { create } from 'zustand';
|
||||
import { mutative } from 'zustand-mutative';
|
||||
|
||||
import { settingsSchema, type Settings } from 'pl-fe/schemas/pl-fe/settings';
|
||||
|
||||
|
@ -35,39 +35,39 @@ const changeSetting = (object: APIEntity, path: string[], value: any) => {
|
|||
|
||||
const mergeSettings = (state: State) => state.settings = { ...state.defaultSettings, ...state.userSettings };
|
||||
|
||||
const useSettingsStore = create<State>((set) => ({
|
||||
const useSettingsStore = create<State>()(mutative((set) => ({
|
||||
defaultSettings: v.parse(settingsSchema, {}),
|
||||
userSettings: {},
|
||||
|
||||
settings: v.parse(settingsSchema, {}),
|
||||
|
||||
loadDefaultSettings: (settings: APIEntity) => set(produce((state: State) => {
|
||||
loadDefaultSettings: (settings: APIEntity) => set((state: State) => {
|
||||
if (typeof settings !== 'object') return;
|
||||
|
||||
state.defaultSettings = v.parse(settingsSchema, settings);
|
||||
mergeSettings(state);
|
||||
})),
|
||||
}),
|
||||
|
||||
loadUserSettings: (settings?: APIEntity) => set(produce((state: State) => {
|
||||
loadUserSettings: (settings?: APIEntity) => set((state: State) => {
|
||||
if (typeof settings !== 'object') return;
|
||||
|
||||
state.userSettings = v.parse(settingsSchemaPartial, settings);
|
||||
mergeSettings(state);
|
||||
})),
|
||||
}),
|
||||
|
||||
userSettingsSaving: () => set(produce((state: State) => {
|
||||
userSettingsSaving: () => set((state: State) => {
|
||||
state.userSettings.saved = true;
|
||||
|
||||
mergeSettings(state);
|
||||
})),
|
||||
}),
|
||||
|
||||
changeSetting: (path: string[], value: any) => set(produce((state: State) => {
|
||||
changeSetting: (path: string[], value: any) => set((state: State) => {
|
||||
changeSetting(state.userSettings, path, value);
|
||||
|
||||
mergeSettings(state);
|
||||
})),
|
||||
}),
|
||||
|
||||
rememberEmojiUse: (emoji: Emoji) => set(produce((state: State) => {
|
||||
rememberEmojiUse: (emoji: Emoji) => set((state: State) => {
|
||||
const settings = state.userSettings;
|
||||
if (!settings.frequentlyUsedEmojis) settings.frequentlyUsedEmojis = {};
|
||||
|
||||
|
@ -75,9 +75,9 @@ const useSettingsStore = create<State>((set) => ({
|
|||
settings.saved = false;
|
||||
|
||||
mergeSettings(state);
|
||||
})),
|
||||
}),
|
||||
|
||||
rememberLanguageUse: (language: string) => set(produce((state: State) => {
|
||||
rememberLanguageUse: (language: string) => set((state: State) => {
|
||||
const settings = state.userSettings;
|
||||
if (!settings.frequentlyUsedLanguages) settings.frequentlyUsedLanguages = {};
|
||||
|
||||
|
@ -85,8 +85,8 @@ const useSettingsStore = create<State>((set) => ({
|
|||
settings.saved = false;
|
||||
|
||||
mergeSettings(state);
|
||||
})),
|
||||
}));
|
||||
}),
|
||||
}), { enableAutoFreeze: true }));
|
||||
|
||||
export { useSettingsStore };
|
||||
|
||||
|
|
|
@ -5812,7 +5812,7 @@ immediate@~3.0.5:
|
|||
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
|
||||
integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==
|
||||
|
||||
immer@^10.0.3, immer@^10.1.1:
|
||||
immer@^10.0.3:
|
||||
version "10.1.1"
|
||||
resolved "https://registry.yarnpkg.com/immer/-/immer-10.1.1.tgz#206f344ea372d8ea176891545ee53ccc062db7bc"
|
||||
integrity sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==
|
||||
|
@ -7146,6 +7146,11 @@ multiselect-react-dropdown@^2.0.25:
|
|||
resolved "https://registry.yarnpkg.com/multiselect-react-dropdown/-/multiselect-react-dropdown-2.0.25.tgz#0c8d16f20d78023d5be2f3af4f15a4a164b6b427"
|
||||
integrity sha512-z8kUSyBNOuV7vn4Dk35snzXWtIfTdSEEXhgDdLMvOmR+xJFx35vc1voUlSuOvrk3khb+hXC219Qs9szOvNm25Q==
|
||||
|
||||
mutative@^1.0.11:
|
||||
version "1.0.11"
|
||||
resolved "https://registry.yarnpkg.com/mutative/-/mutative-1.0.11.tgz#a03b48151800129fbc464257eff9ffa869c648a8"
|
||||
integrity sha512-DfxsNvHfJlxp5yul7jhcNSI0EEWlP1vatiOr6Q7cvr8RNFBbIU5nENilUULbNJiOtbXznOxgbxHf4cYbqPDPlg==
|
||||
|
||||
mz@^2.7.0:
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
|
||||
|
@ -10429,6 +10434,11 @@ yocto-queue@^0.1.0:
|
|||
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
||||
|
||||
zustand-mutative@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/zustand-mutative/-/zustand-mutative-1.0.5.tgz#00ce93900a25d812b48d3f0d360da8a3890d0dd9"
|
||||
integrity sha512-/Rc2huxi2SxD21EcSrwW6moCRv+phFcrv3bMyrsQMDkI49LqLqMzhfNCZnOv0TmUctgG0u9xD6gHLUoYEwjkkQ==
|
||||
|
||||
zustand@^5.0.0-rc.2:
|
||||
version "5.0.0-rc.2"
|
||||
resolved "https://registry.yarnpkg.com/zustand/-/zustand-5.0.0-rc.2.tgz#d28d95ffb6f0b20cadbaea39210f18446a5bf989"
|
||||
|
|
Loading…
Reference in a new issue