From 67d141b0e5b0148af8d255bca80b30387eeee0e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Fri, 27 Sep 2024 17:02:02 +0200 Subject: [PATCH 01/32] WIP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-fe/package.json | 2 +- packages/pl-fe/src/actions/notifications.ts | 140 +- .../pl-fe/src/api/hooks/statuses/useStatus.ts | 14 + .../notifications/components/notification.tsx | 18 +- .../src/features/notifications/index.tsx | 78 +- packages/pl-fe/src/features/ui/index.tsx | 17 +- packages/pl-fe/src/pl-hooks/README.md | 1 + .../hooks/notifications/useNotification.ts | 122 + .../hooks/notifications/useNotifications.ts | 94 + packages/pl-fe/src/pl-hooks/importer.ts | 48 + packages/pl-fe/src/reducers/notifications.ts | 23 +- packages/pl-fe/src/selectors/index.ts | 27 +- packages/pl-fe/src/utils/queries.ts | 4 +- packages/pl-fe/yarn.lock | 8 +- packages/pl-hooks/.eslintignore | 7 + packages/pl-hooks/.eslintrc.json | 214 ++ packages/pl-hooks/.gitignore | 24 + packages/pl-hooks/README.md | 18 + packages/pl-hooks/index.html | 11 + packages/pl-hooks/lib/main.ts | 0 packages/pl-hooks/package.json | 40 + packages/pl-hooks/tsconfig-build.json | 4 + packages/pl-hooks/tsconfig.json | 24 + packages/pl-hooks/vite.config.ts | 19 + packages/pl-hooks/yarn.lock | 2556 +++++++++++++++++ 25 files changed, 3281 insertions(+), 232 deletions(-) create mode 100644 packages/pl-fe/src/api/hooks/statuses/useStatus.ts create mode 100644 packages/pl-fe/src/pl-hooks/README.md create mode 100644 packages/pl-fe/src/pl-hooks/hooks/notifications/useNotification.ts create mode 100644 packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts create mode 100644 packages/pl-fe/src/pl-hooks/importer.ts create mode 100644 packages/pl-hooks/.eslintignore create mode 100644 packages/pl-hooks/.eslintrc.json create mode 100644 packages/pl-hooks/.gitignore create mode 100644 packages/pl-hooks/README.md create mode 100644 packages/pl-hooks/index.html create mode 100644 packages/pl-hooks/lib/main.ts create mode 100644 packages/pl-hooks/package.json create mode 100644 packages/pl-hooks/tsconfig-build.json create mode 100644 packages/pl-hooks/tsconfig.json create mode 100644 packages/pl-hooks/vite.config.ts create mode 100644 packages/pl-hooks/yarn.lock diff --git a/packages/pl-fe/package.json b/packages/pl-fe/package.json index efe7a33bb..e760563f1 100644 --- a/packages/pl-fe/package.json +++ b/packages/pl-fe/package.json @@ -172,7 +172,7 @@ "tslib": "^2.3.1", "twemoji": "https://github.com/twitter/twemoji#v14.0.2", "type-fest": "^4.0.0", - "typescript": "^5.4.5", + "typescript": "^5.6.2", "util": "^0.12.5", "uuid": "^9.0.0", "vite": "^5.4.7", diff --git a/packages/pl-fe/src/actions/notifications.ts b/packages/pl-fe/src/actions/notifications.ts index ce23dcd5e..201ff4657 100644 --- a/packages/pl-fe/src/actions/notifications.ts +++ b/packages/pl-fe/src/actions/notifications.ts @@ -2,27 +2,23 @@ import IntlMessageFormat from 'intl-messageformat'; import 'intl-pluralrules'; import { defineMessages } from 'react-intl'; -import { getClient } from 'pl-fe/api'; import { getNotificationStatus } from 'pl-fe/features/notifications/components/notification'; -import { normalizeNotification, normalizeNotifications, type Notification } from 'pl-fe/normalizers'; +import { normalizeNotification } from 'pl-fe/normalizers'; import { getFilters, regexFromFilters } from 'pl-fe/selectors'; import { isLoggedIn } from 'pl-fe/utils/auth'; import { compareId } from 'pl-fe/utils/comparators'; import { unescapeHTML } from 'pl-fe/utils/html'; -import { EXCLUDE_TYPES, NOTIFICATION_TYPES } from 'pl-fe/utils/notification'; import { joinPublicPath } from 'pl-fe/utils/static'; import { fetchRelationships } from './accounts'; import { importFetchedAccount, - importFetchedAccounts, importFetchedStatus, - importFetchedStatuses, } from './importer'; import { saveMarker } from './markers'; import { getSettings, saveSettings } from './settings'; -import type { Account, Notification as BaseNotification, PaginatedResponse, Status } from 'pl-api'; +import type { Notification as BaseNotification } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE' as const; @@ -30,10 +26,6 @@ const NOTIFICATIONS_UPDATE_NOOP = 'NOTIFICATIONS_UPDATE_NOOP' as const; const NOTIFICATIONS_UPDATE_QUEUE = 'NOTIFICATIONS_UPDATE_QUEUE' as const; const NOTIFICATIONS_DEQUEUE = 'NOTIFICATIONS_DEQUEUE' as const; -const NOTIFICATIONS_EXPAND_REQUEST = 'NOTIFICATIONS_EXPAND_REQUEST' as const; -const NOTIFICATIONS_EXPAND_SUCCESS = 'NOTIFICATIONS_EXPAND_SUCCESS' as const; -const NOTIFICATIONS_EXPAND_FAIL = 'NOTIFICATIONS_EXPAND_FAIL' as const; - const NOTIFICATIONS_FILTER_SET = 'NOTIFICATIONS_FILTER_SET' as const; const NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR' as const; @@ -45,18 +37,18 @@ const NOTIFICATIONS_MARK_READ_FAIL = 'NOTIFICATIONS_MARK_READ_FAIL' as const; const MAX_QUEUED_NOTIFICATIONS = 40; -const FILTER_TYPES = { - all: undefined, - mention: ['mention'], - favourite: ['favourite', 'emoji_reaction'], - reblog: ['reblog'], - poll: ['poll'], - status: ['status'], - follow: ['follow', 'follow_request'], - events: ['event_reminder', 'participation_request', 'participation_accepted'], +type FILTER_TYPES = { + all: undefined; + mention: ['mention']; + favourite: ['favourite', 'emoji_reaction']; + reblog: ['reblog']; + poll: ['poll']; + status: ['status']; + follow: ['follow', 'follow_request']; + events: ['event_reminder', 'participation_request', 'participation_accepted']; }; -type FilterType = keyof typeof FILTER_TYPES; +type FilterType = keyof FILTER_TYPES; defineMessages({ mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' }, @@ -174,7 +166,7 @@ const dequeueNotifications = () => dispatch(updateNotifications(block.notification)); }); } else { - dispatch(expandNotifications()); + // dispatch(expandNotifications()); } dispatch({ @@ -183,104 +175,6 @@ const dequeueNotifications = () => dispatch(markReadNotifications()); }; -const excludeTypesFromFilter = (filters: string[]) => NOTIFICATION_TYPES.filter(item => !filters.includes(item)); - -const noOp = () => new Promise(f => f(undefined)); - -let abortExpandNotifications = new AbortController(); - -const expandNotifications = ({ maxId }: Record = {}, done: () => any = noOp, abort?: boolean) => - (dispatch: AppDispatch, getState: () => RootState) => { - if (!isLoggedIn(getState)) return dispatch(noOp); - const state = getState(); - - const features = state.auth.client.features; - const activeFilter = getSettings(state).getIn(['notifications', 'quickFilter', 'active']) as FilterType; - const notifications = state.notifications; - - if (notifications.isLoading) { - if (abort) { - abortExpandNotifications.abort(); - abortExpandNotifications = new AbortController(); - } else { - done(); - return dispatch(noOp); - } - } - - const params: Record = { - max_id: maxId, - }; - - if (activeFilter === 'all') { - if (features.notificationsIncludeTypes) { - params.types = NOTIFICATION_TYPES.filter(type => !EXCLUDE_TYPES.includes(type as any)); - } else { - params.exclude_types = EXCLUDE_TYPES; - } - } else { - const filtered = FILTER_TYPES[activeFilter] || [activeFilter]; - if (features.notificationsIncludeTypes) { - params.types = filtered; - } else { - params.exclude_types = excludeTypesFromFilter(filtered); - } - } - - if (!maxId && notifications.items.size > 0) { - params.since_id = notifications.getIn(['items', 0, 'id']); - } - - dispatch(expandNotificationsRequest()); - - return getClient(state).notifications.getNotifications(params, { signal: abortExpandNotifications.signal }).then(response => { - const entries = (response.items).reduce((acc, item) => { - if (item.account?.id) { - acc.accounts[item.account.id] = item.account; - } - - // Used by Move notification - if (item.type === 'move' && item.target.id) { - acc.accounts[item.target.id] = item.target; - } - - // TODO actually check for type - // @ts-ignore - if (item.status?.id) { - // @ts-ignore - acc.statuses[item.status.id] = item.status; - } - - return acc; - }, { accounts: {}, statuses: {} } as { accounts: Record; statuses: Record }); - - dispatch(importFetchedAccounts(Object.values(entries.accounts))); - dispatch(importFetchedStatuses(Object.values(entries.statuses))); - - const deduplicatedNotifications = normalizeNotifications(response.items, state.notifications.items); - - dispatch(expandNotificationsSuccess(deduplicatedNotifications, response.next)); - fetchRelatedRelationships(dispatch, response.items); - done(); - }).catch(error => { - dispatch(expandNotificationsFail(error)); - done(); - }); - }; - -const expandNotificationsRequest = () => ({ type: NOTIFICATIONS_EXPAND_REQUEST }); - -const expandNotificationsSuccess = (notifications: Array, next: (() => Promise>) | null) => ({ - type: NOTIFICATIONS_EXPAND_SUCCESS, - notifications, - next, -}); - -const expandNotificationsFail = (error: unknown) => ({ - type: NOTIFICATIONS_EXPAND_FAIL, - error, -}); - const scrollTopNotifications = (top: boolean) => (dispatch: AppDispatch) => { dispatch({ @@ -299,7 +193,6 @@ const setFilter = (filterType: FilterType, abort?: boolean) => path: ['notifications', 'quickFilter', 'active'], value: filterType, }); - dispatch(expandNotifications(undefined, undefined, abort)); if (activeFilter !== filterType) dispatch(saveSettings()); }; @@ -327,9 +220,6 @@ export { NOTIFICATIONS_UPDATE_NOOP, NOTIFICATIONS_UPDATE_QUEUE, NOTIFICATIONS_DEQUEUE, - NOTIFICATIONS_EXPAND_REQUEST, - NOTIFICATIONS_EXPAND_SUCCESS, - NOTIFICATIONS_EXPAND_FAIL, NOTIFICATIONS_FILTER_SET, NOTIFICATIONS_CLEAR, NOTIFICATIONS_SCROLL_TOP, @@ -341,10 +231,6 @@ export { updateNotifications, updateNotificationsQueue, dequeueNotifications, - expandNotifications, - expandNotificationsRequest, - expandNotificationsSuccess, - expandNotificationsFail, scrollTopNotifications, setFilter, markReadNotifications, diff --git a/packages/pl-fe/src/api/hooks/statuses/useStatus.ts b/packages/pl-fe/src/api/hooks/statuses/useStatus.ts new file mode 100644 index 000000000..061add38a --- /dev/null +++ b/packages/pl-fe/src/api/hooks/statuses/useStatus.ts @@ -0,0 +1,14 @@ +import { useQuery } from '@tanstack/react-query'; + +import { useClient } from 'pl-fe/hooks'; + +const useStatus = (statusId: string) => { + const client = useClient(); + + return useQuery({ + queryKey: ['statuses', statusId], + queryFn: () => client.statuses.getStatus(statusId), + }); +}; + +export { useStatus }; diff --git a/packages/pl-fe/src/features/notifications/components/notification.tsx b/packages/pl-fe/src/features/notifications/components/notification.tsx index ddc2cac3e..29a9ce7c0 100644 --- a/packages/pl-fe/src/features/notifications/components/notification.tsx +++ b/packages/pl-fe/src/features/notifications/components/notification.tsx @@ -6,20 +6,19 @@ import { mentionCompose } from 'pl-fe/actions/compose'; import { reblog, favourite, unreblog, unfavourite } from 'pl-fe/actions/interactions'; import { getSettings } from 'pl-fe/actions/settings'; import { toggleStatusMediaHidden } from 'pl-fe/actions/statuses'; +import { useNotification } from 'pl-fe/pl-hooks/hooks/notifications/useNotification'; import Icon from 'pl-fe/components/icon'; import RelativeTimestamp from 'pl-fe/components/relative-timestamp'; import { HStack, Text, Emoji } from 'pl-fe/components/ui'; import AccountContainer from 'pl-fe/containers/account-container'; import StatusContainer from 'pl-fe/containers/status-container'; import { HotKeys } from 'pl-fe/features/ui/components/hotkeys'; -import { useAppDispatch, useAppSelector, useInstance, useLoggedIn } from 'pl-fe/hooks'; -import { makeGetNotification } from 'pl-fe/selectors'; +import { useAppDispatch, useInstance, useLoggedIn } from 'pl-fe/hooks'; import { useModalsStore } from 'pl-fe/stores'; import { NotificationType } from 'pl-fe/utils/notification'; import type { Notification as BaseNotification } from 'pl-api'; import type { Account, Notification as NotificationEntity, Status as StatusEntity } from 'pl-fe/normalizers'; -import type { MinifiedNotification } from 'pl-fe/reducers/notifications'; const notificationForScreenReader = (intl: IntlShape, message: string, timestamp: string) => { const output = [message]; @@ -174,29 +173,28 @@ const avatarSize = 48; interface INotification { hidden?: boolean; - notification: MinifiedNotification; + id: string; + // notification: MinifiedNotification; onMoveUp?: (notificationId: string) => void; onMoveDown?: (notificationId: string) => void; onReblog?: (status: StatusEntity, e?: KeyboardEvent) => void; } -const getNotificationStatus = (n: NotificationEntity | BaseNotification) => { +const getNotificationStatus = (n: Pick) => { if (['mention', 'status', 'reblog', 'favourite', 'poll', 'update', 'emoji_reaction', 'event_reminder', 'participation_accepted', 'participation_request'].includes(n.type)) // @ts-ignore return n.status; return null; }; -const Notification: React.FC = (props) => { - const { hidden = false, onMoveUp, onMoveDown } = props; +const Notification: React.FC = ({ hidden = false, id, onMoveUp, onMoveDown }) => { + const notificationQuery = useNotification(id); + const notification = notificationQuery.data!; const dispatch = useAppDispatch(); - const getNotification = useCallback(makeGetNotification(), []); - const { me } = useLoggedIn(); const { openModal } = useModalsStore(); - const notification = useAppSelector((state) => getNotification(state, props.notification)); const history = useHistory(); const intl = useIntl(); diff --git a/packages/pl-fe/src/features/notifications/index.tsx b/packages/pl-fe/src/features/notifications/index.tsx index bb8a2a4f0..dbfd216ab 100644 --- a/packages/pl-fe/src/features/notifications/index.tsx +++ b/packages/pl-fe/src/features/notifications/index.tsx @@ -1,72 +1,78 @@ import clsx from 'clsx'; -import { List as ImmutableList } from 'immutable'; import debounce from 'lodash/debounce'; import React, { useCallback, useEffect, useRef } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; -import { createSelector } from 'reselect'; import { - expandNotifications, scrollTopNotifications, dequeueNotifications, } from 'pl-fe/actions/notifications'; +import { useNotifications } from 'pl-fe/pl-hooks/hooks/notifications/useNotifications'; import PullToRefresh from 'pl-fe/components/pull-to-refresh'; import ScrollTopButton from 'pl-fe/components/scroll-top-button'; import ScrollableList from 'pl-fe/components/scrollable-list'; import { Column, Portal } from 'pl-fe/components/ui'; import PlaceholderNotification from 'pl-fe/features/placeholder/components/placeholder-notification'; import { useAppDispatch, useAppSelector, useSettings } from 'pl-fe/hooks'; +import { NotificationType } from 'pl-fe/utils/notification'; import FilterBar from './components/filter-bar'; import Notification from './components/notification'; -import type { RootState } from 'pl-fe/store'; - const messages = defineMessages({ title: { id: 'column.notifications', defaultMessage: 'Notifications' }, queue: { id: 'notifications.queue_label', defaultMessage: 'Click to see {count} new {count, plural, one {notification} other {notifications}}' }, }); -const getNotifications = createSelector([ - (state: RootState) => state.notifications.items.toList(), -], (notifications) => notifications.filter(item => item !== null && !item.duplicate)); +const FILTER_TYPES: Record | undefined> = { + all: undefined, + mention: ['mention'], + favourite: ['favourite', 'emoji_reaction'], + reblog: ['reblog'], + poll: ['poll'], + status: ['status'], + follow: ['follow', 'follow_request'], + events: ['event_reminder', 'participation_request', 'participation_accepted'], +}; + +type FilterType = keyof typeof FILTER_TYPES; const Notifications = () => { const dispatch = useAppDispatch(); const intl = useIntl(); const settings = useSettings(); + const activeFilter = settings.notifications.quickFilter.active as FilterType; + + const params = activeFilter === 'all' ? {} : { + types: FILTER_TYPES[activeFilter] || [activeFilter] as Array, + }; + + const notificationsQuery = useNotifications(params); + + const notifications = notificationsQuery.data; + const showFilterBar = settings.notifications.quickFilter.show; - const activeFilter = settings.notifications.quickFilter.active; - const notifications = useAppSelector(state => getNotifications(state)); - const isLoading = useAppSelector(state => state.notifications.isLoading); - // const isUnread = useAppSelector(state => state.notifications.unread > 0); - const hasMore = useAppSelector(state => state.notifications.hasMore); const totalQueuedNotificationsCount = useAppSelector(state => state.notifications.totalQueuedNotificationsCount || 0); const column = useRef(null); - const scrollableContentRef = useRef | null>(null); - - // const handleLoadGap = (maxId) => { - // dispatch(expandNotifications({ maxId })); - // }; + const scrollableContentRef = useRef | null>(null); const handleLoadOlder = useCallback(debounce(() => { - const last = notifications.last(); - dispatch(expandNotifications({ maxId: last && last.id })); - }, 300, { leading: true }), [notifications]); + if (notificationsQuery.hasNextPage) notificationsQuery.fetchNextPage(); + }, 300, { leading: true }), [notificationsQuery.hasNextPage]); const handleScroll = useCallback(debounce((startIndex?: number) => { dispatch(scrollTopNotifications(startIndex === 0)); }, 100), []); const handleMoveUp = (id: string) => { - const elementIndex = notifications.findIndex(item => item !== null && item.id === id) - 1; + const elementIndex = notifications.findIndex(item => item !== null && item === id) - 1; _selectChild(elementIndex); }; const handleMoveDown = (id: string) => { - const elementIndex = notifications.findIndex(item => item !== null && item.id === id) + 1; + const elementIndex = notifications.findIndex(item => item !== null && item === id) + 1; _selectChild(elementIndex); }; @@ -81,7 +87,7 @@ const Notifications = () => { dispatch(dequeueNotifications()); }, []); - const handleRefresh = useCallback(() => dispatch(expandNotifications()), []); + const handleRefresh = useCallback(() => notificationsQuery.refetch(), []); useEffect(() => { handleDequeueNotifications(); @@ -98,19 +104,19 @@ const Notifications = () => { ? : ; - let scrollableContent: ImmutableList | null = null; + let scrollableContent: Array | null = null; const filterBarContainer = showFilterBar ? () : null; - if (isLoading && scrollableContentRef.current) { + if (notificationsQuery.isLoading && scrollableContentRef.current) { scrollableContent = scrollableContentRef.current; - } else if (notifications.size > 0 || hasMore) { - scrollableContent = notifications.map((item) => ( + } else if (notifications.length > 0 || notificationsQuery.hasNextPage) { + scrollableContent = notifications.map((notificationId) => ( @@ -123,19 +129,19 @@ const Notifications = () => { const scrollContainer = ( - {scrollableContent as ImmutableList} + {scrollableContent!} ); @@ -158,4 +164,4 @@ const Notifications = () => { ); }; -export { Notifications as default }; +export { Notifications as default, FILTER_TYPES, type FilterType }; diff --git a/packages/pl-fe/src/features/ui/index.tsx b/packages/pl-fe/src/features/ui/index.tsx index d1ccd0557..9385b796e 100644 --- a/packages/pl-fe/src/features/ui/index.tsx +++ b/packages/pl-fe/src/features/ui/index.tsx @@ -8,16 +8,17 @@ import { fetchCustomEmojis } from 'pl-fe/actions/custom-emojis'; import { fetchDraftStatuses } from 'pl-fe/actions/draft-statuses'; import { fetchFilters } from 'pl-fe/actions/filters'; import { fetchMarker } from 'pl-fe/actions/markers'; -import { expandNotifications } from 'pl-fe/actions/notifications'; +import { FilterType } from 'pl-fe/actions/notifications'; import { register as registerPushNotifications } from 'pl-fe/actions/push-notifications'; import { fetchScheduledStatuses } from 'pl-fe/actions/scheduled-statuses'; import { fetchSuggestionsForTimeline } from 'pl-fe/actions/suggestions'; import { fetchHomeTimeline } from 'pl-fe/actions/timelines'; import { useUserStream } from 'pl-fe/api/hooks'; +import { prefetchNotifications } from 'pl-fe/pl-hooks/hooks/notifications/useNotifications'; import SidebarNavigation from 'pl-fe/components/sidebar-navigation'; import ThumbNavigation from 'pl-fe/components/thumb-navigation'; import { Layout } from 'pl-fe/components/ui'; -import { useAppDispatch, useAppSelector, useOwnAccount, usePlFeConfig, useFeatures, useDraggedFiles, useInstance, useLoggedIn } from 'pl-fe/hooks'; +import { useAppDispatch, useAppSelector, useOwnAccount, usePlFeConfig, useFeatures, useDraggedFiles, useInstance, useLoggedIn, useClient, useSettings } from 'pl-fe/hooks'; import AdminLayout from 'pl-fe/layouts/admin-layout'; import ChatsLayout from 'pl-fe/layouts/chats-layout'; import DefaultLayout from 'pl-fe/layouts/default-layout'; @@ -38,6 +39,8 @@ import { useDropdownMenuStore } from 'pl-fe/stores'; import { getVapidKey } from 'pl-fe/utils/auth'; import { isStandalone } from 'pl-fe/utils/state'; +import { FILTER_TYPES } from '../notifications'; + import BackgroundShapes from './components/background-shapes'; import { Status, @@ -135,6 +138,8 @@ import { import GlobalHotkeys from './util/global-hotkeys'; import { WrappedRoute } from './util/react-router-helpers'; +import type { NotificationType } from 'pl-fe/utils/notification'; + // Dummy import, to make sure that ends up in the application bundle. // Without this it ends up in ~8 very commonly used bundles. import 'pl-fe/components/status'; @@ -344,6 +349,7 @@ interface IUI { } const UI: React.FC = ({ children }) => { + const client = useClient(); const history = useHistory(); const dispatch = useAppDispatch(); const node = useRef(null); @@ -351,6 +357,7 @@ const UI: React.FC = ({ children }) => { const { account } = useOwnAccount(); const features = useFeatures(); const vapidKey = useAppSelector(state => getVapidKey(state)); + const notificationFilter = useSettings().notifications.quickFilter.active as FilterType; const { isOpen: dropdownMenuIsOpen } = useDropdownMenuStore(); const standalone = useAppSelector(isStandalone); @@ -372,6 +379,9 @@ const UI: React.FC = ({ children }) => { /** Load initial data when a user is logged in */ const loadAccountData = () => { + const notificationsParams = notificationFilter === 'all' ? {} : { + types: FILTER_TYPES[notificationFilter] || [notificationFilter] as Array, + }; if (!account) return; dispatch(fetchDraftStatuses()); @@ -380,8 +390,7 @@ const UI: React.FC = ({ children }) => { dispatch(fetchSuggestionsForTimeline()); })); - dispatch(expandNotifications()) - // @ts-ignore + prefetchNotifications(client, notificationsParams) .then(() => dispatch(fetchMarker(['notifications']))) .catch(console.error); diff --git a/packages/pl-fe/src/pl-hooks/README.md b/packages/pl-fe/src/pl-hooks/README.md new file mode 100644 index 000000000..b823d8b38 --- /dev/null +++ b/packages/pl-fe/src/pl-hooks/README.md @@ -0,0 +1 @@ +everything that's temporarily placed here is supposed to land in the [pl-hooks](../../../pl-hooks/README.md) package \ No newline at end of file diff --git a/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotification.ts b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotification.ts new file mode 100644 index 000000000..9b65e8f37 --- /dev/null +++ b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotification.ts @@ -0,0 +1,122 @@ +import { useQuery } from '@tanstack/react-query'; +import omit from 'lodash/omit'; + +import { useAppSelector, useClient } from 'pl-fe/hooks'; +import { normalizeNotification, type Notification } from 'pl-fe/normalizers'; +import { queryClient } from 'pl-fe/queries/client'; +import { selectAccount, selectAccounts } from 'pl-fe/selectors'; + +import type { AccountWarning, RelationshipSeveranceEvent } from 'pl-api'; + +type Account = ReturnType; + +const minifyNotification = (notification: Notification) => { + // @ts-ignore + const minifiedNotification: { + duplicate: boolean; + account_id: string; + account_ids: string[]; + created_at: string; + id: string; + group_key: string; + } & ( + | { type: 'follow' | 'follow_request' | 'admin.sign_up' | 'bite' } + | { + type: 'mention'; + subtype?: 'reply'; + status_id: string; + } + | { + type: 'status' | 'reblog' | 'favourite' | 'poll' | 'update' | 'event_reminder'; + status_id: string; + } + | { + type: 'admin.report'; + report: Report; + } + | { + type: 'severed_relationships'; + relationship_severance_event: RelationshipSeveranceEvent; + } + | { + type: 'moderation_warning'; + moderation_warning: AccountWarning; + } + | { + type: 'move'; + target_id: string; + } + | { + type: 'emoji_reaction'; + emoji: string; + emoji_url: string | null; + status_id: string; + } + | { + type: 'chat_mention'; + chat_message_id: string; + } + | { + type: 'participation_accepted' | 'participation_request'; + status_id: string; + participation_message: string | null; + } + ) = { + ...omit(notification, ['account', 'accounts']), + created_at: notification.created_at, + id: notification.id, + type: notification.type, + }; + + // @ts-ignore + if (notification.status) minifiedNotification.status_id = notification.status.id; + // @ts-ignore + if (notification.target) minifiedNotification.target_id = notification.target.id; + // @ts-ignore + if (notification.chat_message) minifiedNotification.chat_message_id = notification.chat_message.id; + + return minifiedNotification; +}; + +type MinifiedNotification = ReturnType; + +const importNotification = (notification: MinifiedNotification) => { + queryClient.setQueryData( + ['notifications', 'entities', notification.id], + existingNotification => existingNotification?.duplicate ? existingNotification : notification, + ); +}; + +const useNotification = (notificationId: string) => { + const client = useClient(); + + const notificationQuery = useQuery({ + queryKey: ['notifications', 'entities', notificationId], + queryFn: () => client.notifications.getNotification(notificationId) + .then(normalizeNotification) + .then(minifyNotification), + }); + + const data: Notification | null = useAppSelector((state) => { + const notification = notificationQuery.data; + if (!notification) return null; + const account = selectAccount(state, notification.account_id)!; + // @ts-ignore + const target = selectAccount(state, notification.target_id)!; + // @ts-ignore + const status = state.statuses.get(notification.status_id)!; + const accounts = selectAccounts(state, notification.account_ids).filter((account): account is Account => account !== undefined); + + return { + ...notification, + account, + target, + status, + accounts, + }; + }); + + return { ...notificationQuery, data }; +}; + +export { useNotification, importNotification, minifyNotification }; diff --git a/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts new file mode 100644 index 000000000..47bc5f4cd --- /dev/null +++ b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts @@ -0,0 +1,94 @@ +import { useInfiniteQuery } from '@tanstack/react-query'; + +import { importFetchedAccounts, importFetchedStatuses } from 'pl-fe/actions/importer'; +import { useClient } from 'pl-fe/hooks'; +import { normalizeNotifications } from 'pl-fe/normalizers'; +import { queryClient } from 'pl-fe/queries/client'; +import { AppDispatch, store } from 'pl-fe/store'; +import { flattenPages } from 'pl-fe/utils/queries'; + +import { importNotification, minifyNotification } from './useNotification'; + +import type { + Account as BaseAccount, + Notification as BaseNotification, + PaginatedResponse, + PlApiClient, + Status as BaseStatus, +} from 'pl-api'; +import type { NotificationType } from 'pl-fe/utils/notification'; + + +type UseNotificationParams = { + types?: Array; + excludeTypes?: Array; +} + +const getQueryKey = (params: UseNotificationParams) => [ + 'notifications', + params.types ? params.types.join('|') : params.excludeTypes ? ('exclude:' + params.excludeTypes.join('|')) : 'all', +]; + +const importNotifications = (response: PaginatedResponse) => { + const accounts: Record = {}; + const statuses: Record = {}; + + response.items.forEach((notification) => { + accounts[notification.account.id] = notification.account; + + if (notification.type === 'move') accounts[notification.target.id] = notification.target; + + // @ts-ignore + if (notification.status?.id) { + // @ts-ignore + statuses[notification.status.id] = notification.status; + } + }); + + store.dispatch(importFetchedStatuses(Object.values(statuses))); + store.dispatch(importFetchedAccounts(Object.values(accounts))); + + const normalizedNotifications = normalizeNotifications(response.items); + + normalizedNotifications.map(minifyNotification).forEach(importNotification); + + return { + items: normalizedNotifications.filter(({ duplicate }) => !duplicate).map(({ id }) => id), + previous: response.previous, + next: response.next, + }; +}; + +const useNotifications = (params: UseNotificationParams) => { + const client = useClient(); + + const notificationsQuery = useInfiniteQuery({ + queryKey: getQueryKey(params), + queryFn: ({ pageParam }) => (pageParam.next ? pageParam.next() : client.notifications.getNotifications({ + types: params.types, + exclude_types: params.excludeTypes, + })).then(importNotifications), + initialPageParam: { previous: null, next: null } as Pick, 'previous' | 'next'>, + getNextPageParam: (response) => response, + }); + + const data = flattenPages(notificationsQuery.data) || []; + + return { + ...notificationsQuery, + data, + }; +}; + +const prefetchNotifications = (client: PlApiClient, params: UseNotificationParams) => + queryClient.prefetchInfiniteQuery({ + queryKey: getQueryKey(params), + queryFn: ({ pageParam }) => (pageParam.next ? pageParam.next() : client.notifications.getNotifications({ + types: params.types, + exclude_types: params.excludeTypes, + })).then(importNotifications), + initialPageParam: { previous: null, next: null } as Pick, 'previous' | 'next'>, + getNextPageParam: (response) => response, + }); + +export { useNotifications, prefetchNotifications }; diff --git a/packages/pl-fe/src/pl-hooks/importer.ts b/packages/pl-fe/src/pl-hooks/importer.ts new file mode 100644 index 000000000..6f4105dc5 --- /dev/null +++ b/packages/pl-fe/src/pl-hooks/importer.ts @@ -0,0 +1,48 @@ +import type { + Account as BaseAccount, + Group as BaseGroup, + Notification as BaseNotification, + Poll as BasePoll, + Status as BaseStatus, +} from 'pl-api'; + +const importEntities = (entities: { + accounts?: Array; + notifications?: Array; + statuses?: Array; +}) => { + const accounts: Record = {}; + const groups: Record = {}; + const notifications: Record = {}; + const polls: Record = {}; + const statuses: Record = {}; + + const processAccount = (account: BaseAccount) => { + accounts[account.id] = account; + if (account.moved) processAccount(account.moved); + }; + + const processNotification = (notification: BaseNotification) => { + notifications[notification.id] = notification; + + processAccount(notification.account); + if (notification.type === 'move') processAccount(notification.target); + + if (['mention', 'status', 'reblog', 'favourite', 'poll', 'update', 'emoji_reaction', 'event_reminder', 'participation_accepted', 'participation_request'].includes(notification.type)) + // @ts-ignore + processStatus(notification.status); + }; + + const processStatus = (status: BaseStatus) => { + statuses[status.id] = status; + + if (status.quote) processStatus(status.quote); + if (status.reblog) processStatus(status.reblog); + }; + + entities.accounts?.forEach(processAccount); + entities.notifications?.forEach(processNotification); + entities.statuses?.forEach(processStatus); +}; + +export { importEntities }; diff --git a/packages/pl-fe/src/reducers/notifications.ts b/packages/pl-fe/src/reducers/notifications.ts index 5106c12f9..bf7b3a903 100644 --- a/packages/pl-fe/src/reducers/notifications.ts +++ b/packages/pl-fe/src/reducers/notifications.ts @@ -14,9 +14,6 @@ import { } from '../actions/markers'; import { NOTIFICATIONS_UPDATE, - NOTIFICATIONS_EXPAND_SUCCESS, - NOTIFICATIONS_EXPAND_REQUEST, - NOTIFICATIONS_EXPAND_FAIL, NOTIFICATIONS_FILTER_SET, NOTIFICATIONS_CLEAR, NOTIFICATIONS_SCROLL_TOP, @@ -27,7 +24,7 @@ import { } from '../actions/notifications'; import { TIMELINE_DELETE } from '../actions/timelines'; -import type { AccountWarning, Notification as BaseNotification, Markers, PaginatedResponse, Relationship, RelationshipSeveranceEvent, Report } from 'pl-api'; +import type { AccountWarning, Notification as BaseNotification, Markers, Relationship, RelationshipSeveranceEvent, Report } from 'pl-api'; import type { Notification } from 'pl-fe/normalizers'; import type { AnyAction } from 'redux'; @@ -149,17 +146,6 @@ const importNotification = (state: State, notification: Notification) => { }); }; -const expandNormalizedNotifications = (state: State, notifications: Notification[], next: (() => Promise>) | null) => { - const items = ImmutableOrderedMap(notifications.map(minifyNotification).map(n => [n.id, n])); - - return state.withMutations(mutable => { - mutable.update('items', map => map.merge(items).sort(comparator)); - - if (!next) mutable.set('hasMore', false); - mutable.set('isLoading', false); - }); -}; - const filterNotifications = (state: State, relationship: Relationship) => state.update('items', map => map.filterNot(item => item !== null && item.account_ids.includes(relationship.id))); @@ -217,11 +203,6 @@ const importMarker = (state: State, marker: Markers) => { const notifications = (state: State = ReducerRecord(), action: AnyAction) => { switch (action.type) { - case NOTIFICATIONS_EXPAND_REQUEST: - return state.set('isLoading', true); - case NOTIFICATIONS_EXPAND_FAIL: - if (action.error?.message === 'canceled') return state; - return state.set('isLoading', false); case NOTIFICATIONS_FILTER_SET: return state.set('items', ImmutableOrderedMap()).set('hasMore', true); case NOTIFICATIONS_SCROLL_TOP: @@ -235,8 +216,6 @@ const notifications = (state: State = ReducerRecord(), action: AnyAction) => { mutable.delete('queuedNotifications'); mutable.set('totalQueuedNotificationsCount', 0); }); - case NOTIFICATIONS_EXPAND_SUCCESS: - return expandNormalizedNotifications(state, action.notifications, action.next); case ACCOUNT_BLOCK_SUCCESS: return filterNotifications(state, action.relationship); case ACCOUNT_MUTE_SUCCESS: diff --git a/packages/pl-fe/src/selectors/index.ts b/packages/pl-fe/src/selectors/index.ts index 490e43f47..b84bac052 100644 --- a/packages/pl-fe/src/selectors/index.ts +++ b/packages/pl-fe/src/selectors/index.ts @@ -15,14 +15,11 @@ import { shouldFilter } from 'pl-fe/utils/timelines'; import type { Account as BaseAccount, Filter, MediaAttachment } from 'pl-api'; import type { EntityStore } from 'pl-fe/entity-store/types'; -import type { Account, Group, Notification } from 'pl-fe/normalizers'; -import type { MinifiedNotification } from 'pl-fe/reducers/notifications'; +import type { Account, Group } from 'pl-fe/normalizers'; import type { MinifiedStatus } from 'pl-fe/reducers/statuses'; import type { MRFSimple } from 'pl-fe/schemas/pleroma'; import type { RootState } from 'pl-fe/store'; -const normalizeId = (id: any): string => typeof id === 'string' ? id : typeof id === 'object' ? normalizeId(id.id) : ''; - const selectAccount = (state: RootState, accountId: string) => state.entities[Entities.ACCOUNTS]?.store[accountId] as Account | undefined; @@ -176,27 +173,6 @@ const makeGetStatus = () => createSelector( type SelectedStatus = Exclude>, null>; -const makeGetNotification = () => createSelector([ - (_state: RootState, notification: MinifiedNotification) => notification, - // @ts-ignore - (state: RootState, notification: MinifiedNotification) => selectAccount(state, normalizeId(notification.account_id)), - // @ts-ignore - (state: RootState, notification: MinifiedNotification) => selectAccount(state, normalizeId(notification.target_id)), - // @ts-ignore - (state: RootState, notification: MinifiedNotification) => state.statuses.get(normalizeId(notification.status_id)), - (state: RootState, notification: MinifiedNotification) => notification.account_ids ? selectAccounts(state, notification.account_ids?.map(normalizeId)) : null, -], (notification, account, target, status, accounts): Notification => ({ - ...notification, - // @ts-ignore - account: account || null, - // @ts-ignore - target: target || null, - // @ts-ignore - status: status || null, - // @ts-ignore - accounts, -})); - type AccountGalleryAttachment = MediaAttachment & { status: MinifiedStatus; account: BaseAccount; @@ -357,7 +333,6 @@ export { regexFromFilters, makeGetStatus, type SelectedStatus, - makeGetNotification, type AccountGalleryAttachment, getAccountGallery, getGroupGallery, diff --git a/packages/pl-fe/src/utils/queries.ts b/packages/pl-fe/src/utils/queries.ts index 7cae4da8b..4221d1e31 100644 --- a/packages/pl-fe/src/utils/queries.ts +++ b/packages/pl-fe/src/utils/queries.ts @@ -18,9 +18,9 @@ const deduplicateById = (entities: T[]): T[] => { }; /** Flatten paginated results into a single array. */ -const flattenPages = (queryData: InfiniteData> | undefined) => { +const flattenPages = (queryData: InfiniteData, 'items'>> | undefined) => { const data = queryData?.pages.reduce( - (prev: T[], curr) => [...prev, ...((curr as any).result || (curr as any).items)], + (prev: T[], curr) => [...prev, ...(curr.items)], [], ); diff --git a/packages/pl-fe/yarn.lock b/packages/pl-fe/yarn.lock index a13e76c4a..d1ab5ddb6 100644 --- a/packages/pl-fe/yarn.lock +++ b/packages/pl-fe/yarn.lock @@ -11105,10 +11105,10 @@ typescript@^4.5.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== -typescript@^5.4.5: - version "5.4.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" - integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== +typescript@^5.6.2: + version "5.6.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0" + integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw== unbox-primitive@^1.0.2: version "1.0.2" diff --git a/packages/pl-hooks/.eslintignore b/packages/pl-hooks/.eslintignore new file mode 100644 index 000000000..256b5ff45 --- /dev/null +++ b/packages/pl-hooks/.eslintignore @@ -0,0 +1,7 @@ +/node_modules/** +/dist/** +/static/** +/public/** +/tmp/** +/coverage/** +/custom/** diff --git a/packages/pl-hooks/.eslintrc.json b/packages/pl-hooks/.eslintrc.json new file mode 100644 index 000000000..15ab81b31 --- /dev/null +++ b/packages/pl-hooks/.eslintrc.json @@ -0,0 +1,214 @@ +{ + "root": true, + "extends": [ + "eslint:recommended", + "plugin:import/typescript", + "plugin:compat/recommended" + ], + "env": { + "browser": true, + "node": true, + "es6": true, + "jest": true + }, + "globals": { + "ATTACHMENT_HOST": false + }, + "plugins": [ + "import", + "promise", + "@typescript-eslint" + ], + "parserOptions": { + "sourceType": "module", + "ecmaFeatures": { + "experimentalObjectRestSpread": true + }, + "ecmaVersion": 2018 + }, + "settings": { + "import/extensions": [ + ".js", + ".cjs", + ".mjs", + ".ts" + ], + "import/ignore": [ + "node_modules", + "\\.(css|scss|json)$" + ], + "import/resolver": { + "typescript": true, + "node": true + }, + "polyfills": [ + "es:all", + "fetch", + "IntersectionObserver", + "Promise", + "ResizeObserver", + "URL", + "URLSearchParams" + ], + "tailwindcss": { + "config": "tailwind.config.ts" + } + }, + "rules": { + "brace-style": "error", + "comma-dangle": [ + "error", + "always-multiline" + ], + "comma-spacing": [ + "warn", + { + "before": false, + "after": true + } + ], + "comma-style": [ + "warn", + "last" + ], + "import/no-duplicates": "error", + "space-before-function-paren": [ + "error", + "never" + ], + "space-infix-ops": "error", + "space-in-parens": [ + "error", + "never" + ], + "keyword-spacing": "error", + "dot-notation": "error", + "eqeqeq": "error", + "indent": [ + "error", + 2, + { + "SwitchCase": 1, + "ignoredNodes": [ + "TemplateLiteral" + ] + } + ], + "key-spacing": [ + "error", + { + "mode": "minimum" + } + ], + "no-catch-shadow": "error", + "no-cond-assign": "error", + "no-console": [ + "warn", + { + "allow": [ + "error", + "warn" + ] + } + ], + "no-extra-semi": "error", + "no-const-assign": "error", + "no-fallthrough": "error", + "no-irregular-whitespace": "error", + "no-loop-func": "error", + "no-mixed-spaces-and-tabs": "error", + "no-nested-ternary": "warn", + "no-trailing-spaces": "warn", + "no-undef": "error", + "no-unreachable": "error", + "no-unused-expressions": "error", + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": [ + "error", + { + "vars": "all", + "args": "none", + "ignoreRestSiblings": true + } + ], + "no-useless-escape": "warn", + "no-var": "error", + "object-curly-spacing": [ + "error", + "always" + ], + "padded-blocks": [ + "error", + { + "classes": "always" + } + ], + "prefer-const": "error", + "quotes": [ + "error", + "single" + ], + "semi": "error", + "space-unary-ops": [ + "error", + { + "words": true, + "nonwords": false + } + ], + "strict": "off", + "valid-typeof": "error", + "import/extensions": [ + "error", + "always", + { + "js": "never", + "mjs": "ignorePackages", + "ts": "never" + } + ], + "import/newline-after-import": "error", + "import/no-extraneous-dependencies": "error", + "import/no-unresolved": "error", + "import/no-webpack-loader-syntax": "error", + "import/order": [ + "error", + { + "groups": [ + "builtin", + "external", + "internal", + "parent", + "sibling", + "index", + "object", + "type" + ], + "newlines-between": "always", + "alphabetize": { + "order": "asc" + } + } + ], + "@typescript-eslint/member-delimiter-style": "error", + "promise/catch-or-return": "error", + "sort-imports": [ + "error", + { + "ignoreCase": true, + "ignoreDeclarationSort": true + } + ], + "eol-last": "error" + }, + "overrides": [ + { + "files": ["**/*.ts"], + "rules": { + "no-undef": "off", + "space-before-function-paren": "off" + }, + "parser": "@typescript-eslint/parser" + } + ] +} \ No newline at end of file diff --git a/packages/pl-hooks/.gitignore b/packages/pl-hooks/.gitignore new file mode 100644 index 000000000..a547bf36d --- /dev/null +++ b/packages/pl-hooks/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/packages/pl-hooks/README.md b/packages/pl-hooks/README.md new file mode 100644 index 000000000..6055266a7 --- /dev/null +++ b/packages/pl-hooks/README.md @@ -0,0 +1,18 @@ +# `pl-hooks` + +> This project should be considered unstable before the 1.0.0 release. I will not provide any changelog or information on breaking changes until then. + +## License + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . \ No newline at end of file diff --git a/packages/pl-hooks/index.html b/packages/pl-hooks/index.html new file mode 100644 index 000000000..9292e94f9 --- /dev/null +++ b/packages/pl-hooks/index.html @@ -0,0 +1,11 @@ + + + + + + pl-hooks + + + + + diff --git a/packages/pl-hooks/lib/main.ts b/packages/pl-hooks/lib/main.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/pl-hooks/package.json b/packages/pl-hooks/package.json new file mode 100644 index 000000000..22fa86cd1 --- /dev/null +++ b/packages/pl-hooks/package.json @@ -0,0 +1,40 @@ +{ + "name": "pl-hooks", + "version": "0.0.1", + "type": "module", + "homepage": "https://github.com/mkljczk/pl-fe/tree/fork/packages/pl-hooks", + "repository": { + "type": "git", + "url": "https://github.com/mkljczk/pl-fe" + }, + "bugs": { + "url": "https://github.com/mkljczk/pl-fe/issues" + }, + "scripts": { + "dev": "vite", + "build": "tsc --p ./tsconfig-build.json && vite build", + "preview": "vite preview", + "lint": "npx eslint --ext .js,.jsx,.cjs,.mjs,.ts,.tsx . --cache" + }, + "license": "AGPL-3.0-or-later", + "devDependencies": { + "@types/node": "^20.14.12", + "@typescript-eslint/eslint-plugin": "^7.18.0", + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.49.0", + "eslint-import-resolver-typescript": "^3.6.3", + "eslint-plugin-compat": "^6.0.1", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-promise": "^6.0.0", + "typescript": "^5.6.2", + "vite": "^5.4.0", + "vite-plugin-dts": "^4.2.1" + }, + "dependencies": { + }, + "module": "./dist/main.es.js", + "types": "dist/main.d.ts", + "files": [ + "dist" + ] +} diff --git a/packages/pl-hooks/tsconfig-build.json b/packages/pl-hooks/tsconfig-build.json new file mode 100644 index 000000000..160480b19 --- /dev/null +++ b/packages/pl-hooks/tsconfig-build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "include": ["lib"] + } \ No newline at end of file diff --git a/packages/pl-hooks/tsconfig.json b/packages/pl-hooks/tsconfig.json new file mode 100644 index 000000000..dc67c03f5 --- /dev/null +++ b/packages/pl-hooks/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src", "lib"] +} diff --git a/packages/pl-hooks/vite.config.ts b/packages/pl-hooks/vite.config.ts new file mode 100644 index 000000000..79e513c5f --- /dev/null +++ b/packages/pl-hooks/vite.config.ts @@ -0,0 +1,19 @@ +import { resolve } from 'path'; + +import { defineConfig } from 'vite'; +import dts from 'vite-plugin-dts'; + +export default defineConfig({ + plugins: [dts({ include: ['lib'], insertTypesEntry: true })], + build: { + copyPublicDir: false, + lib: { + entry: resolve(__dirname, 'lib/main.ts'), + fileName: (format) => `main.${format}.js`, + formats: ['es'], + name: 'pl-api', + }, + target: 'esnext', + sourcemap: true, + }, +}); diff --git a/packages/pl-hooks/yarn.lock b/packages/pl-hooks/yarn.lock new file mode 100644 index 000000000..82877a665 --- /dev/null +++ b/packages/pl-hooks/yarn.lock @@ -0,0 +1,2556 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/parser@^7.24.7": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.0.tgz#9fdc9237504d797b6e7b8f66e78ea7f570d256ad" + integrity sha512-CzdIU9jdP0dg7HdyB+bHvDJGagUv+qtzZt5rYCWwW6tITNqV9odjp6Qu41gkG0ca5UfdDUWrKkiAnHHdGRnOrA== + +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.6.1": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz#b0ffd0312b4a3fd2d6f77237e7248a5ad3a680ae" + integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A== + +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.57.0": + version "8.57.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" + integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== + +"@humanwhocodes/config-array@^0.11.14": + version "0.11.14" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" + integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== + dependencies: + "@humanwhocodes/object-schema" "^2.0.2" + debug "^4.3.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" + integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== + +"@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@mdn/browser-compat-data@^5.2.34", "@mdn/browser-compat-data@^5.5.35": + version "5.6.2" + resolved "https://registry.yarnpkg.com/@mdn/browser-compat-data/-/browser-compat-data-5.6.2.tgz#f98f8fea544f26fa9cda6f22ab8053ef295dc281" + integrity sha512-U/93wDghb2w/vwRO9vw+DiTi+y7AdVcABMJqDqVO4GqKfqB/NbVlmbYPzU0ZUXEVpy7H6SStyqarHFKlZqSPdg== + +"@microsoft/api-extractor-model@7.29.6": + version "7.29.6" + resolved "https://registry.yarnpkg.com/@microsoft/api-extractor-model/-/api-extractor-model-7.29.6.tgz#e5941514502049b06ca9af21e2096f8f1ad5a01b" + integrity sha512-gC0KGtrZvxzf/Rt9oMYD2dHvtN/1KPEYsrQPyMKhLHnlVuO/f4AFN3E4toqZzD2pt4LhkKoYmL2H9tX3yCOyRw== + dependencies: + "@microsoft/tsdoc" "~0.15.0" + "@microsoft/tsdoc-config" "~0.17.0" + "@rushstack/node-core-library" "5.7.0" + +"@microsoft/api-extractor@7.47.7": + version "7.47.7" + resolved "https://registry.yarnpkg.com/@microsoft/api-extractor/-/api-extractor-7.47.7.tgz#3bc4450fe46c265bef857ab938aa15b9fc7a85de" + integrity sha512-fNiD3G55ZJGhPOBPMKD/enozj8yxJSYyVJWxRWdcUtw842rvthDHJgUWq9gXQTensFlMHv2wGuCjjivPv53j0A== + dependencies: + "@microsoft/api-extractor-model" "7.29.6" + "@microsoft/tsdoc" "~0.15.0" + "@microsoft/tsdoc-config" "~0.17.0" + "@rushstack/node-core-library" "5.7.0" + "@rushstack/rig-package" "0.5.3" + "@rushstack/terminal" "0.14.0" + "@rushstack/ts-command-line" "4.22.6" + lodash "~4.17.15" + minimatch "~3.0.3" + resolve "~1.22.1" + semver "~7.5.4" + source-map "~0.6.1" + typescript "5.4.2" + +"@microsoft/tsdoc-config@~0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@microsoft/tsdoc-config/-/tsdoc-config-0.17.0.tgz#82605152b3c1d3f5cd4a11697bc298437484d55d" + integrity sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg== + dependencies: + "@microsoft/tsdoc" "0.15.0" + ajv "~8.12.0" + jju "~1.4.0" + resolve "~1.22.2" + +"@microsoft/tsdoc@0.15.0", "@microsoft/tsdoc@~0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz#f29a55df17cb6e87cfbabce33ff6a14a9f85076d" + integrity sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@nolyfill/is-core-module@1.0.39": + version "1.0.39" + resolved "https://registry.yarnpkg.com/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz#3dc35ba0f1e66b403c00b39344f870298ebb1c8e" + integrity sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA== + +"@rollup/pluginutils@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" + integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" + +"@rollup/rollup-android-arm-eabi@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz#8b613b9725e8f9479d142970b106b6ae878610d5" + integrity sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w== + +"@rollup/rollup-android-arm64@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz#654ca1049189132ff602bfcf8df14c18da1f15fb" + integrity sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA== + +"@rollup/rollup-darwin-arm64@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz#6d241d099d1518ef0c2205d96b3fa52e0fe1954b" + integrity sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q== + +"@rollup/rollup-darwin-x64@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz#42bd19d292a57ee11734c980c4650de26b457791" + integrity sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw== + +"@rollup/rollup-linux-arm-gnueabihf@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz#f23555ee3d8fe941c5c5fd458cd22b65eb1c2232" + integrity sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ== + +"@rollup/rollup-linux-arm-musleabihf@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz#f3bbd1ae2420f5539d40ac1fde2b38da67779baa" + integrity sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg== + +"@rollup/rollup-linux-arm64-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz#7abe900120113e08a1f90afb84c7c28774054d15" + integrity sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw== + +"@rollup/rollup-linux-arm64-musl@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz#9e655285c8175cd44f57d6a1e8e5dedfbba1d820" + integrity sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA== + +"@rollup/rollup-linux-powerpc64le-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz#9a79ae6c9e9d8fe83d49e2712ecf4302db5bef5e" + integrity sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg== + +"@rollup/rollup-linux-riscv64-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz#67ac70eca4ace8e2942fabca95164e8874ab8128" + integrity sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA== + +"@rollup/rollup-linux-s390x-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz#9f883a7440f51a22ed7f99e1d070bd84ea5005fc" + integrity sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q== + +"@rollup/rollup-linux-x64-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz#70116ae6c577fe367f58559e2cffb5641a1dd9d0" + integrity sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg== + +"@rollup/rollup-linux-x64-musl@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz#f473f88219feb07b0b98b53a7923be716d1d182f" + integrity sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g== + +"@rollup/rollup-win32-arm64-msvc@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz#4349482d17f5d1c58604d1c8900540d676f420e0" + integrity sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw== + +"@rollup/rollup-win32-ia32-msvc@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz#a6fc39a15db618040ec3c2a24c1e26cb5f4d7422" + integrity sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g== + +"@rollup/rollup-win32-x64-msvc@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz#3dd5d53e900df2a40841882c02e56f866c04d202" + integrity sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q== + +"@rushstack/node-core-library@5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@rushstack/node-core-library/-/node-core-library-5.7.0.tgz#f28699c7d0b3de0120a207f8b9d5bd7c69806e18" + integrity sha512-Ff9Cz/YlWu9ce4dmqNBZpA45AEya04XaBFIjV7xTVeEf+y/kTjEasmozqFELXlNG4ROdevss75JrrZ5WgufDkQ== + dependencies: + ajv "~8.13.0" + ajv-draft-04 "~1.0.0" + ajv-formats "~3.0.1" + fs-extra "~7.0.1" + import-lazy "~4.0.0" + jju "~1.4.0" + resolve "~1.22.1" + semver "~7.5.4" + +"@rushstack/rig-package@0.5.3": + version "0.5.3" + resolved "https://registry.yarnpkg.com/@rushstack/rig-package/-/rig-package-0.5.3.tgz#ea4d8a3458540b1295500149c04e645f23134e5d" + integrity sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow== + dependencies: + resolve "~1.22.1" + strip-json-comments "~3.1.1" + +"@rushstack/terminal@0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@rushstack/terminal/-/terminal-0.14.0.tgz#967ecc586d7172204353059f8fdb1760666e9381" + integrity sha512-juTKMAMpTIJKudeFkG5slD8Z/LHwNwGZLtU441l/u82XdTBfsP+LbGKJLCNwP5se+DMCT55GB8x9p6+C4UL7jw== + dependencies: + "@rushstack/node-core-library" "5.7.0" + supports-color "~8.1.1" + +"@rushstack/ts-command-line@4.22.6": + version "4.22.6" + resolved "https://registry.yarnpkg.com/@rushstack/ts-command-line/-/ts-command-line-4.22.6.tgz#2aee4fc98c6043c026ce278880fbffb5227de5ca" + integrity sha512-QSRqHT/IfoC5nk9zn6+fgyqOPXHME0BfchII9EUPR19pocsNp/xSbeBCbD3PIR2Lg+Q5qk7OFqk1VhWPMdKHJg== + dependencies: + "@rushstack/terminal" "0.14.0" + "@types/argparse" "1.0.38" + argparse "~1.0.9" + string-argv "~0.3.1" + +"@types/argparse@1.0.38": + version "1.0.38" + resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9" + integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA== + +"@types/estree@1.0.5", "@types/estree@^1.0.0": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/node@^20.14.12": + version "20.14.12" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.12.tgz#129d7c3a822cb49fc7ff661235f19cfefd422b49" + integrity sha512-r7wNXakLeSsGT0H1AU863vS2wa5wBOK4bWMjZz2wj+8nBx+m5PeIn0k8AloSLpRuiwdRQZwarZqHE4FNArPuJQ== + dependencies: + undici-types "~5.26.4" + +"@typescript-eslint/eslint-plugin@^7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz#b16d3cf3ee76bf572fdf511e79c248bdec619ea3" + integrity sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw== + dependencies: + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "7.18.0" + "@typescript-eslint/type-utils" "7.18.0" + "@typescript-eslint/utils" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" + graphemer "^1.4.0" + ignore "^5.3.1" + natural-compare "^1.4.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/parser@^7.0.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.17.0.tgz#be8e32c159190cd40a305a2121220eadea5a88e7" + integrity sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A== + dependencies: + "@typescript-eslint/scope-manager" "7.17.0" + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/typescript-estree" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz#e072d0f914662a7bfd6c058165e3c2b35ea26b9d" + integrity sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA== + dependencies: + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" + +"@typescript-eslint/scope-manager@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz#c928e7a9fc2c0b3ed92ab3112c614d6bd9951c83" + integrity sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA== + dependencies: + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" + +"@typescript-eslint/type-utils@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz#2165ffaee00b1fbbdd2d40aa85232dab6998f53b" + integrity sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA== + dependencies: + "@typescript-eslint/typescript-estree" "7.18.0" + "@typescript-eslint/utils" "7.18.0" + debug "^4.3.4" + ts-api-utils "^1.3.0" + +"@typescript-eslint/types@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.17.0.tgz#7ce8185bdf06bc3494e73d143dbf3293111b9cff" + integrity sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A== + +"@typescript-eslint/types@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.18.0.tgz#b90a57ccdea71797ffffa0321e744f379ec838c9" + integrity sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ== + +"@typescript-eslint/typescript-estree@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz#dcab3fea4c07482329dd6107d3c6480e228e4130" + integrity sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw== + dependencies: + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/typescript-estree@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz#b5868d486c51ce8f312309ba79bdb9f331b37931" + integrity sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA== + dependencies: + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/utils@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.18.0.tgz#bca01cde77f95fc6a8d5b0dbcbfb3d6ca4be451f" + integrity sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "7.18.0" + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/typescript-estree" "7.18.0" + +"@typescript-eslint/visitor-keys@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz#680465c734be30969e564b4647f38d6cdf49bfb0" + integrity sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A== + dependencies: + "@typescript-eslint/types" "7.17.0" + eslint-visitor-keys "^3.4.3" + +"@typescript-eslint/visitor-keys@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz#0564629b6124d67607378d0f0332a0495b25e7d7" + integrity sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg== + dependencies: + "@typescript-eslint/types" "7.18.0" + eslint-visitor-keys "^3.4.3" + +"@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + +"@volar/language-core@2.4.5", "@volar/language-core@~2.4.1": + version "2.4.5" + resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-2.4.5.tgz#af8ba724b05fc4dce2339c49662e732e9c22c897" + integrity sha512-F4tA0DCO5Q1F5mScHmca0umsi2ufKULAnMOVBfMsZdT4myhVl4WdKRwCaKcfOkIEuyrAVvtq1ESBdZ+rSyLVww== + dependencies: + "@volar/source-map" "2.4.5" + +"@volar/source-map@2.4.5": + version "2.4.5" + resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-2.4.5.tgz#81223a06321aaa067b40619189b44a9f0b7ac2d8" + integrity sha512-varwD7RaKE2J/Z+Zu6j3mNNJbNT394qIxXwdvz/4ao/vxOfyClZpSDtLKkwWmecinkOVos5+PWkWraelfMLfpw== + +"@volar/typescript@^2.4.4": + version "2.4.5" + resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-2.4.5.tgz#1210c1e8561ac20af46348ceaf8e6e96c797063f" + integrity sha512-mcT1mHvLljAEtHviVcBuOyAwwMKz1ibXTi5uYtP/pf4XxoAzpdkQ+Br2IC0NPCvLCbjPZmbf3I0udndkfB1CDg== + dependencies: + "@volar/language-core" "2.4.5" + path-browserify "^1.0.1" + vscode-uri "^3.0.8" + +"@vue/compiler-core@3.4.34": + version "3.4.34" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.34.tgz#4e6af7a00927284f1f67571e2e1a8a6e93ee2d1f" + integrity sha512-Z0izUf32+wAnQewjHu+pQf1yw00EGOmevl1kE+ljjjMe7oEfpQ+BI3/JNK7yMB4IrUsqLDmPecUrpj3mCP+yJQ== + dependencies: + "@babel/parser" "^7.24.7" + "@vue/shared" "3.4.34" + entities "^4.5.0" + estree-walker "^2.0.2" + source-map-js "^1.2.0" + +"@vue/compiler-dom@^3.4.0": + version "3.4.34" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.34.tgz#fd3b8df142b063c2cc0ec3e168b76b0d7774b78c" + integrity sha512-3PUOTS1h5cskdOJMExCu2TInXuM0j60DRPpSCJDqOCupCfUZCJoyQmKtRmA8EgDNZ5kcEE7vketamRZfrEuVDw== + dependencies: + "@vue/compiler-core" "3.4.34" + "@vue/shared" "3.4.34" + +"@vue/compiler-vue2@^2.7.16": + version "2.7.16" + resolved "https://registry.yarnpkg.com/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz#2ba837cbd3f1b33c2bc865fbe1a3b53fb611e249" + integrity sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A== + dependencies: + de-indent "^1.0.2" + he "^1.2.0" + +"@vue/language-core@2.1.6": + version "2.1.6" + resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-2.1.6.tgz#b48186bdb9b3ef2b83e1f76d5b1ac357b3a7ed94" + integrity sha512-MW569cSky9R/ooKMh6xa2g1D0AtRKbL56k83dzus/bx//RDJk24RHWkMzbAlXjMdDNyxAaagKPRquBIxkxlCkg== + dependencies: + "@volar/language-core" "~2.4.1" + "@vue/compiler-dom" "^3.4.0" + "@vue/compiler-vue2" "^2.7.16" + "@vue/shared" "^3.4.0" + computeds "^0.0.1" + minimatch "^9.0.3" + muggle-string "^0.4.1" + path-browserify "^1.0.1" + +"@vue/shared@3.4.34", "@vue/shared@^3.4.0": + version "3.4.34" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.34.tgz#130858419e634a427ca82c36e1da75c66a39ba8e" + integrity sha512-x5LmiRLpRsd9KTjAB8MPKf0CDPMcuItjP0gbNqFCIgL1I8iYp4zglhj9w9FPCdIbHG2M91RVeIbArFfFTz9I3A== + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^8.11.3, acorn@^8.9.0: + version "8.12.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== + +ajv-draft-04@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz#3b64761b268ba0b9e668f0b41ba53fce0ad77fc8" + integrity sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw== + +ajv-formats@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-3.0.1.tgz#3d5dc762bca17679c3c2ea7e90ad6b7532309578" + integrity sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ== + dependencies: + ajv "^8.0.0" + +ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + +ajv@~8.12.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ajv@~8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.13.0.tgz#a3939eaec9fb80d217ddf0c3376948c023f28c91" + integrity sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA== + dependencies: + fast-deep-equal "^3.1.3" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.4.1" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +argparse@~1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +array-buffer-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f" + integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg== + dependencies: + call-bind "^1.0.5" + is-array-buffer "^3.0.4" + +array-includes@^3.1.7: + version "3.1.8" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.8.tgz#5e370cbe172fdd5dd6530c1d4aadda25281ba97d" + integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.4" + is-string "^1.0.7" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array.prototype.findlastindex@^1.2.3: + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz#8c35a755c72908719453f87145ca011e39334d0d" + integrity sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-shim-unscopables "^1.0.2" + +array.prototype.flat@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" + integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.flatmap@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" + integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +arraybuffer.prototype.slice@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz#097972f4255e41bc3425e37dc3f6421cf9aefde6" + integrity sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A== + dependencies: + array-buffer-byte-length "^1.0.1" + call-bind "^1.0.5" + define-properties "^1.2.1" + es-abstract "^1.22.3" + es-errors "^1.2.1" + get-intrinsic "^1.2.3" + is-array-buffer "^3.0.4" + is-shared-array-buffer "^1.0.2" + +ast-metadata-inferer@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/ast-metadata-inferer/-/ast-metadata-inferer-0.8.0.tgz#0f94c3425e310d8da45823ab2161142e3f134343" + integrity sha512-jOMKcHht9LxYIEQu+RVd22vtgrPaVCtDRQ/16IGmurdzxvYbDd5ynxjnyrzLnieG96eTcAyaoj/wN/4/1FyyeA== + dependencies: + "@mdn/browser-compat-data" "^5.2.34" + +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +browserslist@^4.23.1: + version "4.23.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" + integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== + dependencies: + caniuse-lite "^1.0.30001646" + electron-to-chromium "^1.5.4" + node-releases "^2.0.18" + update-browserslist-db "^1.1.0" + +call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +caniuse-lite@^1.0.30001639, caniuse-lite@^1.0.30001646: + version "1.0.30001662" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001662.tgz#3574b22dfec54a3f3b6787331da1040fe8e763ec" + integrity sha512-sgMUVwLmGseH8ZIrm1d51UbrhqMCH3jvS7gF/M6byuHOnKyLOBL7W8yz5V02OHwgLGA36o/AFhWzzh4uc5aqTA== + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +compare-versions@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.1.1.tgz#7af3cc1099ba37d244b3145a9af5201b629148a9" + integrity sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg== + +computeds@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/computeds/-/computeds-0.0.1.tgz#215b08a4ba3e08a11ff6eee5d6d8d7166a97ce2e" + integrity sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +confbox@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.1.7.tgz#ccfc0a2bcae36a84838e83a3b7f770fb17d6c579" + integrity sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA== + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +data-view-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2" + integrity sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz#90721ca95ff280677eb793749fce1011347669e2" + integrity sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz#5e0bbfb4828ed2d1b9b400cd8a7d119bca0ff18a" + integrity sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +de-indent@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" + integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg== + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +define-data-property@^1.0.1, define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +define-properties@^1.2.0, define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +electron-to-chromium@^1.5.4: + version "1.5.27" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz#5203ce5d6054857d84ba84d3681cbe59132ade78" + integrity sha512-o37j1vZqCoEgBuWWXLHQgTN/KDKe7zwpiY5CPeq2RvUqOyJw9xnrULzZAEVQ5p4h+zjMk7hgtOoPdnLxr7m/jw== + +enhanced-resolve@^5.15.0: + version "5.17.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" + integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +entities@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.2: + version "1.23.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0" + integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== + dependencies: + array-buffer-byte-length "^1.0.1" + arraybuffer.prototype.slice "^1.0.3" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + data-view-buffer "^1.0.1" + data-view-byte-length "^1.0.1" + data-view-byte-offset "^1.0.0" + es-define-property "^1.0.0" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-set-tostringtag "^2.0.3" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.4" + get-symbol-description "^1.0.2" + globalthis "^1.0.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + has-proto "^1.0.3" + has-symbols "^1.0.3" + hasown "^2.0.2" + internal-slot "^1.0.7" + is-array-buffer "^3.0.4" + is-callable "^1.2.7" + is-data-view "^1.0.1" + is-negative-zero "^2.0.3" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.3" + is-string "^1.0.7" + is-typed-array "^1.1.13" + is-weakref "^1.0.2" + object-inspect "^1.13.1" + object-keys "^1.1.1" + object.assign "^4.1.5" + regexp.prototype.flags "^1.5.2" + safe-array-concat "^1.1.2" + safe-regex-test "^1.0.3" + string.prototype.trim "^1.2.9" + string.prototype.trimend "^1.0.8" + string.prototype.trimstart "^1.0.8" + typed-array-buffer "^1.0.2" + typed-array-byte-length "^1.0.1" + typed-array-byte-offset "^1.0.2" + typed-array-length "^1.0.6" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.15" + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.2.1, es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-object-atoms@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz#ddb55cd47ac2e240701260bc2a8e31ecb643d941" + integrity sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw== + dependencies: + es-errors "^1.3.0" + +es-set-tostringtag@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz#8bb60f0a440c2e4281962428438d58545af39777" + integrity sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ== + dependencies: + get-intrinsic "^1.2.4" + has-tostringtag "^1.0.2" + hasown "^2.0.1" + +es-shim-unscopables@^1.0.0, es-shim-unscopables@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== + dependencies: + hasown "^2.0.0" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +esbuild@^0.21.3: + version "0.21.5" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== + optionalDependencies: + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" + +escalade@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-import-resolver-node@^0.3.9: + version "0.3.9" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== + dependencies: + debug "^3.2.7" + is-core-module "^2.13.0" + resolve "^1.22.4" + +eslint-import-resolver-typescript@^3.6.3: + version "3.6.3" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.3.tgz#bb8e388f6afc0f940ce5d2c5fd4a3d147f038d9e" + integrity sha512-ud9aw4szY9cCT1EWWdGv1L1XR6hh2PaRWif0j2QjQ0pgTY/69iw+W0Z4qZv5wHahOl8isEr+k/JnyAqNQkLkIA== + dependencies: + "@nolyfill/is-core-module" "1.0.39" + debug "^4.3.5" + enhanced-resolve "^5.15.0" + eslint-module-utils "^2.8.1" + fast-glob "^3.3.2" + get-tsconfig "^4.7.5" + is-bun-module "^1.0.2" + is-glob "^4.0.3" + +eslint-module-utils@^2.8.0, eslint-module-utils@^2.8.1: + version "2.11.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.11.0.tgz#b99b211ca4318243f09661fae088f373ad5243c4" + integrity sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ== + dependencies: + debug "^3.2.7" + +eslint-plugin-compat@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-compat/-/eslint-plugin-compat-6.0.1.tgz#2852f41893802870a530b2ac087499b4556882b6" + integrity sha512-0MeIEuoy8kWkOhW38kK8hU4vkb6l/VvyjpuYDymYOXmUY9NvTgyErF16lYuX+HPS5hkmym7lfA+XpYZiWYWmYA== + dependencies: + "@mdn/browser-compat-data" "^5.5.35" + ast-metadata-inferer "^0.8.0" + browserslist "^4.23.1" + caniuse-lite "^1.0.30001639" + find-up "^5.0.0" + globals "^15.7.0" + lodash.memoize "^4.1.2" + semver "^7.6.2" + +eslint-plugin-import@^2.28.1: + version "2.29.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" + integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== + dependencies: + array-includes "^3.1.7" + array.prototype.findlastindex "^1.2.3" + array.prototype.flat "^1.3.2" + array.prototype.flatmap "^1.3.2" + debug "^3.2.7" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.9" + eslint-module-utils "^2.8.0" + hasown "^2.0.0" + is-core-module "^2.13.1" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.fromentries "^2.0.7" + object.groupby "^1.0.1" + object.values "^1.1.7" + semver "^6.3.1" + tsconfig-paths "^3.15.0" + +eslint-plugin-promise@^6.0.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz#acd3fd7d55cead7a10f92cf698f36c0aafcd717a" + integrity sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ== + +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint@^8.49.0: + version "8.57.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" + integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.57.0" + "@humanwhocodes/config-array" "^0.11.14" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esquery@^1.4.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.9, fast-glob@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fast-uri@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.1.tgz#cddd2eecfc83a71c1be2cc2ef2061331be8a7134" + integrity sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw== + +fastq@^1.6.0: + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.3" + rimraf "^3.0.2" + +flatted@^3.2.9: + version "3.3.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" + integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +fs-extra@~7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" + +functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-symbol-description@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz#533744d5aa20aca4e079c8e5daf7fd44202821f5" + integrity sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg== + dependencies: + call-bind "^1.0.5" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + +get-tsconfig@^4.7.5: + version "4.8.1" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.8.1.tgz#8995eb391ae6e1638d251118c7b56de7eb425471" + integrity sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg== + dependencies: + resolve-pkg-maps "^1.0.0" + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^13.19.0: + version "13.24.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== + dependencies: + type-fest "^0.20.2" + +globals@^15.7.0: + version "15.9.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-15.9.0.tgz#e9de01771091ffbc37db5714dab484f9f69ff399" + integrity sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA== + +globalthis@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" + integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== + dependencies: + define-properties "^1.2.1" + gopd "^1.0.1" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.4: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1, has-proto@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + +hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +ignore@^5.2.0, ignore@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-lazy@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153" + integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +internal-slot@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802" + integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== + dependencies: + es-errors "^1.3.0" + hasown "^2.0.0" + side-channel "^1.0.4" + +is-array-buffer@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz#7a1f92b3d61edd2bc65d24f130530ea93d7fae98" + integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-bun-module@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-bun-module/-/is-bun-module-1.2.1.tgz#495e706f42e29f086fd5fe1ac3c51f106062b9fc" + integrity sha512-AmidtEM6D6NmUiLOvvU7+IePxjEjOzra2h0pSrsfSAcXwl/83zLLXDByafUJy9k/rKK0pvXMLdwKwGHlX2Ke6Q== + dependencies: + semver "^7.6.3" + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.13.0, is-core-module@^2.13.1: + version "2.15.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.0.tgz#71c72ec5442ace7e76b306e9d48db361f22699ea" + integrity sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA== + dependencies: + hasown "^2.0.2" + +is-data-view@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.1.tgz#4b4d3a511b70f3dc26d42c03ca9ca515d847759f" + integrity sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w== + dependencies: + is-typed-array "^1.1.13" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-negative-zero@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" + integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz#1237f1cba059cdb62431d378dcc37d9680181688" + integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== + dependencies: + call-bind "^1.0.7" + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.13: + version "1.1.13" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" + integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== + dependencies: + which-typed-array "^1.1.14" + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +jju@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a" + integrity sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +kolorist@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/kolorist/-/kolorist-1.8.0.tgz#edddbbbc7894bc13302cdf740af6374d4a04743c" + integrity sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +local-pkg@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.5.0.tgz#093d25a346bae59a99f80e75f6e9d36d7e8c925c" + integrity sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg== + dependencies: + mlly "^1.4.2" + pkg-types "^1.0.3" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash@~4.17.15: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +magic-string@^0.30.11: + version "0.30.11" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.11.tgz#301a6f93b3e8c2cb13ac1a7a673492c0dfd12954" + integrity sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.7" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5" + integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^9.0.3, minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + +minimatch@~3.0.3: + version "3.0.8" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.8.tgz#5e6a59bd11e2ab0de1cfb843eb2d82e546c321c1" + integrity sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mlly@^1.4.2, mlly@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.7.1.tgz#e0336429bb0731b6a8e887b438cbdae522c8f32f" + integrity sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA== + dependencies: + acorn "^8.11.3" + pathe "^1.1.2" + pkg-types "^1.1.1" + ufo "^1.5.3" + +ms@^2.1.1, ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +muggle-string@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/muggle-string/-/muggle-string-0.4.1.tgz#3b366bd43b32f809dc20659534dd30e7c8a0d328" + integrity sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ== + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== + +object-inspect@^1.13.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== + dependencies: + call-bind "^1.0.5" + define-properties "^1.2.1" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.fromentries@^2.0.7: + version "2.0.8" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65" + integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + +object.groupby@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e" + integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + +object.values@^1.1.7: + version "1.2.0" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.0.tgz#65405a9d92cee68ac2d303002e0b8470a4d9ab1b" + integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +optionator@^0.9.3: + version "0.9.4" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.5" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pathe@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" + integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== + +picocolors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== + +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pkg-types@^1.0.3, pkg-types@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.1.3.tgz#161bb1242b21daf7795036803f28e30222e476e3" + integrity sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA== + dependencies: + confbox "^0.1.7" + mlly "^1.7.1" + pathe "^1.1.2" + +possible-typed-array-names@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" + integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== + +postcss@^8.4.40: + version "8.4.41" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.41.tgz#d6104d3ba272d882fe18fc07d15dc2da62fa2681" + integrity sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.1" + source-map-js "^1.2.0" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +regexp.prototype.flags@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" + integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== + dependencies: + call-bind "^1.0.6" + define-properties "^1.2.1" + es-errors "^1.3.0" + set-function-name "^2.0.1" + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + +resolve@^1.22.4, resolve@~1.22.1, resolve@~1.22.2: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rollup@^4.13.0: + version "4.22.4" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.22.4.tgz#4135a6446671cd2a2453e1ad42a45d5973ec3a0f" + integrity sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A== + dependencies: + "@types/estree" "1.0.5" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.22.4" + "@rollup/rollup-android-arm64" "4.22.4" + "@rollup/rollup-darwin-arm64" "4.22.4" + "@rollup/rollup-darwin-x64" "4.22.4" + "@rollup/rollup-linux-arm-gnueabihf" "4.22.4" + "@rollup/rollup-linux-arm-musleabihf" "4.22.4" + "@rollup/rollup-linux-arm64-gnu" "4.22.4" + "@rollup/rollup-linux-arm64-musl" "4.22.4" + "@rollup/rollup-linux-powerpc64le-gnu" "4.22.4" + "@rollup/rollup-linux-riscv64-gnu" "4.22.4" + "@rollup/rollup-linux-s390x-gnu" "4.22.4" + "@rollup/rollup-linux-x64-gnu" "4.22.4" + "@rollup/rollup-linux-x64-musl" "4.22.4" + "@rollup/rollup-win32-arm64-msvc" "4.22.4" + "@rollup/rollup-win32-ia32-msvc" "4.22.4" + "@rollup/rollup-win32-x64-msvc" "4.22.4" + fsevents "~2.3.2" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-array-concat@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb" + integrity sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q== + dependencies: + call-bind "^1.0.7" + get-intrinsic "^1.2.4" + has-symbols "^1.0.3" + isarray "^2.0.5" + +safe-regex-test@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377" + integrity sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-regex "^1.1.4" + +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.6.0, semver@^7.6.2, semver@^7.6.3: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + +semver@~7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +set-function-name@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" + integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map-js@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== + +source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +string-argv@~0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" + integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== + +string.prototype.trim@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4" + integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.0" + es-object-atoms "^1.0.0" + +string.prototype.trimend@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz#3651b8513719e8a9f48de7f2f77640b26652b229" + integrity sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + +string.prototype.trimstart@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" + integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + +strip-json-comments@^3.1.1, strip-json-comments@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@~8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +ts-api-utils@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" + integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== + +tsconfig-paths@^3.15.0: + version "3.15.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +typed-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3" + integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-typed-array "^1.1.13" + +typed-array-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz#d92972d3cff99a3fa2e765a28fcdc0f1d89dec67" + integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw== + dependencies: + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + +typed-array-byte-offset@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz#f9ec1acb9259f395093e4567eb3c28a580d02063" + integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + +typed-array-length@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.6.tgz#57155207c76e64a3457482dfdc1c9d1d3c4c73a3" + integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g== + dependencies: + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + possible-typed-array-names "^1.0.0" + +typescript@5.4.2: + version "5.4.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372" + integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ== + +typescript@^5.6.2: + version "5.6.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0" + integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw== + +ufo@^1.5.3: + version "1.5.4" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.5.4.tgz#16d6949674ca0c9e0fbbae1fa20a71d7b1ded754" + integrity sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ== + +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== + dependencies: + escalade "^3.1.2" + picocolors "^1.0.1" + +uri-js@^4.2.2, uri-js@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +vite-plugin-dts@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/vite-plugin-dts/-/vite-plugin-dts-4.2.1.tgz#f8bee33b732929717ce13ef7a382696d51200c30" + integrity sha512-/QlYvgUMiv8+ZTEerhNCYnYaZMM07cdlX6hQCR/w/g/nTh0tUXPoYwbT6SitizLJ9BybT1lnrcZgqheI6wromQ== + dependencies: + "@microsoft/api-extractor" "7.47.7" + "@rollup/pluginutils" "^5.1.0" + "@volar/typescript" "^2.4.4" + "@vue/language-core" "2.1.6" + compare-versions "^6.1.1" + debug "^4.3.6" + kolorist "^1.8.0" + local-pkg "^0.5.0" + magic-string "^0.30.11" + +vite@^5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.0.tgz#11dca8a961369ba8b5cae42d068c7ad684d5370f" + integrity sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg== + dependencies: + esbuild "^0.21.3" + postcss "^8.4.40" + rollup "^4.13.0" + optionalDependencies: + fsevents "~2.3.3" + +vscode-uri@^3.0.8: + version "3.0.8" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f" + integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw== + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-typed-array@^1.1.14, which-typed-array@^1.1.15: + version "1.1.15" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" + integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.2" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 9b17240f01fa93292ad956bc92bce670c7c1a8d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sat, 28 Sep 2024 16:29:15 +0200 Subject: [PATCH 02/32] pl-hooks: add deps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-hooks/package.json | 2 + packages/pl-hooks/yarn.lock | 74 ++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/packages/pl-hooks/package.json b/packages/pl-hooks/package.json index 22fa86cd1..86d8bb0d7 100644 --- a/packages/pl-hooks/package.json +++ b/packages/pl-hooks/package.json @@ -31,6 +31,8 @@ "vite-plugin-dts": "^4.2.1" }, "dependencies": { + "@tanstack/react-query": "^5.56.2", + "pl-api": "^0.0.37" }, "module": "./dist/main.es.js", "types": "dist/main.d.ts", diff --git a/packages/pl-hooks/yarn.lock b/packages/pl-hooks/yarn.lock index 82877a665..2571337ef 100644 --- a/packages/pl-hooks/yarn.lock +++ b/packages/pl-hooks/yarn.lock @@ -381,6 +381,18 @@ argparse "~1.0.9" string-argv "~0.3.1" +"@tanstack/query-core@5.56.2": + version "5.56.2" + resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.56.2.tgz#2def2fb0290cd2836bbb08afb0c175595bb8109b" + integrity sha512-gor0RI3/R5rVV3gXfddh1MM+hgl0Z4G7tj6Xxpq6p2I03NGPaJ8dITY9Gz05zYYb/EJq9vPas/T4wn9EaDPd4Q== + +"@tanstack/react-query@^5.56.2": + version "5.56.2" + resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.56.2.tgz#3a0241b9d010910905382f5e99160997b8795f91" + integrity sha512-SR0GzHVo6yzhN72pnRhkEFRAHMsUo5ZPzAxfTMvUxFIDVS6W9LYUp6nXW3fcHVdg0ZJl8opSH85jqahvm6DSVg== + dependencies: + "@tanstack/query-core" "5.56.2" + "@types/argparse@1.0.38": version "1.0.38" resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9" @@ -767,6 +779,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +blurhash@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-2.0.5.tgz#efde729fc14a2f03571a6aa91b49cba80d1abe4b" + integrity sha512-cRygWd7kGBQO3VEhPiTgq4Wc43ctsM+o46urrmPOiuAe+07fzlSB9OJVdpgDL0jPqXUVQ9ht7aq7kxOeJHRK+w== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -915,6 +932,11 @@ debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6: dependencies: ms "^2.1.3" +decode-uri-component@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.4.1.tgz#2ac4859663c704be22bf7db760a1494a49ab2cc5" + integrity sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ== + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -1331,6 +1353,11 @@ fill-range@^7.1.1: dependencies: to-regex-range "^5.0.1" +filter-obj@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-5.1.0.tgz#5bd89676000a713d7db2e197f660274428e524ed" + integrity sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng== + find-up@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" @@ -1547,6 +1574,11 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +http-link-header@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/http-link-header/-/http-link-header-1.1.3.tgz#b367b7a0ad1cf14027953f31aa1df40bb433da2a" + integrity sha512-3cZ0SRL8fb9MUlU3mKM61FcQvPfXx2dBrZW3Vbg5CXa8jFlK8OaEpePenLe1oEXQduhz8b0QjsqfS59QP4AJDQ== + ignore@^5.2.0, ignore@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" @@ -1826,6 +1858,11 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.pick@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q== + lodash@~4.17.15: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -1929,6 +1966,11 @@ object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== +object-to-formdata@^4.5.1: + version "4.5.1" + resolved "https://registry.yarnpkg.com/object-to-formdata/-/object-to-formdata-4.5.1.tgz#b6955a9c505b58df15852fee5f844b418b3eb6fe" + integrity sha512-QiM9D0NiU5jV6J6tjE1g7b4Z2tcUnKs1OPUi4iMb2zH+7jwlcUrASghgkFk9GtzqNNq8rTQJtT8AzjBAvLoNMw== + object.assign@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" @@ -2061,6 +2103,19 @@ pkg-types@^1.0.3, pkg-types@^1.1.1: mlly "^1.7.1" pathe "^1.1.2" +pl-api@^0.0.37: + version "0.0.37" + resolved "https://registry.yarnpkg.com/pl-api/-/pl-api-0.0.37.tgz#1475be139a3733b8a60dc3dd5fdfb00f83743eea" + integrity sha512-oCeKkJtUYC5XwM5PIVt+VPdLrJT7rjvfXgiv+qrUydK++cHnO1ZiixCaBnYW3M5D1BLZ6/OS4T+mk5hlCt8+1g== + dependencies: + blurhash "^2.0.5" + http-link-header "^1.1.3" + lodash.pick "^4.4.0" + object-to-formdata "^4.5.1" + query-string "^9.1.0" + semver "^7.6.3" + zod "^3.23.8" + possible-typed-array-names@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" @@ -2085,6 +2140,15 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== +query-string@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-9.1.0.tgz#5f12a4653a4ba56021e113b5cf58e56581823e7a" + integrity sha512-t6dqMECpCkqfyv2FfwVS1xcB6lgXW/0XZSaKdsCNGYkqMO76AFiJEg4vINzoDKcZa6MS7JX+OHIjwh06K5vczw== + dependencies: + decode-uri-component "^0.4.1" + filter-obj "^5.1.0" + split-on-first "^3.0.0" + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -2263,6 +2327,11 @@ source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +split-on-first@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-3.0.0.tgz#f04959c9ea8101b9b0bbf35a61b9ebea784a23e7" + integrity sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -2554,3 +2623,8 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zod@^3.23.8: + version "3.23.8" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" + integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== From 14ecf62f4eedb26ac15d8cee55df01f501589d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sat, 28 Sep 2024 22:10:31 +0200 Subject: [PATCH 03/32] WIP hooks migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-fe/package.json | 6 +- packages/pl-fe/src/actions/accounts.ts | 37 +++--- packages/pl-fe/src/actions/directory.ts | 7 +- packages/pl-fe/src/actions/events.ts | 11 +- .../pl-fe/src/actions/familiar-followers.ts | 4 +- packages/pl-fe/src/actions/groups.ts | 6 +- packages/pl-fe/src/actions/history.ts | 5 +- packages/pl-fe/src/actions/importer/index.ts | 24 ++-- packages/pl-fe/src/actions/interactions.ts | 32 ++--- .../src/features/account-timeline/index.tsx | 2 +- .../hooks/notifications/useNotifications.ts | 70 +++++++---- packages/pl-fe/src/pl-hooks/importer.ts | 114 +++++++++++++++++- packages/pl-fe/src/queries/chats.ts | 10 +- packages/pl-fe/yarn.lock | 35 +++--- 14 files changed, 249 insertions(+), 114 deletions(-) diff --git a/packages/pl-fe/package.json b/packages/pl-fe/package.json index 134ad20ce..c558fb1b3 100644 --- a/packages/pl-fe/package.json +++ b/packages/pl-fe/package.json @@ -60,7 +60,7 @@ "@reach/popover": "^0.18.0", "@reach/rect": "^0.18.0", "@reach/tabs": "^0.18.0", - "@reduxjs/toolkit": "^2.0.1", + "@reduxjs/toolkit": "^2.2.7", "@sentry/browser": "^7.74.1", "@sentry/react": "^7.74.1", "@tabler/icons": "^3.18.0", @@ -121,7 +121,7 @@ "react-inlinesvg": "^4.0.0", "react-intl": "^6.7.0", "react-motion": "^0.5.2", - "react-redux": "^9.0.4", + "react-redux": "^9.1.2", "react-router-dom": "^5.3.4", "react-router-dom-v5-compat": "^6.24.1", "react-router-scroll-4": "^1.0.0-beta.2", @@ -129,7 +129,7 @@ "react-sparklines": "^1.7.0", "react-sticky-box": "^2.0.0", "react-swipeable-views": "^0.14.0", - "redux": "^5.0.0", + "redux": "^5.0.1", "redux-immutable": "^4.0.0", "redux-thunk": "^3.1.0", "reselect": "^5.0.0", diff --git a/packages/pl-fe/src/actions/accounts.ts b/packages/pl-fe/src/actions/accounts.ts index e0f27c4cd..0f8e72805 100644 --- a/packages/pl-fe/src/actions/accounts.ts +++ b/packages/pl-fe/src/actions/accounts.ts @@ -1,14 +1,11 @@ import { PLEROMA, type UpdateNotificationSettingsParams, type Account, type CreateAccountParams, type PaginatedResponse, type Relationship } from 'pl-api'; -import { importEntities } from 'pl-fe/entity-store/actions'; -import { Entities } from 'pl-fe/entity-store/entities'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { selectAccount } from 'pl-fe/selectors'; import { isLoggedIn } from 'pl-fe/utils/auth'; import { getClient, type PlfeResponse } from '../api'; -import { importFetchedAccount, importFetchedAccounts } from './importer'; - import type { Map as ImmutableMap } from 'immutable'; import type { MinifiedStatus } from 'pl-fe/reducers/statuses'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -128,7 +125,7 @@ const fetchAccount = (accountId: string) => return getClient(getState()).accounts.getAccount(accountId) .then(response => { - dispatch(importFetchedAccount(response)); + importEntities({ accounts: [response] }); dispatch(fetchAccountSuccess(response)); }) .catch(error => { @@ -143,8 +140,8 @@ const fetchAccountByUsername = (username: string, history?: History) => if (features.accountByUsername && (me || !features.accountLookup)) { return getClient(getState()).accounts.getAccount(username).then(response => { + importEntities({ accounts: [response] }); dispatch(fetchRelationships([response.id])); - dispatch(importFetchedAccount(response)); dispatch(fetchAccountSuccess(response)); }).catch(error => { dispatch(fetchAccountFail(null, error)); @@ -198,7 +195,7 @@ const blockAccount = (accountId: string) => return getClient(getState).filtering.blockAccount(accountId) .then(response => { - dispatch(importEntities([response], Entities.RELATIONSHIPS)); + importEntities({ relationships: [response] }); // Pass in entire statuses map so we can use it to filter stuff in different parts of the reducers return dispatch(blockAccountSuccess(response, getState().statuses)); }).catch(error => dispatch(blockAccountFail(error))); @@ -212,7 +209,7 @@ const unblockAccount = (accountId: string) => return getClient(getState).filtering.unblockAccount(accountId) .then(response => { - dispatch(importEntities([response], Entities.RELATIONSHIPS)); + importEntities({ relationships: [response] }); return dispatch(unblockAccountSuccess(response)); }) .catch(error => dispatch(unblockAccountFail(error))); @@ -273,7 +270,7 @@ const muteAccount = (accountId: string, notifications?: boolean, duration = 0) = return client.filtering.muteAccount(accountId, params) .then(response => { - dispatch(importEntities([response], Entities.RELATIONSHIPS)); + importEntities({ relationships: [response] }); // Pass in entire statuses map so we can use it to filter stuff in different parts of the reducers return dispatch(muteAccountSuccess(response, getState().statuses)); }) @@ -288,7 +285,7 @@ const unmuteAccount = (accountId: string) => return getClient(getState()).filtering.unmuteAccount(accountId) .then(response => { - dispatch(importEntities([response], Entities.RELATIONSHIPS)); + importEntities({ relationships: [response] }); return dispatch(unmuteAccountSuccess(response)); }) .catch(error => dispatch(unmuteAccountFail(accountId, error))); @@ -369,7 +366,7 @@ const fetchRelationships = (accountIds: string[]) => return getClient(getState()).accounts.getRelationships(newAccountIds) .then(response => { - dispatch(importEntities(response, Entities.RELATIONSHIPS)); + importEntities({ relationships: response }); dispatch(fetchRelationshipsSuccess(response)); }) .catch(error => dispatch(fetchRelationshipsFail(error))); @@ -398,7 +395,7 @@ const fetchFollowRequests = () => return getClient(getState()).myAccount.getFollowRequests() .then(response => { - dispatch(importFetchedAccounts(response.items)); + importEntities({ accounts: response.items }); dispatch(fetchFollowRequestsSuccess(response.items, response.next)); }) .catch(error => dispatch(fetchFollowRequestsFail(error))); @@ -430,7 +427,7 @@ const expandFollowRequests = () => dispatch(expandFollowRequestsRequest()); return next().then(response => { - dispatch(importFetchedAccounts(response.items)); + importEntities({ accounts: response.items }); dispatch(expandFollowRequestsSuccess(response.items, response.next)); }).catch(error => dispatch(expandFollowRequestsFail(error))); }; @@ -576,7 +573,7 @@ const fetchPinnedAccounts = (accountId: string) => dispatch(fetchPinnedAccountsRequest(accountId)); return getClient(getState).accounts.getAccountEndorsements(accountId).then(response => { - dispatch(importFetchedAccounts(response)); + importEntities({ accounts: response }); dispatch(fetchPinnedAccountsSuccess(accountId, response, null)); }).catch(error => { dispatch(fetchPinnedAccountsFail(accountId, error)); @@ -604,10 +601,10 @@ const fetchPinnedAccountsFail = (accountId: string, error: unknown) => ({ const accountSearch = (q: string, signal?: AbortSignal) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch({ type: ACCOUNT_SEARCH_REQUEST, params: { q } }); - return getClient(getState()).accounts.searchAccounts(q, { resolve: false, limit: 4, following: true }, { signal }).then((accounts) => { - dispatch(importFetchedAccounts(accounts)); - dispatch({ type: ACCOUNT_SEARCH_SUCCESS, accounts }); - return accounts; + return getClient(getState()).accounts.searchAccounts(q, { resolve: false, limit: 4, following: true }, { signal }).then((response) => { + importEntities({ accounts: response }); + dispatch({ type: ACCOUNT_SEARCH_SUCCESS, accounts: response }); + return response; }).catch(error => { dispatch({ type: ACCOUNT_SEARCH_FAIL, skipAlert: true }); throw error; @@ -618,7 +615,7 @@ const accountLookup = (acct: string, signal?: AbortSignal) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch({ type: ACCOUNT_LOOKUP_REQUEST, acct }); return getClient(getState()).accounts.lookupAccount(acct, { signal }).then((account) => { - if (account && account.id) dispatch(importFetchedAccount(account)); + if (account && account.id) importEntities({ accounts: [account] }); dispatch({ type: ACCOUNT_LOOKUP_SUCCESS, account }); return account; }).catch(error => { @@ -636,7 +633,7 @@ const fetchBirthdayReminders = (month: number, day: number) => dispatch({ type: BIRTHDAY_REMINDERS_FETCH_REQUEST, day, month, accountId: me }); return getClient(getState).accounts.getBirthdays(day, month).then(response => { - dispatch(importFetchedAccounts(response)); + importEntities({ accounts: response }); dispatch({ type: BIRTHDAY_REMINDERS_FETCH_SUCCESS, accounts: response, diff --git a/packages/pl-fe/src/actions/directory.ts b/packages/pl-fe/src/actions/directory.ts index 14a5e8151..4fecad216 100644 --- a/packages/pl-fe/src/actions/directory.ts +++ b/packages/pl-fe/src/actions/directory.ts @@ -1,7 +1,8 @@ +import { importEntities } from 'pl-fe/pl-hooks/importer'; + import { getClient } from '../api'; import { fetchRelationships } from './accounts'; -import { importFetchedAccounts } from './importer'; import type { Account, ProfileDirectoryParams } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -19,7 +20,7 @@ const fetchDirectory = (params: ProfileDirectoryParams) => dispatch(fetchDirectoryRequest()); return getClient(getState()).instance.profileDirectory({ ...params, limit: 20 }).then((data) => { - dispatch(importFetchedAccounts(data)); + importEntities({ accounts: data }); dispatch(fetchDirectorySuccess(data)); dispatch(fetchRelationships(data.map((x) => x.id))); }).catch(error => dispatch(fetchDirectoryFail(error))); @@ -46,7 +47,7 @@ const expandDirectory = (params: Record) => const loadedItems = getState().user_lists.directory.items.size; return getClient(getState()).instance.profileDirectory({ ...params, offset: loadedItems, limit: 20 }).then((data) => { - dispatch(importFetchedAccounts(data)); + importEntities({ accounts: data }); dispatch(expandDirectorySuccess(data)); dispatch(fetchRelationships(data.map((x) => x.id))); }).catch(error => dispatch(expandDirectoryFail(error))); diff --git a/packages/pl-fe/src/actions/events.ts b/packages/pl-fe/src/actions/events.ts index 984ffd68a..1ac8520db 100644 --- a/packages/pl-fe/src/actions/events.ts +++ b/packages/pl-fe/src/actions/events.ts @@ -1,10 +1,11 @@ import { defineMessages } from 'react-intl'; import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { useModalsStore } from 'pl-fe/stores'; import toast from 'pl-fe/toast'; -import { importFetchedAccounts, importFetchedStatus, importFetchedStatuses } from './importer'; +import { importFetchedStatus, importFetchedStatuses } from './importer'; import { STATUS_FETCH_SOURCE_FAIL, STATUS_FETCH_SOURCE_REQUEST, STATUS_FETCH_SOURCE_SUCCESS } from './statuses'; import type { Account, CreateEventParams, Location, MediaAttachment, PaginatedResponse, Status } from 'pl-api'; @@ -241,7 +242,7 @@ const fetchEventParticipations = (statusId: string) => dispatch(fetchEventParticipationsRequest(statusId)); return getClient(getState).events.getEventParticipations(statusId).then(response => { - dispatch(importFetchedAccounts(response.items)); + importEntities({ accounts: response.items }); return dispatch(fetchEventParticipationsSuccess(statusId, response.items, response.next)); }).catch(error => { dispatch(fetchEventParticipationsFail(statusId, error)); @@ -277,7 +278,7 @@ const expandEventParticipations = (statusId: string) => dispatch(expandEventParticipationsRequest(statusId)); return next().then(response => { - dispatch(importFetchedAccounts(response.items)); + importEntities({ accounts: response.items }); return dispatch(expandEventParticipationsSuccess(statusId, response.items, response.next)); }).catch(error => { dispatch(expandEventParticipationsFail(statusId, error)); @@ -307,7 +308,7 @@ const fetchEventParticipationRequests = (statusId: string) => dispatch(fetchEventParticipationRequestsRequest(statusId)); return getClient(getState).events.getEventParticipationRequests(statusId).then(response => { - dispatch(importFetchedAccounts(response.items.map(({ account }) => account))); + importEntities({ accounts: response.items.map(({ account }) => account) }); return dispatch(fetchEventParticipationRequestsSuccess(statusId, response.items, response.next)); }).catch(error => { dispatch(fetchEventParticipationRequestsFail(statusId, error)); @@ -346,7 +347,7 @@ const expandEventParticipationRequests = (statusId: string) => dispatch(expandEventParticipationRequestsRequest(statusId)); return next().then(response => { - dispatch(importFetchedAccounts(response.items.map(({ account }) => account))); + importEntities({ accounts: response.items.map(({ account }) => account) }); return dispatch(expandEventParticipationRequestsSuccess(statusId, response.items, response.next)); }).catch(error => { dispatch(expandEventParticipationRequestsFail(statusId, error)); diff --git a/packages/pl-fe/src/actions/familiar-followers.ts b/packages/pl-fe/src/actions/familiar-followers.ts index 12bf81f83..d314f9128 100644 --- a/packages/pl-fe/src/actions/familiar-followers.ts +++ b/packages/pl-fe/src/actions/familiar-followers.ts @@ -1,9 +1,9 @@ +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { AppDispatch, RootState } from 'pl-fe/store'; import { getClient } from '../api'; import { fetchRelationships } from './accounts'; -import { importFetchedAccounts } from './importer'; const FAMILIAR_FOLLOWERS_FETCH_REQUEST = 'FAMILIAR_FOLLOWERS_FETCH_REQUEST' as const; const FAMILIAR_FOLLOWERS_FETCH_SUCCESS = 'FAMILIAR_FOLLOWERS_FETCH_SUCCESS' as const; @@ -19,7 +19,7 @@ const fetchAccountFamiliarFollowers = (accountId: string) => (dispatch: AppDispa .then((data) => { const accounts = data.find(({ id }: { id: string }) => id === accountId)!.accounts; - dispatch(importFetchedAccounts(accounts)); + importEntities({ accounts }); dispatch(fetchRelationships(accounts.map((item) => item.id))); dispatch({ type: FAMILIAR_FOLLOWERS_FETCH_SUCCESS, diff --git a/packages/pl-fe/src/actions/groups.ts b/packages/pl-fe/src/actions/groups.ts index ed201388a..fc8b469db 100644 --- a/packages/pl-fe/src/actions/groups.ts +++ b/packages/pl-fe/src/actions/groups.ts @@ -1,6 +1,6 @@ -import { getClient } from '../api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; -import { importFetchedAccounts } from './importer'; +import { getClient } from '../api'; import type { Account, PaginatedResponse } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -23,7 +23,7 @@ const fetchGroupBlocks = (groupId: string) => dispatch(fetchGroupBlocksRequest(groupId)); return getClient(getState).experimental.groups.getGroupBlocks(groupId).then(response => { - dispatch(importFetchedAccounts(response.items)); + importEntities({ accounts: response.items }); dispatch(fetchGroupBlocksSuccess(groupId, response.items, response.next)); }).catch(error => { dispatch(fetchGroupBlocksFail(groupId, error)); diff --git a/packages/pl-fe/src/actions/history.ts b/packages/pl-fe/src/actions/history.ts index 733871b17..1f110f11e 100644 --- a/packages/pl-fe/src/actions/history.ts +++ b/packages/pl-fe/src/actions/history.ts @@ -1,6 +1,5 @@ import { getClient } from 'pl-fe/api'; - -import { importFetchedAccounts } from './importer'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import type { StatusEdit } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -18,7 +17,7 @@ const fetchHistory = (statusId: string) => dispatch(fetchHistoryRequest(statusId)); return getClient(getState()).statuses.getStatusHistory(statusId).then(data => { - dispatch(importFetchedAccounts(data.map((x) => x.account))); + importEntities({ accounts: data.map((x) => x.account) }); dispatch(fetchHistorySuccess(statusId, data)); }).catch(error => dispatch(fetchHistoryFail(statusId, error))); }; diff --git a/packages/pl-fe/src/actions/importer/index.ts b/packages/pl-fe/src/actions/importer/index.ts index ed63ddb13..b205cc4c4 100644 --- a/packages/pl-fe/src/actions/importer/index.ts +++ b/packages/pl-fe/src/actions/importer/index.ts @@ -1,8 +1,8 @@ import { importEntities } from 'pl-fe/entity-store/actions'; import { Entities } from 'pl-fe/entity-store/entities'; -import { normalizeAccount, normalizeGroup } from 'pl-fe/normalizers'; +import { normalizeAccount, normalizeGroup, type Account, type Group } from 'pl-fe/normalizers'; -import type { Account as BaseAccount, Group, Poll, Status as BaseStatus } from 'pl-api'; +import type { Account as BaseAccount, Group as BaseGroup, Poll, Status as BaseStatus } from 'pl-api'; import type { AppDispatch } from 'pl-fe/store'; const ACCOUNT_IMPORT = 'ACCOUNT_IMPORT'; @@ -13,25 +13,29 @@ const POLLS_IMPORT = 'POLLS_IMPORT'; const importAccount = (data: BaseAccount) => importAccounts([data]); -const importAccounts = (data: Array) => (dispatch: AppDispatch) => { - dispatch({ type: ACCOUNTS_IMPORT, accounts: data }); +const importAccounts = (data: Array) => { + let accounts: Array = []; + try { - const accounts = data.map(normalizeAccount); - dispatch(importEntities(accounts, Entities.ACCOUNTS)); + accounts = data.map(normalizeAccount); } catch (e) { // } + + return importEntities(accounts, Entities.ACCOUNTS); }; -const importGroup = (data: Group) => importGroups([data]); +const importGroup = (data: BaseGroup) => importGroups([data]); -const importGroups = (data: Array) => (dispatch: AppDispatch) => { +const importGroups = (data: Array) => { + let groups: Array = []; try { - const groups = data.map(normalizeGroup); - dispatch(importEntities(groups, Entities.GROUPS)); + groups = data.map(normalizeGroup); } catch (e) { // } + + return importEntities(groups, Entities.GROUPS); }; const importStatus = (status: BaseStatus & { expectsCard?: boolean }, idempotencyKey?: string) => ({ type: STATUS_IMPORT, status, idempotencyKey }); diff --git a/packages/pl-fe/src/actions/interactions.ts b/packages/pl-fe/src/actions/interactions.ts index 5bc7f1dcd..2473768e2 100644 --- a/packages/pl-fe/src/actions/interactions.ts +++ b/packages/pl-fe/src/actions/interactions.ts @@ -1,5 +1,6 @@ import { defineMessages } from 'react-intl'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { useModalsStore } from 'pl-fe/stores'; import toast, { type IToastOptions } from 'pl-fe/toast'; import { isLoggedIn } from 'pl-fe/utils/auth'; @@ -7,7 +8,6 @@ import { isLoggedIn } from 'pl-fe/utils/auth'; import { getClient } from '../api'; import { fetchRelationships } from './accounts'; -import { importFetchedAccounts, importFetchedStatus } from './importer'; import type { Account, EmojiReaction, PaginatedResponse, Status } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -97,7 +97,7 @@ const reblog = (status: Pick) => return getClient(getState()).statuses.reblogStatus(status.id).then((response) => { // The reblog API method returns a new status wrapped around the original. In this case we are only // interested in how the original is modified, hence passing it skipping the wrapper - if (response.reblog) dispatch(importFetchedStatus(response.reblog as Status)); + if (response.reblog) importEntities({ statuses: [response] }); dispatch(reblogSuccess(response)); }).catch(error => { dispatch(reblogFail(status.id, error)); @@ -110,8 +110,8 @@ const unreblog = (status: Pick) => dispatch(unreblogRequest(status.id)); - return getClient(getState()).statuses.unreblogStatus(status.id).then((status) => { - dispatch(unreblogSuccess(status)); + return getClient(getState()).statuses.unreblogStatus(status.id).then((response) => { + dispatch(unreblogSuccess(response)); }).catch(error => { dispatch(unreblogFail(status.id, error)); }); @@ -306,9 +306,9 @@ const bookmark = (status: Pick, folderId?: string) => dispatch(bookmarkRequest(status.id)); - return getClient(getState()).statuses.bookmarkStatus(status.id, folderId).then((response) => { - dispatch(importFetchedStatus(response)); - dispatch(bookmarkSuccess(response)); + return getClient(getState()).statuses.bookmarkStatus(status.id, folderId).then((status) => { + importEntities({ statuses: [status] }); + dispatch(bookmarkSuccess(status)); let opts: IToastOptions = { actionLabel: messages.view, @@ -335,7 +335,7 @@ const unbookmark = (status: Pick) => dispatch(unbookmarkRequest(status.id)); return getClient(getState()).statuses.unbookmarkStatus(status.id).then(response => { - dispatch(importFetchedStatus(response)); + importEntities({ statuses: [response] }); dispatch(unbookmarkSuccess(response)); toast.success(messages.bookmarkRemoved); }).catch(error => { @@ -391,7 +391,7 @@ const fetchReblogs = (statusId: string) => dispatch(fetchReblogsRequest(statusId)); return getClient(getState()).statuses.getRebloggedBy(statusId).then(response => { - dispatch(importFetchedAccounts(response.items)); + importEntities({ accounts: response.items }); dispatch(fetchRelationships(response.items.map((item) => item.id))); dispatch(fetchReblogsSuccess(statusId, response.items, response.next)); }).catch(error => { @@ -420,7 +420,7 @@ const fetchReblogsFail = (statusId: string, error: unknown) => ({ const expandReblogs = (statusId: string, next: AccountListLink) => (dispatch: AppDispatch, getState: () => RootState) => { next().then(response => { - dispatch(importFetchedAccounts(response.items)); + importEntities({ accounts: response.items }); dispatch(fetchRelationships(response.items.map((item) => item.id))); dispatch(expandReblogsSuccess(statusId, response.items, response.next)); }).catch(error => { @@ -446,7 +446,7 @@ const fetchFavourites = (statusId: string) => dispatch(fetchFavouritesRequest(statusId)); return getClient(getState()).statuses.getFavouritedBy(statusId).then(response => { - dispatch(importFetchedAccounts(response.items)); + importEntities({ accounts: response.items }); dispatch(fetchRelationships(response.items.map((item) => item.id))); dispatch(fetchFavouritesSuccess(statusId, response.items, response.next)); }).catch(error => { @@ -475,7 +475,7 @@ const fetchFavouritesFail = (statusId: string, error: unknown) => ({ const expandFavourites = (statusId: string, next: AccountListLink) => (dispatch: AppDispatch) => { next().then(response => { - dispatch(importFetchedAccounts(response.items)); + importEntities({ accounts: response.items }); dispatch(fetchRelationships(response.items.map((item) => item.id))); dispatch(expandFavouritesSuccess(statusId, response.items, response.next)); }).catch(error => { @@ -501,7 +501,7 @@ const fetchDislikes = (statusId: string) => dispatch(fetchDislikesRequest(statusId)); return getClient(getState).statuses.getDislikedBy(statusId).then(response => { - dispatch(importFetchedAccounts(response)); + importEntities({ accounts: response }); dispatch(fetchRelationships(response.map((item) => item.id))); dispatch(fetchDislikesSuccess(statusId, response)); }).catch(error => { @@ -531,7 +531,7 @@ const fetchReactions = (statusId: string) => dispatch(fetchReactionsRequest(statusId)); return getClient(getState).statuses.getStatusReactions(statusId).then(response => { - dispatch(importFetchedAccounts((response).map(({ accounts }) => accounts).flat())); + importEntities({ accounts: (response).map(({ accounts }) => accounts).flat() }); dispatch(fetchReactionsSuccess(statusId, response)); }).catch(error => { dispatch(fetchReactionsFail(statusId, error)); @@ -562,7 +562,7 @@ const pin = (status: Pick, accountId: string) => dispatch(pinRequest(status.id, accountId)); return getClient(getState()).statuses.pinStatus(status.id).then(response => { - dispatch(importFetchedStatus(response)); + importEntities({ statuses: [response] }); dispatch(pinSuccess(response, accountId)); }).catch(error => { dispatch(pinFail(status.id, error, accountId)); @@ -596,7 +596,7 @@ const unpin = (status: Pick, accountId: string) => dispatch(unpinRequest(status.id, accountId)); return getClient(getState()).statuses.unpinStatus(status.id).then(response => { - dispatch(importFetchedStatus(response)); + importEntities({ statuses: [response] }); dispatch(unpinSuccess(response, accountId)); }).catch(error => { dispatch(unpinFail(status.id, error, accountId)); diff --git a/packages/pl-fe/src/features/account-timeline/index.tsx b/packages/pl-fe/src/features/account-timeline/index.tsx index 47fee24d1..fd8db60f7 100644 --- a/packages/pl-fe/src/features/account-timeline/index.tsx +++ b/packages/pl-fe/src/features/account-timeline/index.tsx @@ -34,7 +34,7 @@ const AccountTimeline: React.FC = ({ params, withReplies = fal const statusIds = useAppSelector(state => getStatusIds(state, { type: `account:${path}`, prefix: 'account_timeline' })); const featuredStatusIds = useAppSelector(state => getStatusIds(state, { type: `account:${account?.id}:with_replies:pinned`, prefix: 'account_timeline' })); - const isBlocked = useAppSelector(state => state.relationships.getIn([account?.id, 'blocked_by']) === true); + const isBlocked = account?.relationship?.blocked_by; const unavailable = isBlocked && !features.blockersVisible; const isLoading = useAppSelector(state => state.timelines.get(`account:${path}`)?.isLoading === true); const hasMore = useAppSelector(state => state.timelines.get(`account:${path}`)?.hasMore === true); diff --git a/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts index 47bc5f4cd..c38f3a938 100644 --- a/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts +++ b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts @@ -1,20 +1,16 @@ import { useInfiniteQuery } from '@tanstack/react-query'; -import { importFetchedAccounts, importFetchedStatuses } from 'pl-fe/actions/importer'; +import { getNotificationStatus } from 'pl-fe/features/notifications/components/notification'; import { useClient } from 'pl-fe/hooks'; -import { normalizeNotifications } from 'pl-fe/normalizers'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { queryClient } from 'pl-fe/queries/client'; -import { AppDispatch, store } from 'pl-fe/store'; import { flattenPages } from 'pl-fe/utils/queries'; -import { importNotification, minifyNotification } from './useNotification'; - import type { Account as BaseAccount, Notification as BaseNotification, PaginatedResponse, PlApiClient, - Status as BaseStatus, } from 'pl-api'; import type { NotificationType } from 'pl-fe/utils/notification'; @@ -29,31 +25,59 @@ const getQueryKey = (params: UseNotificationParams) => [ params.types ? params.types.join('|') : params.excludeTypes ? ('exclude:' + params.excludeTypes.join('|')) : 'all', ]; -const importNotifications = (response: PaginatedResponse) => { - const accounts: Record = {}; - const statuses: Record = {}; +type DeduplicatedNotification = BaseNotification & { + accounts: Array; + duplicate?: boolean; +} - response.items.forEach((notification) => { - accounts[notification.account.id] = notification.account; +const STATUS_NOTIFICATION_TYPES = [ + 'favourite', + 'reblog', + 'emoji_reaction', + 'event_reminder', + 'participation_accepted', + 'participation_request', +]; - if (notification.type === 'move') accounts[notification.target.id] = notification.target; +const deduplicateNotifications = (notifications: Array) => { + const deduplicatedNotifications: DeduplicatedNotification[] = []; - // @ts-ignore - if (notification.status?.id) { - // @ts-ignore - statuses[notification.status.id] = notification.status; + for (const notification of notifications) { + if (STATUS_NOTIFICATION_TYPES.includes(notification.type)) { + const existingNotification = deduplicatedNotifications + .find(deduplicated => + deduplicated.type === notification.type + && ((notification.type === 'emoji_reaction' && deduplicated.type === 'emoji_reaction') ? notification.emoji === deduplicated.emoji : true) + && getNotificationStatus(deduplicated)?.id === getNotificationStatus(notification)?.id, + ); + + if (existingNotification) { + existingNotification.accounts.push(notification.account); + deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: true }); + } else { + deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: false }); + } + } else { + deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: false }); } + } + + return deduplicatedNotifications; +}; + +const importNotifications = (response: PaginatedResponse) => { + const deduplicatedNotifications = deduplicateNotifications(response.items); + + importEntities({ + notifications: deduplicatedNotifications, }); - store.dispatch(importFetchedStatuses(Object.values(statuses))); - store.dispatch(importFetchedAccounts(Object.values(accounts))); + // const normalizedNotifications = normalizeNotifications(response.items); - const normalizedNotifications = normalizeNotifications(response.items); - - normalizedNotifications.map(minifyNotification).forEach(importNotification); + // normalizedNotifications.map(minifyNotification).forEach(importNotification); return { - items: normalizedNotifications.filter(({ duplicate }) => !duplicate).map(({ id }) => id), + items: deduplicatedNotifications.filter(({ duplicate }) => !duplicate).map(({ id }) => id), previous: response.previous, next: response.next, }; @@ -91,4 +115,4 @@ const prefetchNotifications = (client: PlApiClient, params: UseNotificationParam getNextPageParam: (response) => response, }); -export { useNotifications, prefetchNotifications }; +export { useNotifications, prefetchNotifications, type DeduplicatedNotification }; diff --git a/packages/pl-fe/src/pl-hooks/importer.ts b/packages/pl-fe/src/pl-hooks/importer.ts index 6f4105dc5..84f56786e 100644 --- a/packages/pl-fe/src/pl-hooks/importer.ts +++ b/packages/pl-fe/src/pl-hooks/importer.ts @@ -1,28 +1,125 @@ +import omit from 'lodash/omit'; + +import { importAccounts, importGroups, importPolls, importStatuses } from 'pl-fe/actions/importer'; +import { importEntities as importEntityStoreEntities } from 'pl-fe/entity-store/actions'; +import { Entities } from 'pl-fe/entity-store/entities'; +import { queryClient } from 'pl-fe/queries/client'; +import { store } from 'pl-fe/store'; + +import { DeduplicatedNotification } from './hooks/notifications/useNotifications'; + import type { + AccountWarning, Account as BaseAccount, Group as BaseGroup, - Notification as BaseNotification, Poll as BasePoll, + Relationship as BaseRelationship, Status as BaseStatus, + RelationshipSeveranceEvent, } from 'pl-api'; + +const minifyNotification = (notification: DeduplicatedNotification) => { + // @ts-ignore + const minifiedNotification: { + duplicate: boolean; + account_id: string; + account_ids: string[]; + created_at: string; + id: string; + group_key: string; + } & ( + | { type: 'follow' | 'follow_request' | 'admin.sign_up' | 'bite' } + | { + type: 'mention'; + subtype?: 'reply'; + status_id: string; + } + | { + type: 'status' | 'reblog' | 'favourite' | 'poll' | 'update' | 'event_reminder'; + status_id: string; + } + | { + type: 'admin.report'; + report: Report; + } + | { + type: 'severed_relationships'; + relationship_severance_event: RelationshipSeveranceEvent; + } + | { + type: 'moderation_warning'; + moderation_warning: AccountWarning; + } + | { + type: 'move'; + target_id: string; + } + | { + type: 'emoji_reaction'; + emoji: string; + emoji_url: string | null; + status_id: string; + } + | { + type: 'chat_mention'; + chat_message_id: string; + } + | { + type: 'participation_accepted' | 'participation_request'; + status_id: string; + participation_message: string | null; + } + ) = { + ...omit(notification, ['account', 'accounts', 'status', 'target', 'chat_message']), + account_id: notification.account.id, + account_ids: notification.accounts.map(({ id }) => id), + created_at: notification.created_at, + id: notification.id, + type: notification.type, + }; + + // @ts-ignore + if (notification.status) minifiedNotification.status_id = notification.status.id; + // @ts-ignore + if (notification.target) minifiedNotification.target_id = notification.target.id; + // @ts-ignore + if (notification.chat_message) minifiedNotification.chat_message_id = notification.chat_message.id; + + return minifiedNotification; +}; + +type MinifiedNotification = ReturnType; + +const importNotification = (notification: DeduplicatedNotification) => { + queryClient.setQueryData( + ['notifications', 'entities', notification.id], + existingNotification => existingNotification?.duplicate ? existingNotification : minifyNotification(notification), + ); +}; + const importEntities = (entities: { accounts?: Array; - notifications?: Array; + notifications?: Array; statuses?: Array; + relationships?: Array; }) => { + const { dispatch } = store; + const accounts: Record = {}; const groups: Record = {}; - const notifications: Record = {}; + const notifications: Record = {}; const polls: Record = {}; + const relationships: Record = {}; const statuses: Record = {}; const processAccount = (account: BaseAccount) => { accounts[account.id] = account; if (account.moved) processAccount(account.moved); + if (account.relationship) relationships[account.relationship.id] = account.relationship; }; - const processNotification = (notification: BaseNotification) => { + const processNotification = (notification: DeduplicatedNotification) => { notifications[notification.id] = notification; processAccount(notification.account); @@ -38,11 +135,20 @@ const importEntities = (entities: { if (status.quote) processStatus(status.quote); if (status.reblog) processStatus(status.reblog); + if (status.poll) polls[status.poll.id] = status.poll; + if (status.group) groups[status.group.id] = status.group; }; entities.accounts?.forEach(processAccount); entities.notifications?.forEach(processNotification); entities.statuses?.forEach(processStatus); + + dispatch(importAccounts(Object.values(accounts))); + dispatch(importGroups(Object.values(groups))); + Object.values(notifications).forEach(importNotification); + dispatch(importPolls(Object.values(polls))); + dispatch(importStatuses(Object.values(statuses))); + dispatch(importEntityStoreEntities(Object.values(relationships), Entities.RELATIONSHIPS)); }; export { importEntities }; diff --git a/packages/pl-fe/src/queries/chats.ts b/packages/pl-fe/src/queries/chats.ts index 1aa00f812..6b1f08c71 100644 --- a/packages/pl-fe/src/queries/chats.ts +++ b/packages/pl-fe/src/queries/chats.ts @@ -2,11 +2,11 @@ import { InfiniteData, keepPreviousData, useInfiniteQuery, useMutation, useQuery import sumBy from 'lodash/sumBy'; import { type Chat, type ChatMessage as BaseChatMessage, type PaginatedResponse, chatMessageSchema } from 'pl-api'; -import { importFetchedAccount, importFetchedAccounts } from 'pl-fe/actions/importer'; import { ChatWidgetScreens, useChatContext } from 'pl-fe/contexts/chat-context'; import { useStatContext } from 'pl-fe/contexts/stat-context'; -import { useAppDispatch, useAppSelector, useClient, useFeatures, useLoggedIn, useOwnAccount } from 'pl-fe/hooks'; +import { useAppSelector, useClient, useFeatures, useLoggedIn, useOwnAccount } from 'pl-fe/hooks'; import { type ChatMessage, normalizeChatMessage } from 'pl-fe/normalizers'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { reOrderChatListItems } from 'pl-fe/utils/chats'; import { flattenPages, updatePageItem } from 'pl-fe/utils/queries'; @@ -51,7 +51,6 @@ const useChatMessages = (chat: Chat) => { const useChats = () => { const client = useClient(); - const dispatch = useAppDispatch(); const features = useFeatures(); const { setUnreadChatsCount } = useStatContext(); const fetchRelationships = useFetchRelationships(); @@ -65,7 +64,7 @@ const useChats = () => { // Set the relationships to these users in the redux store. fetchRelationships.mutate({ accountIds: items.map((item) => item.account.id) }); - dispatch(importFetchedAccounts(items.map((item) => item.account))); + importEntities({ accounts: items.map((item) => item.account) }); return response; }; @@ -94,7 +93,6 @@ const useChats = () => { const useChat = (chatId?: string) => { const client = useClient(); - const dispatch = useAppDispatch(); const fetchRelationships = useFetchRelationships(); const getChat = async () => { @@ -102,7 +100,7 @@ const useChat = (chatId?: string) => { const data = await client.chats.getChat(chatId); fetchRelationships.mutate({ accountIds: [data.account.id] }); - dispatch(importFetchedAccount(data.account)); + importEntities({ accounts: [data.account] }); return data; } diff --git a/packages/pl-fe/yarn.lock b/packages/pl-fe/yarn.lock index a937fcc2c..4375ddf75 100644 --- a/packages/pl-fe/yarn.lock +++ b/packages/pl-fe/yarn.lock @@ -2171,15 +2171,15 @@ resolved "https://registry.yarnpkg.com/@reach/utils/-/utils-0.18.0.tgz#4f3cebe093dd436eeaff633809bf0f68f4f9d2ee" integrity sha512-KdVMdpTgDyK8FzdKO9SCpiibuy/kbv3pwgfXshTI6tEcQT1OOwj7BAksnzGC0rPz0UholwC+AgkqEl3EJX3M1A== -"@reduxjs/toolkit@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-2.0.1.tgz#0a5233c1e35c1941b03aece39cceade3467a1062" - integrity sha512-fxIjrR9934cmS8YXIGd9e7s1XRsEU++aFc9DVNMFMRTM5Vtsg2DCRMj21eslGtDt43IUf9bJL3h5bwUlZleibA== +"@reduxjs/toolkit@^2.2.7": + version "2.2.7" + resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-2.2.7.tgz#199e3d10ccb39267cb5aee92c0262fd9da7fdfb2" + integrity sha512-faI3cZbSdFb8yv9dhDTmGwclW0vk0z5o1cia+kf7gCbaCwHI5e+7tP57mJUv22pNcNbeA62GSrPpfrUfdXcQ6g== dependencies: immer "^10.0.3" - redux "^5.0.0" + redux "^5.0.1" redux-thunk "^3.1.0" - reselect "^5.0.1" + reselect "^5.1.0" "@remix-run/router@1.18.0": version "1.18.0" @@ -9713,10 +9713,10 @@ react-property@2.0.2: resolved "https://registry.yarnpkg.com/react-property/-/react-property-2.0.2.tgz#d5ac9e244cef564880a610bc8d868bd6f60fdda6" integrity sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug== -react-redux@^9.0.4: - version "9.0.4" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-9.0.4.tgz#6892d465f086507a517d4b53eb589876e6bc8344" - integrity sha512-9J1xh8sWO0vYq2sCxK2My/QO7MzUMRi3rpiILP/+tDr8krBHixC6JMM17fMK88+Oh3e4Ae6/sHIhNBgkUivwFA== +react-redux@^9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-9.1.2.tgz#deba38c64c3403e9abd0c3fbeab69ffd9d8a7e4b" + integrity sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w== dependencies: "@types/use-sync-external-store" "^0.0.3" use-sync-external-store "^1.0.0" @@ -9908,10 +9908,10 @@ redux@^4.0.5: dependencies: "@babel/runtime" "^7.9.2" -redux@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/redux/-/redux-5.0.0.tgz#29572e29a439e094ff8fec46883fc45053f6736d" - integrity sha512-blLIYmYetpZMET6Q6uCY7Jtl/Im5OBldy+vNPauA8vvsdqyt66oep4EUpAMWNHauTC6xa9JuRPhRB72rY82QGA== +redux@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-5.0.1.tgz#97fa26881ce5746500125585d5642c77b6e9447b" + integrity sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w== reflect.getprototypeof@^1.0.4: version "1.0.4" @@ -10051,11 +10051,16 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== -reselect@^5.0.0, reselect@^5.0.1: +reselect@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/reselect/-/reselect-5.0.1.tgz#587cdaaeb4e0e8927cff80ebe2bbef05f74b1648" integrity sha512-D72j2ubjgHpvuCiORWkOUxndHJrxDaSolheiz5CO+roz8ka97/4msh2E8F5qay4GawR5vzBt5MkbDHT+Rdy/Wg== +reselect@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-5.1.1.tgz#c766b1eb5d558291e5e550298adb0becc24bb72e" + integrity sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w== + resize-observer-polyfill@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" From c740b19e30e1a7d80950fc29e6fcd193c60b58c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sat, 28 Sep 2024 22:51:54 +0200 Subject: [PATCH 04/32] wip hooks migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-fe/src/actions/polls.ts | 8 ++++---- packages/pl-fe/src/pl-hooks/importer.ts | 21 ++++++++++++++------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/packages/pl-fe/src/actions/polls.ts b/packages/pl-fe/src/actions/polls.ts index f343be4ec..f4f7e0c7a 100644 --- a/packages/pl-fe/src/actions/polls.ts +++ b/packages/pl-fe/src/actions/polls.ts @@ -1,6 +1,6 @@ -import { getClient } from '../api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; -import { importFetchedPoll } from './importer'; +import { getClient } from '../api'; import type { Poll } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -18,7 +18,7 @@ const vote = (pollId: string, choices: number[]) => dispatch(voteRequest()); return getClient(getState()).polls.vote(pollId, choices).then((data) => { - dispatch(importFetchedPoll(data)); + importEntities({ polls: [data] }); dispatch(voteSuccess(data)); }).catch(err => dispatch(voteFail(err))); }; @@ -28,7 +28,7 @@ const fetchPoll = (pollId: string) => dispatch(fetchPollRequest()); return getClient(getState()).polls.getPoll(pollId).then((data) => { - dispatch(importFetchedPoll(data)); + importEntities({ polls: [data] }); dispatch(fetchPollSuccess(data)); }).catch(err => dispatch(fetchPollFail(err))); }; diff --git a/packages/pl-fe/src/pl-hooks/importer.ts b/packages/pl-fe/src/pl-hooks/importer.ts index 84f56786e..127284d35 100644 --- a/packages/pl-fe/src/pl-hooks/importer.ts +++ b/packages/pl-fe/src/pl-hooks/importer.ts @@ -18,7 +18,6 @@ import type { RelationshipSeveranceEvent, } from 'pl-api'; - const minifyNotification = (notification: DeduplicatedNotification) => { // @ts-ignore const minifiedNotification: { @@ -98,9 +97,15 @@ const importNotification = (notification: DeduplicatedNotification) => { ); }; +const isEmpty = (object: Record) => { + for (const i in object) return false; + return true; +}; + const importEntities = (entities: { accounts?: Array; notifications?: Array; + polls?: Array; statuses?: Array; relationships?: Array; }) => { @@ -141,14 +146,16 @@ const importEntities = (entities: { entities.accounts?.forEach(processAccount); entities.notifications?.forEach(processNotification); + entities.polls?.forEach(poll => polls[poll.id] = poll); + entities.relationships?.forEach(relationship => relationships[relationship.id] = relationship); entities.statuses?.forEach(processStatus); - dispatch(importAccounts(Object.values(accounts))); - dispatch(importGroups(Object.values(groups))); - Object.values(notifications).forEach(importNotification); - dispatch(importPolls(Object.values(polls))); - dispatch(importStatuses(Object.values(statuses))); - dispatch(importEntityStoreEntities(Object.values(relationships), Entities.RELATIONSHIPS)); + if (!isEmpty(accounts)) dispatch(importAccounts(Object.values(accounts))); + if (!isEmpty(groups)) dispatch(importGroups(Object.values(groups))); + if (!isEmpty(notifications)) Object.values(notifications).forEach(importNotification); + if (!isEmpty(polls)) dispatch(importPolls(Object.values(polls))); + if (!isEmpty(relationships)) dispatch(importEntityStoreEntities(Object.values(relationships), Entities.RELATIONSHIPS)); + if (!isEmpty(statuses)) dispatch(importStatuses(Object.values(statuses))); }; export { importEntities }; From a140baddf41cfe07fd34035753ac6796e08ff0bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sat, 28 Sep 2024 22:56:47 +0200 Subject: [PATCH 05/32] pl-fe: revert updates? MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-fe/package.json | 6 +++--- packages/pl-fe/yarn.lock | 35 +++++++++++++++-------------------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/packages/pl-fe/package.json b/packages/pl-fe/package.json index c558fb1b3..134ad20ce 100644 --- a/packages/pl-fe/package.json +++ b/packages/pl-fe/package.json @@ -60,7 +60,7 @@ "@reach/popover": "^0.18.0", "@reach/rect": "^0.18.0", "@reach/tabs": "^0.18.0", - "@reduxjs/toolkit": "^2.2.7", + "@reduxjs/toolkit": "^2.0.1", "@sentry/browser": "^7.74.1", "@sentry/react": "^7.74.1", "@tabler/icons": "^3.18.0", @@ -121,7 +121,7 @@ "react-inlinesvg": "^4.0.0", "react-intl": "^6.7.0", "react-motion": "^0.5.2", - "react-redux": "^9.1.2", + "react-redux": "^9.0.4", "react-router-dom": "^5.3.4", "react-router-dom-v5-compat": "^6.24.1", "react-router-scroll-4": "^1.0.0-beta.2", @@ -129,7 +129,7 @@ "react-sparklines": "^1.7.0", "react-sticky-box": "^2.0.0", "react-swipeable-views": "^0.14.0", - "redux": "^5.0.1", + "redux": "^5.0.0", "redux-immutable": "^4.0.0", "redux-thunk": "^3.1.0", "reselect": "^5.0.0", diff --git a/packages/pl-fe/yarn.lock b/packages/pl-fe/yarn.lock index 4375ddf75..a937fcc2c 100644 --- a/packages/pl-fe/yarn.lock +++ b/packages/pl-fe/yarn.lock @@ -2171,15 +2171,15 @@ resolved "https://registry.yarnpkg.com/@reach/utils/-/utils-0.18.0.tgz#4f3cebe093dd436eeaff633809bf0f68f4f9d2ee" integrity sha512-KdVMdpTgDyK8FzdKO9SCpiibuy/kbv3pwgfXshTI6tEcQT1OOwj7BAksnzGC0rPz0UholwC+AgkqEl3EJX3M1A== -"@reduxjs/toolkit@^2.2.7": - version "2.2.7" - resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-2.2.7.tgz#199e3d10ccb39267cb5aee92c0262fd9da7fdfb2" - integrity sha512-faI3cZbSdFb8yv9dhDTmGwclW0vk0z5o1cia+kf7gCbaCwHI5e+7tP57mJUv22pNcNbeA62GSrPpfrUfdXcQ6g== +"@reduxjs/toolkit@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-2.0.1.tgz#0a5233c1e35c1941b03aece39cceade3467a1062" + integrity sha512-fxIjrR9934cmS8YXIGd9e7s1XRsEU++aFc9DVNMFMRTM5Vtsg2DCRMj21eslGtDt43IUf9bJL3h5bwUlZleibA== dependencies: immer "^10.0.3" - redux "^5.0.1" + redux "^5.0.0" redux-thunk "^3.1.0" - reselect "^5.1.0" + reselect "^5.0.1" "@remix-run/router@1.18.0": version "1.18.0" @@ -9713,10 +9713,10 @@ react-property@2.0.2: resolved "https://registry.yarnpkg.com/react-property/-/react-property-2.0.2.tgz#d5ac9e244cef564880a610bc8d868bd6f60fdda6" integrity sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug== -react-redux@^9.1.2: - version "9.1.2" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-9.1.2.tgz#deba38c64c3403e9abd0c3fbeab69ffd9d8a7e4b" - integrity sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w== +react-redux@^9.0.4: + version "9.0.4" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-9.0.4.tgz#6892d465f086507a517d4b53eb589876e6bc8344" + integrity sha512-9J1xh8sWO0vYq2sCxK2My/QO7MzUMRi3rpiILP/+tDr8krBHixC6JMM17fMK88+Oh3e4Ae6/sHIhNBgkUivwFA== dependencies: "@types/use-sync-external-store" "^0.0.3" use-sync-external-store "^1.0.0" @@ -9908,10 +9908,10 @@ redux@^4.0.5: dependencies: "@babel/runtime" "^7.9.2" -redux@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/redux/-/redux-5.0.1.tgz#97fa26881ce5746500125585d5642c77b6e9447b" - integrity sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w== +redux@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-5.0.0.tgz#29572e29a439e094ff8fec46883fc45053f6736d" + integrity sha512-blLIYmYetpZMET6Q6uCY7Jtl/Im5OBldy+vNPauA8vvsdqyt66oep4EUpAMWNHauTC6xa9JuRPhRB72rY82QGA== reflect.getprototypeof@^1.0.4: version "1.0.4" @@ -10051,16 +10051,11 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== -reselect@^5.0.0: +reselect@^5.0.0, reselect@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/reselect/-/reselect-5.0.1.tgz#587cdaaeb4e0e8927cff80ebe2bbef05f74b1648" integrity sha512-D72j2ubjgHpvuCiORWkOUxndHJrxDaSolheiz5CO+roz8ka97/4msh2E8F5qay4GawR5vzBt5MkbDHT+Rdy/Wg== -reselect@^5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-5.1.1.tgz#c766b1eb5d558291e5e550298adb0becc24bb72e" - integrity sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w== - resize-observer-polyfill@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" From 881a03b24af322ba7bc285f9ab302806157fe09c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sun, 29 Sep 2024 00:03:28 +0200 Subject: [PATCH 06/32] WIP hooks migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-api/lib/entities/status.ts | 10 ++- packages/pl-fe/src/actions/about.ts | 2 +- packages/pl-fe/src/actions/account-notes.ts | 3 +- packages/pl-fe/src/actions/accounts.ts | 3 +- packages/pl-fe/src/actions/admin.ts | 17 ++-- packages/pl-fe/src/actions/aliases.ts | 8 +- packages/pl-fe/src/actions/auth.ts | 12 ++- packages/pl-fe/src/actions/backups.ts | 2 +- packages/pl-fe/src/actions/bookmarks.ts | 9 +- packages/pl-fe/src/actions/compose.ts | 4 +- packages/pl-fe/src/actions/conversations.ts | 23 +++-- packages/pl-fe/src/actions/custom-emojis.ts | 2 +- packages/pl-fe/src/actions/directory.ts | 3 +- packages/pl-fe/src/actions/domain-blocks.ts | 3 +- packages/pl-fe/src/actions/draft-statuses.ts | 6 +- packages/pl-fe/src/actions/emoji-reacts.ts | 10 +-- packages/pl-fe/src/actions/events.ts | 14 ++- .../pl-fe/src/actions/familiar-followers.ts | 3 +- packages/pl-fe/src/actions/favourites.ts | 14 ++- packages/pl-fe/src/actions/filters.ts | 3 +- packages/pl-fe/src/actions/groups.ts | 3 +- packages/pl-fe/src/actions/import-data.ts | 3 +- packages/pl-fe/src/actions/importer/index.ts | 46 ---------- packages/pl-fe/src/actions/instance.ts | 3 +- packages/pl-fe/src/actions/interactions.ts | 3 +- packages/pl-fe/src/actions/lists.ts | 10 +-- packages/pl-fe/src/actions/markers.ts | 2 +- packages/pl-fe/src/actions/me.ts | 7 +- packages/pl-fe/src/actions/media.ts | 3 +- packages/pl-fe/src/actions/mfa.ts | 2 +- packages/pl-fe/src/actions/notifications.ts | 28 ++---- packages/pl-fe/src/actions/pin-statuses.ts | 8 +- packages/pl-fe/src/actions/pl-fe.ts | 3 +- packages/pl-fe/src/actions/polls.ts | 3 +- packages/pl-fe/src/actions/preload.ts | 5 +- .../pl-fe/src/actions/push-subscriptions.ts | 2 +- packages/pl-fe/src/actions/reports.ts | 3 +- .../pl-fe/src/actions/scheduled-statuses.ts | 2 +- packages/pl-fe/src/actions/search.ts | 20 +---- packages/pl-fe/src/actions/status-quotes.ts | 9 +- packages/pl-fe/src/actions/statuses.ts | 14 +-- packages/pl-fe/src/actions/suggestions.ts | 7 +- packages/pl-fe/src/actions/tags.ts | 2 +- packages/pl-fe/src/actions/timelines.ts | 13 ++- .../pl-fe/src/actions/trending-statuses.ts | 7 +- packages/pl-fe/src/actions/trends.ts | 2 +- .../pl-fe/src/components/status-content.tsx | 2 +- .../src/features/test-timeline/index.tsx | 4 +- .../compose-event-modal/upload-button.tsx | 1 - packages/pl-fe/src/normalizers/index.ts | 2 +- .../pl-fe/src/normalizers/notification.ts | 56 +----------- .../hooks/notifications/useNotification.ts | 74 +--------------- .../hooks/notifications/useNotifications.ts | 56 +----------- packages/pl-fe/src/pl-hooks/importer.ts | 86 ++----------------- .../pl-hooks/minifiers/minifyNotification.ts | 79 +++++++++++++++++ .../normalizers/deduplicateNotifications.ts | 45 ++++++++++ packages/pl-fe/src/queries/suggestions.ts | 6 +- packages/pl-fe/src/reducers/index.ts | 3 +- 58 files changed, 276 insertions(+), 499 deletions(-) create mode 100644 packages/pl-fe/src/pl-hooks/minifiers/minifyNotification.ts create mode 100644 packages/pl-fe/src/pl-hooks/normalizers/deduplicateNotifications.ts diff --git a/packages/pl-api/lib/entities/status.ts b/packages/pl-api/lib/entities/status.ts index 4512e8062..69dc9e2b4 100644 --- a/packages/pl-api/lib/entities/status.ts +++ b/packages/pl-api/lib/entities/status.ts @@ -1,7 +1,7 @@ import pick from 'lodash.pick'; import { z } from 'zod'; -import { accountSchema } from './account'; +import { type Account, accountSchema } from './account'; import { customEmojiSchema } from './custom-emoji'; import { emojiReactionSchema } from './emoji-reaction'; import { filterResultSchema } from './filter-result'; @@ -147,9 +147,15 @@ const statusWithoutAccountSchema = z.preprocess(preprocess, baseStatusSchema.omi quote: z.lazy(() => statusSchema).nullable().catch(null), })); +type StatusWithoutAccount = Omit, 'account'> & { + account: Account | null; + reblog: Status | null; + quote: Status | null; +} + type Status = z.infer & { reblog: Status | null; quote: Status | null; } -export { statusSchema, statusWithoutAccountSchema, type Status }; +export { statusSchema, statusWithoutAccountSchema, type Status, type StatusWithoutAccount }; diff --git a/packages/pl-fe/src/actions/about.ts b/packages/pl-fe/src/actions/about.ts index a1927d1da..c2237403a 100644 --- a/packages/pl-fe/src/actions/about.ts +++ b/packages/pl-fe/src/actions/about.ts @@ -1,4 +1,4 @@ -import { staticFetch } from '../api'; +import { staticFetch } from 'pl-fe/api'; import type { RootState } from 'pl-fe/store'; import type { AnyAction } from 'redux'; diff --git a/packages/pl-fe/src/actions/account-notes.ts b/packages/pl-fe/src/actions/account-notes.ts index eba436dcc..98794dd69 100644 --- a/packages/pl-fe/src/actions/account-notes.ts +++ b/packages/pl-fe/src/actions/account-notes.ts @@ -1,8 +1,7 @@ +import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/entity-store/actions'; import { Entities } from 'pl-fe/entity-store/entities'; -import { getClient } from '../api'; - import type { RootState } from 'pl-fe/store'; import type { AnyAction } from 'redux'; diff --git a/packages/pl-fe/src/actions/accounts.ts b/packages/pl-fe/src/actions/accounts.ts index 284cc2d68..f52b6002e 100644 --- a/packages/pl-fe/src/actions/accounts.ts +++ b/packages/pl-fe/src/actions/accounts.ts @@ -1,12 +1,11 @@ import { PLEROMA, type UpdateNotificationSettingsParams, type Account, type CreateAccountParams, type PaginatedResponse, type Relationship } from 'pl-api'; +import { getClient, type PlfeResponse } from 'pl-fe/api'; import { Entities } from 'pl-fe/entity-store/entities'; import { importEntities } from 'pl-fe/pl-hooks/importer'; import { selectAccount } from 'pl-fe/selectors'; import { isLoggedIn } from 'pl-fe/utils/auth'; -import { getClient, type PlfeResponse } from '../api'; - import type { Map as ImmutableMap } from 'immutable'; import type { MinifiedStatus } from 'pl-fe/reducers/statuses'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/admin.ts b/packages/pl-fe/src/actions/admin.ts index 23d11ff07..9f6f3ff8c 100644 --- a/packages/pl-fe/src/actions/admin.ts +++ b/packages/pl-fe/src/actions/admin.ts @@ -1,9 +1,8 @@ import { fetchRelationships } from 'pl-fe/actions/accounts'; -import { importFetchedAccount, importFetchedAccounts, importFetchedStatus, importFetchedStatuses } from 'pl-fe/actions/importer'; +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { filterBadges, getTagDiff } from 'pl-fe/utils/badges'; -import { getClient } from '../api'; - import { deleteFromTimelines } from './timelines'; import type { Account, AdminGetAccountsParams, AdminGetReportsParams, PleromaConfig } from 'pl-api'; @@ -111,9 +110,10 @@ const fetchReports = (params?: AdminGetReportsParams) => return getClient(state).admin.reports.getReports(params) .then(({ items }) => { items.forEach((report) => { - if (report.account?.account) dispatch(importFetchedAccount(report.account.account)); - if (report.target_account?.account) dispatch(importFetchedAccount(report.target_account.account)); - dispatch(importFetchedStatuses(report.statuses)); + const accounts = []; + if (report.account?.account) accounts.push(report.account.account); + if (report.target_account?.account) accounts.push(report.target_account.account); + importEntities({ accounts, statuses: report.statuses }); dispatch({ type: ADMIN_REPORTS_FETCH_SUCCESS, reports: items, params }); }); }).catch(error => { @@ -141,7 +141,8 @@ const fetchUsers = (params?: AdminGetAccountsParams) => dispatch({ type: ADMIN_USERS_FETCH_REQUEST, params }); return getClient(state).admin.accounts.getAccounts(params).then((res) => { - dispatch(importFetchedAccounts(res.items.map(({ account }) => account).filter((account): account is Account => account !== null))); + const accounts = res.items.map(({ account }) => account).filter((account): account is Account => account !== null); + importEntities({ accounts }); dispatch(fetchRelationships(res.items.map((account) => account.id))); dispatch({ type: ADMIN_USERS_FETCH_SUCCESS, users: res.items, params, next: res.next }); return res; @@ -203,7 +204,7 @@ const toggleStatusSensitivity = (statusId: string, sensitive: boolean) => dispatch({ type: ADMIN_STATUS_TOGGLE_SENSITIVITY_REQUEST, statusId }); return getClient(getState).admin.statuses.updateStatus(statusId, { sensitive: !sensitive }) .then((status) => { - dispatch(importFetchedStatus(status)); + importEntities({ statuses: [status] }); dispatch({ type: ADMIN_STATUS_TOGGLE_SENSITIVITY_SUCCESS, statusId, status }); }).catch(error => { dispatch({ type: ADMIN_STATUS_TOGGLE_SENSITIVITY_FAIL, error, statusId }); diff --git a/packages/pl-fe/src/actions/aliases.ts b/packages/pl-fe/src/actions/aliases.ts index c0af413d2..aad1dc396 100644 --- a/packages/pl-fe/src/actions/aliases.ts +++ b/packages/pl-fe/src/actions/aliases.ts @@ -1,12 +1,10 @@ import { defineMessages } from 'react-intl'; +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import toast from 'pl-fe/toast'; import { isLoggedIn } from 'pl-fe/utils/auth'; -import { getClient } from '../api'; - -import { importFetchedAccounts } from './importer'; - import type { Account as BaseAccount } from 'pl-api'; import type { Account } from 'pl-fe/normalizers'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -63,7 +61,7 @@ const fetchAliasesSuggestions = (q: string) => return getClient(getState()).accounts.searchAccounts(q, { resolve: true, limit: 4 }) .then((data) => { - dispatch(importFetchedAccounts(data)); + importEntities({ accounts: data }); dispatch(fetchAliasesSuggestionsReady(q, data)); }).catch(error => toast.showAlertForError(error)); }; diff --git a/packages/pl-fe/src/actions/auth.ts b/packages/pl-fe/src/actions/auth.ts index a438cef01..efb65ec74 100644 --- a/packages/pl-fe/src/actions/auth.ts +++ b/packages/pl-fe/src/actions/auth.ts @@ -14,8 +14,10 @@ import { createApp } from 'pl-fe/actions/apps'; import { fetchMeSuccess, fetchMeFail } from 'pl-fe/actions/me'; import { obtainOAuthToken, revokeOAuthToken } from 'pl-fe/actions/oauth'; import { startOnboarding } from 'pl-fe/actions/onboarding'; +import { type PlfeResponse, getClient } from 'pl-fe/api'; import * as BuildConfig from 'pl-fe/build-config'; import { custom } from 'pl-fe/custom'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { queryClient } from 'pl-fe/queries/client'; import { selectAccount } from 'pl-fe/selectors'; import { unsetSentryAccount } from 'pl-fe/sentry'; @@ -27,10 +29,6 @@ import { normalizeUsername } from 'pl-fe/utils/input'; import { getScopes } from 'pl-fe/utils/scopes'; import { isStandalone } from 'pl-fe/utils/state'; -import { type PlfeResponse, getClient } from '../api'; - -import { importFetchedAccount } from './importer'; - import type { AppDispatch, RootState } from 'pl-fe/store'; const SWITCH_ACCOUNT = 'SWITCH_ACCOUNT' as const; @@ -149,7 +147,7 @@ const verifyCredentials = (token: string, accountUrl?: string) => const client = new PlApiClient(baseURL, token); return client.settings.verifyCredentials().then((account) => { - dispatch(importFetchedAccount(account)); + importEntities({ accounts: [account] }); dispatch({ type: VERIFY_CREDENTIALS_SUCCESS, token, account }); if (account.id === getState().me) dispatch(fetchMeSuccess(account)); return account; @@ -158,7 +156,7 @@ const verifyCredentials = (token: string, accountUrl?: string) => // The user is waitlisted const account = error.response.json; const parsedAccount = credentialAccountSchema.parse(error.response.json); - dispatch(importFetchedAccount(parsedAccount)); + importEntities({ accounts: [parsedAccount] }); dispatch({ type: VERIFY_CREDENTIALS_SUCCESS, token, account: parsedAccount }); if (account.id === getState().me) dispatch(fetchMeSuccess(parsedAccount)); return parsedAccount; @@ -174,7 +172,7 @@ const rememberAuthAccount = (accountUrl: string) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch({ type: AUTH_ACCOUNT_REMEMBER_REQUEST, accountUrl }); return KVStore.getItemOrError(`authAccount:${accountUrl}`).then(account => { - dispatch(importFetchedAccount(account)); + importEntities({ accounts: [account] }); dispatch({ type: AUTH_ACCOUNT_REMEMBER_SUCCESS, account, accountUrl }); if (account.id === getState().me) dispatch(fetchMeSuccess(account)); return account; diff --git a/packages/pl-fe/src/actions/backups.ts b/packages/pl-fe/src/actions/backups.ts index 4a3d85994..f16178f42 100644 --- a/packages/pl-fe/src/actions/backups.ts +++ b/packages/pl-fe/src/actions/backups.ts @@ -1,4 +1,4 @@ -import { getClient } from '../api'; +import { getClient } from 'pl-fe/api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/bookmarks.ts b/packages/pl-fe/src/actions/bookmarks.ts index 276e1b397..f116a5995 100644 --- a/packages/pl-fe/src/actions/bookmarks.ts +++ b/packages/pl-fe/src/actions/bookmarks.ts @@ -1,6 +1,5 @@ -import { getClient } from '../api'; - -import { importFetchedStatuses } from './importer'; +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import type { PaginatedResponse, Status } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -24,7 +23,7 @@ const fetchBookmarkedStatuses = (folderId?: string) => dispatch(fetchBookmarkedStatusesRequest(folderId)); return getClient(getState()).myAccount.getBookmarks({ folder_id: folderId }).then(response => { - dispatch(importFetchedStatuses(response.items)); + importEntities({ statuses: response.items }); return dispatch(fetchBookmarkedStatusesSuccess(response.items, response.next, folderId)); }).catch(error => { dispatch(fetchBookmarkedStatusesFail(error, folderId)); @@ -61,7 +60,7 @@ const expandBookmarkedStatuses = (folderId?: string) => dispatch(expandBookmarkedStatusesRequest(folderId)); return next().then(response => { - dispatch(importFetchedStatuses(response.items)); + importEntities({ statuses: response.items }); return dispatch(expandBookmarkedStatusesSuccess(response.items, response.next, folderId)); }).catch(error => { dispatch(expandBookmarkedStatusesFail(error, folderId)); diff --git a/packages/pl-fe/src/actions/compose.ts b/packages/pl-fe/src/actions/compose.ts index 2e2c10d52..64d6d643f 100644 --- a/packages/pl-fe/src/actions/compose.ts +++ b/packages/pl-fe/src/actions/compose.ts @@ -5,6 +5,7 @@ import { getClient } from 'pl-fe/api'; import { isNativeEmoji } from 'pl-fe/features/emoji'; import emojiSearch from 'pl-fe/features/emoji/search'; import { Language } from 'pl-fe/features/preferences'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { selectAccount, selectOwnAccount, makeGetAccount } from 'pl-fe/selectors'; import { tagHistory } from 'pl-fe/settings'; import { useModalsStore } from 'pl-fe/stores'; @@ -12,7 +13,6 @@ import toast from 'pl-fe/toast'; import { isLoggedIn } from 'pl-fe/utils/auth'; import { chooseEmoji } from './emojis'; -import { importFetchedAccounts } from './importer'; import { rememberLanguageUse } from './languages'; import { uploadFile, updateMedia } from './media'; import { getSettings } from './settings'; @@ -590,7 +590,7 @@ const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, composeId, return getClient(getState).accounts.searchAccounts(token.slice(1), { resolve: false, limit: 10 }, { signal }) .then(response => { - dispatch(importFetchedAccounts(response)); + importEntities({ accounts: response }); dispatch(readyComposeSuggestionsAccounts(composeId, token, response)); }).catch(error => { if (!signal.aborted) { diff --git a/packages/pl-fe/src/actions/conversations.ts b/packages/pl-fe/src/actions/conversations.ts index 3f4a26ba7..adac3b19f 100644 --- a/packages/pl-fe/src/actions/conversations.ts +++ b/packages/pl-fe/src/actions/conversations.ts @@ -1,13 +1,7 @@ +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { isLoggedIn } from 'pl-fe/utils/auth'; -import { getClient } from '../api'; - -import { - importFetchedAccounts, - importFetchedStatuses, - importFetchedStatus, -} from './importer'; - import type { Account, Conversation, PaginatedResponse, Status } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -48,8 +42,11 @@ const expandConversations = (expand = true) => (dispatch: AppDispatch, getState: return (state.conversations.next?.() || getClient(state).timelines.getConversations()) .then(response => { - dispatch(importFetchedAccounts(response.items.reduce((aggr: Array, item) => aggr.concat(item.accounts), []))); - dispatch(importFetchedStatuses(response.items.map((item) => item.last_status).filter((x): x is Status => x !== null))); + const accounts = response.items.reduce((aggr: Array, item) => aggr.concat(item.accounts), []); + const statuses = response.items.map((item) => item.last_status).filter((x): x is Status => x !== null); + + importEntities({ accounts, statuses }); + dispatch(expandConversationsSuccess(response.items, response.next, isLoadingRecent)); }) .catch(err => dispatch(expandConversationsFail(err))); @@ -74,12 +71,14 @@ const expandConversationsFail = (error: unknown) => ({ }); const updateConversations = (conversation: Conversation) => (dispatch: AppDispatch) => { - dispatch(importFetchedAccounts(conversation.accounts)); + const statuses: Array = []; if (conversation.last_status) { - dispatch(importFetchedStatus(conversation.last_status)); + statuses.push(conversation.last_status); } + importEntities({ accounts: conversation.accounts, statuses }); + return dispatch({ type: CONVERSATIONS_UPDATE, conversation, diff --git a/packages/pl-fe/src/actions/custom-emojis.ts b/packages/pl-fe/src/actions/custom-emojis.ts index f5733b8fc..1e057cc8a 100644 --- a/packages/pl-fe/src/actions/custom-emojis.ts +++ b/packages/pl-fe/src/actions/custom-emojis.ts @@ -1,4 +1,4 @@ -import { getClient } from '../api'; +import { getClient } from 'pl-fe/api'; import type { CustomEmoji } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/directory.ts b/packages/pl-fe/src/actions/directory.ts index 4fecad216..bff0c19ba 100644 --- a/packages/pl-fe/src/actions/directory.ts +++ b/packages/pl-fe/src/actions/directory.ts @@ -1,7 +1,6 @@ +import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; -import { getClient } from '../api'; - import { fetchRelationships } from './accounts'; import type { Account, ProfileDirectoryParams } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/domain-blocks.ts b/packages/pl-fe/src/actions/domain-blocks.ts index c8a71b794..be29cdc8b 100644 --- a/packages/pl-fe/src/actions/domain-blocks.ts +++ b/packages/pl-fe/src/actions/domain-blocks.ts @@ -1,8 +1,7 @@ +import { getClient } from 'pl-fe/api'; import { Entities } from 'pl-fe/entity-store/entities'; import { isLoggedIn } from 'pl-fe/utils/auth'; -import { getClient } from '../api'; - import type { PaginatedResponse } from 'pl-api'; import type { EntityStore } from 'pl-fe/entity-store/types'; import type { Account } from 'pl-fe/normalizers'; diff --git a/packages/pl-fe/src/actions/draft-statuses.ts b/packages/pl-fe/src/actions/draft-statuses.ts index 09acdfae5..336121e13 100644 --- a/packages/pl-fe/src/actions/draft-statuses.ts +++ b/packages/pl-fe/src/actions/draft-statuses.ts @@ -5,10 +5,10 @@ import KVStore from 'pl-fe/storage/kv-store'; import type { AppDispatch, RootState } from 'pl-fe/store'; -const DRAFT_STATUSES_FETCH_SUCCESS = 'DRAFT_STATUSES_FETCH_SUCCESS'; +const DRAFT_STATUSES_FETCH_SUCCESS = 'DRAFT_STATUSES_FETCH_SUCCESS' as const; -const PERSIST_DRAFT_STATUS = 'PERSIST_DRAFT_STATUS'; -const CANCEL_DRAFT_STATUS = 'DELETE_DRAFT_STATUS'; +const PERSIST_DRAFT_STATUS = 'PERSIST_DRAFT_STATUS' as const; +const CANCEL_DRAFT_STATUS = 'DELETE_DRAFT_STATUS' as const; const getAccount = makeGetAccount(); diff --git a/packages/pl-fe/src/actions/emoji-reacts.ts b/packages/pl-fe/src/actions/emoji-reacts.ts index 5643b8b8f..54bc4899d 100644 --- a/packages/pl-fe/src/actions/emoji-reacts.ts +++ b/packages/pl-fe/src/actions/emoji-reacts.ts @@ -1,9 +1,7 @@ +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { isLoggedIn } from 'pl-fe/utils/auth'; -import { getClient } from '../api'; - -import { importFetchedStatus } from './importer'; - import type { Status } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -24,7 +22,7 @@ const emojiReact = (status: Pick, emoji: string, custom?: string) dispatch(emojiReactRequest(status.id, emoji, custom)); return getClient(getState).statuses.createStatusReaction(status.id, emoji).then((response) => { - dispatch(importFetchedStatus(response)); + importEntities({ statuses: [response] }); dispatch(emojiReactSuccess(response, emoji)); }).catch((error) => { dispatch(emojiReactFail(status.id, emoji, error)); @@ -38,7 +36,7 @@ const unEmojiReact = (status: Pick, emoji: string) => dispatch(unEmojiReactRequest(status.id, emoji)); return getClient(getState).statuses.deleteStatusReaction(status.id, emoji).then(response => { - dispatch(importFetchedStatus(response)); + importEntities({ statuses: [response] }); dispatch(unEmojiReactSuccess(response, emoji)); }).catch(error => { dispatch(unEmojiReactFail(status.id, emoji, error)); diff --git a/packages/pl-fe/src/actions/events.ts b/packages/pl-fe/src/actions/events.ts index 1ac8520db..515646a71 100644 --- a/packages/pl-fe/src/actions/events.ts +++ b/packages/pl-fe/src/actions/events.ts @@ -1,13 +1,11 @@ import { defineMessages } from 'react-intl'; +import { STATUS_FETCH_SOURCE_FAIL, STATUS_FETCH_SOURCE_REQUEST, STATUS_FETCH_SOURCE_SUCCESS } from 'pl-fe/actions/statuses'; import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; import { useModalsStore } from 'pl-fe/stores'; import toast from 'pl-fe/toast'; -import { importFetchedStatus, importFetchedStatuses } from './importer'; -import { STATUS_FETCH_SOURCE_FAIL, STATUS_FETCH_SOURCE_REQUEST, STATUS_FETCH_SOURCE_SUCCESS } from './statuses'; - import type { Account, CreateEventParams, Location, MediaAttachment, PaginatedResponse, Status } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -133,7 +131,7 @@ const submitEvent = ({ : getClient(state).events.editEvent(statusId, params) ).then((data) => { useModalsStore.getState().closeModal('COMPOSE_EVENT'); - dispatch(importFetchedStatus(data)); + importEntities({ statuses: [data] }); dispatch(submitEventSuccess(data)); toast.success( statusId ? messages.editSuccess : messages.success, @@ -172,7 +170,7 @@ const joinEvent = (statusId: string, participationMessage?: string) => dispatch(joinEventRequest(status.id)); return getClient(getState).events.joinEvent(statusId, participationMessage).then((data) => { - dispatch(importFetchedStatus(data)); + importEntities({ statuses: [data] }); dispatch(joinEventSuccess(status.id)); toast.success( data.event?.join_state === 'pending' ? messages.joinRequestSuccess : messages.joinSuccess, @@ -214,7 +212,7 @@ const leaveEvent = (statusId: string) => dispatch(leaveEventRequest(status.id)); return getClient(getState).events.leaveEvent(statusId).then((data) => { - dispatch(importFetchedStatus(data)); + importEntities({ statuses: [data] }); dispatch(leaveEventSuccess(status.id)); }).catch((error) => { dispatch(leaveEventFail(error, status.id)); @@ -480,7 +478,7 @@ const fetchRecentEvents = () => return getClient(getState()).timelines.publicTimeline({ only_events: true, }).then(response => { - dispatch(importFetchedStatuses(response.items)); + importEntities({ statuses: response.items }); dispatch({ type: RECENT_EVENTS_FETCH_SUCCESS, statuses: response.items, @@ -500,7 +498,7 @@ const fetchJoinedEvents = () => dispatch({ type: JOINED_EVENTS_FETCH_REQUEST }); getClient(getState).events.getJoinedEvents().then(response => { - dispatch(importFetchedStatuses(response.items)); + importEntities({ statuses: response.items }); dispatch({ type: JOINED_EVENTS_FETCH_SUCCESS, statuses: response.items, diff --git a/packages/pl-fe/src/actions/familiar-followers.ts b/packages/pl-fe/src/actions/familiar-followers.ts index d314f9128..404a99259 100644 --- a/packages/pl-fe/src/actions/familiar-followers.ts +++ b/packages/pl-fe/src/actions/familiar-followers.ts @@ -1,8 +1,7 @@ +import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; import { AppDispatch, RootState } from 'pl-fe/store'; -import { getClient } from '../api'; - import { fetchRelationships } from './accounts'; const FAMILIAR_FOLLOWERS_FETCH_REQUEST = 'FAMILIAR_FOLLOWERS_FETCH_REQUEST' as const; diff --git a/packages/pl-fe/src/actions/favourites.ts b/packages/pl-fe/src/actions/favourites.ts index 958e6517b..2ba10fcd5 100644 --- a/packages/pl-fe/src/actions/favourites.ts +++ b/packages/pl-fe/src/actions/favourites.ts @@ -1,9 +1,7 @@ +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { isLoggedIn } from 'pl-fe/utils/auth'; -import { getClient } from '../api'; - -import { importFetchedStatuses } from './importer'; - import type { PaginatedResponse, Status } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -34,7 +32,7 @@ const fetchFavouritedStatuses = () => dispatch(fetchFavouritedStatusesRequest()); return getClient(getState()).myAccount.getFavourites().then(response => { - dispatch(importFetchedStatuses(response.items)); + importEntities({ statuses: response.items }); dispatch(fetchFavouritedStatusesSuccess(response.items, response.next)); }).catch(error => { dispatch(fetchFavouritedStatusesFail(error)); @@ -69,7 +67,7 @@ const expandFavouritedStatuses = () => dispatch(expandFavouritedStatusesRequest()); return next().then(response => { - dispatch(importFetchedStatuses(response.items)); + importEntities({ statuses: response.items }); dispatch(expandFavouritedStatusesSuccess(response.items, response.next)); }).catch(error => { dispatch(expandFavouritedStatusesFail(error)); @@ -102,7 +100,7 @@ const fetchAccountFavouritedStatuses = (accountId: string) => dispatch(fetchAccountFavouritedStatusesRequest(accountId)); return getClient(getState).accounts.getAccountFavourites(accountId).then(response => { - dispatch(importFetchedStatuses(response.items)); + importEntities({ statuses: response.items }); dispatch(fetchAccountFavouritedStatusesSuccess(accountId, response.items, response.next)); }).catch(error => { dispatch(fetchAccountFavouritedStatusesFail(accountId, error)); @@ -140,7 +138,7 @@ const expandAccountFavouritedStatuses = (accountId: string) => dispatch(expandAccountFavouritedStatusesRequest(accountId)); return next().then(response => { - dispatch(importFetchedStatuses(response.items)); + importEntities({ statuses: response.items }); dispatch(expandAccountFavouritedStatusesSuccess(accountId, response.items, response.next)); }).catch(error => { dispatch(expandAccountFavouritedStatusesFail(accountId, error)); diff --git a/packages/pl-fe/src/actions/filters.ts b/packages/pl-fe/src/actions/filters.ts index 1499664ea..0959b10b3 100644 --- a/packages/pl-fe/src/actions/filters.ts +++ b/packages/pl-fe/src/actions/filters.ts @@ -1,10 +1,9 @@ import { defineMessages } from 'react-intl'; +import { getClient } from 'pl-fe/api'; import toast from 'pl-fe/toast'; import { isLoggedIn } from 'pl-fe/utils/auth'; -import { getClient } from '../api'; - import type { FilterContext } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/groups.ts b/packages/pl-fe/src/actions/groups.ts index fc8b469db..3c719c877 100644 --- a/packages/pl-fe/src/actions/groups.ts +++ b/packages/pl-fe/src/actions/groups.ts @@ -1,7 +1,6 @@ +import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; -import { getClient } from '../api'; - import type { Account, PaginatedResponse } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/import-data.ts b/packages/pl-fe/src/actions/import-data.ts index b5a01f72b..8fdb9a093 100644 --- a/packages/pl-fe/src/actions/import-data.ts +++ b/packages/pl-fe/src/actions/import-data.ts @@ -1,9 +1,8 @@ import { defineMessages } from 'react-intl'; +import { getClient } from 'pl-fe/api'; import toast from 'pl-fe/toast'; -import { getClient } from '../api'; - import type { RootState } from 'pl-fe/store'; const IMPORT_FOLLOWS_REQUEST = 'IMPORT_FOLLOWS_REQUEST' as const; diff --git a/packages/pl-fe/src/actions/importer/index.ts b/packages/pl-fe/src/actions/importer/index.ts index 20d5d4ebe..f1d1955ef 100644 --- a/packages/pl-fe/src/actions/importer/index.ts +++ b/packages/pl-fe/src/actions/importer/index.ts @@ -9,8 +9,6 @@ const STATUS_IMPORT = 'STATUS_IMPORT'; const STATUSES_IMPORT = 'STATUSES_IMPORT'; const POLLS_IMPORT = 'POLLS_IMPORT'; -const importAccount = (data: BaseAccount) => importAccounts([data]); - const importAccounts = (data: Array) => { let accounts: Array = []; @@ -111,44 +109,6 @@ const isBroken = (status: BaseStatus) => { } }; -const importFetchedStatuses = (statuses: Array & { account: BaseAccount | null }>) => (dispatch: AppDispatch) => { - const accounts: Record = {}; - const normalStatuses: Array = []; - const polls: Array = []; - - const processStatus = (status: BaseStatus) => { - if (status.account === null) return; - // Skip broken statuses - if (isBroken(status)) return; - - normalStatuses.push(status); - - accounts[status.account.id] = status.account; - // if (status.accounts) { - // accounts.push(...status.accounts); - // } - - if (status.reblog?.id) { - processStatus(status.reblog as BaseStatus); - } - - // Fedibird quotes - if (status.quote?.id) { - processStatus(status.quote as BaseStatus); - } - - if (status.poll?.id) { - polls.push(status.poll); - } - }; - - (statuses as Array).forEach(processStatus); - - dispatch(importPolls(polls)); - dispatch(importFetchedAccounts(Object.values(accounts))); - dispatch(importStatuses(normalStatuses)); -}; - const importFetchedPoll = (poll: Poll) => (dispatch: AppDispatch) => { dispatch(importPolls([poll])); @@ -158,16 +118,10 @@ export { STATUS_IMPORT, STATUSES_IMPORT, POLLS_IMPORT, - importAccount, importAccounts, - importGroup, importGroups, importStatus, importStatuses, importPolls, - importFetchedAccount, - importFetchedAccounts, importFetchedStatus, - importFetchedStatuses, - importFetchedPoll, }; diff --git a/packages/pl-fe/src/actions/instance.ts b/packages/pl-fe/src/actions/instance.ts index 629db73f8..565f97f45 100644 --- a/packages/pl-fe/src/actions/instance.ts +++ b/packages/pl-fe/src/actions/instance.ts @@ -1,7 +1,6 @@ +import { getClient } from 'pl-fe/api'; import { getAuthUserUrl, getMeUrl } from 'pl-fe/utils/auth'; -import { getClient } from '../api'; - import type { Instance } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/interactions.ts b/packages/pl-fe/src/actions/interactions.ts index 2473768e2..81a36c9c8 100644 --- a/packages/pl-fe/src/actions/interactions.ts +++ b/packages/pl-fe/src/actions/interactions.ts @@ -1,12 +1,11 @@ import { defineMessages } from 'react-intl'; +import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; import { useModalsStore } from 'pl-fe/stores'; import toast, { type IToastOptions } from 'pl-fe/toast'; import { isLoggedIn } from 'pl-fe/utils/auth'; -import { getClient } from '../api'; - import { fetchRelationships } from './accounts'; import type { Account, EmojiReaction, PaginatedResponse, Status } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/lists.ts b/packages/pl-fe/src/actions/lists.ts index df7ba4c0e..502a363a9 100644 --- a/packages/pl-fe/src/actions/lists.ts +++ b/packages/pl-fe/src/actions/lists.ts @@ -1,11 +1,9 @@ +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { selectAccount } from 'pl-fe/selectors'; import toast from 'pl-fe/toast'; import { isLoggedIn } from 'pl-fe/utils/auth'; -import { getClient } from '../api'; - -import { importFetchedAccounts } from './importer'; - import type { Account, List, PaginatedResponse } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -229,7 +227,7 @@ const fetchListAccounts = (listId: string) => (dispatch: AppDispatch, getState: dispatch(fetchListAccountsRequest(listId)); return getClient(getState()).lists.getListAccounts(listId).then(({ items, next }) => { - dispatch(importFetchedAccounts(items)); + importEntities({ accounts: items }); dispatch(fetchListAccountsSuccess(listId, items, next)); }).catch(err => dispatch(fetchListAccountsFail(listId, err))); }; @@ -256,7 +254,7 @@ const fetchListSuggestions = (q: string) => (dispatch: AppDispatch, getState: () if (!isLoggedIn(getState)) return; return getClient(getState()).accounts.searchAccounts(q, { resolve: false, limit: 4, following: true }).then((data) => { - dispatch(importFetchedAccounts(data)); + importEntities({ accounts: data }); dispatch(fetchListSuggestionsReady(q, data)); }).catch(error => toast.showAlertForError(error)); }; diff --git a/packages/pl-fe/src/actions/markers.ts b/packages/pl-fe/src/actions/markers.ts index 743a54744..988236b73 100644 --- a/packages/pl-fe/src/actions/markers.ts +++ b/packages/pl-fe/src/actions/markers.ts @@ -1,4 +1,4 @@ -import { getClient } from '../api'; +import { getClient } from 'pl-fe/api'; import type { SaveMarkersParams } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/me.ts b/packages/pl-fe/src/actions/me.ts index 25d5fe41d..0febc7f61 100644 --- a/packages/pl-fe/src/actions/me.ts +++ b/packages/pl-fe/src/actions/me.ts @@ -1,12 +1,11 @@ +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { selectAccount } from 'pl-fe/selectors'; import { setSentryAccount } from 'pl-fe/sentry'; import KVStore from 'pl-fe/storage/kv-store'; import { getAuthUserId, getAuthUserUrl } from 'pl-fe/utils/auth'; -import { getClient } from '../api'; - import { loadCredentials } from './auth'; -import { importFetchedAccount } from './importer'; import type { CredentialAccount, UpdateCredentialsParams } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -123,7 +122,7 @@ const patchMeSuccess = (me: CredentialAccount) => me, }; - dispatch(importFetchedAccount(me)); + importEntities({ accounts: [me] }); dispatch(action); }; diff --git a/packages/pl-fe/src/actions/media.ts b/packages/pl-fe/src/actions/media.ts index 7bfd4b293..f70d6f31c 100644 --- a/packages/pl-fe/src/actions/media.ts +++ b/packages/pl-fe/src/actions/media.ts @@ -1,12 +1,11 @@ import { defineMessages, type IntlShape } from 'react-intl'; +import { getClient } from 'pl-fe/api'; import toast from 'pl-fe/toast'; import { isLoggedIn } from 'pl-fe/utils/auth'; import { formatBytes, getVideoDuration } from 'pl-fe/utils/media'; import resizeImage from 'pl-fe/utils/resize-image'; -import { getClient } from '../api'; - import type { MediaAttachment, UploadMediaParams } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/mfa.ts b/packages/pl-fe/src/actions/mfa.ts index dbdad8d8e..9f63d43b0 100644 --- a/packages/pl-fe/src/actions/mfa.ts +++ b/packages/pl-fe/src/actions/mfa.ts @@ -1,4 +1,4 @@ -import { getClient } from '../api'; +import { getClient } from 'pl-fe/api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/notifications.ts b/packages/pl-fe/src/actions/notifications.ts index 201ff4657..a8e8dbad2 100644 --- a/packages/pl-fe/src/actions/notifications.ts +++ b/packages/pl-fe/src/actions/notifications.ts @@ -4,6 +4,7 @@ import { defineMessages } from 'react-intl'; import { getNotificationStatus } from 'pl-fe/features/notifications/components/notification'; import { normalizeNotification } from 'pl-fe/normalizers'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { getFilters, regexFromFilters } from 'pl-fe/selectors'; import { isLoggedIn } from 'pl-fe/utils/auth'; import { compareId } from 'pl-fe/utils/comparators'; @@ -11,14 +12,10 @@ import { unescapeHTML } from 'pl-fe/utils/html'; import { joinPublicPath } from 'pl-fe/utils/static'; import { fetchRelationships } from './accounts'; -import { - importFetchedAccount, - importFetchedStatus, -} from './importer'; import { saveMarker } from './markers'; import { getSettings, saveSettings } from './settings'; -import type { Notification as BaseNotification } from 'pl-api'; +import type { Notification } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE' as const; @@ -54,7 +51,7 @@ defineMessages({ mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' }, }); -const fetchRelatedRelationships = (dispatch: AppDispatch, notifications: Array) => { +const fetchRelatedRelationships = (dispatch: AppDispatch, notifications: Array) => { const accountIds = notifications.filter(item => item.type === 'follow').map(item => item.account.id); if (accountIds.length > 0) { @@ -62,24 +59,11 @@ const fetchRelatedRelationships = (dispatch: AppDispatch, notifications: Array +const updateNotifications = (notification: Notification) => (dispatch: AppDispatch, getState: () => RootState) => { const showInColumn = getSettings(getState()).getIn(['notifications', 'shows', notification.type], true); - if (notification.account) { - dispatch(importFetchedAccount(notification.account)); - } - - // Used by Move notification - if (notification.type === 'move' && notification.target) { - dispatch(importFetchedAccount(notification.target)); - } - - const status = getNotificationStatus(notification); - - if (status) { - dispatch(importFetchedStatus(status)); - } + importEntities({ notifications: [{ ...notification, accounts: [notification.account], duplicate: false }] }); if (showInColumn) { dispatch({ @@ -91,7 +75,7 @@ const updateNotifications = (notification: BaseNotification) => } }; -const updateNotificationsQueue = (notification: BaseNotification, intlMessages: Record, intlLocale: string, curPath: string) => +const updateNotificationsQueue = (notification: Notification, intlMessages: Record, intlLocale: string, curPath: string) => (dispatch: AppDispatch, getState: () => RootState) => { if (!notification.type) return; // drop invalid notifications if (notification.type === 'chat_mention') return; // Drop chat notifications, handle them per-chat diff --git a/packages/pl-fe/src/actions/pin-statuses.ts b/packages/pl-fe/src/actions/pin-statuses.ts index 86b18e6b9..f4968f194 100644 --- a/packages/pl-fe/src/actions/pin-statuses.ts +++ b/packages/pl-fe/src/actions/pin-statuses.ts @@ -1,9 +1,7 @@ +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { isLoggedIn } from 'pl-fe/utils/auth'; -import { getClient } from '../api'; - -import { importFetchedStatuses } from './importer'; - import type { Status } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -19,7 +17,7 @@ const fetchPinnedStatuses = () => dispatch(fetchPinnedStatusesRequest()); return getClient(getState()).accounts.getAccountStatuses(me as string, { pinned: true }).then(response => { - dispatch(importFetchedStatuses(response.items)); + importEntities({ statuses: response.items }); dispatch(fetchPinnedStatusesSuccess(response.items, null)); }).catch(error => { dispatch(fetchPinnedStatusesFail(error)); diff --git a/packages/pl-fe/src/actions/pl-fe.ts b/packages/pl-fe/src/actions/pl-fe.ts index 899be612c..7a150d263 100644 --- a/packages/pl-fe/src/actions/pl-fe.ts +++ b/packages/pl-fe/src/actions/pl-fe.ts @@ -1,11 +1,10 @@ import { createSelector } from 'reselect'; import { getHost } from 'pl-fe/actions/instance'; +import { getClient, staticFetch } from 'pl-fe/api'; import { normalizePlFeConfig } from 'pl-fe/normalizers'; import KVStore from 'pl-fe/storage/kv-store'; -import { getClient, staticFetch } from '../api'; - import type { AppDispatch, RootState } from 'pl-fe/store'; import type { APIEntity } from 'pl-fe/types/entities'; diff --git a/packages/pl-fe/src/actions/polls.ts b/packages/pl-fe/src/actions/polls.ts index f4f7e0c7a..c913f9ef8 100644 --- a/packages/pl-fe/src/actions/polls.ts +++ b/packages/pl-fe/src/actions/polls.ts @@ -1,7 +1,6 @@ +import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; -import { getClient } from '../api'; - import type { Poll } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/preload.ts b/packages/pl-fe/src/actions/preload.ts index 4b77263eb..7925046ea 100644 --- a/packages/pl-fe/src/actions/preload.ts +++ b/packages/pl-fe/src/actions/preload.ts @@ -1,7 +1,8 @@ import mapValues from 'lodash/mapValues'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; + import { verifyCredentials } from './auth'; -import { importFetchedAccounts } from './importer'; import type { AppDispatch } from 'pl-fe/store'; @@ -54,7 +55,7 @@ const preloadMastodon = (data: Record) => const { me, access_token } = data.meta; const { url } = data.accounts[me]; - dispatch(importFetchedAccounts(Object.values(data.accounts))); + importEntities({ accounts: Object.values(data.accounts) }); dispatch(verifyCredentials(access_token, url)); dispatch({ type: MASTODON_PRELOAD_IMPORT, data }); }; diff --git a/packages/pl-fe/src/actions/push-subscriptions.ts b/packages/pl-fe/src/actions/push-subscriptions.ts index 306fc5dfc..08d1370ed 100644 --- a/packages/pl-fe/src/actions/push-subscriptions.ts +++ b/packages/pl-fe/src/actions/push-subscriptions.ts @@ -1,4 +1,4 @@ -import { getClient } from '../api'; +import { getClient } from 'pl-fe/api'; import type { CreatePushNotificationsSubscriptionParams, UpdatePushNotificationsSubscriptionParams } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/reports.ts b/packages/pl-fe/src/actions/reports.ts index c0a1701c6..457403a5a 100644 --- a/packages/pl-fe/src/actions/reports.ts +++ b/packages/pl-fe/src/actions/reports.ts @@ -1,7 +1,6 @@ +import { getClient } from 'pl-fe/api'; import { useModalsStore } from 'pl-fe/stores'; -import { getClient } from '../api'; - import type { Account, Status } from 'pl-fe/normalizers'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/scheduled-statuses.ts b/packages/pl-fe/src/actions/scheduled-statuses.ts index 75da24ddf..6cc32e32b 100644 --- a/packages/pl-fe/src/actions/scheduled-statuses.ts +++ b/packages/pl-fe/src/actions/scheduled-statuses.ts @@ -1,4 +1,4 @@ -import { getClient } from '../api'; +import { getClient } from 'pl-fe/api'; import type { PaginatedResponse, ScheduledStatus } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/search.ts b/packages/pl-fe/src/actions/search.ts index d37c7f469..c7c03ad81 100644 --- a/packages/pl-fe/src/actions/search.ts +++ b/packages/pl-fe/src/actions/search.ts @@ -1,7 +1,7 @@ -import { getClient } from '../api'; +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { fetchRelationships } from './accounts'; -import { importFetchedAccounts, importFetchedStatuses } from './importer'; import type { Search } from 'pl-api'; import type { SearchFilter } from 'pl-fe/reducers/search'; @@ -52,13 +52,7 @@ const submitSearch = (value: string, filter?: SearchFilter) => if (accountId) params.account_id = accountId; return getClient(getState()).search.search(value, params).then(response => { - if (response.accounts) { - dispatch(importFetchedAccounts(response.accounts)); - } - - if (response.statuses) { - dispatch(importFetchedStatuses(response.statuses)); - } + importEntities({ accounts: response.accounts, statuses: response.statuses, groups: response.groups }); dispatch(fetchSearchSuccess(response, value, type)); dispatch(fetchRelationships(response.accounts.map((item) => item.id))); @@ -110,13 +104,7 @@ const expandSearch = (type: SearchFilter) => (dispatch: AppDispatch, getState: ( if (accountId) params.account_id = accountId; return getClient(getState()).search.search(value, params).then(response => { - if (response.accounts) { - dispatch(importFetchedAccounts(response.accounts)); - } - - if (response.statuses) { - dispatch(importFetchedStatuses(response.statuses)); - } + importEntities({ accounts: response.accounts, statuses: response.statuses, groups: response.groups }); dispatch(expandSearchSuccess(response, value, type)); dispatch(fetchRelationships(response.accounts.map((item) => item.id))); diff --git a/packages/pl-fe/src/actions/status-quotes.ts b/packages/pl-fe/src/actions/status-quotes.ts index b0669e409..a865e23cd 100644 --- a/packages/pl-fe/src/actions/status-quotes.ts +++ b/packages/pl-fe/src/actions/status-quotes.ts @@ -1,6 +1,5 @@ -import { getClient } from '../api'; - -import { importFetchedStatuses } from './importer'; +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import type { Status as BaseStatus, PaginatedResponse } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -43,7 +42,7 @@ const fetchStatusQuotes = (statusId: string) => dispatch(action); return getClient(getState).statuses.getStatusQuotes(statusId).then(response => { - dispatch(importFetchedStatuses(response.items)); + importEntities({ statuses: response.items }); const action: FetchStatusQuotesSuccessAction = { type: STATUS_QUOTES_FETCH_SUCCESS, statusId, @@ -94,7 +93,7 @@ const expandStatusQuotes = (statusId: string) => dispatch(action); return next().then(response => { - dispatch(importFetchedStatuses(response.items)); + importEntities({ statuses: response.items }); const action: ExpandStatusQuotesSuccessAction = { type: STATUS_QUOTES_EXPAND_SUCCESS, statusId, diff --git a/packages/pl-fe/src/actions/statuses.ts b/packages/pl-fe/src/actions/statuses.ts index 5be8c1341..cd0934ece 100644 --- a/packages/pl-fe/src/actions/statuses.ts +++ b/packages/pl-fe/src/actions/statuses.ts @@ -1,11 +1,11 @@ +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { useModalsStore } from 'pl-fe/stores'; import { isLoggedIn } from 'pl-fe/utils/auth'; import { shouldHaveCard } from 'pl-fe/utils/status'; -import { getClient } from '../api'; - import { setComposeToStatus } from './compose'; -import { importFetchedStatus, importFetchedStatuses } from './importer'; +import { importFetchedStatus } from './importer'; import { getSettings } from './settings'; import { deleteFromTimelines } from './timelines'; @@ -76,7 +76,7 @@ const createStatus = (params: CreateStatusParams, idempotencyKey: string, status const poll = (retries = 5) => { return getClient(getState()).statuses.getStatus(status.id).then(response => { if (response.card) { - dispatch(importFetchedStatus(response)); + importEntities({ statuses: [response] }); } else if (retries > 0 && response) { setTimeout(() => poll(retries - 1), delay); } @@ -119,7 +119,7 @@ const fetchStatus = (statusId: string, intl?: IntlShape) => } : undefined; return getClient(getState()).statuses.getStatus(statusId, params).then(status => { - dispatch(importFetchedStatus(status)); + importEntities({ statuses: [status] }); dispatch({ type: STATUS_FETCH_SUCCESS, status }); return status; }).catch(error => { @@ -153,7 +153,7 @@ const deleteStatus = (statusId: string, withRedraft = false) => }; const updateStatus = (status: BaseStatus) => (dispatch: AppDispatch) => - dispatch(importFetchedStatus(status)); + importEntities({ statuses: [status] }); const fetchContext = (statusId: string, intl?: IntlShape) => (dispatch: AppDispatch, getState: () => RootState) => { @@ -167,7 +167,7 @@ const fetchContext = (statusId: string, intl?: IntlShape) => if (typeof context === 'object') { const { ancestors, descendants } = context; const statuses = ancestors.concat(descendants); - dispatch(importFetchedStatuses(statuses)); + importEntities({ statuses }); dispatch({ type: CONTEXT_FETCH_SUCCESS, statusId, ancestors, descendants }); } else { throw context; diff --git a/packages/pl-fe/src/actions/suggestions.ts b/packages/pl-fe/src/actions/suggestions.ts index 8e8a8a7ad..59baafb7c 100644 --- a/packages/pl-fe/src/actions/suggestions.ts +++ b/packages/pl-fe/src/actions/suggestions.ts @@ -1,7 +1,7 @@ -import { getClient } from '../api'; +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { fetchRelationships } from './accounts'; -import { importFetchedAccounts } from './importer'; import { insertSuggestionsIntoTimeline } from './timelines'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -24,7 +24,8 @@ const fetchSuggestions = (limit = 50) => return getClient(getState).myAccount.getSuggestions(limit).then((suggestions) => { const accounts = suggestions.map(({ account }) => account); - dispatch(importFetchedAccounts(accounts)); + importEntities({ accounts }); + dispatch({ type: SUGGESTIONS_FETCH_SUCCESS, suggestions }); dispatch(fetchRelationships(accounts.map(({ id }) => id))); diff --git a/packages/pl-fe/src/actions/tags.ts b/packages/pl-fe/src/actions/tags.ts index bb7c6a3b6..72b428440 100644 --- a/packages/pl-fe/src/actions/tags.ts +++ b/packages/pl-fe/src/actions/tags.ts @@ -1,4 +1,4 @@ -import { getClient } from '../api'; +import { getClient } from 'pl-fe/api'; import type { PaginatedResponse, Tag } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/timelines.ts b/packages/pl-fe/src/actions/timelines.ts index bf7545367..641fe377f 100644 --- a/packages/pl-fe/src/actions/timelines.ts +++ b/packages/pl-fe/src/actions/timelines.ts @@ -1,12 +1,10 @@ import { Map as ImmutableMap } from 'immutable'; import { getLocale, getSettings } from 'pl-fe/actions/settings'; +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { shouldFilter } from 'pl-fe/utils/timelines'; -import { getClient } from '../api'; - -import { importFetchedStatus, importFetchedStatuses } from './importer'; - import type { PaginatedResponse, Status as BaseStatus, PublicTimelineParams, HomeTimelineParams, ListTimelineParams, HashtagTimelineParams, GetAccountStatusesParams, GroupTimelineParams } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -45,7 +43,7 @@ const processTimelineUpdate = (timeline: string, status: BaseStatus) => return; } - dispatch(importFetchedStatus(status)); + importEntities({ statuses: [status] }); if (shouldSkipQueue) { dispatch(updateTimeline(timeline, status.id)); @@ -158,10 +156,9 @@ const handleTimelineExpand = (timelineId: string, fn: Promise { - dispatch(importFetchedStatuses(response.items)); - const statuses = deduplicateStatuses(response.items); - dispatch(importFetchedStatuses(statuses.filter(status => status.accounts))); + + importEntities({ statuses: [...response.items, ...statuses.filter(status => status.accounts)] }); dispatch(expandTimelineSuccess( timelineId, diff --git a/packages/pl-fe/src/actions/trending-statuses.ts b/packages/pl-fe/src/actions/trending-statuses.ts index 692f13241..9534c4e18 100644 --- a/packages/pl-fe/src/actions/trending-statuses.ts +++ b/packages/pl-fe/src/actions/trending-statuses.ts @@ -1,6 +1,5 @@ -import { getClient } from '../api'; - -import { importFetchedStatuses } from './importer'; +import { getClient } from 'pl-fe/api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import type { AppDispatch, RootState } from 'pl-fe/store'; @@ -18,7 +17,7 @@ const fetchTrendingStatuses = () => dispatch({ type: TRENDING_STATUSES_FETCH_REQUEST }); return client.trends.getTrendingStatuses().then((statuses) => { - dispatch(importFetchedStatuses(statuses)); + importEntities({ statuses }); dispatch({ type: TRENDING_STATUSES_FETCH_SUCCESS, statuses }); return statuses; }).catch(error => { diff --git a/packages/pl-fe/src/actions/trends.ts b/packages/pl-fe/src/actions/trends.ts index 703b0cd43..ae7f7e01a 100644 --- a/packages/pl-fe/src/actions/trends.ts +++ b/packages/pl-fe/src/actions/trends.ts @@ -1,6 +1,6 @@ import type { Tag } from 'pl-api'; -const TRENDS_FETCH_SUCCESS = 'TRENDS_FETCH_SUCCESS'; +const TRENDS_FETCH_SUCCESS = 'TRENDS_FETCH_SUCCESS' as const; const fetchTrendsSuccess = (tags: Array) => ({ type: TRENDS_FETCH_SUCCESS, diff --git a/packages/pl-fe/src/components/status-content.tsx b/packages/pl-fe/src/components/status-content.tsx index b5c68b05e..7186d7609 100644 --- a/packages/pl-fe/src/components/status-content.tsx +++ b/packages/pl-fe/src/components/status-content.tsx @@ -1,7 +1,7 @@ import clsx from 'clsx'; import parse, { Element, type HTMLReactParserOptions, domToReact, type DOMNode } from 'html-react-parser'; import React, { useState, useRef, useLayoutEffect, useMemo, useEffect } from 'react'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; import { collapseStatusSpoiler, expandStatusSpoiler } from 'pl-fe/actions/statuses'; diff --git a/packages/pl-fe/src/features/test-timeline/index.tsx b/packages/pl-fe/src/features/test-timeline/index.tsx index 74c8006a0..ac7a8c8e2 100644 --- a/packages/pl-fe/src/features/test-timeline/index.tsx +++ b/packages/pl-fe/src/features/test-timeline/index.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { importFetchedStatuses } from 'pl-fe/actions/importer'; import { expandTimelineSuccess } from 'pl-fe/actions/timelines'; import { useAppDispatch, useTheme } from 'pl-fe/hooks'; import { useIsMobile } from 'pl-fe/hooks/useIsMobile'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { Column } from '../../components/ui'; import Timeline from '../ui/components/timeline'; @@ -35,7 +35,7 @@ const TestTimeline: React.FC = () => { const isMobile = useIsMobile(); React.useEffect(() => { - dispatch(importFetchedStatuses(MOCK_STATUSES)); + importEntities({ statuses: MOCK_STATUSES }); dispatch(expandTimelineSuccess(timelineId, MOCK_STATUSES, null, null, false, false)); }, []); diff --git a/packages/pl-fe/src/features/ui/components/modals/compose-event-modal/upload-button.tsx b/packages/pl-fe/src/features/ui/components/modals/compose-event-modal/upload-button.tsx index 7931b8d32..842ec67a5 100644 --- a/packages/pl-fe/src/features/ui/components/modals/compose-event-modal/upload-button.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/compose-event-modal/upload-button.tsx @@ -29,7 +29,6 @@ const UploadButton: React.FC = ({ disabled, onSelectFile }) => { fileElement.current?.click(); }; - return ( ({ - ...notification, + accounts: [notification.account], duplicate: false, - account: normalizeAccount(notification.account), - account_id: notification.account.id, - accounts: [normalizeAccount(notification.account)], - account_ids: [notification.account.id], + ...notification, }); -const normalizeNotifications = (notifications: Array, stateNotifications?: ImmutableOrderedMap) => { - const deduplicatedNotifications: Notification[] = []; - - for (const notification of notifications) { - const existingNotification = stateNotifications?.get(notification.id); - - // Do not update grouped notifications - if (existingNotification && (existingNotification.duplicate || existingNotification.account_ids.length)) continue; - - if (STATUS_NOTIFICATION_TYPES.includes(notification.type)) { - const existingNotification = deduplicatedNotifications - .find(deduplicated => - deduplicated.type === notification.type - && ((notification.type === 'emoji_reaction' && deduplicated.type === 'emoji_reaction') ? notification.emoji === deduplicated.emoji : true) - && getNotificationStatus(deduplicated)?.id === getNotificationStatus(notification)?.id, - ); - - if (existingNotification) { - existingNotification.accounts.push(normalizeAccount(notification.account)); - existingNotification.account_ids.push(notification.account.id); - deduplicatedNotifications.push({ ...normalizeNotification(notification), duplicate: true }); - } else { - deduplicatedNotifications.push(normalizeNotification(notification)); - } - } else { - deduplicatedNotifications.push(normalizeNotification(notification)); - } - } - - return deduplicatedNotifications; -}; - type Notification = ReturnType; -export { normalizeNotification, normalizeNotifications, type Notification }; +export { normalizeNotification, type Notification }; diff --git a/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotification.ts b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotification.ts index 9b65e8f37..8274260ff 100644 --- a/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotification.ts +++ b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotification.ts @@ -1,85 +1,13 @@ import { useQuery } from '@tanstack/react-query'; -import omit from 'lodash/omit'; import { useAppSelector, useClient } from 'pl-fe/hooks'; import { normalizeNotification, type Notification } from 'pl-fe/normalizers'; +import { type MinifiedNotification, minifyNotification } from 'pl-fe/pl-hooks/minifiers/minifyNotification'; import { queryClient } from 'pl-fe/queries/client'; import { selectAccount, selectAccounts } from 'pl-fe/selectors'; -import type { AccountWarning, RelationshipSeveranceEvent } from 'pl-api'; - type Account = ReturnType; -const minifyNotification = (notification: Notification) => { - // @ts-ignore - const minifiedNotification: { - duplicate: boolean; - account_id: string; - account_ids: string[]; - created_at: string; - id: string; - group_key: string; - } & ( - | { type: 'follow' | 'follow_request' | 'admin.sign_up' | 'bite' } - | { - type: 'mention'; - subtype?: 'reply'; - status_id: string; - } - | { - type: 'status' | 'reblog' | 'favourite' | 'poll' | 'update' | 'event_reminder'; - status_id: string; - } - | { - type: 'admin.report'; - report: Report; - } - | { - type: 'severed_relationships'; - relationship_severance_event: RelationshipSeveranceEvent; - } - | { - type: 'moderation_warning'; - moderation_warning: AccountWarning; - } - | { - type: 'move'; - target_id: string; - } - | { - type: 'emoji_reaction'; - emoji: string; - emoji_url: string | null; - status_id: string; - } - | { - type: 'chat_mention'; - chat_message_id: string; - } - | { - type: 'participation_accepted' | 'participation_request'; - status_id: string; - participation_message: string | null; - } - ) = { - ...omit(notification, ['account', 'accounts']), - created_at: notification.created_at, - id: notification.id, - type: notification.type, - }; - - // @ts-ignore - if (notification.status) minifiedNotification.status_id = notification.status.id; - // @ts-ignore - if (notification.target) minifiedNotification.target_id = notification.target.id; - // @ts-ignore - if (notification.chat_message) minifiedNotification.chat_message_id = notification.chat_message.id; - - return minifiedNotification; -}; - -type MinifiedNotification = ReturnType; - const importNotification = (notification: MinifiedNotification) => { queryClient.setQueryData( ['notifications', 'entities', notification.id], diff --git a/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts index c38f3a938..b8b6e92c2 100644 --- a/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts +++ b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts @@ -1,20 +1,14 @@ import { useInfiniteQuery } from '@tanstack/react-query'; -import { getNotificationStatus } from 'pl-fe/features/notifications/components/notification'; import { useClient } from 'pl-fe/hooks'; import { importEntities } from 'pl-fe/pl-hooks/importer'; +import { deduplicateNotifications } from 'pl-fe/pl-hooks/normalizers/deduplicateNotifications'; import { queryClient } from 'pl-fe/queries/client'; import { flattenPages } from 'pl-fe/utils/queries'; -import type { - Account as BaseAccount, - Notification as BaseNotification, - PaginatedResponse, - PlApiClient, -} from 'pl-api'; +import type { Notification as BaseNotification, PaginatedResponse, PlApiClient } from 'pl-api'; import type { NotificationType } from 'pl-fe/utils/notification'; - type UseNotificationParams = { types?: Array; excludeTypes?: Array; @@ -25,46 +19,6 @@ const getQueryKey = (params: UseNotificationParams) => [ params.types ? params.types.join('|') : params.excludeTypes ? ('exclude:' + params.excludeTypes.join('|')) : 'all', ]; -type DeduplicatedNotification = BaseNotification & { - accounts: Array; - duplicate?: boolean; -} - -const STATUS_NOTIFICATION_TYPES = [ - 'favourite', - 'reblog', - 'emoji_reaction', - 'event_reminder', - 'participation_accepted', - 'participation_request', -]; - -const deduplicateNotifications = (notifications: Array) => { - const deduplicatedNotifications: DeduplicatedNotification[] = []; - - for (const notification of notifications) { - if (STATUS_NOTIFICATION_TYPES.includes(notification.type)) { - const existingNotification = deduplicatedNotifications - .find(deduplicated => - deduplicated.type === notification.type - && ((notification.type === 'emoji_reaction' && deduplicated.type === 'emoji_reaction') ? notification.emoji === deduplicated.emoji : true) - && getNotificationStatus(deduplicated)?.id === getNotificationStatus(notification)?.id, - ); - - if (existingNotification) { - existingNotification.accounts.push(notification.account); - deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: true }); - } else { - deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: false }); - } - } else { - deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: false }); - } - } - - return deduplicatedNotifications; -}; - const importNotifications = (response: PaginatedResponse) => { const deduplicatedNotifications = deduplicateNotifications(response.items); @@ -72,10 +26,6 @@ const importNotifications = (response: PaginatedResponse) => { notifications: deduplicatedNotifications, }); - // const normalizedNotifications = normalizeNotifications(response.items); - - // normalizedNotifications.map(minifyNotification).forEach(importNotification); - return { items: deduplicatedNotifications.filter(({ duplicate }) => !duplicate).map(({ id }) => id), previous: response.previous, @@ -115,4 +65,4 @@ const prefetchNotifications = (client: PlApiClient, params: UseNotificationParam getNextPageParam: (response) => response, }); -export { useNotifications, prefetchNotifications, type DeduplicatedNotification }; +export { useNotifications, prefetchNotifications }; diff --git a/packages/pl-fe/src/pl-hooks/importer.ts b/packages/pl-fe/src/pl-hooks/importer.ts index 127284d35..879338c63 100644 --- a/packages/pl-fe/src/pl-hooks/importer.ts +++ b/packages/pl-fe/src/pl-hooks/importer.ts @@ -1,95 +1,20 @@ -import omit from 'lodash/omit'; - import { importAccounts, importGroups, importPolls, importStatuses } from 'pl-fe/actions/importer'; import { importEntities as importEntityStoreEntities } from 'pl-fe/entity-store/actions'; import { Entities } from 'pl-fe/entity-store/entities'; import { queryClient } from 'pl-fe/queries/client'; import { store } from 'pl-fe/store'; -import { DeduplicatedNotification } from './hooks/notifications/useNotifications'; +import { MinifiedNotification, minifyNotification } from './minifiers/minifyNotification'; +import { DeduplicatedNotification } from './normalizers/deduplicateNotifications'; import type { - AccountWarning, Account as BaseAccount, Group as BaseGroup, Poll as BasePoll, Relationship as BaseRelationship, - Status as BaseStatus, - RelationshipSeveranceEvent, + StatusWithoutAccount as BaseStatus, } from 'pl-api'; -const minifyNotification = (notification: DeduplicatedNotification) => { - // @ts-ignore - const minifiedNotification: { - duplicate: boolean; - account_id: string; - account_ids: string[]; - created_at: string; - id: string; - group_key: string; - } & ( - | { type: 'follow' | 'follow_request' | 'admin.sign_up' | 'bite' } - | { - type: 'mention'; - subtype?: 'reply'; - status_id: string; - } - | { - type: 'status' | 'reblog' | 'favourite' | 'poll' | 'update' | 'event_reminder'; - status_id: string; - } - | { - type: 'admin.report'; - report: Report; - } - | { - type: 'severed_relationships'; - relationship_severance_event: RelationshipSeveranceEvent; - } - | { - type: 'moderation_warning'; - moderation_warning: AccountWarning; - } - | { - type: 'move'; - target_id: string; - } - | { - type: 'emoji_reaction'; - emoji: string; - emoji_url: string | null; - status_id: string; - } - | { - type: 'chat_mention'; - chat_message_id: string; - } - | { - type: 'participation_accepted' | 'participation_request'; - status_id: string; - participation_message: string | null; - } - ) = { - ...omit(notification, ['account', 'accounts', 'status', 'target', 'chat_message']), - account_id: notification.account.id, - account_ids: notification.accounts.map(({ id }) => id), - created_at: notification.created_at, - id: notification.id, - type: notification.type, - }; - - // @ts-ignore - if (notification.status) minifiedNotification.status_id = notification.status.id; - // @ts-ignore - if (notification.target) minifiedNotification.target_id = notification.target.id; - // @ts-ignore - if (notification.chat_message) minifiedNotification.chat_message_id = notification.chat_message.id; - - return minifiedNotification; -}; - -type MinifiedNotification = ReturnType; - const importNotification = (notification: DeduplicatedNotification) => { queryClient.setQueryData( ['notifications', 'entities', notification.id], @@ -104,6 +29,7 @@ const isEmpty = (object: Record) => { const importEntities = (entities: { accounts?: Array; + groups?: Array; notifications?: Array; polls?: Array; statuses?: Array; @@ -136,8 +62,9 @@ const importEntities = (entities: { }; const processStatus = (status: BaseStatus) => { - statuses[status.id] = status; + if (!statuses[status.id] || status.account || !statuses[status.id].account) statuses[status.id] = status; + if (status.account) processAccount(status.account); if (status.quote) processStatus(status.quote); if (status.reblog) processStatus(status.reblog); if (status.poll) polls[status.poll.id] = status.poll; @@ -145,6 +72,7 @@ const importEntities = (entities: { }; entities.accounts?.forEach(processAccount); + entities.groups?.forEach(group => groups[group.id] = group); entities.notifications?.forEach(processNotification); entities.polls?.forEach(poll => polls[poll.id] = poll); entities.relationships?.forEach(relationship => relationships[relationship.id] = relationship); diff --git a/packages/pl-fe/src/pl-hooks/minifiers/minifyNotification.ts b/packages/pl-fe/src/pl-hooks/minifiers/minifyNotification.ts new file mode 100644 index 000000000..3a972088c --- /dev/null +++ b/packages/pl-fe/src/pl-hooks/minifiers/minifyNotification.ts @@ -0,0 +1,79 @@ +import omit from 'lodash/omit'; + +import { DeduplicatedNotification } from '../normalizers/deduplicateNotifications'; + +import type { AccountWarning, RelationshipSeveranceEvent } from 'pl-api'; + +const minifyNotification = (notification: DeduplicatedNotification) => { + // @ts-ignore + const minifiedNotification: { + duplicate: boolean; + account_id: string; + account_ids: string[]; + created_at: string; + id: string; + group_key: string; + } & ( + | { type: 'follow' | 'follow_request' | 'admin.sign_up' | 'bite' } + | { + type: 'mention'; + subtype?: 'reply'; + status_id: string; + } + | { + type: 'status' | 'reblog' | 'favourite' | 'poll' | 'update' | 'event_reminder'; + status_id: string; + } + | { + type: 'admin.report'; + report: Report; + } + | { + type: 'severed_relationships'; + relationship_severance_event: RelationshipSeveranceEvent; + } + | { + type: 'moderation_warning'; + moderation_warning: AccountWarning; + } + | { + type: 'move'; + target_id: string; + } + | { + type: 'emoji_reaction'; + emoji: string; + emoji_url: string | null; + status_id: string; + } + | { + type: 'chat_mention'; + chat_message_id: string; + } + | { + type: 'participation_accepted' | 'participation_request'; + status_id: string; + participation_message: string | null; + } + ) = { + ...omit(notification, ['account', 'accounts', 'status', 'target', 'chat_message']), + account_id: notification.account.id, + account_ids: notification.accounts.map(({ id }) => id), + created_at: notification.created_at, + id: notification.id, + type: notification.type, + }; + + // @ts-ignore + if (notification.status) minifiedNotification.status_id = notification.status.id; + // @ts-ignore + if (notification.target) minifiedNotification.target_id = notification.target.id; + // @ts-ignore + if (notification.chat_message) minifiedNotification.chat_message_id = notification.chat_message.id; + + return minifiedNotification; +}; + +type MinifiedNotification = ReturnType; + +export { minifyNotification, type MinifiedNotification }; diff --git a/packages/pl-fe/src/pl-hooks/normalizers/deduplicateNotifications.ts b/packages/pl-fe/src/pl-hooks/normalizers/deduplicateNotifications.ts new file mode 100644 index 000000000..41e0d7cfd --- /dev/null +++ b/packages/pl-fe/src/pl-hooks/normalizers/deduplicateNotifications.ts @@ -0,0 +1,45 @@ +import { getNotificationStatus } from 'pl-fe/features/notifications/components/notification'; + +import type { Account as BaseAccount, Notification as BaseNotification } from 'pl-api'; + +type DeduplicatedNotification = BaseNotification & { + accounts: Array; + duplicate?: boolean; +} + +const STATUS_NOTIFICATION_TYPES = [ + 'favourite', + 'reblog', + 'emoji_reaction', + 'event_reminder', + 'participation_accepted', + 'participation_request', +]; + +const deduplicateNotifications = (notifications: Array) => { + const deduplicatedNotifications: DeduplicatedNotification[] = []; + + for (const notification of notifications) { + if (STATUS_NOTIFICATION_TYPES.includes(notification.type)) { + const existingNotification = deduplicatedNotifications + .find(deduplicated => + deduplicated.type === notification.type + && ((notification.type === 'emoji_reaction' && deduplicated.type === 'emoji_reaction') ? notification.emoji === deduplicated.emoji : true) + && getNotificationStatus(deduplicated)?.id === getNotificationStatus(notification)?.id, + ); + + if (existingNotification) { + existingNotification.accounts.push(notification.account); + deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: true }); + } else { + deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: false }); + } + } else { + deduplicatedNotifications.push({ ...notification, accounts: [notification.account], duplicate: false }); + } + } + + return deduplicatedNotifications; +}; + +export { deduplicateNotifications, type DeduplicatedNotification }; diff --git a/packages/pl-fe/src/queries/suggestions.ts b/packages/pl-fe/src/queries/suggestions.ts index 427c73dcd..3484a03eb 100644 --- a/packages/pl-fe/src/queries/suggestions.ts +++ b/packages/pl-fe/src/queries/suggestions.ts @@ -1,8 +1,8 @@ import { useMutation, keepPreviousData, useQuery } from '@tanstack/react-query'; import { fetchRelationships } from 'pl-fe/actions/accounts'; -import { importFetchedAccounts } from 'pl-fe/actions/importer'; import { useAppDispatch, useClient } from 'pl-fe/hooks'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { removePageItem } from '../utils/queries'; @@ -19,7 +19,7 @@ const useSuggestions = () => { const accounts = response.map(({ account }) => account); const accountIds = accounts.map((account) => account.id); - dispatch(importFetchedAccounts(accounts)); + importEntities({ accounts }); dispatch(fetchRelationships(accountIds)); return response.map(({ account, ...x }) => ({ ...x, account_id: account.id })); @@ -59,7 +59,7 @@ const useOnboardingSuggestions = () => { const accounts = response.map(({ account }) => account); const accountIds = accounts.map((account) => account.id); - dispatch(importFetchedAccounts(accounts)); + importEntities({ accounts }); dispatch(fetchRelationships(accountIds)); return response; diff --git a/packages/pl-fe/src/reducers/index.ts b/packages/pl-fe/src/reducers/index.ts index 862844512..4f24b9e52 100644 --- a/packages/pl-fe/src/reducers/index.ts +++ b/packages/pl-fe/src/reducers/index.ts @@ -1,7 +1,6 @@ import { Record as ImmutableRecord } from 'immutable'; import { combineReducers } from 'redux-immutable'; -import { AUTH_LOGGED_OUT } from 'pl-fe/actions/auth'; import * as BuildConfig from 'pl-fe/build-config'; import entities from 'pl-fe/entity-store/reducer'; @@ -126,7 +125,7 @@ const logOut = (state: any = StateRecord()): ReturnType => { const rootReducer: typeof appReducer = (state, action) => { switch (action.type) { - case AUTH_LOGGED_OUT: + case 'AUTH_LOGGED_OUT': return appReducer(logOut(state), action); default: return appReducer(state, action); From 6a232f204efdacb93b7034450c05ef1e25c2d524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sun, 29 Sep 2024 12:53:06 +0200 Subject: [PATCH 07/32] Fix imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-fe/src/pl-hooks/importer.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/pl-fe/src/pl-hooks/importer.ts b/packages/pl-fe/src/pl-hooks/importer.ts index 84f56786e..c1155a625 100644 --- a/packages/pl-fe/src/pl-hooks/importer.ts +++ b/packages/pl-fe/src/pl-hooks/importer.ts @@ -4,7 +4,10 @@ import { importAccounts, importGroups, importPolls, importStatuses } from 'pl-fe import { importEntities as importEntityStoreEntities } from 'pl-fe/entity-store/actions'; import { Entities } from 'pl-fe/entity-store/entities'; import { queryClient } from 'pl-fe/queries/client'; -import { store } from 'pl-fe/store'; + +let dispatch: AppDispatch; + +import('pl-fe/store').then(value => dispatch = value.store.dispatch).catch(() => {}); import { DeduplicatedNotification } from './hooks/notifications/useNotifications'; @@ -17,6 +20,7 @@ import type { Status as BaseStatus, RelationshipSeveranceEvent, } from 'pl-api'; +import type { AppDispatch } from 'pl-fe/store'; const minifyNotification = (notification: DeduplicatedNotification) => { @@ -104,8 +108,6 @@ const importEntities = (entities: { statuses?: Array; relationships?: Array; }) => { - const { dispatch } = store; - const accounts: Record = {}; const groups: Record = {}; const notifications: Record = {}; From 79c17473fee82b5d65ec9c8c00612e0aeebb57bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sun, 29 Sep 2024 13:26:09 +0200 Subject: [PATCH 08/32] improve display, fix importing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-fe/src/actions/admin.ts | 11 ++++++++--- packages/pl-fe/src/components/scrollable-list.tsx | 2 +- packages/pl-fe/src/features/notifications/index.tsx | 4 ++-- packages/pl-fe/src/pl-hooks/importer.ts | 8 +++++--- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/pl-fe/src/actions/admin.ts b/packages/pl-fe/src/actions/admin.ts index 9f6f3ff8c..4be3d0741 100644 --- a/packages/pl-fe/src/actions/admin.ts +++ b/packages/pl-fe/src/actions/admin.ts @@ -5,7 +5,7 @@ import { filterBadges, getTagDiff } from 'pl-fe/utils/badges'; import { deleteFromTimelines } from './timelines'; -import type { Account, AdminGetAccountsParams, AdminGetReportsParams, PleromaConfig } from 'pl-api'; +import type { Account, AdminGetAccountsParams, AdminGetReportsParams, PleromaConfig, Status } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; const ADMIN_CONFIG_FETCH_REQUEST = 'ADMIN_CONFIG_FETCH_REQUEST' as const; @@ -109,13 +109,18 @@ const fetchReports = (params?: AdminGetReportsParams) => return getClient(state).admin.reports.getReports(params) .then(({ items }) => { + const accounts: Array = []; + const statuses: Array = []; + items.forEach((report) => { - const accounts = []; if (report.account?.account) accounts.push(report.account.account); if (report.target_account?.account) accounts.push(report.target_account.account); - importEntities({ accounts, statuses: report.statuses }); + statuses.push(...report.statuses as Array); + dispatch({ type: ADMIN_REPORTS_FETCH_SUCCESS, reports: items, params }); }); + + importEntities({ accounts, statuses }); }).catch(error => { dispatch({ type: ADMIN_REPORTS_FETCH_FAIL, error, params }); }); diff --git a/packages/pl-fe/src/components/scrollable-list.tsx b/packages/pl-fe/src/components/scrollable-list.tsx index 7aa8b5b10..edaf7e1af 100644 --- a/packages/pl-fe/src/components/scrollable-list.tsx +++ b/packages/pl-fe/src/components/scrollable-list.tsx @@ -185,7 +185,7 @@ const ScrollableList = React.forwardRef, IScrollableList & position: 'relative', }} > - {!showLoading && data.length ? ( + {(!showLoading || showPlaceholder) && data.length ? ( <> {prepend} {virtualItems.map((item) => ( diff --git a/packages/pl-fe/src/features/notifications/index.tsx b/packages/pl-fe/src/features/notifications/index.tsx index d72436344..3df7e3042 100644 --- a/packages/pl-fe/src/features/notifications/index.tsx +++ b/packages/pl-fe/src/features/notifications/index.tsx @@ -129,8 +129,8 @@ const Notifications = () => { const scrollContainer = ( { - if (!statuses[status.id] || status.account || !statuses[status.id].account) statuses[status.id] = status; + if (status.account) { + statuses[status.id] = status; + processAccount(status.account); + } - if (status.account) processAccount(status.account); if (status.quote) processStatus(status.quote); if (status.reblog) processStatus(status.reblog); if (status.poll) polls[status.poll.id] = status.poll; From f2fba8e4db012e8d57351ad306e075a998c1c641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sun, 29 Sep 2024 18:07:55 +0200 Subject: [PATCH 09/32] wip hooks migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-fe/src/actions/markers.ts | 43 ------------- packages/pl-fe/src/actions/notifications.ts | 47 +-------------- .../src/api/hooks/streaming/useUserStream.ts | 5 +- .../src/features/notifications/index.tsx | 51 ++++++++++------ packages/pl-fe/src/features/ui/index.tsx | 6 +- .../src/pl-hooks/hooks/markers/useMarkers.ts | 42 +++++++++++++ ...otifications.ts => useNotificationList.ts} | 9 ++- packages/pl-fe/src/reducers/notifications.ts | 60 +------------------ 8 files changed, 86 insertions(+), 177 deletions(-) delete mode 100644 packages/pl-fe/src/actions/markers.ts create mode 100644 packages/pl-fe/src/pl-hooks/hooks/markers/useMarkers.ts rename packages/pl-fe/src/pl-hooks/hooks/notifications/{useNotifications.ts => useNotificationList.ts} (87%) diff --git a/packages/pl-fe/src/actions/markers.ts b/packages/pl-fe/src/actions/markers.ts deleted file mode 100644 index 988236b73..000000000 --- a/packages/pl-fe/src/actions/markers.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { getClient } from 'pl-fe/api'; - -import type { SaveMarkersParams } from 'pl-api'; -import type { AppDispatch, RootState } from 'pl-fe/store'; - -const MARKER_FETCH_REQUEST = 'MARKER_FETCH_REQUEST' as const; -const MARKER_FETCH_SUCCESS = 'MARKER_FETCH_SUCCESS' as const; -const MARKER_FETCH_FAIL = 'MARKER_FETCH_FAIL' as const; - -const MARKER_SAVE_REQUEST = 'MARKER_SAVE_REQUEST' as const; -const MARKER_SAVE_SUCCESS = 'MARKER_SAVE_SUCCESS' as const; -const MARKER_SAVE_FAIL = 'MARKER_SAVE_FAIL' as const; - -const fetchMarker = (timeline: Array) => - (dispatch: AppDispatch, getState: () => RootState) => { - dispatch({ type: MARKER_FETCH_REQUEST }); - return getClient(getState).timelines.getMarkers(timeline).then((marker) => { - dispatch({ type: MARKER_FETCH_SUCCESS, marker }); - }).catch(error => { - dispatch({ type: MARKER_FETCH_FAIL, error }); - }); - }; - -const saveMarker = (marker: SaveMarkersParams) => - (dispatch: AppDispatch, getState: () => RootState) => { - dispatch({ type: MARKER_SAVE_REQUEST, marker }); - return getClient(getState).timelines.saveMarkers(marker).then((marker) => { - dispatch({ type: MARKER_SAVE_SUCCESS, marker }); - }).catch(error => { - dispatch({ type: MARKER_SAVE_FAIL, error }); - }); - }; - -export { - MARKER_FETCH_REQUEST, - MARKER_FETCH_SUCCESS, - MARKER_FETCH_FAIL, - MARKER_SAVE_REQUEST, - MARKER_SAVE_SUCCESS, - MARKER_SAVE_FAIL, - fetchMarker, - saveMarker, -}; diff --git a/packages/pl-fe/src/actions/notifications.ts b/packages/pl-fe/src/actions/notifications.ts index a8e8dbad2..9a3311f8a 100644 --- a/packages/pl-fe/src/actions/notifications.ts +++ b/packages/pl-fe/src/actions/notifications.ts @@ -6,13 +6,10 @@ import { getNotificationStatus } from 'pl-fe/features/notifications/components/n import { normalizeNotification } from 'pl-fe/normalizers'; import { importEntities } from 'pl-fe/pl-hooks/importer'; import { getFilters, regexFromFilters } from 'pl-fe/selectors'; -import { isLoggedIn } from 'pl-fe/utils/auth'; -import { compareId } from 'pl-fe/utils/comparators'; import { unescapeHTML } from 'pl-fe/utils/html'; import { joinPublicPath } from 'pl-fe/utils/static'; import { fetchRelationships } from './accounts'; -import { saveMarker } from './markers'; import { getSettings, saveSettings } from './settings'; import type { Notification } from 'pl-api'; @@ -25,13 +22,6 @@ const NOTIFICATIONS_DEQUEUE = 'NOTIFICATIONS_DEQUEUE' as const; const NOTIFICATIONS_FILTER_SET = 'NOTIFICATIONS_FILTER_SET' as const; -const NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR' as const; -const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP' as const; - -const NOTIFICATIONS_MARK_READ_REQUEST = 'NOTIFICATIONS_MARK_READ_REQUEST' as const; -const NOTIFICATIONS_MARK_READ_SUCCESS = 'NOTIFICATIONS_MARK_READ_SUCCESS' as const; -const NOTIFICATIONS_MARK_READ_FAIL = 'NOTIFICATIONS_MARK_READ_FAIL' as const; - const MAX_QUEUED_NOTIFICATIONS = 40; type FILTER_TYPES = { @@ -156,16 +146,7 @@ const dequeueNotifications = () => dispatch({ type: NOTIFICATIONS_DEQUEUE, }); - dispatch(markReadNotifications()); - }; - -const scrollTopNotifications = (top: boolean) => - (dispatch: AppDispatch) => { - dispatch({ - type: NOTIFICATIONS_SCROLL_TOP, - top, - }); - dispatch(markReadNotifications()); + // dispatch(markReadNotifications()); }; const setFilter = (filterType: FilterType, abort?: boolean) => @@ -180,42 +161,16 @@ const setFilter = (filterType: FilterType, abort?: boolean) => if (activeFilter !== filterType) dispatch(saveSettings()); }; -const markReadNotifications = () => - (dispatch: AppDispatch, getState: () => RootState) => { - if (!isLoggedIn(getState)) return; - - const state = getState(); - const topNotificationId = state.notifications.items.first()?.id; - const lastReadId = state.notifications.lastRead; - - if (topNotificationId && (lastReadId === -1 || compareId(topNotificationId, lastReadId) > 0)) { - const marker = { - notifications: { - last_read_id: topNotificationId, - }, - }; - - dispatch(saveMarker(marker)); - } - }; - export { NOTIFICATIONS_UPDATE, NOTIFICATIONS_UPDATE_NOOP, NOTIFICATIONS_UPDATE_QUEUE, NOTIFICATIONS_DEQUEUE, NOTIFICATIONS_FILTER_SET, - NOTIFICATIONS_CLEAR, - NOTIFICATIONS_SCROLL_TOP, - NOTIFICATIONS_MARK_READ_REQUEST, - NOTIFICATIONS_MARK_READ_SUCCESS, - NOTIFICATIONS_MARK_READ_FAIL, MAX_QUEUED_NOTIFICATIONS, type FilterType, updateNotifications, updateNotificationsQueue, dequeueNotifications, - scrollTopNotifications, setFilter, - markReadNotifications, }; diff --git a/packages/pl-fe/src/api/hooks/streaming/useUserStream.ts b/packages/pl-fe/src/api/hooks/streaming/useUserStream.ts index 976db0d4a..fb962f459 100644 --- a/packages/pl-fe/src/api/hooks/streaming/useUserStream.ts +++ b/packages/pl-fe/src/api/hooks/streaming/useUserStream.ts @@ -2,7 +2,6 @@ import { useCallback } from 'react'; import { updateConversations } from 'pl-fe/actions/conversations'; import { fetchFilters } from 'pl-fe/actions/filters'; -import { MARKER_FETCH_SUCCESS } from 'pl-fe/actions/markers'; import { updateNotificationsQueue } from 'pl-fe/actions/notifications'; import { getLocale, getSettings } from 'pl-fe/actions/settings'; import { updateStatus } from 'pl-fe/actions/statuses'; @@ -21,7 +20,7 @@ import { updateReactions } from '../announcements/useAnnouncements'; import { useTimelineStream } from './useTimelineStream'; -import type { Announcement, AnnouncementReaction, FollowRelationshipUpdate, Relationship, StreamingEvent } from 'pl-api'; +import type { Announcement, AnnouncementReaction, FollowRelationshipUpdate, Marker, Relationship, StreamingEvent } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; const updateAnnouncementReactions = ({ announcement_id: id, name }: AnnouncementReaction) => { @@ -169,7 +168,7 @@ const useUserStream = () => { deleteAnnouncement(event.payload); break; case 'marker': - dispatch({ type: MARKER_FETCH_SUCCESS, marker: event.payload }); + Object.entries(event.payload).forEach(([key, marker]) => queryClient.setQueryData(['markers', key], marker)); break; } }, []); diff --git a/packages/pl-fe/src/features/notifications/index.tsx b/packages/pl-fe/src/features/notifications/index.tsx index 3df7e3042..0e0e7d1cd 100644 --- a/packages/pl-fe/src/features/notifications/index.tsx +++ b/packages/pl-fe/src/features/notifications/index.tsx @@ -3,17 +3,16 @@ import debounce from 'lodash/debounce'; import React, { useCallback, useEffect, useRef } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; -import { - scrollTopNotifications, - dequeueNotifications, -} from 'pl-fe/actions/notifications'; +import { dequeueNotifications } from 'pl-fe/actions/notifications'; import PullToRefresh from 'pl-fe/components/pull-to-refresh'; import ScrollTopButton from 'pl-fe/components/scroll-top-button'; import ScrollableList from 'pl-fe/components/scrollable-list'; import { Column, Portal } from 'pl-fe/components/ui'; import PlaceholderNotification from 'pl-fe/features/placeholder/components/placeholder-notification'; import { useAppDispatch, useAppSelector, useSettings } from 'pl-fe/hooks'; -import { useNotifications } from 'pl-fe/pl-hooks/hooks/notifications/useNotifications'; +import { useMarker, useUpdateMarkerMutation } from 'pl-fe/pl-hooks/hooks/markers/useMarkers'; +import { useNotificationList } from 'pl-fe/pl-hooks/hooks/notifications/useNotificationList'; +import { compareId } from 'pl-fe/utils/comparators'; import { NotificationType } from 'pl-fe/utils/notification'; import FilterBar from './components/filter-bar'; @@ -42,15 +41,19 @@ const Notifications = () => { const intl = useIntl(); const settings = useSettings(); + const activeFilter = settings.notifications.quickFilter.active as FilterType; const params = activeFilter === 'all' ? {} : { types: FILTER_TYPES[activeFilter] || [activeFilter] as Array, }; - const notificationsQuery = useNotifications(params); + const notificationListQuery = useNotificationList(params); - const notifications = notificationsQuery.data; + const markerQuery = useMarker('notifications'); + const updateMarkerMutation = useUpdateMarkerMutation('notifications'); + + const notifications = notificationListQuery.data; const showFilterBar = settings.notifications.quickFilter.show; const totalQueuedNotificationsCount = useAppSelector(state => state.notifications.totalQueuedNotificationsCount || 0); @@ -59,12 +62,23 @@ const Notifications = () => { const scrollableContentRef = useRef | null>(null); const handleLoadOlder = useCallback(debounce(() => { - if (notificationsQuery.hasNextPage) notificationsQuery.fetchNextPage(); - }, 300, { leading: true }), [notificationsQuery.hasNextPage]); + if (notificationListQuery.hasNextPage) notificationListQuery.fetchNextPage(); + }, 300, { leading: true }), [notificationListQuery.hasNextPage]); + + const handleScrollToTop = () => { + const topNotificationId = notificationListQuery.data[0]; + const lastReadId = markerQuery.data?.last_read_id || -1; + + if (topNotificationId && (lastReadId === -1 || compareId(topNotificationId, lastReadId) > 0)) { + updateMarkerMutation.mutate(topNotificationId); + } + }; const handleScroll = useCallback(debounce((startIndex?: number) => { - dispatch(scrollTopNotifications(startIndex === 0)); - }, 100), []); + if (startIndex !== 0) return; + + handleScrollToTop(); + }, 100), [handleScrollToTop]); const handleMoveUp = (id: string) => { const elementIndex = notifications.findIndex(item => item !== null && item === id) - 1; @@ -87,16 +101,15 @@ const Notifications = () => { dispatch(dequeueNotifications()); }, []); - const handleRefresh = useCallback(() => notificationsQuery.refetch(), []); + const handleRefresh = useCallback(() => notificationListQuery.refetch(), []); useEffect(() => { handleDequeueNotifications(); - dispatch(scrollTopNotifications(true)); + handleScrollToTop(); return () => { handleLoadOlder.cancel(); handleScroll.cancel(); - dispatch(scrollTopNotifications(false)); }; }, []); @@ -110,9 +123,9 @@ const Notifications = () => { ? () : null; - if (notificationsQuery.isLoading && scrollableContentRef.current) { + if (notificationListQuery.isLoading && scrollableContentRef.current) { scrollableContent = scrollableContentRef.current; - } else if (notifications.length > 0 || notificationsQuery.hasNextPage) { + } else if (notifications.length > 0 || notificationListQuery.hasNextPage) { scrollableContent = notifications.map((notificationId) => ( { const scrollContainer = ( = ({ children }) => { })); prefetchNotifications(client, notificationsParams) - .then(() => dispatch(fetchMarker(['notifications']))) + .then(() => prefetchMarker(client, 'notifications')) .catch(console.error); if (account.is_admin || account.is_moderator) { diff --git a/packages/pl-fe/src/pl-hooks/hooks/markers/useMarkers.ts b/packages/pl-fe/src/pl-hooks/hooks/markers/useMarkers.ts new file mode 100644 index 000000000..7c4fda46d --- /dev/null +++ b/packages/pl-fe/src/pl-hooks/hooks/markers/useMarkers.ts @@ -0,0 +1,42 @@ +import { useMutation, useQuery } from '@tanstack/react-query'; + +import { useClient } from 'pl-fe/hooks'; +import { queryClient } from 'pl-fe/queries/client'; + +import type { Marker, PlApiClient } from 'pl-api'; + +type Timeline = 'home' | 'notifications'; + +const useMarker = (timeline: Timeline) => { + const client = useClient(); + + return useQuery({ + queryKey: ['markers', timeline], + queryFn: () => client.timelines.getMarkers([timeline]).then(markers => markers[timeline]), + }); +}; + +const useUpdateMarkerMutation = (timeline: Timeline) => { + const client = useClient(); + + return useMutation({ + mutationFn: (lastReadId: string) => client.timelines.saveMarkers({ + [timeline]: { + last_read_id: lastReadId, + }, + }), + retry: false, + onMutate: (lastReadId) => queryClient.setQueryData(['markers', timeline], (marker) => marker ? ({ + ...marker, + last_read_id: lastReadId, + }) : undefined), + }); +}; + +const prefetchMarker = (client: PlApiClient, timeline: 'home' | 'notifications') => + queryClient.prefetchQuery({ + queryKey: ['markers', timeline], + queryFn: () => client.timelines.getMarkers([timeline]).then(markers => markers[timeline]), + }); + +export { useMarker, prefetchMarker, useUpdateMarkerMutation }; diff --git a/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotificationList.ts similarity index 87% rename from packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts rename to packages/pl-fe/src/pl-hooks/hooks/notifications/useNotificationList.ts index b8b6e92c2..9ccd33cc3 100644 --- a/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotifications.ts +++ b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotificationList.ts @@ -33,7 +33,7 @@ const importNotifications = (response: PaginatedResponse) => { }; }; -const useNotifications = (params: UseNotificationParams) => { +const useNotificationList = (params: UseNotificationParams) => { const client = useClient(); const notificationsQuery = useInfiniteQuery({ @@ -57,12 +57,11 @@ const useNotifications = (params: UseNotificationParams) => { const prefetchNotifications = (client: PlApiClient, params: UseNotificationParams) => queryClient.prefetchInfiniteQuery({ queryKey: getQueryKey(params), - queryFn: ({ pageParam }) => (pageParam.next ? pageParam.next() : client.notifications.getNotifications({ + queryFn: () => client.notifications.getNotifications({ types: params.types, exclude_types: params.excludeTypes, - })).then(importNotifications), + }).then(importNotifications), initialPageParam: { previous: null, next: null } as Pick, 'previous' | 'next'>, - getNextPageParam: (response) => response, }); -export { useNotifications, prefetchNotifications }; +export { useNotificationList, prefetchNotifications }; diff --git a/packages/pl-fe/src/reducers/notifications.ts b/packages/pl-fe/src/reducers/notifications.ts index bf7b3a903..6c9ad4af7 100644 --- a/packages/pl-fe/src/reducers/notifications.ts +++ b/packages/pl-fe/src/reducers/notifications.ts @@ -7,24 +7,15 @@ import { FOLLOW_REQUEST_AUTHORIZE_SUCCESS, FOLLOW_REQUEST_REJECT_SUCCESS, } from '../actions/accounts'; -import { - MARKER_FETCH_SUCCESS, - MARKER_SAVE_REQUEST, - MARKER_SAVE_SUCCESS, -} from '../actions/markers'; import { NOTIFICATIONS_UPDATE, - NOTIFICATIONS_FILTER_SET, - NOTIFICATIONS_CLEAR, - NOTIFICATIONS_SCROLL_TOP, NOTIFICATIONS_UPDATE_QUEUE, NOTIFICATIONS_DEQUEUE, - NOTIFICATIONS_MARK_READ_REQUEST, MAX_QUEUED_NOTIFICATIONS, } from '../actions/notifications'; import { TIMELINE_DELETE } from '../actions/timelines'; -import type { AccountWarning, Notification as BaseNotification, Markers, Relationship, RelationshipSeveranceEvent, Report } from 'pl-api'; +import type { AccountWarning, Notification as BaseNotification, Relationship, RelationshipSeveranceEvent, Report } from 'pl-api'; import type { Notification } from 'pl-fe/normalizers'; import type { AnyAction } from 'redux'; @@ -36,13 +27,9 @@ const QueuedNotificationRecord = ImmutableRecord({ const ReducerRecord = ImmutableRecord({ items: ImmutableOrderedMap(), - hasMore: true, - top: false, unread: 0, - isLoading: false, queuedNotifications: ImmutableOrderedMap(), //max = MAX_QUEUED_NOTIFICATIONS totalQueuedNotificationsCount: 0, //used for queuedItems overflow for MAX_QUEUED_NOTIFICATIONS+ - lastRead: -1 as string | -1, }); type State = ReturnType; @@ -122,18 +109,8 @@ const minifyNotification = (notification: Notification) => { type MinifiedNotification = ReturnType; -// Count how many notifications appear after the given ID (for unread count) -const countFuture = (notifications: ImmutableOrderedMap, lastId: string | number) => - notifications.reduce((acc, notification) => { - if (!notification.duplicate && parseId(notification.id) > parseId(lastId)) { - return acc + 1; - } else { - return acc; - } - }, 0); - const importNotification = (state: State, notification: Notification) => { - const top = state.top; + const top = false; // state.top; if (!top && !notification.duplicate) state = state.update('unread', unread => unread + 1); @@ -154,11 +131,6 @@ const filterNotificationIds = (state: State, accountIds: Array, type?: s return state.update('items', helper); }; -const updateTop = (state: State, top: boolean) => { - if (top) state = state.set('unread', 0); - return state.set('top', top); -}; - const deleteByStatus = (state: State, statusId: string) => // @ts-ignore state.update('items', map => map.filterNot(item => item !== null && item.status === statusId)); @@ -185,28 +157,8 @@ const updateNotificationsQueue = (state: State, notification: BaseNotification, }); }; -const importMarker = (state: State, marker: Markers) => { - const lastReadId = marker.notifications.last_read_id || -1 as string | -1; - - if (!lastReadId) { - return state; - } - - return state.withMutations(state => { - const notifications = state.items; - const unread = countFuture(notifications, lastReadId); - - state.set('unread', unread); - state.set('lastRead', lastReadId); - }); -}; - const notifications = (state: State = ReducerRecord(), action: AnyAction) => { switch (action.type) { - case NOTIFICATIONS_FILTER_SET: - return state.set('items', ImmutableOrderedMap()).set('hasMore', true); - case NOTIFICATIONS_SCROLL_TOP: - return updateTop(state, action.top); case NOTIFICATIONS_UPDATE: return importNotification(state, action.notification); case NOTIFICATIONS_UPDATE_QUEUE: @@ -223,14 +175,6 @@ const notifications = (state: State = ReducerRecord(), action: AnyAction) => { case FOLLOW_REQUEST_AUTHORIZE_SUCCESS: case FOLLOW_REQUEST_REJECT_SUCCESS: return filterNotificationIds(state, [action.accountId], 'follow_request'); - case NOTIFICATIONS_CLEAR: - return state.set('items', ImmutableOrderedMap()).set('hasMore', false); - case NOTIFICATIONS_MARK_READ_REQUEST: - return state.set('lastRead', action.lastRead); - case MARKER_FETCH_SUCCESS: - case MARKER_SAVE_REQUEST: - case MARKER_SAVE_SUCCESS: - return importMarker(state, action.marker); case TIMELINE_DELETE: return deleteByStatus(state, action.statusId); default: From 8b0863c6d88001eb8dc24b013f1c23e8f5c09762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Tue, 1 Oct 2024 00:12:08 +0200 Subject: [PATCH 10/32] refresh on notification filter type change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-fe/src/actions/notifications.ts | 31 +++++-------------- .../notifications/components/filter-bar.tsx | 2 +- .../src/features/notifications/index.tsx | 8 ++--- .../notifications/useNotificationList.ts | 1 + 4 files changed, 13 insertions(+), 29 deletions(-) diff --git a/packages/pl-fe/src/actions/notifications.ts b/packages/pl-fe/src/actions/notifications.ts index 9a3311f8a..635d4484a 100644 --- a/packages/pl-fe/src/actions/notifications.ts +++ b/packages/pl-fe/src/actions/notifications.ts @@ -2,9 +2,11 @@ import IntlMessageFormat from 'intl-messageformat'; import 'intl-pluralrules'; import { defineMessages } from 'react-intl'; +import { FILTER_TYPES, type FilterType } from 'pl-fe/features/notifications'; import { getNotificationStatus } from 'pl-fe/features/notifications/components/notification'; import { normalizeNotification } from 'pl-fe/normalizers'; import { importEntities } from 'pl-fe/pl-hooks/importer'; +import { queryClient } from 'pl-fe/queries/client'; import { getFilters, regexFromFilters } from 'pl-fe/selectors'; import { unescapeHTML } from 'pl-fe/utils/html'; import { joinPublicPath } from 'pl-fe/utils/static'; @@ -16,7 +18,6 @@ import type { Notification } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE' as const; -const NOTIFICATIONS_UPDATE_NOOP = 'NOTIFICATIONS_UPDATE_NOOP' as const; const NOTIFICATIONS_UPDATE_QUEUE = 'NOTIFICATIONS_UPDATE_QUEUE' as const; const NOTIFICATIONS_DEQUEUE = 'NOTIFICATIONS_DEQUEUE' as const; @@ -24,19 +25,6 @@ const NOTIFICATIONS_FILTER_SET = 'NOTIFICATIONS_FILTER_SET' as const; const MAX_QUEUED_NOTIFICATIONS = 40; -type FILTER_TYPES = { - all: undefined; - mention: ['mention']; - favourite: ['favourite', 'emoji_reaction']; - reblog: ['reblog']; - poll: ['poll']; - status: ['status']; - follow: ['follow', 'follow_request']; - events: ['event_reminder', 'participation_request', 'participation_accepted']; -}; - -type FilterType = keyof FILTER_TYPES; - defineMessages({ mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' }, }); @@ -71,7 +59,6 @@ const updateNotificationsQueue = (notification: Notification, intlMessages: Reco if (notification.type === 'chat_mention') return; // Drop chat notifications, handle them per-chat const filters = getFilters(getState(), { contextType: 'notifications' }); - const playSound = getSettings(getState()).getIn(['notifications', 'sounds', notification.type]); const status = getNotificationStatus(notification); @@ -109,13 +96,6 @@ const updateNotificationsQueue = (notification: Notification, intlMessages: Reco console.warn(e); } - if (playSound && !filtered) { - dispatch({ - type: NOTIFICATIONS_UPDATE_NOOP, - meta: { sound: 'boop' }, - }); - } - if (isOnNotificationsPage) { dispatch({ type: NOTIFICATIONS_UPDATE_QUEUE, @@ -149,10 +129,14 @@ const dequeueNotifications = () => // dispatch(markReadNotifications()); }; -const setFilter = (filterType: FilterType, abort?: boolean) => +const setFilter = (filterType: FilterType | 'all') => (dispatch: AppDispatch, getState: () => RootState) => { const activeFilter = getSettings(getState()).getIn(['notifications', 'quickFilter', 'active']); + queryClient.resetQueries({ + queryKey: ['notifications', 'lists', filterType === 'all' ? 'all' : FILTER_TYPES[filterType].join('|')], + }); + dispatch({ type: NOTIFICATIONS_FILTER_SET, path: ['notifications', 'quickFilter', 'active'], @@ -163,7 +147,6 @@ const setFilter = (filterType: FilterType, abort?: boolean) => export { NOTIFICATIONS_UPDATE, - NOTIFICATIONS_UPDATE_NOOP, NOTIFICATIONS_UPDATE_QUEUE, NOTIFICATIONS_DEQUEUE, NOTIFICATIONS_FILTER_SET, diff --git a/packages/pl-fe/src/features/notifications/components/filter-bar.tsx b/packages/pl-fe/src/features/notifications/components/filter-bar.tsx index 6e76d5747..e5344da5b 100644 --- a/packages/pl-fe/src/features/notifications/components/filter-bar.tsx +++ b/packages/pl-fe/src/features/notifications/components/filter-bar.tsx @@ -29,7 +29,7 @@ const NotificationFilterBar = () => { const onClick = (notificationType: FilterType) => () => { try { - dispatch(setFilter(notificationType, true)); + dispatch(setFilter(notificationType)); } catch (e) { console.error(e); } diff --git a/packages/pl-fe/src/features/notifications/index.tsx b/packages/pl-fe/src/features/notifications/index.tsx index 0e0e7d1cd..19ecd97e9 100644 --- a/packages/pl-fe/src/features/notifications/index.tsx +++ b/packages/pl-fe/src/features/notifications/index.tsx @@ -23,7 +23,9 @@ const messages = defineMessages({ queue: { id: 'notifications.queue_label', defaultMessage: 'Click to see {count} new {count, plural, one {notification} other {notifications}}' }, }); -const FILTER_TYPES: Record | undefined> = { +type FilterType = 'mention' | 'favourite' | 'reblog' | 'poll' | 'status' | 'follow' | 'events'; + +const FILTER_TYPES: { all: undefined } & Record> = { all: undefined, mention: ['mention'], favourite: ['favourite', 'emoji_reaction'], @@ -34,15 +36,13 @@ const FILTER_TYPES: Record | undefined> = { events: ['event_reminder', 'participation_request', 'participation_accepted'], }; -type FilterType = keyof typeof FILTER_TYPES; - const Notifications = () => { const dispatch = useAppDispatch(); const intl = useIntl(); const settings = useSettings(); - const activeFilter = settings.notifications.quickFilter.active as FilterType; + const activeFilter = settings.notifications.quickFilter.active as FilterType | 'all'; const params = activeFilter === 'all' ? {} : { types: FILTER_TYPES[activeFilter] || [activeFilter] as Array, diff --git a/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotificationList.ts b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotificationList.ts index 9ccd33cc3..9d1ac3c2f 100644 --- a/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotificationList.ts +++ b/packages/pl-fe/src/pl-hooks/hooks/notifications/useNotificationList.ts @@ -16,6 +16,7 @@ type UseNotificationParams = { const getQueryKey = (params: UseNotificationParams) => [ 'notifications', + 'lists', params.types ? params.types.join('|') : params.excludeTypes ? ('exclude:' + params.excludeTypes.join('|')) : 'all', ]; From ae3d98505e7578b97a3ba745ece770ac70f25d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Tue, 1 Oct 2024 16:49:17 +0200 Subject: [PATCH 11/32] wip hooks migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- packages/pl-fe/src/actions/accounts.ts | 2 +- packages/pl-fe/src/actions/admin.ts | 3 +- packages/pl-fe/src/actions/aliases.ts | 2 +- packages/pl-fe/src/actions/auth.ts | 2 +- packages/pl-fe/src/actions/bookmarks.ts | 3 +- packages/pl-fe/src/actions/compose.ts | 2 +- packages/pl-fe/src/actions/conversations.ts | 3 +- packages/pl-fe/src/actions/directory.ts | 3 +- packages/pl-fe/src/actions/emoji-reacts.ts | 3 +- packages/pl-fe/src/actions/events.ts | 2 +- .../pl-fe/src/actions/familiar-followers.ts | 3 +- packages/pl-fe/src/actions/favourites.ts | 3 +- packages/pl-fe/src/actions/groups.ts | 3 +- packages/pl-fe/src/actions/history.ts | 3 +- packages/pl-fe/src/actions/interactions.ts | 2 +- packages/pl-fe/src/actions/lists.ts | 3 +- packages/pl-fe/src/actions/me.ts | 3 +- packages/pl-fe/src/actions/notifications.ts | 4 +- packages/pl-fe/src/actions/pin-statuses.ts | 3 +- packages/pl-fe/src/actions/polls.ts | 3 +- packages/pl-fe/src/actions/preload.ts | 1 - packages/pl-fe/src/actions/search.ts | 3 +- packages/pl-fe/src/actions/status-quotes.ts | 3 +- packages/pl-fe/src/actions/statuses.ts | 3 +- packages/pl-fe/src/actions/suggestions.ts | 3 +- packages/pl-fe/src/actions/timelines.ts | 2 +- .../pl-fe/src/actions/trending-statuses.ts | 3 +- packages/pl-fe/src/components/account.tsx | 2 +- .../announcements/announcements-panel.tsx | 2 +- .../src/components/announcements/reaction.tsx | 4 +- .../src/components/autosuggest-input.tsx | 2 +- .../pl-fe/src/components/avatar-stack.tsx | 2 +- packages/pl-fe/src/components/big-card.tsx | 2 +- .../dropdown-menu/dropdown-menu-item.tsx | 4 +- .../dropdown-menu/dropdown-menu.tsx | 4 +- .../pl-fe/src/components/event-preview.tsx | 4 +- packages/pl-fe/src/components/group-card.tsx | 4 +- .../groups/popover/group-popover.tsx | 4 +- .../pl-fe/src/components/landing-gradient.tsx | 2 +- packages/pl-fe/src/components/link.tsx | 2 +- packages/pl-fe/src/components/list.tsx | 2 +- packages/pl-fe/src/components/mention.tsx | 2 +- packages/pl-fe/src/components/modal-root.tsx | 2 +- packages/pl-fe/src/components/navlinks.tsx | 2 +- .../src/components/pending-items-row.tsx | 2 +- .../src/components/polls/poll-option.tsx | 10 +- .../src/components/profile-hover-card.tsx | 2 +- packages/pl-fe/src/components/radio.tsx | 2 +- .../src/components/scroll-top-button.tsx | 2 +- .../pl-fe/src/components/sidebar-menu.tsx | 12 +- .../src/components/site-error-boundary.tsx | 8 +- .../src/components/status-action-button.tsx | 2 +- .../pl-fe/src/components/status-content.tsx | 2 +- .../src/components/status-hover-card.tsx | 2 +- .../pl-fe/src/components/status-mention.tsx | 2 +- .../src/components/status-reactions-bar.tsx | 2 +- .../src/components/status-reply-mentions.tsx | 2 +- packages/pl-fe/src/components/status.tsx | 4 +- .../src/components/statuses/status-info.tsx | 2 +- .../pl-fe/src/components/thumb-navigation.tsx | 6 +- .../pl-fe/src/components/trending-link.tsx | 2 +- .../src/components/ui/accordion/accordion.tsx | 2 +- .../pl-fe/src/components/ui/card/card.tsx | 2 +- .../src/components/ui/carousel/carousel.tsx | 4 +- .../src/components/ui/checkbox/checkbox.tsx | 2 +- .../src/components/ui/counter/counter.tsx | 2 +- .../src/components/ui/divider/divider.tsx | 4 +- .../components/ui/form-group/form-group.tsx | 4 +- .../components/ui/icon-button/icon-button.tsx | 2 +- .../inline-multiselect/inline-multiselect.tsx | 4 +- .../pl-fe/src/components/ui/input/input.tsx | 4 +- .../pl-fe/src/components/ui/layout/layout.tsx | 2 +- .../pl-fe/src/components/ui/menu/menu.tsx | 4 +- .../pl-fe/src/components/ui/modal/modal.tsx | 8 +- .../src/components/ui/popover/popover.tsx | 4 +- .../ui/progress-bar/progress-bar.tsx | 4 +- .../ui/radio-button/radio-button.tsx | 2 +- .../pl-fe/src/components/ui/select/select.tsx | 2 +- .../pl-fe/src/components/ui/slider/slider.tsx | 6 +- .../pl-fe/src/components/ui/tabs/tabs.tsx | 4 +- .../src/components/ui/tag-input/tag-input.tsx | 2 +- .../pl-fe/src/components/ui/tag-input/tag.tsx | 2 +- .../src/components/ui/textarea/textarea.tsx | 2 +- .../pl-fe/src/components/ui/toast/toast.tsx | 8 +- .../pl-fe/src/components/ui/toggle/toggle.tsx | 2 +- .../pl-fe/src/components/ui/widget/widget.tsx | 2 +- .../src/components/verification-badge.tsx | 4 +- packages/pl-fe/src/features/about/index.tsx | 2 +- .../components/moved-note.tsx | 2 +- .../features/account/components/header.tsx | 8 +- .../src/features/admin/announcements.tsx | 2 +- .../src/features/admin/components/report.tsx | 2 +- packages/pl-fe/src/features/admin/domains.tsx | 2 +- packages/pl-fe/src/features/admin/relays.tsx | 2 +- packages/pl-fe/src/features/admin/rules.tsx | 2 +- .../features/aliases/components/search.tsx | 2 +- packages/pl-fe/src/features/audio/index.tsx | 4 +- .../auth-login/components/consumers-list.tsx | 2 +- .../src/features/auth-token-list/index.tsx | 2 +- packages/pl-fe/src/features/backups/index.tsx | 2 +- .../chats/components/chat-composer.tsx | 4 +- .../chats/components/chat-list-item.tsx | 4 +- .../features/chats/components/chat-list.tsx | 4 +- .../chats/components/chat-page/chat-page.tsx | 6 +- .../chat-page/components/chat-page-main.tsx | 4 +- .../chats/components/chat-pending-upload.tsx | 2 +- .../chats/components/chat-search/results.tsx | 4 +- .../chats/components/chat-textarea.tsx | 16 +- .../features/chats/components/chat-upload.tsx | 4 +- .../chat-widget/chat-pane-header.tsx | 2 +- .../components/chat-widget/chat-settings.tsx | 6 +- .../components/chat-widget/chat-window.tsx | 2 +- .../headers/chat-search-header.tsx | 2 +- .../src/features/chats/components/ui/pane.tsx | 2 +- packages/pl-fe/src/features/circle/index.tsx | 2 +- .../compose/components/compose-form.tsx | 2 +- .../compose/components/language-dropdown.tsx | 2 +- .../compose/components/reply-indicator.tsx | 2 +- .../compose/components/reply-mentions.tsx | 2 +- .../plugins/floating-link-editor-plugin.tsx | 2 +- .../floating-text-format-toolbar-plugin.tsx | 4 +- .../directory/components/account-card.tsx | 4 +- .../edit-profile/components/avatar-picker.tsx | 2 +- .../edit-profile/components/header-picker.tsx | 2 +- .../src/features/embedded-status/index.tsx | 2 +- .../event/components/event-header.tsx | 6 +- .../src/features/event/event-information.tsx | 4 +- .../feed-suggestions/feed-suggestions.tsx | 4 +- packages/pl-fe/src/features/filters/index.tsx | 2 +- .../group/components/group-header.tsx | 8 +- .../src/features/hashtag-timeline/index.tsx | 2 +- .../src/features/home-timeline/index.tsx | 2 +- .../landing-timeline/components/logo-text.tsx | 2 +- .../pl-fe/src/features/migration/index.tsx | 2 +- .../notifications/components/notification.tsx | 4 +- .../src/features/notifications/index.tsx | 14 +- .../steps/avatar-selection-step.tsx | 2 +- .../onboarding/steps/completed-step.tsx | 2 +- .../steps/cover-photo-selection-step.tsx | 4 +- .../onboarding/steps/fediverse-step.tsx | 6 +- .../steps/suggested-accounts-step.tsx | 2 +- .../components/icon-picker-menu.tsx | 4 +- .../pl-fe-config/components/site-preview.tsx | 2 +- .../components/placeholder-avatar.tsx | 4 +- .../components/placeholder-card.tsx | 2 +- .../components/placeholder-chat-message.tsx | 4 +- .../components/placeholder-display-name.tsx | 2 +- .../components/placeholder-event-header.tsx | 2 +- .../components/placeholder-event-preview.tsx | 4 +- .../components/placeholder-group-card.tsx | 4 +- .../components/placeholder-group-search.tsx | 2 +- .../components/placeholder-hashtag.tsx | 2 +- .../components/placeholder-media-gallery.tsx | 2 +- .../components/placeholder-notification.tsx | 2 +- .../placeholder-sidebar-suggestions.tsx | 2 +- .../components/placeholder-sidebar-trends.tsx | 2 +- .../components/placeholder-status-content.tsx | 2 +- .../src/features/public-timeline/index.tsx | 2 +- .../components/pinned-hosts-picker.tsx | 2 +- .../status/components/detailed-status.tsx | 2 +- .../status/components/thread-status.tsx | 2 +- .../src/features/status/components/thread.tsx | 6 +- .../src/features/test-timeline/index.tsx | 2 +- .../ui/components/background-shapes.tsx | 2 +- .../ui/components/column-forbidden.tsx | 2 +- .../ui/components/floating-action-button.tsx | 4 +- .../modals/compare-history-modal.tsx | 2 +- .../modals/compose-event-modal/index.tsx | 4 +- .../compose-event-modal/upload-button.tsx | 2 +- .../components/modals/dropdown-menu-modal.tsx | 2 +- .../modals/edit-bookmark-folder-modal.tsx | 2 +- .../ui/components/modals/hotkeys-modal.tsx | 2 +- .../steps/confirmation-step.tsx | 6 +- .../report-modal/steps/confirmation-step.tsx | 2 +- .../modals/report-modal/steps/reason-step.tsx | 2 +- .../ui/components/profile-dropdown.tsx | 4 +- packages/pl-fe/src/features/ui/index.tsx | 6 +- packages/pl-fe/src/features/video/index.tsx | 2 +- packages/pl-fe/src/init/pl-fe-head.tsx | 2 +- packages/pl-fe/src/layouts/chats-layout.tsx | 2 +- packages/pl-fe/src/layouts/home-layout.tsx | 2 +- packages/pl-fe/src/layouts/landing-layout.tsx | 2 +- packages/pl-fe/src/normalizers/status.ts | 1 - packages/pl-fe/src/pl-hooks | 1 + packages/pl-fe/src/pl-hooks/README.md | 1 - packages/pl-fe/src/queries/chats.ts | 2 +- packages/pl-fe/src/queries/suggestions.ts | 2 +- packages/pl-fe/tsconfig.json | 3 +- .../lib}/hooks/markers/useMarkers.ts | 0 .../hooks/notifications/useNotification.ts | 4 +- .../notifications/useNotificationList.ts | 4 +- .../pl-hooks/lib/hooks/statuses/useStatus.ts | 46 +++++ .../src/pl-hooks => pl-hooks/lib}/importer.ts | 0 .../lib}/minifiers/minifyNotification.ts | 0 .../pl-hooks/lib/minifiers/minifyStatus.ts | 15 ++ .../normalizers/deduplicateNotifications.ts | 0 .../lib/normalizers/normalizeStatus.ts | 170 ++++++++++++++++++ packages/pl-hooks/tsconfig.json | 2 +- packages/pl-hooks/vite.config.ts | 2 +- 199 files changed, 535 insertions(+), 287 deletions(-) create mode 120000 packages/pl-fe/src/pl-hooks delete mode 100644 packages/pl-fe/src/pl-hooks/README.md rename packages/{pl-fe/src/pl-hooks => pl-hooks/lib}/hooks/markers/useMarkers.ts (100%) rename packages/{pl-fe/src/pl-hooks => pl-hooks/lib}/hooks/notifications/useNotification.ts (96%) rename packages/{pl-fe/src/pl-hooks => pl-hooks/lib}/hooks/notifications/useNotificationList.ts (100%) create mode 100644 packages/pl-hooks/lib/hooks/statuses/useStatus.ts rename packages/{pl-fe/src/pl-hooks => pl-hooks/lib}/importer.ts (100%) rename packages/{pl-fe/src/pl-hooks => pl-hooks/lib}/minifiers/minifyNotification.ts (100%) create mode 100644 packages/pl-hooks/lib/minifiers/minifyStatus.ts rename packages/{pl-fe/src/pl-hooks => pl-hooks/lib}/normalizers/deduplicateNotifications.ts (100%) create mode 100644 packages/pl-hooks/lib/normalizers/normalizeStatus.ts diff --git a/packages/pl-fe/src/actions/accounts.ts b/packages/pl-fe/src/actions/accounts.ts index f52b6002e..9b386f1bf 100644 --- a/packages/pl-fe/src/actions/accounts.ts +++ b/packages/pl-fe/src/actions/accounts.ts @@ -1,8 +1,8 @@ import { PLEROMA, type UpdateNotificationSettingsParams, type Account, type CreateAccountParams, type PaginatedResponse, type Relationship } from 'pl-api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { getClient, type PlfeResponse } from 'pl-fe/api'; import { Entities } from 'pl-fe/entity-store/entities'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { selectAccount } from 'pl-fe/selectors'; import { isLoggedIn } from 'pl-fe/utils/auth'; diff --git a/packages/pl-fe/src/actions/admin.ts b/packages/pl-fe/src/actions/admin.ts index 4be3d0741..d3f13137a 100644 --- a/packages/pl-fe/src/actions/admin.ts +++ b/packages/pl-fe/src/actions/admin.ts @@ -1,6 +1,7 @@ +import { importEntities } from 'pl-fe/pl-hooks/importer'; + import { fetchRelationships } from 'pl-fe/actions/accounts'; import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { filterBadges, getTagDiff } from 'pl-fe/utils/badges'; import { deleteFromTimelines } from './timelines'; diff --git a/packages/pl-fe/src/actions/aliases.ts b/packages/pl-fe/src/actions/aliases.ts index aad1dc396..1d31a4aa1 100644 --- a/packages/pl-fe/src/actions/aliases.ts +++ b/packages/pl-fe/src/actions/aliases.ts @@ -1,7 +1,7 @@ +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { defineMessages } from 'react-intl'; import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import toast from 'pl-fe/toast'; import { isLoggedIn } from 'pl-fe/utils/auth'; diff --git a/packages/pl-fe/src/actions/auth.ts b/packages/pl-fe/src/actions/auth.ts index efb65ec74..711518a33 100644 --- a/packages/pl-fe/src/actions/auth.ts +++ b/packages/pl-fe/src/actions/auth.ts @@ -7,6 +7,7 @@ * @see module:pl-fe/actions/security */ import { credentialAccountSchema, PlApiClient, type CreateAccountParams, type Token } from 'pl-api'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { defineMessages } from 'react-intl'; import { createAccount } from 'pl-fe/actions/accounts'; @@ -17,7 +18,6 @@ import { startOnboarding } from 'pl-fe/actions/onboarding'; import { type PlfeResponse, getClient } from 'pl-fe/api'; import * as BuildConfig from 'pl-fe/build-config'; import { custom } from 'pl-fe/custom'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { queryClient } from 'pl-fe/queries/client'; import { selectAccount } from 'pl-fe/selectors'; import { unsetSentryAccount } from 'pl-fe/sentry'; diff --git a/packages/pl-fe/src/actions/bookmarks.ts b/packages/pl-fe/src/actions/bookmarks.ts index f116a5995..9967c73ea 100644 --- a/packages/pl-fe/src/actions/bookmarks.ts +++ b/packages/pl-fe/src/actions/bookmarks.ts @@ -1,6 +1,7 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; +import { getClient } from 'pl-fe/api'; + import type { PaginatedResponse, Status } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/compose.ts b/packages/pl-fe/src/actions/compose.ts index 64d6d643f..f54de5f54 100644 --- a/packages/pl-fe/src/actions/compose.ts +++ b/packages/pl-fe/src/actions/compose.ts @@ -1,11 +1,11 @@ import throttle from 'lodash/throttle'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { defineMessages, IntlShape } from 'react-intl'; import { getClient } from 'pl-fe/api'; import { isNativeEmoji } from 'pl-fe/features/emoji'; import emojiSearch from 'pl-fe/features/emoji/search'; import { Language } from 'pl-fe/features/preferences'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { selectAccount, selectOwnAccount, makeGetAccount } from 'pl-fe/selectors'; import { tagHistory } from 'pl-fe/settings'; import { useModalsStore } from 'pl-fe/stores'; diff --git a/packages/pl-fe/src/actions/conversations.ts b/packages/pl-fe/src/actions/conversations.ts index adac3b19f..e32c19810 100644 --- a/packages/pl-fe/src/actions/conversations.ts +++ b/packages/pl-fe/src/actions/conversations.ts @@ -1,5 +1,6 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; + +import { getClient } from 'pl-fe/api'; import { isLoggedIn } from 'pl-fe/utils/auth'; import type { Account, Conversation, PaginatedResponse, Status } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/directory.ts b/packages/pl-fe/src/actions/directory.ts index bff0c19ba..effb747eb 100644 --- a/packages/pl-fe/src/actions/directory.ts +++ b/packages/pl-fe/src/actions/directory.ts @@ -1,6 +1,7 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; +import { getClient } from 'pl-fe/api'; + import { fetchRelationships } from './accounts'; import type { Account, ProfileDirectoryParams } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/emoji-reacts.ts b/packages/pl-fe/src/actions/emoji-reacts.ts index 54bc4899d..90a44e8b1 100644 --- a/packages/pl-fe/src/actions/emoji-reacts.ts +++ b/packages/pl-fe/src/actions/emoji-reacts.ts @@ -1,5 +1,6 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; + +import { getClient } from 'pl-fe/api'; import { isLoggedIn } from 'pl-fe/utils/auth'; import type { Status } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/events.ts b/packages/pl-fe/src/actions/events.ts index 515646a71..b4aa9ecb4 100644 --- a/packages/pl-fe/src/actions/events.ts +++ b/packages/pl-fe/src/actions/events.ts @@ -1,8 +1,8 @@ +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { defineMessages } from 'react-intl'; import { STATUS_FETCH_SOURCE_FAIL, STATUS_FETCH_SOURCE_REQUEST, STATUS_FETCH_SOURCE_SUCCESS } from 'pl-fe/actions/statuses'; import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { useModalsStore } from 'pl-fe/stores'; import toast from 'pl-fe/toast'; diff --git a/packages/pl-fe/src/actions/familiar-followers.ts b/packages/pl-fe/src/actions/familiar-followers.ts index 404a99259..f4e185820 100644 --- a/packages/pl-fe/src/actions/familiar-followers.ts +++ b/packages/pl-fe/src/actions/familiar-followers.ts @@ -1,5 +1,6 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; + +import { getClient } from 'pl-fe/api'; import { AppDispatch, RootState } from 'pl-fe/store'; import { fetchRelationships } from './accounts'; diff --git a/packages/pl-fe/src/actions/favourites.ts b/packages/pl-fe/src/actions/favourites.ts index 2ba10fcd5..c4c3b747b 100644 --- a/packages/pl-fe/src/actions/favourites.ts +++ b/packages/pl-fe/src/actions/favourites.ts @@ -1,5 +1,6 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; + +import { getClient } from 'pl-fe/api'; import { isLoggedIn } from 'pl-fe/utils/auth'; import type { PaginatedResponse, Status } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/groups.ts b/packages/pl-fe/src/actions/groups.ts index 3c719c877..3844a606d 100644 --- a/packages/pl-fe/src/actions/groups.ts +++ b/packages/pl-fe/src/actions/groups.ts @@ -1,6 +1,7 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; +import { getClient } from 'pl-fe/api'; + import type { Account, PaginatedResponse } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/history.ts b/packages/pl-fe/src/actions/history.ts index 1f110f11e..59f48fdb0 100644 --- a/packages/pl-fe/src/actions/history.ts +++ b/packages/pl-fe/src/actions/history.ts @@ -1,6 +1,7 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; +import { getClient } from 'pl-fe/api'; + import type { StatusEdit } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/interactions.ts b/packages/pl-fe/src/actions/interactions.ts index 81a36c9c8..65b5d58bc 100644 --- a/packages/pl-fe/src/actions/interactions.ts +++ b/packages/pl-fe/src/actions/interactions.ts @@ -1,7 +1,7 @@ +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { defineMessages } from 'react-intl'; import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { useModalsStore } from 'pl-fe/stores'; import toast, { type IToastOptions } from 'pl-fe/toast'; import { isLoggedIn } from 'pl-fe/utils/auth'; diff --git a/packages/pl-fe/src/actions/lists.ts b/packages/pl-fe/src/actions/lists.ts index 502a363a9..c30f83a58 100644 --- a/packages/pl-fe/src/actions/lists.ts +++ b/packages/pl-fe/src/actions/lists.ts @@ -1,5 +1,6 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; + +import { getClient } from 'pl-fe/api'; import { selectAccount } from 'pl-fe/selectors'; import toast from 'pl-fe/toast'; import { isLoggedIn } from 'pl-fe/utils/auth'; diff --git a/packages/pl-fe/src/actions/me.ts b/packages/pl-fe/src/actions/me.ts index 0febc7f61..38958f894 100644 --- a/packages/pl-fe/src/actions/me.ts +++ b/packages/pl-fe/src/actions/me.ts @@ -1,5 +1,6 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; + +import { getClient } from 'pl-fe/api'; import { selectAccount } from 'pl-fe/selectors'; import { setSentryAccount } from 'pl-fe/sentry'; import KVStore from 'pl-fe/storage/kv-store'; diff --git a/packages/pl-fe/src/actions/notifications.ts b/packages/pl-fe/src/actions/notifications.ts index 635d4484a..6687ff683 100644 --- a/packages/pl-fe/src/actions/notifications.ts +++ b/packages/pl-fe/src/actions/notifications.ts @@ -1,11 +1,11 @@ import IntlMessageFormat from 'intl-messageformat'; import 'intl-pluralrules'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { defineMessages } from 'react-intl'; import { FILTER_TYPES, type FilterType } from 'pl-fe/features/notifications'; import { getNotificationStatus } from 'pl-fe/features/notifications/components/notification'; import { normalizeNotification } from 'pl-fe/normalizers'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { queryClient } from 'pl-fe/queries/client'; import { getFilters, regexFromFilters } from 'pl-fe/selectors'; import { unescapeHTML } from 'pl-fe/utils/html'; @@ -129,7 +129,7 @@ const dequeueNotifications = () => // dispatch(markReadNotifications()); }; -const setFilter = (filterType: FilterType | 'all') => +const setFilter = (filterType: FilterType) => (dispatch: AppDispatch, getState: () => RootState) => { const activeFilter = getSettings(getState()).getIn(['notifications', 'quickFilter', 'active']); diff --git a/packages/pl-fe/src/actions/pin-statuses.ts b/packages/pl-fe/src/actions/pin-statuses.ts index f4968f194..e67474afe 100644 --- a/packages/pl-fe/src/actions/pin-statuses.ts +++ b/packages/pl-fe/src/actions/pin-statuses.ts @@ -1,5 +1,6 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; + +import { getClient } from 'pl-fe/api'; import { isLoggedIn } from 'pl-fe/utils/auth'; import type { Status } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/polls.ts b/packages/pl-fe/src/actions/polls.ts index c913f9ef8..82af7b4c5 100644 --- a/packages/pl-fe/src/actions/polls.ts +++ b/packages/pl-fe/src/actions/polls.ts @@ -1,6 +1,7 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; +import { getClient } from 'pl-fe/api'; + import type { Poll } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/preload.ts b/packages/pl-fe/src/actions/preload.ts index 7925046ea..a523f6c9c 100644 --- a/packages/pl-fe/src/actions/preload.ts +++ b/packages/pl-fe/src/actions/preload.ts @@ -1,5 +1,4 @@ import mapValues from 'lodash/mapValues'; - import { importEntities } from 'pl-fe/pl-hooks/importer'; import { verifyCredentials } from './auth'; diff --git a/packages/pl-fe/src/actions/search.ts b/packages/pl-fe/src/actions/search.ts index c7c03ad81..b04f18940 100644 --- a/packages/pl-fe/src/actions/search.ts +++ b/packages/pl-fe/src/actions/search.ts @@ -1,6 +1,7 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; +import { getClient } from 'pl-fe/api'; + import { fetchRelationships } from './accounts'; import type { Search } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/status-quotes.ts b/packages/pl-fe/src/actions/status-quotes.ts index a865e23cd..8bdd19f5c 100644 --- a/packages/pl-fe/src/actions/status-quotes.ts +++ b/packages/pl-fe/src/actions/status-quotes.ts @@ -1,6 +1,7 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; +import { getClient } from 'pl-fe/api'; + import type { Status as BaseStatus, PaginatedResponse } from 'pl-api'; import type { AppDispatch, RootState } from 'pl-fe/store'; diff --git a/packages/pl-fe/src/actions/statuses.ts b/packages/pl-fe/src/actions/statuses.ts index cd0934ece..db782b070 100644 --- a/packages/pl-fe/src/actions/statuses.ts +++ b/packages/pl-fe/src/actions/statuses.ts @@ -1,5 +1,6 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; + +import { getClient } from 'pl-fe/api'; import { useModalsStore } from 'pl-fe/stores'; import { isLoggedIn } from 'pl-fe/utils/auth'; import { shouldHaveCard } from 'pl-fe/utils/status'; diff --git a/packages/pl-fe/src/actions/suggestions.ts b/packages/pl-fe/src/actions/suggestions.ts index 59baafb7c..cee2f3908 100644 --- a/packages/pl-fe/src/actions/suggestions.ts +++ b/packages/pl-fe/src/actions/suggestions.ts @@ -1,6 +1,7 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; +import { getClient } from 'pl-fe/api'; + import { fetchRelationships } from './accounts'; import { insertSuggestionsIntoTimeline } from './timelines'; diff --git a/packages/pl-fe/src/actions/timelines.ts b/packages/pl-fe/src/actions/timelines.ts index 641fe377f..41bcbc347 100644 --- a/packages/pl-fe/src/actions/timelines.ts +++ b/packages/pl-fe/src/actions/timelines.ts @@ -1,8 +1,8 @@ import { Map as ImmutableMap } from 'immutable'; +import { importEntities } from 'pl-fe/pl-hooks/importer'; import { getLocale, getSettings } from 'pl-fe/actions/settings'; import { getClient } from 'pl-fe/api'; -import { importEntities } from 'pl-fe/pl-hooks/importer'; import { shouldFilter } from 'pl-fe/utils/timelines'; import type { PaginatedResponse, Status as BaseStatus, PublicTimelineParams, HomeTimelineParams, ListTimelineParams, HashtagTimelineParams, GetAccountStatusesParams, GroupTimelineParams } from 'pl-api'; diff --git a/packages/pl-fe/src/actions/trending-statuses.ts b/packages/pl-fe/src/actions/trending-statuses.ts index 9534c4e18..c6d8db428 100644 --- a/packages/pl-fe/src/actions/trending-statuses.ts +++ b/packages/pl-fe/src/actions/trending-statuses.ts @@ -1,6 +1,7 @@ -import { getClient } from 'pl-fe/api'; import { importEntities } from 'pl-fe/pl-hooks/importer'; +import { getClient } from 'pl-fe/api'; + import type { AppDispatch, RootState } from 'pl-fe/store'; const TRENDING_STATUSES_FETCH_REQUEST = 'TRENDING_STATUSES_FETCH_REQUEST' as const; diff --git a/packages/pl-fe/src/components/account.tsx b/packages/pl-fe/src/components/account.tsx index d306b0adf..b074b9e49 100644 --- a/packages/pl-fe/src/components/account.tsx +++ b/packages/pl-fe/src/components/account.tsx @@ -47,7 +47,7 @@ const InstanceFavicon: React.FC = ({ account, disabled }) => { return ( diff --git a/packages/pl-fe/src/components/autosuggest-input.tsx b/packages/pl-fe/src/components/autosuggest-input.tsx index 4ce065837..557376496 100644 --- a/packages/pl-fe/src/components/autosuggest-input.tsx +++ b/packages/pl-fe/src/components/autosuggest-input.tsx @@ -230,7 +230,7 @@ class AutosuggestInput extends ImmutablePureComponent { return menu.map((item, i) => ( = ({ accountIds, limit = 3 }) => { style={{ zIndex: limit - i }} > = ({ title, subtitle, children }) => ( -
+
{title} {subtitle && {subtitle}} diff --git a/packages/pl-fe/src/components/dropdown-menu/dropdown-menu-item.tsx b/packages/pl-fe/src/components/dropdown-menu/dropdown-menu-item.tsx index b203c2348..430a56c0e 100644 --- a/packages/pl-fe/src/components/dropdown-menu/dropdown-menu-item.tsx +++ b/packages/pl-fe/src/components/dropdown-menu/dropdown-menu-item.tsx @@ -99,7 +99,7 @@ const DropdownMenuItem = ({ index, item, onClick, autoFocus, onSetTab }: IDropdo } return ( -
  • +
  • { } const getClassName = () => { - const className = clsx('z-[1001] bg-white py-1 shadow-lg ease-in-out focus:outline-none black:bg-black no-reduce-motion:transition-all dark:bg-gray-900 dark:ring-2 dark:ring-primary-700', { + const className = clsx('black:bg-black no-reduce-motion:transition-all dark:ring-primary-700 z-[1001] bg-white py-1 shadow-lg ease-in-out focus:outline-none dark:bg-gray-900 dark:ring-2', { 'rounded-md min-w-56 max-w-sm duration-100': true, 'no-reduce-motion:scale-0': !(isDisplayed && isOpen), 'scale-100': isDisplayed && isOpen, @@ -368,7 +368,7 @@ const DropdownMenu = (props: IDropdownMenu) => {
  • diff --git a/packages/pl-fe/src/components/event-preview.tsx b/packages/pl-fe/src/components/event-preview.tsx index 575facdcc..a224dc2ce 100644 --- a/packages/pl-fe/src/components/event-preview.tsx +++ b/packages/pl-fe/src/components/event-preview.tsx @@ -51,11 +51,11 @@ const EventPreview: React.FC = ({ status, className, hideAction, )); return ( -
    +
    {floatingAction && action}
    -
    +
    {banner && {intl.formatMessage(messages.eventBanner)}}
    diff --git a/packages/pl-fe/src/components/group-card.tsx b/packages/pl-fe/src/components/group-card.tsx index 11c1d2b21..644609695 100644 --- a/packages/pl-fe/src/components/group-card.tsx +++ b/packages/pl-fe/src/components/group-card.tsx @@ -16,11 +16,11 @@ interface IGroupCard { const GroupCard: React.FC = ({ group }) => ( {/* Group Cover Image */} - + { content={ {/* Group Cover Image */} - + {group.header && ( ( -
    +
    ); export { LandingGradient as default }; diff --git a/packages/pl-fe/src/components/link.tsx b/packages/pl-fe/src/components/link.tsx index 413061279..7516ce49f 100644 --- a/packages/pl-fe/src/components/link.tsx +++ b/packages/pl-fe/src/components/link.tsx @@ -4,7 +4,7 @@ import { Link as Comp, LinkProps } from 'react-router-dom'; const Link = (props: LinkProps) => ( ); diff --git a/packages/pl-fe/src/components/list.tsx b/packages/pl-fe/src/components/list.tsx index 4d5934d26..82541544c 100644 --- a/packages/pl-fe/src/components/list.tsx +++ b/packages/pl-fe/src/components/list.tsx @@ -56,7 +56,7 @@ const ListItem: React.FC = ({ className, label, hint, children, to, h return null; }), [children, domId]); - const classNames = clsx('flex items-center justify-between overflow-hidden bg-gradient-to-r from-gradient-start/20 to-gradient-end/20 first:rounded-t-lg last:rounded-b-lg dark:from-gradient-start/10 dark:to-gradient-end/10', + const classNames = clsx('from-gradient-start/20 to-gradient-end/20 dark:from-gradient-start/10 dark:to-gradient-end/10 flex items-center justify-between overflow-hidden bg-gradient-to-r first:rounded-t-lg last:rounded-b-lg', className, { 'px-4 py-2': size === 'md', diff --git a/packages/pl-fe/src/components/mention.tsx b/packages/pl-fe/src/components/mention.tsx index 582d98990..5dbbca63b 100644 --- a/packages/pl-fe/src/components/mention.tsx +++ b/packages/pl-fe/src/components/mention.tsx @@ -23,7 +23,7 @@ const Mention: React.FC = ({ mention: { acct, username }, disabled }) diff --git a/packages/pl-fe/src/components/modal-root.tsx b/packages/pl-fe/src/components/modal-root.tsx index dd658e786..2b1801e54 100644 --- a/packages/pl-fe/src/components/modal-root.tsx +++ b/packages/pl-fe/src/components/modal-root.tsx @@ -233,7 +233,7 @@ const ModalRoot: React.FC = ({ children, onCancel, onClose, type })