// tools/create-spec-hu/frontend-perf-hu-adapter.ts — SPEC-057
// Generates HU.md acceptance criteria for frontend performance, MFE boundaries,
// code splitting, SSR hydration strategy, and visual regression testing.
// Criteria: S2 (Core Web Vitals), S4 (bundle size), S5 (MFE boundary),
//           S6 (MFE shared deps), S8 (MFE error isolation), S10 (code splitting),
//           S12 (SSR hydration), S14 (visual regression)
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
function isWebTarget(knowledge) {
    const apps = Array.isArray(knowledge.apps) ? knowledge.apps : [];
    return apps.some((app) => app.type === 'frontend' || app.type === 'desktop' || app.platform === 'web');
}
function hasMfeDetected(knowledge) {
    const mfe = knowledge.mfeDetection;
    if (!mfe) {
        return false;
    }
    return mfe.moduleFederation !== undefined || mfe.singleSpa === true || mfe.nxMfe === true;
}
function getSsrHydrationHint(ssrFramework) {
    if (ssrFramework === 'nextjs') {
        return 'Componentes interactivos usan `"use client"` directive con justificacion documentada; server components por defecto';
    }
    if (ssrFramework === 'astro') {
        return 'Islands interactivos usan `client:load` o `client:visible` segun necesidad; HTML estatico por defecto';
    }
    if (ssrFramework === 'sveltekit') {
        return 'Paginas usan SSR por defecto; `+page.ts` con `ssr = false` solo cuando se justifica; hydration selectiva via `$app/stores`';
    }
    if (ssrFramework === 'nuxt') {
        return 'Componentes usan server rendering por defecto; `<ClientOnly>` wrapper solo cuando se justifica; `useAsyncData` para data fetching en servidor';
    }
    if (ssrFramework === 'remix') {
        return 'Loaders ejecutan en servidor; actions manejan mutaciones server-side; `useLoaderData()` para hydration; client-only code en `useEffect`';
    }
    if (ssrFramework === 'qwik') {
        return 'Resumability por defecto (sin hydration); `useVisibleTask$` solo cuando se necesita acceso al DOM; lazy-loading automatico via $';
    }
    return 'Componentes server-rendered por defecto; hydration selectiva para interactividad; documentar que componentes necesitan JS client-side';
}
// ---------------------------------------------------------------------------
// S2: Core Web Vitals criteria
// ---------------------------------------------------------------------------
function buildWebVitalsCriteria() {
    return [
        '',
        '### Core Web Vitals (Performance Budget)',
        '',
        '- [ ] LCP (Largest Contentful Paint) < 2.5s en mobile 4G throttled (medido con Lighthouse CI)',
        '- [ ] INP (Interaction to Next Paint) < 200ms para todas las interacciones principales',
        '- [ ] CLS (Cumulative Layout Shift) < 0.1 — sin layout shifts visibles durante carga',
    ];
}
// ---------------------------------------------------------------------------
// S4: Bundle size budget criteria
// ---------------------------------------------------------------------------
function buildBundleSizeCriteria() {
    return [
        '',
        '### Bundle Size Budget',
        '',
        '- [ ] JS bundle inicial < 200KB gzipped — medido en CI con `bundlesize` o equivalente',
        '- [ ] Lazy-loaded chunks individuales < 50KB gzipped cada uno',
        '- [ ] CSS total < 50KB gzipped (excluyendo critical CSS inlined)',
    ];
}
// ---------------------------------------------------------------------------
// S5: MFE boundary enforcement criteria
// ---------------------------------------------------------------------------
function buildMfeBoundaryCriteria() {
    return [
        '',
        '### Micro-Frontend Boundary Enforcement',
        '',
        '- [ ] Cada MFE expone contrato publico tipado (TypeScript interface o schema JSON) — no imports cross-MFE internos',
        '- [ ] Comunicacion entre MFEs exclusivamente via eventos custom (CustomEvent) o state bus compartido — no dependencias directas',
    ];
}
// ---------------------------------------------------------------------------
// S6: MFE shared deps versioning criteria
// ---------------------------------------------------------------------------
function buildMfeSharedDepsCriteria() {
    return [
        '',
        '### MFE Shared Dependencies Versioning',
        '',
        '- [ ] Shared libraries siguen semver estricto — breaking changes requieren migration guide documentada',
        '- [ ] Estrategia de versionado de shared deps definida: singleton (una version) vs multiple (cada MFE con su version)',
    ];
}
// ---------------------------------------------------------------------------
// S8: MFE error isolation criteria
// ---------------------------------------------------------------------------
function buildMfeErrorIsolationCriteria() {
    return [
        '',
        '### MFE Error Isolation',
        '',
        '- [ ] Un MFE que falla no puede derribar el shell application — error boundaries (React) o try/catch wrappers requeridos en cada MFE mount point',
        '- [ ] Fallback UI definido para cada MFE que falla — muestra mensaje de error user-friendly sin afectar otros MFEs',
    ];
}
// ---------------------------------------------------------------------------
// S10: Code splitting criteria
// ---------------------------------------------------------------------------
function buildCodeSplittingCriteria() {
    return [
        '',
        '### Code Splitting Strategy',
        '',
        '- [ ] Rutas principales lazy-loaded con `React.lazy()` / `defineAsyncComponent()` / dynamic `import()` — no bundles monoliticos',
        '- [ ] Componentes > 50KB (pre-gzip) lazy-loaded con loading fallback (skeleton o spinner)',
        '- [ ] Third-party libs pesadas (chart libs, editors, maps) en chunks separados via dynamic import',
    ];
}
// ---------------------------------------------------------------------------
// S12: SSR hydration criteria
// ---------------------------------------------------------------------------
function buildSsrHydrationCriteria(ssrFramework) {
    const hint = getSsrHydrationHint(ssrFramework);
    const frameworkLabel = ssrFramework ?? 'SSR framework';
    return [
        '',
        `### Hydration Strategy (${frameworkLabel})`,
        '',
        `- [ ] ${hint}`,
        '- [ ] Hydration mismatch errors = 0 en dev mode (verificado en console)',
    ];
}
// ---------------------------------------------------------------------------
// S14: Visual regression testing criteria
// ---------------------------------------------------------------------------
function buildVisualRegressionCriteria() {
    return [
        '',
        '### Visual Regression Testing',
        '',
        '- [ ] Storybook snapshot tests cubren todos los variants de componentes criticos del design system',
        '- [ ] Visual regression CI pipeline configurado — PRs bloqueados si diff visual > threshold definido',
    ];
}
// ---------------------------------------------------------------------------
// Main export
// ---------------------------------------------------------------------------
/**
 * SPEC-057: Build frontend performance and architecture HU.md criteria section.
 * Returns markdown lines for web projects based on detected frontend capabilities.
 *
 * Uses FrontendPerfDetectionResult when available, otherwise derives from ProjectKnowledge.
 */
export function buildFrontendPerfHuSection(knowledge, detection) {
    if (!knowledge) {
        return [];
    }
    // Only generate for web-facing projects
    const isWeb = isWebTarget(knowledge);
    const lang = knowledge.language?.toLowerCase() ?? '';
    const isFrontendLang = lang === 'typescript' || lang === 'javascript';
    if (!isWeb && !isFrontendLang) {
        return [];
    }
    const lines = ['', '## Frontend Architecture Requirements'];
    const mfe = hasMfeDetected(knowledge);
    // S2: Core Web Vitals
    if (!detection?.hasPerformanceBudget) {
        lines.push(...buildWebVitalsCriteria());
    }
    // S4: Bundle size budget
    lines.push(...buildBundleSizeCriteria());
    // S5: MFE boundary enforcement (only when MFE detected)
    if (mfe) {
        lines.push(...buildMfeBoundaryCriteria());
    }
    // S6: MFE shared deps versioning (only when MFE detected)
    if (mfe) {
        lines.push(...buildMfeSharedDepsCriteria());
    }
    // S8: MFE error isolation (only when MFE detected)
    if (mfe) {
        lines.push(...buildMfeErrorIsolationCriteria());
    }
    // S10: Code splitting
    lines.push(...buildCodeSplittingCriteria());
    // S12: SSR hydration strategy (only when SSR detected)
    if (detection?.hasSsr) {
        lines.push(...buildSsrHydrationCriteria(detection.ssrFramework));
    }
    // S14: Visual regression testing (only when Storybook detected)
    if (detection?.hasStorybook) {
        lines.push(...buildVisualRegressionCriteria());
    }
    lines.push('');
    return lines;
}
//# sourceMappingURL=frontend-perf-hu-adapter.js.map