From 0f8929026c5ff28d266a8c2a2c632a0adb913908 Mon Sep 17 00:00:00 2001 From: Jonas Daniels Date: Mon, 24 Feb 2025 14:23:05 -0800 Subject: [PATCH] migrate user op analytics to server components --- apps/dashboard/package.json | 1 + apps/dashboard/src/@/actions/proxies.ts | 9 - apps/dashboard/src/@/api/analytics.ts | 48 ++++- apps/dashboard/src/@/api/chain.ts | 20 ++ .../src/@3rdweb-sdk/react/hooks/useApi.ts | 130 +----------- .../components/server/chain-table.tsx | 4 +- .../src/app/(dashboard)/(chain)/utils.ts | 28 +-- apps/dashboard/src/app/providers.tsx | 41 ++-- .../[team_slug]/(team)/~/analytics/page.tsx | 4 +- .../~/usage/overview/components/Usage.tsx | 6 +- .../AccountAbstractionPage.tsx | 10 +- .../connect/account-abstraction/layout.tsx | 7 + .../connect/account-abstraction/page.tsx | 57 ++++-- .../account-abstraction/search-params.ts | 17 ++ .../team/[team_slug]/[project_slug]/page.tsx | 15 +- .../AccountAbstractionAnalytics/index.tsx | 85 +++++--- pnpm-lock.yaml | 190 ++++++++++++------ 17 files changed, 374 insertions(+), 298 deletions(-) create mode 100644 apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/search-params.ts diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index c7f4b640d30..0cc0d38d6ec 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -72,6 +72,7 @@ "next-plausible": "^3.12.4", "next-themes": "^0.4.4", "nextjs-toploader": "^1.6.12", + "nuqs": "^2.4.0", "p-limit": "^6.2.0", "papaparse": "^5.5.2", "pluralize": "^8.0.0", diff --git a/apps/dashboard/src/@/actions/proxies.ts b/apps/dashboard/src/@/actions/proxies.ts index 0d5551689d3..268b8e78533 100644 --- a/apps/dashboard/src/@/actions/proxies.ts +++ b/apps/dashboard/src/@/actions/proxies.ts @@ -71,15 +71,6 @@ async function proxy( }; } -export async function analyticsServerProxy( - params: ProxyActionParams, -) { - return proxy( - process.env.ANALYTICS_SERVICE_URL || "https://analytics.thirdweb.com", - params, - ); -} - export async function apiServerProxy( params: ProxyActionParams, ) { diff --git a/apps/dashboard/src/@/api/analytics.ts b/apps/dashboard/src/@/api/analytics.ts index fd9b0adf9a2..a1a0d151aa5 100644 --- a/apps/dashboard/src/@/api/analytics.ts +++ b/apps/dashboard/src/@/api/analytics.ts @@ -9,6 +9,7 @@ import type { WalletStats, WalletUserStats, } from "types/analytics"; +import { getChains } from "./chain"; function buildSearchParams( params: AnalyticsQueryParams | AnalyticsQueryParamsV2, @@ -93,13 +94,16 @@ export async function getInAppWalletUsage( } export async function getUserOpUsage( - params: AnalyticsQueryParams, + params: AnalyticsQueryParamsV2, ): Promise { const searchParams = buildSearchParams(params); - const res = await fetchAnalytics(`v1/user-ops?${searchParams.toString()}`, { - method: "GET", - headers: { "Content-Type": "application/json" }, - }); + const res = await fetchAnalytics( + `v2/bundler/usage?${searchParams.toString()}`, + { + method: "GET", + headers: { "Content-Type": "application/json" }, + }, + ); if (res?.status !== 200) { const reason = await res?.text(); @@ -113,6 +117,40 @@ export async function getUserOpUsage( return json.data as UserOpStats[]; } +export async function getAggregateUserOpUsage( + params: Omit, +): Promise { + const [userOpStats, chains] = await Promise.all([ + getUserOpUsage({ ...params, period: "all" }), + getChains(), + ]); + // Aggregate stats across wallet types + return userOpStats.reduce( + (acc, curr) => { + // Skip testnets from the aggregated stats + if (curr.chainId) { + const chain = chains.data.find( + (c) => c.chainId.toString() === curr.chainId, + ); + if (chain?.testnet) { + return acc; + } + } + + acc.successful += curr.successful; + acc.failed += curr.failed; + acc.sponsoredUsd += curr.sponsoredUsd; + return acc; + }, + { + date: (params.from || new Date()).toISOString(), + successful: 0, + failed: 0, + sponsoredUsd: 0, + }, + ); +} + export async function getClientTransactions( params: AnalyticsQueryParamsV2, ): Promise { diff --git a/apps/dashboard/src/@/api/chain.ts b/apps/dashboard/src/@/api/chain.ts index f70e8152426..2e2aa4a5e50 100644 --- a/apps/dashboard/src/@/api/chain.ts +++ b/apps/dashboard/src/@/api/chain.ts @@ -1,4 +1,6 @@ import "server-only"; +import type { ChainMetadata } from "thirdweb/chains"; +import type { ChainService } from "../../app/(dashboard)/(chain)/types/chain"; import { API_SERVER_URL, THIRDWEB_API_SECRET } from "../constants/env"; export async function getGasSponsoredChains() { @@ -32,3 +34,21 @@ export async function getGasSponsoredChains() { return []; } } + +export function getChains() { + return fetch( + `${API_SERVER_URL}/v1/chains`, + // revalidate every 60 minutes + { next: { revalidate: 60 * 60 } }, + ).then((res) => res.json()) as Promise<{ data: ChainMetadata[] }>; +} + +export function getChainServices() { + return fetch( + `${API_SERVER_URL}/v1/chains/services`, + // revalidate every 60 minutes + { next: { revalidate: 60 * 60 } }, + ).then((res) => res.json()) as Promise<{ + data: Record>; + }>; +} diff --git a/apps/dashboard/src/@3rdweb-sdk/react/hooks/useApi.ts b/apps/dashboard/src/@3rdweb-sdk/react/hooks/useApi.ts index 926077f6925..9dba9002be5 100644 --- a/apps/dashboard/src/@3rdweb-sdk/react/hooks/useApi.ts +++ b/apps/dashboard/src/@3rdweb-sdk/react/hooks/useApi.ts @@ -1,10 +1,8 @@ -import { analyticsServerProxy, apiServerProxy } from "@/actions/proxies"; +import { apiServerProxy } from "@/actions/proxies"; import type { Project } from "@/api/projects"; import type { Team } from "@/api/team"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { useAllChainsData } from "hooks/chains/allChains"; import { useActiveAccount } from "thirdweb/react"; -import type { UserOpStats } from "types/analytics"; import { accountKeys, authorizedWallets } from "../cache-keys"; // FIXME: We keep repeating types, API server should provide them @@ -142,132 +140,6 @@ export function useAccountCredits() { }); } -type UserOpUsageQueryResult = (UserOpStats & { chainId?: string })[]; - -async function getUserOpUsage(args: { - clientId: string; - from?: Date; - to?: Date; - period?: "day" | "week" | "month" | "year" | "all"; -}) { - const { clientId, from, to, period } = args; - - const searchParams: Record = { - clientId, - }; - - if (from) { - searchParams.from = from.toISOString(); - } - if (to) { - searchParams.to = to.toISOString(); - } - if (period) { - searchParams.period = period; - } - - const res = await analyticsServerProxy<{ data: UserOpUsageQueryResult }>({ - pathname: "/v1/user-ops", - method: "GET", - searchParams: searchParams, - headers: { - "Content-Type": "application/json", - }, - }); - - if (!res.ok) { - throw new Error(res.error); - } - - const json = res.data; - - return json.data; -} - -// TODO - remove this hook, fetch this on server -export function useUserOpUsageAggregate(args: { - clientId: string; - from?: Date; - to?: Date; -}) { - const { clientId, from, to } = args; - const address = useActiveAccount()?.address; - const chainStore = useAllChainsData(); - - return useQuery({ - queryKey: accountKeys.userOpStats( - address || "", - clientId, - from?.toISOString() || "", - to?.toISOString() || "", - "all", - ), - queryFn: async () => { - const userOpStats = await getUserOpUsage({ - clientId, - from, - to, - period: "all", - }); - - // Aggregate stats across wallet types - return userOpStats.reduce( - (acc, curr) => { - // Skip testnets from the aggregated stats - if (curr.chainId) { - const chain = chainStore.idToChain.get(Number(curr.chainId)); - if (chain?.testnet) { - return acc; - } - } - - acc.successful += curr.successful; - acc.failed += curr.failed; - acc.sponsoredUsd += curr.sponsoredUsd; - return acc; - }, - { - date: (from || new Date()).toISOString(), - successful: 0, - failed: 0, - sponsoredUsd: 0, - }, - ); - }, - enabled: !!clientId && !!address, - }); -} - -// TODO - remove this hook, fetch this on server -export function useUserOpUsagePeriod(args: { - clientId: string; - from?: Date; - to?: Date; - period: "day" | "week" | "month" | "year"; -}) { - const { clientId, from, to, period } = args; - const address = useActiveAccount()?.address; - - return useQuery({ - queryKey: accountKeys.userOpStats( - address || "", - clientId as string, - from?.toISOString() || "", - to?.toISOString() || "", - period, - ), - queryFn: async () => { - return getUserOpUsage({ - clientId, - from, - to, - period, - }); - }, - enabled: !!clientId && !!address, - }); -} - export function useUpdateAccount() { const queryClient = useQueryClient(); const address = useActiveAccount()?.address; diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/chainlist/components/server/chain-table.tsx b/apps/dashboard/src/app/(dashboard)/(chain)/chainlist/components/server/chain-table.tsx index 03c548b4cab..51fafdfe7cb 100644 --- a/apps/dashboard/src/app/(dashboard)/(chain)/chainlist/components/server/chain-table.tsx +++ b/apps/dashboard/src/app/(dashboard)/(chain)/chainlist/components/server/chain-table.tsx @@ -12,7 +12,7 @@ import type { ChainMetadataWithServices, ChainSupportedService, } from "../../../types/chain"; -import { getChains } from "../../../utils"; +import { getChainsWithServices } from "../../../utils"; import { ChainlistPagination } from "../client/pagination"; import { ChainListCard } from "../server/chainlist-card"; import { ChainListRow } from "../server/chainlist-row"; @@ -35,7 +35,7 @@ const DEFAULT_PAGE_SIZE = 24; const DEFAULT_PAGE = 1; async function getChainsToRender(params: SearchParams) { - const chains = await getChains(); + const chains = await getChainsWithServices(); // sort the chains const sortedChains = chains.sort((a, b) => { diff --git a/apps/dashboard/src/app/(dashboard)/(chain)/utils.ts b/apps/dashboard/src/app/(dashboard)/(chain)/utils.ts index 22c09c3d347..6a0fec91ec3 100644 --- a/apps/dashboard/src/app/(dashboard)/(chain)/utils.ts +++ b/apps/dashboard/src/app/(dashboard)/(chain)/utils.ts @@ -72,29 +72,19 @@ import zytronBanner from "./temp-assets/zytronBanner.png"; import zytronCTA from "./temp-assets/zytronCTA.jpg"; // END TEMPORARY +import { + getChainServices, + getChains, + getGasSponsoredChains, +} from "@/api/chain"; import { API_SERVER_URL } from "@/constants/env"; import type { ChainMetadata } from "thirdweb/chains"; -import { getGasSponsoredChains } from "../../../@/api/chain"; -import type { - ChainMetadataWithServices, - ChainService, - ChainServices, -} from "./types/chain"; +import type { ChainMetadataWithServices, ChainServices } from "./types/chain"; -export async function getChains() { +export async function getChainsWithServices() { const [chains, chainServices] = await Promise.all([ - fetch( - `${API_SERVER_URL}/v1/chains`, - // revalidate every 60 minutes - { next: { revalidate: 60 * 60 } }, - ).then((res) => res.json()) as Promise<{ data: ChainMetadata[] }>, - fetch( - `${API_SERVER_URL}/v1/chains/services`, - // revalidate every 60 minutes - { next: { revalidate: 60 * 60 } }, - ).then((res) => res.json()) as Promise<{ - data: Record>; - }>, + getChains(), + getChainServices(), ]); if (!chains.data.length) { diff --git a/apps/dashboard/src/app/providers.tsx b/apps/dashboard/src/app/providers.tsx index 8075bf27984..694f8120167 100644 --- a/apps/dashboard/src/app/providers.tsx +++ b/apps/dashboard/src/app/providers.tsx @@ -2,6 +2,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ThemeProvider, useTheme } from "next-themes"; +import { NuqsAdapter } from "nuqs/adapters/next/app"; import { useEffect, useMemo } from "react"; import { Toaster } from "sonner"; import { @@ -20,25 +21,27 @@ const queryClient = new QueryClient(); export function AppRouterProviders(props: { children: React.ReactNode }) { return ( - - - - - - - - - - {props.children} - - - - + + + + + + + + + + + {props.children} + + + + + ); } diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/analytics/page.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/analytics/page.tsx index 53328e11eae..bcc86d74ea1 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/analytics/page.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/analytics/page.tsx @@ -127,13 +127,13 @@ async function OverviewPageContent(props: { }), // User operations usage getUserOpUsage({ - accountId: account.id, + teamId, from: range.from, to: range.to, period: interval, }), getUserOpUsage({ - accountId: account.id, + teamId, from: range.from, to: range.to, period: "all", diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/usage/overview/components/Usage.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/usage/overview/components/Usage.tsx index 47752bae1b9..ebe48bd8944 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/usage/overview/components/Usage.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/usage/overview/components/Usage.tsx @@ -225,17 +225,17 @@ async function AsyncTotalSponsoredChartCard( title: string; }, ) { - const { accountId, from, to } = props; + const { teamId, from, to } = props; const [userOpUsageTimeSeries, userOpUsage] = await Promise.all([ // User operations usage getUserOpUsage({ - accountId: accountId, + teamId, from: from, to: to, period: "week", }), getUserOpUsage({ - accountId: accountId, + teamId, from: from, to: to, period: "all", diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/AccountAbstractionPage.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/AccountAbstractionPage.tsx index a320aa5ad39..dc62e4426fa 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/AccountAbstractionPage.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/AccountAbstractionPage.tsx @@ -1,11 +1,12 @@ "use client"; + import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { TabPathLinks } from "@/components/ui/tabs"; import { TrackedLinkTW } from "@/components/ui/tracked-link"; -import { useUserOpUsageAggregate } from "@3rdweb-sdk/react/hooks/useApi"; import { SmartWalletsBillingAlert } from "components/settings/ApiKeys/Alerts"; import { CircleAlertIcon } from "lucide-react"; import { useActiveWalletChain } from "thirdweb/react"; +import type { UserOpStats } from "types/analytics"; import { AccountAbstractionSummary } from "../../../../../../components/smart-wallets/AccountAbstractionAnalytics/AccountAbstractionSummary"; import { AAFooterSection } from "./AAFooterSection"; import { isOpChainId } from "./isOpChain"; @@ -18,6 +19,7 @@ export function AccountAbstractionLayout(props: { projectKey: string; children: React.ReactNode; hasSmartWalletsWithoutBilling: boolean; + userOpStats: UserOpStats; }) { const chain = useActiveWalletChain(); @@ -25,10 +27,6 @@ export function AccountAbstractionLayout(props: { const smartWalletsLayoutSlug = `/team/${props.teamSlug}/${props.projectSlug}/connect/account-abstraction`; - const aggregateUserOpUsageQuery = useUserOpUsageAggregate({ - clientId: props.projectKey, - }); - return (

@@ -69,7 +67,7 @@ export function AccountAbstractionLayout(props: {
diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/layout.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/layout.tsx index b4250c02371..68d7997bf4b 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/layout.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/layout.tsx @@ -1,3 +1,4 @@ +import { getAggregateUserOpUsage } from "@/api/analytics"; import { getProject } from "@/api/projects"; import { getTeamBySlug } from "@/api/team"; import type { Metadata } from "next"; @@ -31,8 +32,14 @@ export default async function Page(props: { const hasSmartWalletsWithoutBilling = isBundlerServiceEnabled && team.billingStatus !== "validPayment"; + const userOpStats = await getAggregateUserOpUsage({ + teamId: team.id, + projectId: project.id, + }); + return ( ; + params: Promise; + searchParams: Promise; children: React.ReactNode; }) { - const { team_slug, project_slug } = await props.params; - - const [team, project] = await Promise.all([ - getTeamBySlug(team_slug), - getProject(team_slug, project_slug), + const [params, searchParams] = await Promise.all([ + props.params, + searchParamLoader(props.searchParams), ]); - if (!team) { - redirect("/team"); - } + const project = await getProject(params.team_slug, params.project_slug); if (!project) { - redirect(`/team/${team_slug}`); + redirect(`/team/${params.team_slug}`); } - return ; + const interval = searchParams.interval ?? "week"; + const rangeType = searchParams.range || "last-120"; + + const range: Range = { + from: + rangeType === "custom" + ? searchParams.from + : getLastNDaysRange(rangeType).from, + to: + rangeType === "custom" + ? searchParams.to + : getLastNDaysRange(rangeType).to, + type: rangeType, + }; + + const userOpStats = await getUserOpUsage({ + teamId: project.teamId, + projectId: project.id, + from: range.from, + to: range.to, + period: interval, + }); + + return ; } diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/search-params.ts b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/search-params.ts new file mode 100644 index 00000000000..3e11282f10c --- /dev/null +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/search-params.ts @@ -0,0 +1,17 @@ +import { getLastNDaysRange } from "components/analytics/date-range-selector"; +import { createLoader, parseAsIsoDate, parseAsStringEnum } from "nuqs/server"; + +export const searchParams = { + range: parseAsStringEnum([ + "last-120", + "last-60", + "last-30", + "last-7", + "custom", + ]).withDefault("last-120"), + from: parseAsIsoDate.withDefault(getLastNDaysRange("last-120").from), + to: parseAsIsoDate.withDefault(getLastNDaysRange("last-120").to), + interval: parseAsStringEnum(["day", "week"]).withDefault("week"), +}; + +export const searchParamLoader = createLoader(searchParams); diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/page.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/page.tsx index 2a3f97fea9b..aed5efadd88 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/page.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/page.tsx @@ -57,6 +57,11 @@ export default async function ProjectOverviewPage(props: PageProps) { ]); const project = await getProject(params.team_slug, params.project_slug); + + if (!project) { + redirect(`/team/${params.team_slug}`); + } + const interval = (searchParams.interval as "day" | "week") ?? "week"; const rangeType = (searchParams.type as DurationId) || "last-120"; const range: Range = { @@ -65,10 +70,6 @@ export default async function ProjectOverviewPage(props: PageProps) { type: rangeType, }; - if (!project) { - redirect(`/team/${params.team_slug}`); - } - const isActive = await isProjectActive({ clientId: project.publishableKey }); return ( @@ -141,13 +142,15 @@ async function ProjectAnalytics(props: { }), // User operations usage getUserOpUsage({ - clientId: project.publishableKey, + teamId: project.teamId, + projectId: project.id, from: range.from, to: range.to, period: interval, }), getUserOpUsage({ - clientId: project.publishableKey, + teamId: project.teamId, + projectId: project.id, from: range.from, to: range.to, period: "all", diff --git a/apps/dashboard/src/components/smart-wallets/AccountAbstractionAnalytics/index.tsx b/apps/dashboard/src/components/smart-wallets/AccountAbstractionAnalytics/index.tsx index 72cc50958aa..d6c2a4b0ec8 100644 --- a/apps/dashboard/src/components/smart-wallets/AccountAbstractionAnalytics/index.tsx +++ b/apps/dashboard/src/components/smart-wallets/AccountAbstractionAnalytics/index.tsx @@ -1,6 +1,4 @@ "use client"; - -import { useUserOpUsagePeriod } from "@3rdweb-sdk/react/hooks/useApi"; import { DateRangeSelector, type Range, @@ -8,29 +6,56 @@ import { } from "components/analytics/date-range-selector"; import { IntervalSelector } from "components/analytics/interval-selector"; import { differenceInDays } from "date-fns"; -import { useState } from "react"; +import { useQueryState } from "nuqs"; +import { useTransition } from "react"; +import type { UserOpStats } from "types/analytics"; +import { searchParams } from "../../../app/team/[team_slug]/[project_slug]/connect/account-abstraction/search-params"; import { SponsoredTransactionsChartCard } from "./SponsoredTransactionsChartCard"; import { TotalSponsoredChartCard } from "./TotalSponsoredChartCard"; -export function AccountAbstractionAnalytics({ - clientId, -}: { clientId: string }) { - const [range, setRange] = useState(() => - getLastNDaysRange("last-120"), - ); +export function AccountAbstractionAnalytics(props: { + userOpStats: UserOpStats[]; +}) { + const [isLoading, startTransition] = useTransition(); - // use date-fns to calculate the number of days in the range - const daysInRange = differenceInDays(range.to, range.from); - const [intervalType, setIntervalType] = useState<"day" | "week">( - daysInRange > 30 ? "week" : "day", + const [rangeType, setRangeType] = useQueryState( + "range", + searchParams.range.withOptions({ + history: "push", + shallow: false, + startTransition, + }), + ); + const [intervalType, setIntervalType] = useQueryState<"day" | "week">( + "interval", + searchParams.interval.withOptions({ + history: "push", + shallow: false, + startTransition, + }), + ); + const [from, setFrom] = useQueryState( + "from", + searchParams.from.withOptions({ + history: "push", + shallow: false, + startTransition, + }), + ); + const [to, setTo] = useQueryState( + "to", + searchParams.to.withOptions({ + history: "push", + shallow: false, + startTransition, + }), ); - const userOpUsageQuery = useUserOpUsagePeriod({ - clientId: clientId, - from: range.from, - to: range.to, - period: intervalType, - }); + const range: Range = { + from: rangeType === "custom" ? from : getLastNDaysRange(rangeType).from, + to: rangeType === "custom" ? to : getLastNDaysRange(rangeType).to, + type: rangeType, + }; return (
@@ -38,7 +63,19 @@ export function AccountAbstractionAnalytics({ { - setRange(newRange); + // if the new range is "custom", set to and from + if (newRange.type === "custom") { + setFrom(newRange.from); + setTo(newRange.to); + } else { + // otherwise delete to and from -> set range type only + setFrom(null); + setTo(null); + } + + // set the range type (always) + setRangeType(newRange.type); + // also update interval type based on the new range const days = differenceInDays(newRange.to, newRange.from); setIntervalType(days > 30 ? "week" : "day"); }} @@ -53,13 +90,13 @@ export function AccountAbstractionAnalytics({
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 77e0c8e4ee9..aecde506dd0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -135,7 +135,7 @@ importers: version: 1.1.7(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@sentry/nextjs': specifier: 8.53.0 - version: 8.53.0(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.1.6(@babel/core@7.26.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) + version: 8.53.0(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.1.6(@babel/core@7.26.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) '@shazow/whatsabi': specifier: ^0.19.0 version: 0.19.0(@noble/hashes@1.7.1)(typescript@5.7.3)(zod@3.24.1) @@ -211,6 +211,9 @@ importers: nextjs-toploader: specifier: ^1.6.12 version: 1.6.12(next@15.1.6(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + nuqs: + specifier: ^2.4.0 + version: 2.4.0(next@15.1.6(@babel/core@7.26.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0) p-limit: specifier: ^6.2.0 version: 6.2.0 @@ -331,7 +334,7 @@ importers: version: 8.5.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10)) '@storybook/nextjs': specifier: 8.5.2 - version: 8.5.2(@swc/core@1.10.12(@swc/helpers@0.5.15))(next@15.1.6(@babel/core@7.26.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(type-fest@4.33.0)(typescript@5.7.3)(webpack-hot-middleware@2.26.1)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) + version: 8.5.2(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)(next@15.1.6(@babel/core@7.26.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(type-fest@4.33.0)(typescript@5.7.3)(webpack-hot-middleware@2.26.1)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) '@storybook/react': specifier: 8.5.2 version: 8.5.2(@storybook/test@8.5.2(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10)))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(typescript@5.7.3) @@ -1124,7 +1127,7 @@ importers: version: 2.1.0(react-native@0.76.6(@babel/core@7.26.7)(@babel/preset-env@7.26.7(@babel/core@7.26.7))(@types/react@19.0.8)(bufferutil@4.0.9)(encoding@0.1.13)(react@19.0.0)(utf-8-validate@5.0.10)) '@size-limit/preset-big-lib': specifier: 11.1.6 - version: 11.1.6(bufferutil@4.0.9)(esbuild@0.24.2)(size-limit@11.1.6)(utf-8-validate@5.0.10) + version: 11.1.6(bufferutil@4.0.9)(size-limit@11.1.6)(utf-8-validate@5.0.10) '@storybook/addon-essentials': specifier: 8.5.2 version: 8.5.2(@types/react@19.0.8)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.3.3)(utf-8-validate@5.0.10)) @@ -11746,6 +11749,24 @@ packages: number-allocator@1.0.14: resolution: {integrity: sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==} + nuqs@2.4.0: + resolution: {integrity: sha512-+yOdX0q/wdYlseSYtWC8StDDt2QFcYX/zV5/E67J1cOJo3PR0mggxMx4acZGC0Hu66xFHENKQkqI2zSpH742xQ==} + peerDependencies: + '@remix-run/react': '>=2' + next: '>=14.2.0' + react: '>=18.2.0 || ^19.0.0-0' + react-router: ^6 || ^7 + react-router-dom: ^6 || ^7 + peerDependenciesMeta: + '@remix-run/react': + optional: true + next: + optional: true + react-router: + optional: true + react-router-dom: + optional: true + ob1@0.81.0: resolution: {integrity: sha512-6Cvrkxt1tqaRdWqTAMcVYEiO5i1xcF9y7t06nFdjFqkfPsEloCf8WwhXdwBpNUkVYSQlSGS7cDgVQR86miBfBQ==} engines: {node: '>=18.18'} @@ -19670,7 +19691,7 @@ snapshots: dependencies: playwright: 1.50.1 - '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.14.2)(type-fest@4.33.0)(webpack-hot-middleware@2.26.1)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)))': + '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.14.2)(type-fest@4.33.0)(webpack-hot-middleware@2.26.1)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2))': dependencies: ansi-html: 0.0.9 core-js-pure: 3.40.0 @@ -19680,7 +19701,7 @@ snapshots: react-refresh: 0.14.2 schema-utils: 4.3.0 source-map: 0.7.4 - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) optionalDependencies: type-fest: 4.33.0 webpack-hot-middleware: 2.26.1 @@ -20820,7 +20841,7 @@ snapshots: '@sentry/core@8.53.0': {} - '@sentry/nextjs@8.53.0(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.1.6(@babel/core@7.26.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)))': + '@sentry/nextjs@8.53.0(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.1.6(@babel/core@7.26.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2))': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.28.0 @@ -20831,7 +20852,7 @@ snapshots: '@sentry/opentelemetry': 8.53.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.28.0) '@sentry/react': 8.53.0(react@19.0.0) '@sentry/vercel-edge': 8.53.0 - '@sentry/webpack-plugin': 2.22.7(encoding@0.1.13)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) + '@sentry/webpack-plugin': 2.22.7(encoding@0.1.13)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) chalk: 3.0.0 next: 15.1.6(@babel/core@7.26.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) resolve: 1.22.8 @@ -20907,12 +20928,12 @@ snapshots: '@opentelemetry/api': 1.9.0 '@sentry/core': 8.53.0 - '@sentry/webpack-plugin@2.22.7(encoding@0.1.13)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)))': + '@sentry/webpack-plugin@2.22.7(encoding@0.1.13)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2))': dependencies: '@sentry/bundler-plugin-core': 2.22.7(encoding@0.1.13) unplugin: 1.0.1 uuid: 9.0.1 - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) transitivePeerDependencies: - encoding - supports-color @@ -21003,11 +21024,11 @@ snapshots: dependencies: size-limit: 11.1.6 - '@size-limit/preset-big-lib@11.1.6(bufferutil@4.0.9)(esbuild@0.24.2)(size-limit@11.1.6)(utf-8-validate@5.0.10)': + '@size-limit/preset-big-lib@11.1.6(bufferutil@4.0.9)(size-limit@11.1.6)(utf-8-validate@5.0.10)': dependencies: '@size-limit/file': 11.1.6(size-limit@11.1.6) '@size-limit/time': 11.1.6(bufferutil@4.0.9)(size-limit@11.1.6)(utf-8-validate@5.0.10) - '@size-limit/webpack': 11.1.6(esbuild@0.24.2)(size-limit@11.1.6) + '@size-limit/webpack': 11.1.6(size-limit@11.1.6) size-limit: 11.1.6 transitivePeerDependencies: - '@swc/core' @@ -21027,11 +21048,11 @@ snapshots: - supports-color - utf-8-validate - '@size-limit/webpack@11.1.6(esbuild@0.24.2)(size-limit@11.1.6)': + '@size-limit/webpack@11.1.6(size-limit@11.1.6)': dependencies: nanoid: 5.0.9 size-limit: 11.1.6 - webpack: 5.97.1(esbuild@0.24.2) + webpack: 5.97.1 transitivePeerDependencies: - '@swc/core' - esbuild @@ -22000,7 +22021,7 @@ snapshots: ts-dedent: 2.2.0 vite: 6.0.11(@types/node@22.13.0)(jiti@2.4.2)(lightningcss@1.29.1)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0) - '@storybook/builder-webpack5@8.5.2(@swc/core@1.10.12(@swc/helpers@0.5.15))(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(typescript@5.7.3)': + '@storybook/builder-webpack5@8.5.2(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(typescript@5.7.3)': dependencies: '@storybook/core-webpack': 8.5.2(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10)) '@types/semver': 7.5.8 @@ -22008,23 +22029,23 @@ snapshots: case-sensitive-paths-webpack-plugin: 2.4.0 cjs-module-lexer: 1.4.3 constants-browserify: 1.0.0 - css-loader: 6.11.0(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) + css-loader: 6.11.0(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) es-module-lexer: 1.6.0 - fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.7.3)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) - html-webpack-plugin: 5.6.3(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) + fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.7.3)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) + html-webpack-plugin: 5.6.3(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) magic-string: 0.30.17 path-browserify: 1.0.1 process: 0.11.10 semver: 7.7.0 storybook: 8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10) - style-loader: 3.3.4(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) - terser-webpack-plugin: 5.3.11(@swc/core@1.10.12(@swc/helpers@0.5.15))(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) + style-loader: 3.3.4(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) + terser-webpack-plugin: 5.3.11(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) ts-dedent: 2.2.0 url: 0.11.4 util: 0.12.5 util-deprecate: 1.0.2 - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) - webpack-dev-middleware: 6.1.3(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) + webpack-dev-middleware: 6.1.3(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) webpack-hot-middleware: 2.26.1 webpack-virtual-modules: 0.6.2 optionalDependencies: @@ -22139,7 +22160,7 @@ snapshots: dependencies: storybook: 8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10) - '@storybook/nextjs@8.5.2(@swc/core@1.10.12(@swc/helpers@0.5.15))(next@15.1.6(@babel/core@7.26.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(type-fest@4.33.0)(typescript@5.7.3)(webpack-hot-middleware@2.26.1)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)))': + '@storybook/nextjs@8.5.2(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)(next@15.1.6(@babel/core@7.26.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(type-fest@4.33.0)(typescript@5.7.3)(webpack-hot-middleware@2.26.1)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2))': dependencies: '@babel/core': 7.26.7 '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.26.7) @@ -22154,30 +22175,30 @@ snapshots: '@babel/preset-react': 7.26.3(@babel/core@7.26.7) '@babel/preset-typescript': 7.26.0(@babel/core@7.26.7) '@babel/runtime': 7.26.7 - '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.14.2)(type-fest@4.33.0)(webpack-hot-middleware@2.26.1)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) - '@storybook/builder-webpack5': 8.5.2(@swc/core@1.10.12(@swc/helpers@0.5.15))(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(typescript@5.7.3) - '@storybook/preset-react-webpack': 8.5.2(@storybook/test@8.5.2(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10)))(@swc/core@1.10.12(@swc/helpers@0.5.15))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(typescript@5.7.3) + '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.14.2)(type-fest@4.33.0)(webpack-hot-middleware@2.26.1)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) + '@storybook/builder-webpack5': 8.5.2(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(typescript@5.7.3) + '@storybook/preset-react-webpack': 8.5.2(@storybook/test@8.5.2(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10)))(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(typescript@5.7.3) '@storybook/react': 8.5.2(@storybook/test@8.5.2(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10)))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(typescript@5.7.3) '@storybook/test': 8.5.2(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10)) '@types/semver': 7.5.8 - babel-loader: 9.2.1(@babel/core@7.26.7)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) - css-loader: 6.11.0(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) + babel-loader: 9.2.1(@babel/core@7.26.7)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) + css-loader: 6.11.0(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) find-up: 5.0.0 image-size: 1.2.0 loader-utils: 3.3.1 next: 15.1.6(@babel/core@7.26.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - node-polyfill-webpack-plugin: 2.0.1(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) + node-polyfill-webpack-plugin: 2.0.1(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) pnp-webpack-plugin: 1.7.0(typescript@5.7.3) postcss: 8.5.1 - postcss-loader: 8.1.1(postcss@8.5.1)(typescript@5.7.3)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) + postcss-loader: 8.1.1(postcss@8.5.1)(typescript@5.7.3)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) react: 19.0.0 react-dom: 19.0.0(react@19.0.0) react-refresh: 0.14.2 resolve-url-loader: 5.0.0 - sass-loader: 14.2.1(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) + sass-loader: 14.2.1(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) semver: 7.7.0 storybook: 8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10) - style-loader: 3.3.4(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) + style-loader: 3.3.4(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) styled-jsx: 5.1.6(@babel/core@7.26.7)(react@19.0.0) ts-dedent: 2.2.0 tsconfig-paths: 4.2.0 @@ -22185,7 +22206,7 @@ snapshots: optionalDependencies: sharp: 0.33.5 typescript: 5.7.3 - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) transitivePeerDependencies: - '@rspack/core' - '@swc/core' @@ -22204,11 +22225,11 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@storybook/preset-react-webpack@8.5.2(@storybook/test@8.5.2(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10)))(@swc/core@1.10.12(@swc/helpers@0.5.15))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(typescript@5.7.3)': + '@storybook/preset-react-webpack@8.5.2(@storybook/test@8.5.2(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10)))(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(typescript@5.7.3)': dependencies: '@storybook/core-webpack': 8.5.2(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10)) '@storybook/react': 8.5.2(@storybook/test@8.5.2(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10)))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(storybook@8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10))(typescript@5.7.3) - '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.7.3)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))) + '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.7.3)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) '@types/semver': 7.5.8 find-up: 5.0.0 magic-string: 0.30.17 @@ -22219,7 +22240,7 @@ snapshots: semver: 7.7.0 storybook: 8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10) tsconfig-paths: 4.2.0 - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) optionalDependencies: typescript: 5.7.3 transitivePeerDependencies: @@ -22238,7 +22259,7 @@ snapshots: dependencies: storybook: 8.5.2(bufferutil@4.0.9)(prettier@3.4.2)(utf-8-validate@5.0.10) - '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.7.3)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)))': + '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.7.3)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2))': dependencies: debug: 4.4.0(supports-color@8.1.1) endent: 2.1.0 @@ -22248,7 +22269,7 @@ snapshots: react-docgen-typescript: 2.2.2(typescript@5.7.3) tslib: 2.8.1 typescript: 5.7.3 - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) transitivePeerDependencies: - supports-color @@ -24635,12 +24656,12 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@9.2.1(@babel/core@7.26.7)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))): + babel-loader@9.2.1(@babel/core@7.26.7)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)): dependencies: '@babel/core': 7.26.7 find-cache-dir: 4.0.0 schema-utils: 4.3.0 - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) babel-plugin-istanbul@6.1.1: dependencies: @@ -25578,7 +25599,7 @@ snapshots: css-gradient-parser@0.0.16: {} - css-loader@6.11.0(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))): + css-loader@6.11.0(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)): dependencies: icss-utils: 5.1.0(postcss@8.5.1) postcss: 8.5.1 @@ -25589,7 +25610,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.7.0 optionalDependencies: - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) css-select@4.3.0: dependencies: @@ -27402,7 +27423,7 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@8.0.0(typescript@5.7.3)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))): + fork-ts-checker-webpack-plugin@8.0.0(typescript@5.7.3)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)): dependencies: '@babel/code-frame': 7.26.2 chalk: 4.1.2 @@ -27417,7 +27438,7 @@ snapshots: semver: 7.7.0 tapable: 2.2.1 typescript: 5.7.3 - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) form-data-encoder@2.1.4: {} @@ -27889,7 +27910,7 @@ snapshots: html-void-elements@3.0.0: {} - html-webpack-plugin@5.6.3(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))): + html-webpack-plugin@5.6.3(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -27897,7 +27918,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) htmlparser2@3.10.1: dependencies: @@ -30421,7 +30442,7 @@ snapshots: node-int64@0.4.0: {} - node-polyfill-webpack-plugin@2.0.1(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))): + node-polyfill-webpack-plugin@2.0.1(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)): dependencies: assert: 2.1.0 browserify-zlib: 0.2.0 @@ -30448,7 +30469,7 @@ snapshots: url: 0.11.4 util: 0.12.5 vm-browserify: 1.1.2 - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) node-releases@2.0.19: {} @@ -30517,6 +30538,13 @@ snapshots: transitivePeerDependencies: - supports-color + nuqs@2.4.0(next@15.1.6(@babel/core@7.26.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0): + dependencies: + mitt: 3.0.1 + react: 19.0.0 + optionalDependencies: + next: 15.1.6(@babel/core@7.26.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + ob1@0.81.0: dependencies: flow-enums-runtime: 0.0.6 @@ -31118,14 +31146,14 @@ snapshots: tsx: 4.19.2 yaml: 2.7.0 - postcss-loader@8.1.1(postcss@8.5.1)(typescript@5.7.3)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))): + postcss-loader@8.1.1(postcss@8.5.1)(typescript@5.7.3)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)): dependencies: cosmiconfig: 9.0.0(typescript@5.7.3) jiti: 1.21.7 postcss: 8.5.1 semver: 7.7.0 optionalDependencies: - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) transitivePeerDependencies: - typescript @@ -32331,11 +32359,11 @@ snapshots: safer-buffer@2.1.2: {} - sass-loader@14.2.1(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))): + sass-loader@14.2.1(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)): dependencies: neo-async: 2.6.2 optionalDependencies: - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) satori@0.12.1: dependencies: @@ -32936,9 +32964,9 @@ snapshots: structured-headers@0.4.1: {} - style-loader@3.3.4(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))): + style-loader@3.3.4(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)): dependencies: - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) style-to-object@0.4.4: dependencies: @@ -33185,6 +33213,18 @@ snapshots: ansi-escapes: 4.3.2 supports-hyperlinks: 2.3.0 + terser-webpack-plugin@5.3.11(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)): + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + jest-worker: 27.5.1 + schema-utils: 4.3.0 + serialize-javascript: 6.0.2 + terser: 5.37.0 + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) + optionalDependencies: + '@swc/core': 1.10.12(@swc/helpers@0.5.15) + esbuild: 0.24.2 + terser-webpack-plugin@5.3.11(@swc/core@1.10.12(@swc/helpers@0.5.15))(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))): dependencies: '@jridgewell/trace-mapping': 0.3.25 @@ -33196,16 +33236,14 @@ snapshots: optionalDependencies: '@swc/core': 1.10.12(@swc/helpers@0.5.15) - terser-webpack-plugin@5.3.11(esbuild@0.24.2)(webpack@5.97.1(esbuild@0.24.2)): + terser-webpack-plugin@5.3.11(webpack@5.97.1): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 4.3.0 serialize-javascript: 6.0.2 terser: 5.37.0 - webpack: 5.97.1(esbuild@0.24.2) - optionalDependencies: - esbuild: 0.24.2 + webpack: 5.97.1 terser@5.37.0: dependencies: @@ -34161,7 +34199,7 @@ snapshots: - bufferutil - utf-8-validate - webpack-dev-middleware@6.1.3(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))): + webpack-dev-middleware@6.1.3(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)): dependencies: colorette: 2.0.20 memfs: 3.5.3 @@ -34169,7 +34207,7 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.0 optionalDependencies: - webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)) + webpack: 5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2) webpack-hot-middleware@2.26.1: dependencies: @@ -34183,6 +34221,36 @@ snapshots: webpack-virtual-modules@0.6.2: {} + webpack@5.97.1: + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.6 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.14.0 + browserslist: 4.24.4 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.0 + es-module-lexer: 1.6.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.3.0 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.11(webpack@5.97.1) + watchpack: 2.4.2 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15)): dependencies: '@types/eslint-scope': 3.7.7 @@ -34213,7 +34281,7 @@ snapshots: - esbuild - uglify-js - webpack@5.97.1(esbuild@0.24.2): + webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.6 @@ -34235,7 +34303,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.11(esbuild@0.24.2)(webpack@5.97.1(esbuild@0.24.2)) + terser-webpack-plugin: 5.3.11(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack@5.97.1(@swc/core@1.10.12(@swc/helpers@0.5.15))(esbuild@0.24.2)) watchpack: 2.4.2 webpack-sources: 3.2.3 transitivePeerDependencies: