fix: address performance review feedback
This commit is contained in:
1 parent
7266e15356
commit
0b9c4d6375
8 files changed
+42
-12
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import { Suspense } from "react";
|
||||
import { notFound } from "next/navigation";
|
||||
import { Center } from "@mantine/core";
|
||||
import { Center, Loader } from "@mantine/core";
|
||||
|
||||
import { env } from "@homarr/common/env";
|
||||
import { db } from "@homarr/db";
|
||||
import type { WidgetKind } from "@homarr/definitions";
|
||||
import { widgetKinds } from "@homarr/widgets/manifest";
|
||||
@@ -13,7 +13,8 @@ interface Props {
|
||||
}
|
||||
|
||||
export default async function WidgetPreview(props: Props) {
|
||||
if (!(widgetKinds.includes((await props.params).kind as WidgetKind) || env.NODE_ENV !== "development")) {
|
||||
const { kind } = await props.params;
|
||||
if (!widgetKinds.includes(kind as WidgetKind)) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
@@ -26,11 +27,11 @@ export default async function WidgetPreview(props: Props) {
|
||||
},
|
||||
});
|
||||
|
||||
const sort = (await props.params).kind as WidgetKind;
|
||||
|
||||
return (
|
||||
<Center h="100vh">
|
||||
<WidgetPreviewPageContent kind={sort} integrationData={integrationData} />
|
||||
<Suspense fallback={<Loader size="sm" />}>
|
||||
<WidgetPreviewPageContent kind={kind as WidgetKind} integrationData={integrationData} />
|
||||
</Suspense>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
@@ -136,7 +136,7 @@ export const IntegrationMultiSelectGrid = ({
|
||||
);
|
||||
})}
|
||||
|
||||
{filtered.length === 0 && (
|
||||
{!isPending && filtered.length === 0 && (
|
||||
<Center p="xl">
|
||||
<Text c="dimmed">{t("common.noResults")}</Text>
|
||||
</Center>
|
||||
|
||||
@@ -89,7 +89,7 @@ export const IntegrationSelectGrid = ({ onSelect, enableMockIntegration = false
|
||||
</Card>
|
||||
))}
|
||||
|
||||
{filtered.length === 0 && (
|
||||
{!isPending && filtered.length === 0 && (
|
||||
<Center p="xl">
|
||||
<Text c="dimmed">{t("common.noResults")}</Text>
|
||||
</Center>
|
||||
|
||||
@@ -44,6 +44,7 @@ describe("proxy database pools", () => {
|
||||
vi.resetModules();
|
||||
vi.clearAllMocks();
|
||||
for (const key of Object.keys(mocks.dbEnv)) delete mocks.dbEnv[key];
|
||||
mocks.mysqlCreatePool.mockReturnValue({});
|
||||
});
|
||||
|
||||
it("bounds MySQL URL pools instead of falling back to the driver defaults", async () => {
|
||||
@@ -108,4 +109,20 @@ describe("proxy database pools", () => {
|
||||
|
||||
expect(mocks.postgresPool).toHaveBeenCalledWith(expect.objectContaining({ max: 1 }));
|
||||
});
|
||||
|
||||
it("retries initialization after a transient driver failure", async () => {
|
||||
Object.assign(mocks.dbEnv, {
|
||||
DRIVER: "mysql2",
|
||||
URL: "mysql://homarr:test@localhost:3306/homarr",
|
||||
});
|
||||
mocks.mysqlCreatePool.mockImplementationOnce(() => {
|
||||
throw new Error("database unavailable");
|
||||
});
|
||||
|
||||
const { getOnboardingStepForProxyAsync } = await import("./proxy-reader");
|
||||
|
||||
await expect(getOnboardingStepForProxyAsync()).rejects.toThrow("database unavailable");
|
||||
await expect(getOnboardingStepForProxyAsync()).resolves.toBe("finish");
|
||||
expect(mocks.mysqlCreatePool).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
@@ -152,7 +152,12 @@ const createProxyReaderAsync = async (): Promise<ProxyReader> => {
|
||||
let proxyReaderPromise: Promise<ProxyReader> | null = null;
|
||||
|
||||
const getProxyReaderAsync = () => {
|
||||
proxyReaderPromise ??= createProxyReaderAsync();
|
||||
if (!proxyReaderPromise) {
|
||||
proxyReaderPromise = createProxyReaderAsync().catch((error: unknown) => {
|
||||
proxyReaderPromise = null;
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
return proxyReaderPromise;
|
||||
};
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ catalog:
|
||||
"@mantine/notifications": ^9.4.1
|
||||
"@mantine/spotlight": ^9.4.1
|
||||
"@mantine/tiptap": ^9.4.1
|
||||
"@next/eslint-plugin-next": 16.2.10
|
||||
"@octokit/auth-app": ^8.2.0
|
||||
"@paralleldrive/cuid2": ^3.3.0
|
||||
"@playwright/test": ^1.61.1
|
||||
|
||||
@@ -30,7 +30,11 @@ export const summarize = (numbers: Array<number | null | undefined>): NumericSum
|
||||
return { count: 0, medianMs: null, p95Ms: null, standardDeviationMs: null, outliersMs: [] };
|
||||
}
|
||||
|
||||
const medianIndex = Math.floor(sorted.length / 2);
|
||||
const middleIndex = Math.floor(sorted.length / 2);
|
||||
let medianMs = sorted[middleIndex] ?? 0;
|
||||
if (sorted.length % 2 === 0) {
|
||||
medianMs = ((sorted[middleIndex - 1] ?? 0) + medianMs) / 2;
|
||||
}
|
||||
const p95Index = Math.min(sorted.length - 1, Math.ceil(sorted.length * 0.95) - 1);
|
||||
const mean = sorted.reduce((total, value) => total + value, 0) / sorted.length;
|
||||
const variance = sorted.reduce((total, value) => total + (value - mean) ** 2, 0) / sorted.length;
|
||||
@@ -41,7 +45,7 @@ export const summarize = (numbers: Array<number | null | undefined>): NumericSum
|
||||
|
||||
return {
|
||||
count: sorted.length,
|
||||
medianMs: sorted[medianIndex] ?? 0,
|
||||
medianMs,
|
||||
p95Ms: sorted[p95Index] ?? 0,
|
||||
standardDeviationMs: Math.round(Math.sqrt(variance)),
|
||||
outliersMs: sorted.filter((value) => value > outlierLimit),
|
||||
|
||||
@@ -26,6 +26,10 @@ describe("development benchmark measurements", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("averages both middle values for an even sample count", () => {
|
||||
expect(summarize([100, 200]).medianMs).toBe(150);
|
||||
});
|
||||
|
||||
it("requires a successful authenticated board hydration and interaction", () => {
|
||||
expect(
|
||||
validateBrowserMeasurement({
|
||||
|
||||
Reference in new issue
Block a user