mirror of
https://github.com/modrinth/code.git
synced 2026-08-24 16:44:51 +00:00
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:
@@ -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)
|
||||
|
||||
|
||||
@@ -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 = () => {
|
||||
|
||||
@@ -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(),
|
||||
}))
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,9 +14,15 @@
|
||||
"cpu_ms": 5000
|
||||
},
|
||||
"observability": {
|
||||
"traces": {
|
||||
"enabled": true,
|
||||
"head_sampling_rate": 0.0001
|
||||
},
|
||||
"logs": {
|
||||
"enabled": true,
|
||||
"head_sampling_rate": 0.0001
|
||||
}
|
||||
},
|
||||
"keep_vars": false,
|
||||
"secrets_store_secrets": [
|
||||
{
|
||||
@@ -49,9 +54,15 @@
|
||||
"env": {
|
||||
"staging": {
|
||||
"observability": {
|
||||
"traces": {
|
||||
"enabled": true,
|
||||
"head_sampling_rate": 0.1
|
||||
},
|
||||
"logs": {
|
||||
"enabled": true,
|
||||
"head_sampling_rate": 0.1
|
||||
}
|
||||
},
|
||||
"routes": ["staging.modrinth.com/*"],
|
||||
"vars": {
|
||||
"ENVIRONMENT": "staging",
|
||||
|
||||
@@ -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,6 +1,6 @@
|
||||
{
|
||||
"name": "storybook",
|
||||
"compatibility_date": "2026-02-12",
|
||||
"compatibility_date": "2026-08-05",
|
||||
"workers_dev": true,
|
||||
"assets": {
|
||||
"directory": "./storybook-static"
|
||||
|
||||
Generated
+929
-367
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user