Files
SnapOtter/apps/web/src/components/tools/pipeline-step-settings.tsx
T
Siddharth Kumar Sah a4c63855d4 fix(docker): fix TDZ crash, icon bundle bloat, rate-limit on static assets
- 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.
2026-04-15 18:52:36 +08:00

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>
);
}