idk i hate my life lol

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2025-12-18 17:55:51 +01:00
parent d9fad7a520
commit 6014b49f88
21 changed files with 273 additions and 124 deletions

View File

@ -67,6 +67,8 @@
"@tailwindcss/typography": "^0.5.16", "@tailwindcss/typography": "^0.5.16",
"@tanstack/react-pacer": "^0.16.4", "@tanstack/react-pacer": "^0.16.4",
"@tanstack/react-query": "^5.62.11", "@tanstack/react-query": "^5.62.11",
"@tanstack/react-router": "^1.141.6",
"@tanstack/react-router-devtools": "^1.141.6",
"@transfem-org/sfm-js": "^0.24.6", "@transfem-org/sfm-js": "^0.24.6",
"@twemoji/svg": "^15.0.0", "@twemoji/svg": "^15.0.0",
"@uidotdev/usehooks": "^2.4.1", "@uidotdev/usehooks": "^2.4.1",

View File

@ -159,6 +159,7 @@ import { WrappedRoute } from './util/react-router-helpers';
// Dummy import, to make sure that <Status /> ends up in the application bundle. // Dummy import, to make sure that <Status /> ends up in the application bundle.
// Without this it ends up in ~8 very commonly used bundles. // Without this it ends up in ~8 very commonly used bundles.
import 'pl-fe/components/status'; import 'pl-fe/components/status';
import { Outlet } from '@tanstack/react-router';
interface ISwitchingColumnsArea { interface ISwitchingColumnsArea {
children: React.ReactNode; children: React.ReactNode;
@ -383,11 +384,7 @@ const SwitchingColumnsArea: React.FC<ISwitchingColumnsArea> = React.memo(({ chil
); );
}); });
interface IUI { const UI: React.FC = React.memo(() => {
children?: React.ReactNode;
}
const UI: React.FC<IUI> = React.memo(({ children }) => {
const history = useHistory(); const history = useHistory();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const node = useRef<HTMLDivElement | null>(null); const node = useRef<HTMLDivElement | null>(null);
@ -511,9 +508,7 @@ const UI: React.FC<IUI> = React.memo(({ children }) => {
{!(standalone && !me) && <SidebarNavigation shrink={fullWidth} />} {!(standalone && !me) && <SidebarNavigation shrink={fullWidth} />}
</Layout.Sidebar> </Layout.Sidebar>
<SwitchingColumnsArea> <Outlet />
{children}
</SwitchingColumnsArea>
</Layout> </Layout>
<Suspense> <Suspense>

View File

@ -0,0 +1,43 @@
import { createRootRoute, createRoute } from '@tanstack/react-router';
import AdminLayout from 'pl-fe/layouts/admin-layout';
import ChatsLayout from 'pl-fe/layouts/chats-layout';
import DefaultLayout from 'pl-fe/layouts/default-layout';
import EmptyLayout from 'pl-fe/layouts/empty-layout';
import EventLayout from 'pl-fe/layouts/event-layout';
import EventsLayout from 'pl-fe/layouts/events-layout';
import ExternalLoginLayout from 'pl-fe/layouts/external-login-layout';
import GroupLayout from 'pl-fe/layouts/group-layout';
import GroupsLayout from 'pl-fe/layouts/groups-layout';
import HomeLayout from 'pl-fe/layouts/home-layout';
import LandingLayout from 'pl-fe/layouts/landing-layout';
import ManageGroupsLayout from 'pl-fe/layouts/manage-groups-layout';
import ProfileLayout from 'pl-fe/layouts/profile-layout';
import RemoteInstanceLayout from 'pl-fe/layouts/remote-instance-layout';
import SearchLayout from 'pl-fe/layouts/search-layout';
import StatusLayout from 'pl-fe/layouts/status-layout';
import UI from '.';
const rootRoute = createRootRoute({
component: UI,
});
const layouts = {
admin: createRoute({ getParentRoute: () => rootRoute, id: 'admin-layout', component: AdminLayout }),
chats: createRoute({ getParentRoute: () => rootRoute, id: 'chats-layout', component: ChatsLayout }),
default: createRoute({ getParentRoute: () => rootRoute, id: 'default-layout', component: DefaultLayout }),
empty: createRoute({ getParentRoute: () => rootRoute, id: 'empty-layout', component: EmptyLayout }),
event: createRoute({ getParentRoute: () => rootRoute, id: 'event-layout', component: EventLayout }),
events: createRoute({ getParentRoute: () => rootRoute, id: 'events-layout', component: EventsLayout }),
externalLogin: createRoute({ getParentRoute: () => rootRoute, id: 'external-login-layout', component: ExternalLoginLayout }),
group: createRoute({ getParentRoute: () => rootRoute, id: 'group-layout', component: GroupLayout }),
groups: createRoute({ getParentRoute: () => rootRoute, id: 'groups-layout', component: GroupsLayout }),
home: createRoute({ getParentRoute: () => rootRoute, id: 'home-layout', component: HomeLayout }),
landing: createRoute({ getParentRoute: () => rootRoute, id: 'landing-layout', component: LandingLayout }),
manageGroups: createRoute({ getParentRoute: () => rootRoute, id: 'manage-groups-layout', component: ManageGroupsLayout }),
profile: createRoute({ getParentRoute: () => rootRoute, id: 'profile-layout', component: ProfileLayout }),
remoteInstance: createRoute({ getParentRoute: () => rootRoute, id: 'remote-instance-layout', component: RemoteInstanceLayout }),
search: createRoute({ getParentRoute: () => rootRoute, id: 'search-layout', component: SearchLayout }),
status: createRoute({ getParentRoute: () => rootRoute, id: 'status-layout', component: StatusLayout }),
};

View File

@ -8,6 +8,7 @@ import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
import ColumnForbidden from '../components/column-forbidden'; import ColumnForbidden from '../components/column-forbidden';
import ColumnLoading from '../components/column-loading'; import ColumnLoading from '../components/column-loading';
import ErrorColumn from '../components/error-column'; import ErrorColumn from '../components/error-column';
import { Outlet } from '@tanstack/react-router';
type LayoutProps = { type LayoutProps = {
params?: MatchType['params']; params?: MatchType['params'];
@ -77,10 +78,10 @@ interface IFallbackLayout {
children: JSX.Element; children: JSX.Element;
} }
const FallbackLayout: React.FC<IFallbackLayout> = ({ children }) => ( const FallbackLayout: React.FC<IFallbackLayout> = () => (
<> <>
<Layout.Main> <Layout.Main>
{children} <Outlet />
</Layout.Main> </Layout.Main>
<Layout.Aside /> <Layout.Aside />

View File

@ -1,3 +1,4 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
import Layout from 'pl-fe/components/ui/layout'; import Layout from 'pl-fe/components/ui/layout';
@ -5,14 +6,10 @@ import { LatestAccountsPanel } from 'pl-fe/features/ui/util/async-components';
import LinkFooter from '../features/ui/components/link-footer'; import LinkFooter from '../features/ui/components/link-footer';
interface IAdminLayout { const AdminLayout = () => (
children: React.ReactNode;
}
const AdminLayout: React.FC<IAdminLayout> = ({ children }) => (
<> <>
<Layout.Main> <Layout.Main>
{children} <Outlet />
</Layout.Main> </Layout.Main>
<Layout.Aside> <Layout.Aside>

View File

@ -1,13 +1,10 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
interface IChatsLayout {
children: React.ReactNode;
}
/** Custom layout for chats on desktop. */ /** Custom layout for chats on desktop. */
const ChatsLayout: React.FC<IChatsLayout> = ({ children }) => ( const ChatsLayout = () => (
<div className='grow black:border-gray-800 md:col-span-12 lg:col-span-9 lg:black:border-l'> <div className='grow black:border-gray-800 md:col-span-12 lg:col-span-9 lg:black:border-l'>
{children} <Outlet />
</div> </div>
); );

View File

@ -1,3 +1,4 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
import Layout from 'pl-fe/components/ui/layout'; import Layout from 'pl-fe/components/ui/layout';
@ -10,10 +11,6 @@ import {
import { useAppSelector } from 'pl-fe/hooks/use-app-selector'; import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
import { useFeatures } from 'pl-fe/hooks/use-features'; import { useFeatures } from 'pl-fe/hooks/use-features';
interface IDefaultLayout {
children: React.ReactNode;
}
const DefaultLayout: React.FC<IDefaultLayout> = ({ children }) => { const DefaultLayout: React.FC<IDefaultLayout> = ({ children }) => {
const me = useAppSelector(state => state.me); const me = useAppSelector(state => state.me);
const features = useFeatures(); const features = useFeatures();
@ -21,7 +18,7 @@ const DefaultLayout: React.FC<IDefaultLayout> = ({ children }) => {
return ( return (
<> <>
<Layout.Main> <Layout.Main>
{children} <Outlet />
</Layout.Main> </Layout.Main>
<Layout.Aside> <Layout.Aside>

View File

@ -1,15 +1,12 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
import Layout from 'pl-fe/components/ui/layout'; import Layout from 'pl-fe/components/ui/layout';
interface IEmptyLayout { const EmptyLayout = () => (
children: React.ReactNode;
}
const EmptyLayout: React.FC<IEmptyLayout> = ({ children }) => (
<> <>
<Layout.Main> <Layout.Main>
{children} <Outlet />
</Layout.Main> </Layout.Main>
<Layout.Aside /> <Layout.Aside />

View File

@ -1,3 +1,4 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
import { Helmet } from 'react-helmet-async'; import { Helmet } from 'react-helmet-async';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
@ -20,14 +21,7 @@ import { makeGetStatus } from 'pl-fe/selectors';
const getStatus = makeGetStatus(); const getStatus = makeGetStatus();
interface IEventLayout { const EventLayout = () => {
params?: {
statusId?: string;
};
children: React.ReactNode;
}
const EventLayout: React.FC<IEventLayout> = ({ params, children }) => {
const me = useAppSelector(state => state.me); const me = useAppSelector(state => state.me);
const features = useFeatures(); const features = useFeatures();
@ -79,7 +73,7 @@ const EventLayout: React.FC<IEventLayout> = ({ params, children }) => {
<Tabs key={`event-tabs-${status.id}`} items={tabs} activeItem={activeItem} /> <Tabs key={`event-tabs-${status.id}`} items={tabs} activeItem={activeItem} />
)} )}
{children} <Outlet />
</div> </div>
</Column> </Column>
</Layout.Main> </Layout.Main>

View File

@ -1,3 +1,4 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
import Layout from 'pl-fe/components/ui/layout'; import Layout from 'pl-fe/components/ui/layout';
@ -9,18 +10,14 @@ import {
} from 'pl-fe/features/ui/util/async-components'; } from 'pl-fe/features/ui/util/async-components';
import { useFeatures } from 'pl-fe/hooks/use-features'; import { useFeatures } from 'pl-fe/hooks/use-features';
interface IEventsLayout {
children: React.ReactNode;
}
/** Layout to display events list. */ /** Layout to display events list. */
const EventsLayout: React.FC<IEventsLayout> = ({ children }) => { const EventsLayout = () => {
const features = useFeatures(); const features = useFeatures();
return ( return (
<> <>
<Layout.Main> <Layout.Main>
{children} <Outlet />
</Layout.Main> </Layout.Main>
<Layout.Aside> <Layout.Aside>

View File

@ -1,3 +1,4 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
import Layout from 'pl-fe/components/ui/layout'; import Layout from 'pl-fe/components/ui/layout';
@ -11,11 +12,7 @@ import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
import { useFeatures } from 'pl-fe/hooks/use-features'; import { useFeatures } from 'pl-fe/hooks/use-features';
import { isStandalone } from 'pl-fe/utils/state'; import { isStandalone } from 'pl-fe/utils/state';
interface IExternalLoginLayout { const ExternalLoginLayout = () => {
children: React.ReactNode;
}
const ExternalLoginLayout: React.FC<IExternalLoginLayout> = ({ children }) => {
const me = useAppSelector(state => state.me); const me = useAppSelector(state => state.me);
const features = useFeatures(); const features = useFeatures();
const standalone = useAppSelector(isStandalone); const standalone = useAppSelector(isStandalone);
@ -23,7 +20,7 @@ const ExternalLoginLayout: React.FC<IExternalLoginLayout> = ({ children }) => {
return ( return (
<> <>
<Layout.Main> <Layout.Main>
{children} <Outlet />
</Layout.Main> </Layout.Main>
<Layout.Aside> <Layout.Aside>

View File

@ -1,3 +1,4 @@
import { Outlet } from '@tanstack/react-router';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { useRouteMatch } from 'react-router-dom'; import { useRouteMatch } from 'react-router-dom';
@ -24,13 +25,6 @@ const messages = defineMessages({
media: { id: 'group.tabs.media', defaultMessage: 'Media' }, media: { id: 'group.tabs.media', defaultMessage: 'Media' },
}); });
interface IGroupLayout {
params?: {
groupId?: string;
};
children: React.ReactNode;
}
const PrivacyBlankslate = () => ( const PrivacyBlankslate = () => (
<Stack space={4} className='py-10' alignItems='center'> <Stack space={4} className='py-10' alignItems='center'>
<div className='rounded-full bg-gray-200 p-3 dark:bg-gray-800'> <div className='rounded-full bg-gray-200 p-3 dark:bg-gray-800'>
@ -50,7 +44,7 @@ const PrivacyBlankslate = () => (
); );
/** Layout to display a group. */ /** Layout to display a group. */
const GroupLayout: React.FC<IGroupLayout> = ({ params, children }) => { const GroupLayout = () => {
const intl = useIntl(); const intl = useIntl();
const match = useRouteMatch(); const match = useRouteMatch();
const { account: me } = useOwnAccount(); const { account: me } = useOwnAccount();
@ -92,7 +86,7 @@ const GroupLayout: React.FC<IGroupLayout> = ({ params, children }) => {
if (!isMember && isPrivate) { if (!isMember && isPrivate) {
return <PrivacyBlankslate />; return <PrivacyBlankslate />;
} else { } else {
return children; return <Outlet />;
} }
}; };

View File

@ -1,3 +1,4 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
import Column from 'pl-fe/components/ui/column'; import Column from 'pl-fe/components/ui/column';
@ -5,17 +6,13 @@ import Layout from 'pl-fe/components/ui/layout';
import LinkFooter from 'pl-fe/features/ui/components/link-footer'; import LinkFooter from 'pl-fe/features/ui/components/link-footer';
import { MyGroupsPanel, NewGroupPanel } from 'pl-fe/features/ui/util/async-components'; import { MyGroupsPanel, NewGroupPanel } from 'pl-fe/features/ui/util/async-components';
interface IGroupsLayout {
children: React.ReactNode;
}
/** Layout to display groups. */ /** Layout to display groups. */
const GroupsLayout: React.FC<IGroupsLayout> = ({ children }) => ( const GroupsLayout = () => (
<> <>
<Layout.Main> <Layout.Main>
<Column withHeader={false}> <Column withHeader={false}>
<div className='space-y-4'> <div className='space-y-4'>
{children} <Outlet />
</div> </div>
</Column> </Column>
</Layout.Main> </Layout.Main>

View File

@ -1,3 +1,4 @@
import { Outlet } from '@tanstack/react-router';
import clsx from 'clsx'; import clsx from 'clsx';
import React, { useRef } from 'react'; import React, { useRef } from 'react';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
@ -25,11 +26,7 @@ import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config'; import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config';
import { useSettings } from 'pl-fe/stores/settings'; import { useSettings } from 'pl-fe/stores/settings';
interface IHomeLayout { const HomeLayout = () => {
children: React.ReactNode;
}
const HomeLayout: React.FC<IHomeLayout> = ({ children }) => {
const intl = useIntl(); const intl = useIntl();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
@ -84,7 +81,7 @@ const HomeLayout: React.FC<IHomeLayout> = ({ children }) => {
</div> </div>
)} )}
{children} <Outlet />
</Layout.Main > </Layout.Main >
<Layout.Aside> <Layout.Aside>

View File

@ -1,3 +1,4 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
import Layout from 'pl-fe/components/ui/layout'; import Layout from 'pl-fe/components/ui/layout';
@ -9,18 +10,14 @@ import {
import { useAppSelector } from 'pl-fe/hooks/use-app-selector'; import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
import { useFeatures } from 'pl-fe/hooks/use-features'; import { useFeatures } from 'pl-fe/hooks/use-features';
interface ILandingLayout { const LandingLayout = () => {
children: React.ReactNode;
}
const LandingLayout: React.FC<ILandingLayout> = ({ children }) => {
const me = useAppSelector(state => state.me); const me = useAppSelector(state => state.me);
const features = useFeatures(); const features = useFeatures();
return ( return (
<> <>
<Layout.Main className='space-y-3 pt-3 black:divide-gray-800 dark:divide-primary-800 sm:pt-0'> <Layout.Main className='space-y-3 pt-3 black:divide-gray-800 dark:divide-primary-800 sm:pt-0'>
{children} <Outlet />
</Layout.Main> </Layout.Main>
<Layout.Aside> <Layout.Aside>

View File

@ -1,18 +1,15 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
import Layout from 'pl-fe/components/ui/layout'; import Layout from 'pl-fe/components/ui/layout';
import LinkFooter from 'pl-fe/features/ui/components/link-footer'; import LinkFooter from 'pl-fe/features/ui/components/link-footer';
import { MyGroupsPanel, NewGroupPanel } from 'pl-fe/features/ui/util/async-components'; import { MyGroupsPanel, NewGroupPanel } from 'pl-fe/features/ui/util/async-components';
interface IGroupsLayout {
children: React.ReactNode;
}
/** Layout to display groups. */ /** Layout to display groups. */
const ManageGroupsLayout: React.FC<IGroupsLayout> = ({ children }) => ( const ManageGroupsLayout = () => (
<> <>
<Layout.Main> <Layout.Main>
{children} <Outlet />
</Layout.Main> </Layout.Main>
<Layout.Aside> <Layout.Aside>

View File

@ -1,3 +1,4 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
import { Helmet } from 'react-helmet-async'; import { Helmet } from 'react-helmet-async';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
@ -23,15 +24,8 @@ import { useFeatures } from 'pl-fe/hooks/use-features';
import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config'; import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config';
import { getAcct } from 'pl-fe/utils/accounts'; import { getAcct } from 'pl-fe/utils/accounts';
interface IProfileLayout {
params?: {
username?: string;
};
children: React.ReactNode;
}
/** Layout to display a user's profile. */ /** Layout to display a user's profile. */
const ProfileLayout: React.FC<IProfileLayout> = ({ params, children }) => { const ProfileLayout = () => {
const history = useHistory(); const history = useHistory();
const username = params?.username || ''; const username = params?.username || '';
@ -110,7 +104,7 @@ const ProfileLayout: React.FC<IProfileLayout> = ({ params, children }) => {
<Tabs key={`profile-tabs-${account.id}`} items={tabItems} activeItem={activeItem} /> <Tabs key={`profile-tabs-${account.id}`} items={tabItems} activeItem={activeItem} />
)} )}
{children} <Outlet />
</div> </div>
</Column> </Column>
</Layout.Main> </Layout.Main>

View File

@ -1,3 +1,4 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
import Layout from 'pl-fe/components/ui/layout'; import Layout from 'pl-fe/components/ui/layout';
@ -11,15 +12,8 @@ import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
import { useOwnAccount } from 'pl-fe/hooks/use-own-account'; import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
import { federationRestrictionsDisclosed } from 'pl-fe/utils/state'; import { federationRestrictionsDisclosed } from 'pl-fe/utils/state';
interface IRemoteInstanceLayout {
params?: {
instance?: string;
};
children: React.ReactNode;
}
/** Layout for viewing a remote instance timeline. */ /** Layout for viewing a remote instance timeline. */
const RemoteInstanceLayout: React.FC<IRemoteInstanceLayout> = ({ children, params }) => { const RemoteInstanceLayout = () => {
const host = params!.instance!; const host = params!.instance!;
const { account } = useOwnAccount(); const { account } = useOwnAccount();
@ -28,7 +22,7 @@ const RemoteInstanceLayout: React.FC<IRemoteInstanceLayout> = ({ children, param
return ( return (
<> <>
<Layout.Main> <Layout.Main>
{children} <Outlet />
</Layout.Main> </Layout.Main>
<Layout.Aside> <Layout.Aside>

View File

@ -1,3 +1,4 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
import Layout from 'pl-fe/components/ui/layout'; import Layout from 'pl-fe/components/ui/layout';
@ -10,18 +11,14 @@ import {
import { useAppSelector } from 'pl-fe/hooks/use-app-selector'; import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
import { useFeatures } from 'pl-fe/hooks/use-features'; import { useFeatures } from 'pl-fe/hooks/use-features';
interface ISearchLayout { const SearchLayout = () => {
children: React.ReactNode;
}
const SearchLayout: React.FC<ISearchLayout> = ({ children }) => {
const me = useAppSelector(state => state.me); const me = useAppSelector(state => state.me);
const features = useFeatures(); const features = useFeatures();
return ( return (
<> <>
<Layout.Main> <Layout.Main>
{children} <Outlet />
</Layout.Main> </Layout.Main>
<Layout.Aside> <Layout.Aside>

View File

@ -1,3 +1,4 @@
import { Outlet } from '@tanstack/react-router';
import React from 'react'; import React from 'react';
import Layout from 'pl-fe/components/ui/layout'; import Layout from 'pl-fe/components/ui/layout';
@ -6,18 +7,14 @@ import { WhoToFollowPanel, TrendsPanel, SignUpPanel } from 'pl-fe/features/ui/ut
import { useAppSelector } from 'pl-fe/hooks/use-app-selector'; import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
import { useFeatures } from 'pl-fe/hooks/use-features'; import { useFeatures } from 'pl-fe/hooks/use-features';
interface IStatusLayout { const StatusLayout = () => {
children: React.ReactNode;
}
const StatusLayout: React.FC<IStatusLayout> = ({ children }) => {
const me = useAppSelector(state => state.me); const me = useAppSelector(state => state.me);
const features = useFeatures(); const features = useFeatures();
return ( return (
<> <>
<Layout.Main> <Layout.Main>
{children} <Outlet />
</Layout.Main> </Layout.Main>
<Layout.Aside> <Layout.Aside>

182
pnpm-lock.yaml generated
View File

@ -202,6 +202,12 @@ importers:
'@tanstack/react-query': '@tanstack/react-query':
specifier: ^5.62.11 specifier: ^5.62.11
version: 5.84.1(react@18.3.1) version: 5.84.1(react@18.3.1)
'@tanstack/react-router':
specifier: ^1.141.6
version: 1.141.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@tanstack/react-router-devtools':
specifier: ^1.141.6
version: 1.141.6(@tanstack/react-router@1.141.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@tanstack/router-core@1.141.6)(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(solid-js@1.9.10)
'@transfem-org/sfm-js': '@transfem-org/sfm-js':
specifier: ^0.24.6 specifier: ^0.24.6
version: 0.24.8 version: 0.24.8
@ -423,10 +429,10 @@ importers:
version: 1.2.0(typescript@5.7.3) version: 1.2.0(typescript@5.7.3)
zustand: zustand:
specifier: ^5.0.3 specifier: ^5.0.3
version: 5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) version: 5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1))
zustand-mutative: zustand-mutative:
specifier: ^1.2.0 specifier: ^1.2.0
version: 1.3.0(@types/react@18.3.23)(mutative@1.2.0)(react@18.3.1)(zustand@5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1))) version: 1.3.0(@types/react@18.3.23)(mutative@1.2.0)(react@18.3.1)(zustand@5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)))
devDependencies: devDependencies:
'@formatjs/cli': '@formatjs/cli':
specifier: ^6.3.14 specifier: ^6.3.14
@ -2347,6 +2353,10 @@ packages:
resolution: {integrity: sha512-RfV+OPV/M3CGryYqTue684u10jUt55PEqeBOnOtCe6tAmHI9Iqyc8nHeDhWPEV9715gShuauFVaMc9RiUVNdwg==} resolution: {integrity: sha512-RfV+OPV/M3CGryYqTue684u10jUt55PEqeBOnOtCe6tAmHI9Iqyc8nHeDhWPEV9715gShuauFVaMc9RiUVNdwg==}
engines: {node: '>=18'} engines: {node: '>=18'}
'@tanstack/history@1.141.0':
resolution: {integrity: sha512-LS54XNyxyTs5m/pl1lkwlg7uZM3lvsv2FIIV1rsJgnfwVCnI+n4ZGZ2CcjNT13BPu/3hPP+iHmliBSscJxW5FQ==}
engines: {node: '>=12'}
'@tanstack/pacer@0.15.4': '@tanstack/pacer@0.15.4':
resolution: {integrity: sha512-vGY+CWsFZeac3dELgB6UZ4c7OacwsLb8hvL2gLS6hTgy8Fl0Bm/aLokHaeDIP+q9F9HUZTnp360z9uv78eg8pg==} resolution: {integrity: sha512-vGY+CWsFZeac3dELgB6UZ4c7OacwsLb8hvL2gLS6hTgy8Fl0Bm/aLokHaeDIP+q9F9HUZTnp360z9uv78eg8pg==}
engines: {node: '>=18'} engines: {node: '>=18'}
@ -2366,15 +2376,58 @@ packages:
peerDependencies: peerDependencies:
react: ^18 || ^19 react: ^18 || ^19
'@tanstack/react-router-devtools@1.141.6':
resolution: {integrity: sha512-Uzb8GKg5Om8mCw2WjdDW1VBpyF+iaYOO/HK0ELbWO+TC6Nn/9pbbku/3HCMKHeLkmKPaMSW92do4Hu0bDYVglg==}
engines: {node: '>=12'}
peerDependencies:
'@tanstack/react-router': ^1.141.6
'@tanstack/router-core': ^1.141.6
react: '>=18.0.0 || >=19.0.0'
react-dom: '>=18.0.0 || >=19.0.0'
peerDependenciesMeta:
'@tanstack/router-core':
optional: true
'@tanstack/react-router@1.141.6':
resolution: {integrity: sha512-qWFxi2D6eGc1L03RzUuhyEOplZ7Q6q62YOl7Of9Y0q4YjwQwxRm4zxwDVtvUIoy4RLVCpqp5UoE+Nxv2PY9trg==}
engines: {node: '>=12'}
peerDependencies:
react: '>=18.0.0 || >=19.0.0'
react-dom: '>=18.0.0 || >=19.0.0'
'@tanstack/react-store@0.7.7': '@tanstack/react-store@0.7.7':
resolution: {integrity: sha512-qqT0ufegFRDGSof9D/VqaZgjNgp4tRPHZIJq2+QIHkMUtHjaJ0lYrrXjeIUJvjnTbgPfSD1XgOMEt0lmANn6Zg==} resolution: {integrity: sha512-qqT0ufegFRDGSof9D/VqaZgjNgp4tRPHZIJq2+QIHkMUtHjaJ0lYrrXjeIUJvjnTbgPfSD1XgOMEt0lmANn6Zg==}
peerDependencies: peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
'@tanstack/react-store@0.8.0':
resolution: {integrity: sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
'@tanstack/router-core@1.141.6':
resolution: {integrity: sha512-AqH61axLq2xFaM+B0veGQ4OOzMzr2Ih+qXzBmGRy5e0wMJkr1efPZXLF0K7nEjF++bmL/excew2Br6v9xrZ/5g==}
engines: {node: '>=12'}
'@tanstack/router-devtools-core@1.141.6':
resolution: {integrity: sha512-+qzAw16ELQWyj4bTX3zOIZDqGsq+AM6cRn1fp8/nzvw++TvN62k4hHAiRQn4EU+R03qjRUCE9315jzAf9Amslw==}
engines: {node: '>=12'}
peerDependencies:
'@tanstack/router-core': ^1.141.6
csstype: ^3.0.10
solid-js: '>=1.9.5'
peerDependenciesMeta:
csstype:
optional: true
'@tanstack/store@0.7.7': '@tanstack/store@0.7.7':
resolution: {integrity: sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ==} resolution: {integrity: sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ==}
'@tanstack/store@0.8.0':
resolution: {integrity: sha512-Om+BO0YfMZe//X2z0uLF2j+75nQga6TpTJgLJQBiq85aOyZNIhkCgleNcud2KQg4k4v9Y9l+Uhru3qWMPGTOzQ==}
'@testing-library/dom@10.4.1': '@testing-library/dom@10.4.1':
resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==}
engines: {node: '>=18'} engines: {node: '>=18'}
@ -3363,6 +3416,9 @@ packages:
convert-source-map@2.0.0: convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
cookie-es@2.0.0:
resolution: {integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==}
core-js-compat@3.46.0: core-js-compat@3.46.0:
resolution: {integrity: sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==} resolution: {integrity: sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==}
@ -4489,6 +4545,10 @@ packages:
isarray@2.0.5: isarray@2.0.5:
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
isbot@5.1.32:
resolution: {integrity: sha512-VNfjM73zz2IBZmdShMfAUg10prm6t7HFUQmNAEOAVS4YH92ZrZcvkMcGX6cIgBJAzWDzPent/EeAtYEHNPNPBQ==}
engines: {node: '>=18'}
isexe@2.0.0: isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
@ -5948,6 +6008,26 @@ packages:
serialize-query-params@2.0.2: serialize-query-params@2.0.2:
resolution: {integrity: sha512-1chMo1dST4pFA9RDXAtF0Rbjaut4is7bzFbI1Z26IuMub68pNCILku85aYmeFhvnY//BXUPUhoRMjYcsT93J/Q==} resolution: {integrity: sha512-1chMo1dST4pFA9RDXAtF0Rbjaut4is7bzFbI1Z26IuMub68pNCILku85aYmeFhvnY//BXUPUhoRMjYcsT93J/Q==}
seroval-plugins@1.3.3:
resolution: {integrity: sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==}
engines: {node: '>=10'}
peerDependencies:
seroval: ^1.0
seroval-plugins@1.4.0:
resolution: {integrity: sha512-zir1aWzoiax6pbBVjoYVd0O1QQXgIL3eVGBMsBsNmM8Ukq90yGaWlfx0AB9dTS8GPqrOrbXn79vmItCUP9U3BQ==}
engines: {node: '>=10'}
peerDependencies:
seroval: ^1.0
seroval@1.3.2:
resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==}
engines: {node: '>=10'}
seroval@1.4.0:
resolution: {integrity: sha512-BdrNXdzlofomLTiRnwJTSEAaGKyHHZkbMXIywOh7zlzp4uZnXErEwl9XZ+N1hJSNpeTtNxWvVwN0wUzAIQ4Hpg==}
engines: {node: '>=10'}
set-function-length@1.2.2: set-function-length@1.2.2:
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -6016,6 +6096,9 @@ packages:
smob@1.5.0: smob@1.5.0:
resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==}
solid-js@1.9.10:
resolution: {integrity: sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew==}
source-map-js@1.2.1: source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -6540,6 +6623,11 @@ packages:
peerDependencies: peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
use-sync-external-store@1.6.0:
resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
util-deprecate@1.0.2: util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@ -8843,6 +8931,8 @@ snapshots:
'@tanstack/devtools-event-client@0.3.3': {} '@tanstack/devtools-event-client@0.3.3': {}
'@tanstack/history@1.141.0': {}
'@tanstack/pacer@0.15.4': '@tanstack/pacer@0.15.4':
dependencies: dependencies:
'@tanstack/devtools-event-client': 0.3.3 '@tanstack/devtools-event-client': 0.3.3
@ -8862,6 +8952,29 @@ snapshots:
'@tanstack/query-core': 5.83.1 '@tanstack/query-core': 5.83.1
react: 18.3.1 react: 18.3.1
'@tanstack/react-router-devtools@1.141.6(@tanstack/react-router@1.141.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@tanstack/router-core@1.141.6)(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(solid-js@1.9.10)':
dependencies:
'@tanstack/react-router': 1.141.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@tanstack/router-devtools-core': 1.141.6(@tanstack/router-core@1.141.6)(csstype@3.1.3)(solid-js@1.9.10)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
optionalDependencies:
'@tanstack/router-core': 1.141.6
transitivePeerDependencies:
- csstype
- solid-js
'@tanstack/react-router@1.141.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@tanstack/history': 1.141.0
'@tanstack/react-store': 0.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@tanstack/router-core': 1.141.6
isbot: 5.1.32
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
tiny-invariant: 1.3.3
tiny-warning: 1.0.3
'@tanstack/react-store@0.7.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': '@tanstack/react-store@0.7.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies: dependencies:
'@tanstack/store': 0.7.7 '@tanstack/store': 0.7.7
@ -8869,8 +8982,37 @@ snapshots:
react-dom: 18.3.1(react@18.3.1) react-dom: 18.3.1(react@18.3.1)
use-sync-external-store: 1.5.0(react@18.3.1) use-sync-external-store: 1.5.0(react@18.3.1)
'@tanstack/react-store@0.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@tanstack/store': 0.8.0
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
use-sync-external-store: 1.6.0(react@18.3.1)
'@tanstack/router-core@1.141.6':
dependencies:
'@tanstack/history': 1.141.0
'@tanstack/store': 0.8.0
cookie-es: 2.0.0
seroval: 1.4.0
seroval-plugins: 1.4.0(seroval@1.4.0)
tiny-invariant: 1.3.3
tiny-warning: 1.0.3
'@tanstack/router-devtools-core@1.141.6(@tanstack/router-core@1.141.6)(csstype@3.1.3)(solid-js@1.9.10)':
dependencies:
'@tanstack/router-core': 1.141.6
clsx: 2.1.1
goober: 2.1.16(csstype@3.1.3)
solid-js: 1.9.10
tiny-invariant: 1.3.3
optionalDependencies:
csstype: 3.1.3
'@tanstack/store@0.7.7': {} '@tanstack/store@0.7.7': {}
'@tanstack/store@0.8.0': {}
'@testing-library/dom@10.4.1': '@testing-library/dom@10.4.1':
dependencies: dependencies:
'@babel/code-frame': 7.27.1 '@babel/code-frame': 7.27.1
@ -10029,6 +10171,8 @@ snapshots:
convert-source-map@2.0.0: {} convert-source-map@2.0.0: {}
cookie-es@2.0.0: {}
core-js-compat@3.46.0: core-js-compat@3.46.0:
dependencies: dependencies:
browserslist: 4.27.0 browserslist: 4.27.0
@ -10550,7 +10694,7 @@ snapshots:
tinyglobby: 0.2.14 tinyglobby: 0.2.14
unrs-resolver: 1.11.1 unrs-resolver: 1.11.1
optionalDependencies: optionalDependencies:
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.1) eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.38.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -11453,6 +11597,8 @@ snapshots:
isarray@2.0.5: {} isarray@2.0.5: {}
isbot@5.1.32: {}
isexe@2.0.0: {} isexe@2.0.0: {}
isomorphic-dompurify@2.26.0: isomorphic-dompurify@2.26.0:
@ -12913,6 +13059,18 @@ snapshots:
serialize-query-params@2.0.2: {} serialize-query-params@2.0.2: {}
seroval-plugins@1.3.3(seroval@1.3.2):
dependencies:
seroval: 1.3.2
seroval-plugins@1.4.0(seroval@1.4.0):
dependencies:
seroval: 1.4.0
seroval@1.3.2: {}
seroval@1.4.0: {}
set-function-length@1.2.2: set-function-length@1.2.2:
dependencies: dependencies:
define-data-property: 1.1.4 define-data-property: 1.1.4
@ -12997,6 +13155,12 @@ snapshots:
smob@1.5.0: {} smob@1.5.0: {}
solid-js@1.9.10:
dependencies:
csstype: 3.1.3
seroval: 1.3.2
seroval-plugins: 1.3.3(seroval@1.3.2)
source-map-js@1.2.1: {} source-map-js@1.2.1: {}
source-map-support@0.5.21: source-map-support@0.5.21:
@ -13604,6 +13768,10 @@ snapshots:
dependencies: dependencies:
react: 18.3.1 react: 18.3.1
use-sync-external-store@1.6.0(react@18.3.1):
dependencies:
react: 18.3.1
util-deprecate@1.0.2: {} util-deprecate@1.0.2: {}
util@0.12.5: util@0.12.5:
@ -14118,16 +14286,16 @@ snapshots:
yocto-queue@0.1.0: {} yocto-queue@0.1.0: {}
zustand-mutative@1.3.0(@types/react@18.3.23)(mutative@1.2.0)(react@18.3.1)(zustand@5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1))): zustand-mutative@1.3.0(@types/react@18.3.23)(mutative@1.2.0)(react@18.3.1)(zustand@5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1))):
dependencies: dependencies:
'@types/react': 18.3.23 '@types/react': 18.3.23
mutative: 1.2.0 mutative: 1.2.0
react: 18.3.1 react: 18.3.1
zustand: 5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) zustand: 5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1))
zustand@5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)): zustand@5.0.7(@types/react@18.3.23)(immer@10.1.1)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)):
optionalDependencies: optionalDependencies:
'@types/react': 18.3.23 '@types/react': 18.3.23
immer: 10.1.1 immer: 10.1.1
react: 18.3.1 react: 18.3.1
use-sync-external-store: 1.5.0(react@18.3.1) use-sync-external-store: 1.6.0(react@18.3.1)