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