mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
- Fix "Cannot access 'a' before initialization" TDZ error after login caused by manualChunks splitting react-vendor + lucide icons into circular ES-module chunks. Removed manualChunks entirely. - Replace `import * as icons from "lucide-react"` (pulls all ~1000 icons) with a targeted icon-map of ~50 icons actually used by tool definitions. Reduces shared icons chunk from 745KB to 62KB (132KB→16KB gzip). - Exclude static files from @fastify/rate-limit via allowList so rapid page navigations don't 429 on JS/CSS chunk requests. - Move Docker auth defaults (AUTH_ENABLED, DEFAULT_USERNAME, DEFAULT_PASSWORD) from Dockerfile ENV to entrypoint.sh runtime exports to avoid SecretsUsedInArgOrEnv warnings. - Fix Docker CMD to use pnpm --filter for workspace-scoped tsx binary. - Set COREPACK_HOME system-wide so non-root user can access pnpm cache. - Lazy-load all pages in App.tsx and all controls in pipeline-step-settings.tsx to keep main bundle under 300KB.
91 lines
3.3 KiB
TypeScript
91 lines
3.3 KiB
TypeScript
import { lazy, Suspense } from "react";
|
|
|
|
type ControlProps = {
|
|
settings: Record<string, unknown>;
|
|
onChange: (settings: Record<string, unknown>) => void;
|
|
};
|
|
|
|
// Lazy-load every control so these modules are not pulled into the main bundle.
|
|
// The pipeline builder wraps this component in <Suspense> so each control
|
|
// loads on demand when the user selects a step in the pipeline.
|
|
const CONTROLS: Record<string, React.LazyExoticComponent<React.FC<ControlProps>>> = {
|
|
resize: lazy(() => import("./resize-settings").then((m) => ({ default: m.ResizeControls }))),
|
|
crop: lazy(() => import("./crop-settings").then((m) => ({ default: m.CropControls }))),
|
|
rotate: lazy(() => import("./rotate-settings").then((m) => ({ default: m.RotateControls }))),
|
|
convert: lazy(() => import("./convert-settings").then((m) => ({ default: m.ConvertControls }))),
|
|
compress: lazy(() =>
|
|
import("./compress-settings").then((m) => ({ default: m.CompressControls })),
|
|
),
|
|
"strip-metadata": lazy(() =>
|
|
import("./strip-metadata-settings").then((m) => ({ default: m.StripMetadataControls })),
|
|
),
|
|
border: lazy(() => import("./border-settings").then((m) => ({ default: m.BorderControls }))),
|
|
"watermark-text": lazy(() =>
|
|
import("./watermark-text-settings").then((m) => ({ default: m.WatermarkTextControls })),
|
|
),
|
|
"text-overlay": lazy(() =>
|
|
import("./text-overlay-settings").then((m) => ({ default: m.TextOverlayControls })),
|
|
),
|
|
"replace-color": lazy(() =>
|
|
import("./replace-color-settings").then((m) => ({ default: m.ReplaceColorControls })),
|
|
),
|
|
"smart-crop": lazy(() =>
|
|
import("./smart-crop-settings").then((m) => ({ default: m.SmartCropControls })),
|
|
),
|
|
"gif-tools": lazy(() =>
|
|
import("./gif-tools-settings").then((m) => ({ default: m.GifToolsControls })),
|
|
),
|
|
upscale: lazy(() => import("./upscale-settings").then((m) => ({ default: m.UpscaleControls }))),
|
|
"blur-faces": lazy(() =>
|
|
import("./blur-faces-settings").then((m) => ({ default: m.BlurFacesControls })),
|
|
),
|
|
"enhance-faces": lazy(() =>
|
|
import("./enhance-faces-settings").then((m) => ({ default: m.EnhanceFacesControls })),
|
|
),
|
|
"remove-background": lazy(() =>
|
|
import("./remove-bg-settings").then((m) => ({ default: m.RemoveBgControls })),
|
|
),
|
|
"noise-removal": lazy(() =>
|
|
import("./noise-removal-settings").then((m) => ({ default: m.NoiseRemovalControls })),
|
|
),
|
|
};
|
|
|
|
const COLOR_TOOL_IDS = new Set(["adjust-colors"]);
|
|
|
|
// ColorControls needs an extra toolId prop so it lives outside the shared map.
|
|
const LazyColorControls = lazy(() =>
|
|
import("./color-settings").then((m) => ({ default: m.ColorControls })),
|
|
);
|
|
|
|
interface PipelineStepSettingsProps {
|
|
toolId: string;
|
|
settings: Record<string, unknown>;
|
|
onChange: (settings: Record<string, unknown>) => void;
|
|
}
|
|
|
|
export function PipelineStepSettings({ toolId, settings, onChange }: PipelineStepSettingsProps) {
|
|
const Control = CONTROLS[toolId];
|
|
|
|
if (Control) {
|
|
return (
|
|
<Suspense fallback={null}>
|
|
<Control settings={settings} onChange={onChange} />
|
|
</Suspense>
|
|
);
|
|
}
|
|
|
|
if (COLOR_TOOL_IDS.has(toolId)) {
|
|
return (
|
|
<Suspense fallback={null}>
|
|
<LazyColorControls toolId={toolId} settings={settings} onChange={onChange} />
|
|
</Suspense>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<p className="text-xs text-muted-foreground italic">
|
|
No configurable settings. Defaults will be used.
|
|
</p>
|
|
);
|
|
}
|