chore: reduce frontend server memory & tracing (#7014)

* chore: reduce memory usage

* feat: worker tracing

* fix: eslint

* fix: remove compat flag

* fix: prettier
This commit is contained in:
Michael H.
2026-08-05 19:59:15 +02:00
committed by GitHub
parent 0038ea8b15
commit a89711841d
13 changed files with 1014 additions and 433 deletions
+1 -1
View File
@@ -35,7 +35,7 @@
"vite-svg-loader": "^5.1.0",
"vue-component-type-helpers": "^3.1.8",
"vue-tsc": "^2.0.24",
"wrangler": "^4.54.0"
"wrangler": "^4.115.0"
},
"dependencies": {
"@formatjs/intl-localematcher": "^0.5.4",
@@ -96,7 +96,7 @@ import {
import { capitalizeString } from '@modrinth/utils'
import { Tooltip } from 'floating-vue'
import { useGeneratedState } from '~/composables/generated'
import { tremendousIdMap } from '~/generated/state.json'
import { findRail } from '~/utils/muralpay-rails'
type Transaction = Labrinth.Payout.v3.TransactionItem
@@ -110,7 +110,6 @@ const emit = defineEmits<{
}>()
const { addNotification } = injectNotificationManager()
const generatedState = useGeneratedState()
const isIncome = computed(() => props.transaction.type === 'payout_available')
@@ -120,7 +119,7 @@ const methodIconUrl = computed(() => {
const methodId = props.transaction.method_id
if (method === 'tremendous' && methodId) {
const methodInfo = generatedState.value.tremendousIdMap?.[methodId]
const methodInfo = tremendousIdMap?.[methodId]
if (methodInfo?.name?.toLowerCase()?.includes('paypal')) return null
return methodInfo?.image_url ?? null
}
@@ -137,7 +136,7 @@ const methodIconComponent = computed(() => {
case 'tremendous': {
const methodId = props.transaction.method_id
if (methodId) {
const info = generatedState.value.tremendousIdMap?.[methodId]
const info = tremendousIdMap?.[methodId]
if (info?.name?.toLowerCase()?.includes('paypal')) {
return PayPalColorIcon
}
@@ -187,7 +186,7 @@ function formatMethodName(method: string | undefined, method_id: string | undefi
return 'Venmo'
case 'tremendous':
if (method_id) {
const info = generatedState.value.tremendousIdMap?.[method_id]
const info = tremendousIdMap?.[method_id]
if (info) return `${info.name}`
}
return 'Tremendous'
@@ -248,13 +248,12 @@ import { computed, ref, watch } from 'vue'
import RevenueInputField from '@/components/ui/dashboard/RevenueInputField.vue'
import WithdrawFeeBreakdown from '@/components/ui/dashboard/WithdrawFeeBreakdown.vue'
import { useGeneratedState } from '@/composables/generated'
import { useWithdrawContext } from '@/providers/creator-withdraw.ts'
import { getRailConfig } from '@/utils/muralpay-rails'
import { muralBankDetails } from '~/generated/state.json'
const { withdrawData, maxWithdrawAmount, availableMethods, calculateFees } = useWithdrawContext()
const { formatMessage } = useVIntl()
const generatedState = useGeneratedState()
const selectedRail = computed(() => {
const railId = withdrawData.value.selection.method
@@ -285,7 +284,7 @@ const availableBankNames = computed(() => {
const rail = selectedRail.value
if (!rail || !rail.railCode) return []
const bankDetails = generatedState.value.muralBankDetails?.[rail.railCode]
const bankDetails = muralBankDetails?.[rail.railCode as keyof typeof muralBankDetails]
return bankDetails?.bankNames || []
})
@@ -3,18 +3,18 @@
ref="wrapperRef"
:stripe-publishable-key="config.public.stripePublishableKey"
:site-url="config.public.siteUrl"
:products="generatedState.products || []"
:products="(products ?? []) as Labrinth.Billing.Internal.Product[]"
/>
</template>
<script setup lang="ts">
import type { Labrinth } from '@modrinth/api-client'
// TODO: Remove this wrapper when we figure out how to do cross platform state + stripe
import { ServersUpgradeModalWrapper as ServersUpgradeModalWrapperBase } from '@modrinth/ui'
import { useGeneratedState } from '~/composables/generated'
import { products } from '~/generated/state.json'
const config = useRuntimeConfig()
const generatedState = useGeneratedState()
const wrapperRef = ref<InstanceType<typeof ServersUpgradeModalWrapperBase> | null>(null)
+6 -5
View File
@@ -1,9 +1,10 @@
import { useGeneratedState } from '@/composables/generated.ts'
import type { ISO3166 } from '@modrinth/api-client'
import { useRequestHeaders, useState } from '#imports'
import { countries, subdivisions } from '~/generated/state.json'
export const useCountries = () => {
const generated = useGeneratedState()
return computed(() => generated.value.countries ?? [])
return computed(() => (countries ?? []) as ISO3166.Country[])
}
export const useFormattedCountries = () => {
@@ -28,10 +29,10 @@ export const useFormattedCountries = () => {
}
export const useSubdivisions = (countryCode: ComputedRef<string> | Ref<string> | string) => {
const generated = useGeneratedState()
const code = isRef(countryCode) ? countryCode : ref(countryCode)
const byCountry = (subdivisions ?? {}) as Record<string, ISO3166.Subdivision[]>
return computed(() => generated.value.subdivisions?.[unref(code)] ?? [])
return computed(() => byCountry[unref(code)] ?? [])
}
export const useUserCountry = () => {
+40 -30
View File
@@ -1,7 +1,17 @@
import type { ISO3166, Labrinth } from '@modrinth/api-client'
import type { DisplayProjectType } from '@modrinth/utils'
import generatedState from '~/generated/state.json'
import {
apiUrl,
categories,
donationPlatforms,
errors,
gameVersions,
lastGenerated,
loaders,
reportTypes,
taxComplianceThresholds,
} from '~/generated/state.json'
import type { DisplayMode } from '~/plugins/cosmetics'
export interface ProjectType {
@@ -23,7 +33,25 @@ export interface LoaderData {
export type Country = ISO3166.Country
export type Subdivision = ISO3166.Subdivision
export interface GeneratedState extends Labrinth.State.GeneratedState {
/**
* Route-specific slices of the generated state are deliberately excluded here.
* Anything placed on `useGeneratedState` is serialized into the SSR payload of
* every page, so large fields must be imported directly by the pages that need
* them instead (see `useCountries`, `useSubdivisions`, `~/generated/state.json`).
*/
type GloballyUsedState = Omit<
Labrinth.State.GeneratedState,
| 'countries'
| 'subdivisions'
| 'muralBankDetails'
| 'tremendousIdMap'
| 'homePageProjects'
| 'homePageSearch'
| 'homePageNotifs'
| 'products'
>
export interface GeneratedState extends GloballyUsedState {
// Additional runtime-defined fields not from the API
projectTypes: ProjectType[]
loaderData: LoaderData
@@ -40,26 +68,17 @@ export interface GeneratedState extends Labrinth.State.GeneratedState {
}
/**
* Composable for accessing the complete generated state.
* Composable for accessing the globally used generated state.
* This includes both fetched data and runtime-defined constants.
*/
export const useGeneratedState = () =>
useState<GeneratedState>('generatedState', () => ({
// Cast JSON data to typed API responses
categories: (generatedState.categories ?? []) as Labrinth.Tags.v2.Category[],
loaders: (generatedState.loaders ?? []) as Labrinth.Tags.v2.Loader[],
gameVersions: (generatedState.gameVersions ?? []) as Labrinth.Tags.v2.GameVersion[],
donationPlatforms: (generatedState.donationPlatforms ??
[]) as Labrinth.Tags.v2.DonationPlatform[],
reportTypes: (generatedState.reportTypes ?? []) as string[],
muralBankDetails: generatedState.muralBankDetails as
| Record<string, { bankNames: string[] }>
| undefined,
tremendousIdMap: generatedState.tremendousIdMap as
| Record<string, { name: string; image_url: string | null }>
| undefined,
countries: (generatedState.countries ?? []) as ISO3166.Country[],
subdivisions: (generatedState.subdivisions ?? {}) as Record<string, ISO3166.Subdivision[]>,
categories: (categories ?? []) as Labrinth.Tags.v2.Category[],
loaders: (loaders ?? []) as Labrinth.Tags.v2.Loader[],
gameVersions: (gameVersions ?? []) as Labrinth.Tags.v2.GameVersion[],
donationPlatforms: (donationPlatforms ?? []) as Labrinth.Tags.v2.DonationPlatform[],
reportTypes: (reportTypes ?? []) as string[],
projectTypes: [
{
@@ -121,20 +140,11 @@ export const useGeneratedState = () =>
rejectedStatuses: ['rejected', 'withheld'],
staffRoles: ['moderator', 'admin'],
homePageProjects: generatedState.homePageProjects as unknown as
| Labrinth.Projects.v2.Project[]
| undefined,
homePageSearch: generatedState.homePageSearch as Labrinth.Search.v2.SearchResults | undefined,
homePageNotifs: generatedState.homePageNotifs as Labrinth.Search.v2.SearchResults | undefined,
products: generatedState.products as Labrinth.Billing.Internal.Product[] | undefined,
taxComplianceThresholds: (generatedState.taxComplianceThresholds ?? {}) as Record<
string,
number
>,
taxComplianceThresholds: (taxComplianceThresholds ?? {}) as Record<string, number>,
lastGenerated: generatedState.lastGenerated,
apiUrl: generatedState.apiUrl,
errors: generatedState.errors,
lastGenerated,
apiUrl,
errors,
buildYear: new Date().getFullYear(),
}))
+2 -4
View File
@@ -902,13 +902,11 @@ import OrganizationCreateModal from '~/components/ui/create/OrganizationCreateMo
import ProjectCreateModal from '~/components/ui/create/ProjectCreateModal.vue'
import ModrinthFooter from '~/components/ui/ModrinthFooter.vue'
import { getSignInRouteObj } from '~/composables/auth.ts'
import { errors as generatedStateErrors } from '~/generated/state.json'
import { errors as generatedStateErrors, taxComplianceThresholds } from '~/generated/state.json'
import { provideCurrentProjectId } from '~/providers/current-project.ts'
import { getProjectTypeMessage } from '~/utils/i18n-project-type.ts'
import { hasActiveMidas } from '~/utils/user-membership.ts'
const generatedState = useGeneratedState()
const country = useUserCountry()
const { formatMessage } = useVIntl()
@@ -956,7 +954,7 @@ const showTaxComplianceBanner = computed(() => {
if (flags.value.testTaxForm && auth.value.user) return true
const bal = payoutBalance.value
if (!bal) return false
const threshold = getTaxThreshold(generatedState.value?.taxComplianceThresholds)
const threshold = getTaxThreshold(taxComplianceThresholds)
const thresholdMet = (bal.withdrawn_ytd ?? 0) >= threshold
const status = bal.form_completion_status ?? 'unknown'
const isComplete = status === 'complete'
@@ -103,7 +103,7 @@ import { useQuery } from '@tanstack/vue-query'
import dayjs from 'dayjs'
import RevenueTransaction from '~/components/ui/dashboard/RevenueTransaction.vue'
import { useGeneratedState } from '~/composables/generated'
import { tremendousIdMap } from '~/generated/state.json'
import { findRail } from '~/utils/muralpay-rails'
const { formatMessage } = useVIntl()
@@ -114,7 +114,6 @@ const formatMonth = useFormatDateTime({
})
const client = injectModrinthClient()
const generatedState = useGeneratedState()
const messages = defineMessages({
transactionsHeader: {
@@ -281,7 +280,7 @@ function transactionsToCSV() {
break
case 'tremendous':
if (txn.method_id) {
const info = generatedState.value.tremendousIdMap?.[txn.method_id]
const info = tremendousIdMap?.[txn.method_id]
if (info) {
methodOrSource = `Tremendous (${info.name})`
break
@@ -1,7 +1,8 @@
<script setup lang="ts">
import type { Labrinth } from '@modrinth/api-client'
import { ServersManagePageIndex } from '@modrinth/ui'
import { useGeneratedState } from '~/composables/generated'
import { products } from '~/generated/state.json'
definePageMeta({
middleware: 'auth',
@@ -12,14 +13,13 @@ useHead({
})
const config = useRuntimeConfig()
const generatedState = useGeneratedState()
</script>
<template>
<ServersManagePageIndex
:stripe-publishable-key="config.public.stripePublishableKey"
:site-url="config.public.siteUrl"
:products="generatedState.products || []"
:products="(products ?? []) as Labrinth.Billing.Internal.Product[]"
class="max-w-[1280px] py-0"
/>
</template>
+17 -6
View File
@@ -1,13 +1,12 @@
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "frontend",
"compatibility_date": "2025-12-10",
"compatibility_date": "2026-08-05",
"main": "./.output/server/index.mjs",
"assets": {
"binding": "ASSETS",
"directory": "./.output/public/"
},
"compatibility_flags": ["nodejs_compat_v2"],
"routes": ["modrinth.com/*"],
"preview_urls": true,
"workers_dev": true,
@@ -15,8 +14,14 @@
"cpu_ms": 5000
},
"observability": {
"enabled": true,
"head_sampling_rate": 0.0001
"traces": {
"enabled": true,
"head_sampling_rate": 0.0001
},
"logs": {
"enabled": true,
"head_sampling_rate": 0.0001
}
},
"keep_vars": false,
"secrets_store_secrets": [
@@ -49,8 +54,14 @@
"env": {
"staging": {
"observability": {
"enabled": true,
"head_sampling_rate": 0.1
"traces": {
"enabled": true,
"head_sampling_rate": 0.1
},
"logs": {
"enabled": true,
"head_sampling_rate": 0.1
}
},
"routes": ["staging.modrinth.com/*"],
"vars": {
@@ -154,11 +154,13 @@ export class LabrinthStateModule extends AbstractModule {
homePageSearch,
homePageNotifs,
products,
muralBankDetails: muralBankDetails?.bankDetails,
// Always emit a value: `undefined` is dropped by JSON.stringify, and consumers
// import these keys by name from the generated state.
muralBankDetails: muralBankDetails?.bankDetails ?? {},
tremendousIdMap,
countries: iso3166Data.countries,
subdivisions: iso3166Data.subdivisions,
taxComplianceThresholds: globals?.tax_compliance_thresholds,
taxComplianceThresholds: globals?.tax_compliance_thresholds ?? {},
errors,
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "storybook",
"compatibility_date": "2026-02-12",
"compatibility_date": "2026-08-05",
"workers_dev": true,
"assets": {
"directory": "./storybook-static"
+929 -367
View File
File diff suppressed because it is too large Load Diff