WORK-246
ID:WORK-246Status:done

Shared pipeline-stats output across adapters

@refrakt-md/sveltekit prints a Phase 1/2/3/4 + warnings summary at the end of its content load (packages/sveltekit/src/plugin.ts:186–200):

Priority:mediumComplexity:simpleMilestone:v0.14.4Source:SPEC-058
claude/update-adapters-5CJgQ View source

Criteria completion

Criteria completion: 8 of 9 (89%) checked; history from May 21 to May 210%25%50%75%100%May 21May 21
Branches 1
claude/update-adapters-5CJgQ current done
main done
History 2
  1. 7f34b59
    • ☑ `@refrakt-md/content` exports `formatPipelineSummary(stats: PipelineStats, warnings: PipelineWarning[]): string` returning the multi-line summary block currently inlined in the SvelteKit plugin
    • ☑ `formatPipelineSummary` is pure — takes the data, returns the string. Adapters decide where to write it (`process.stderr`, `console.log`, an Eleventy log helper, etc.)
    • ☑ `packages/sveltekit/src/plugin.ts` replaces its inline formatter with `formatPipelineSummary` (zero output diff)
    • ☑ `packages/astro/src/integration.ts` calls `formatPipelineSummary` in the Vite plugin's `buildStart` after the content load and writes to `process.stderr`
    • ☑ `packages/nuxt/src/module.ts` same — calls the formatter after the Vite plugin's content load
    • ☑ `packages/eleventy/src/data.ts` `createDataFile` writes the formatted summary to `process.stderr` after `loadContent` completes
    • ☑ `@refrakt-md/next` exposes a helper `printPipelineSummary(site: Site): void` that adapter consumers call from their `app/layout.tsx` or a setup script; templates wire it in
    • ☑ `@refrakt-md/html` build helper from {% ref "WORK-242" /%} prints the summary by default; option to disable for embedded use
    by bjornolofandersson
  2. 51ec9e4
    Created (ready)by bjornolofandersson

Acceptance Criteria

  • @refrakt-md/content exports formatPipelineSummary(stats: PipelineStats, warnings: PipelineWarning[]): string returning the multi-line summary block currently inlined in the SvelteKit plugin
  • formatPipelineSummary is pure — takes the data, returns the string. Adapters decide where to write it (process.stderr, console.log, an Eleventy log helper, etc.)
  • packages/sveltekit/src/plugin.ts replaces its inline formatter with formatPipelineSummary (zero output diff)
  • packages/astro/src/integration.ts calls formatPipelineSummary in the Vite plugin's buildStart after the content load and writes to process.stderr
  • packages/nuxt/src/module.ts same — calls the formatter after the Vite plugin's content load
  • packages/eleventy/src/data.ts createDataFile writes the formatted summary to process.stderr after loadContent completes
  • @refrakt-md/next exposes a helper printPipelineSummary(site: Site): void that adapter consumers call from their app/layout.tsx or a setup script; templates wire it in
  • @refrakt-md/html build helper from WORK-242 prints the summary by default; option to disable for embedded use
  • All builds across all five non-SvelteKit adapters produce the same multi-line summary as the SvelteKit reference

Approach

The current SvelteKit implementation at packages/sveltekit/src/plugin.ts:186–200 is 15 lines of straight string building. Move it whole into packages/content/src/pipeline.ts (or a new packages/content/src/format.ts) and re-export from @refrakt-md/content.

// packages/content/src/format.ts
export function formatPipelineSummary(
  stats: PipelineStats,
  warnings: PipelineWarning[],
): string {
  // Lines 186–200 lifted verbatim from sveltekit/src/plugin.ts
}

Each adapter then becomes a one-liner:

// Astro / Nuxt / Eleventy / HTML
import { formatPipelineSummary } from '@refrakt-md/content';
process.stderr.write(formatPipelineSummary(site.pipelineStats, site.pipelineWarnings));

For Next.js the helper takes a Site directly:

// packages/next/src/index.ts
export function printPipelineSummary(site: Site): void {
  process.stderr.write(formatPipelineSummary(site.pipelineStats, site.pipelineWarnings));
}

Suppressing during tests: the formatter is pure (returns a string), so writing to stderr only happens at the adapter call site. Tests that don't want the noise simply don't call the writer.

Dependencies

Independent — can land any time after formatPipelineSummary is exported. Pairs naturally with the per-adapter site-tokens wiring items but doesn't block on them.

References

  • SPEC-058 — adapter parity spec (this item moves pipeline-stats output out of "Out of scope")
  • packages/sveltekit/src/plugin.ts:186–200 — current implementation to extract
  • packages/content/src/pipeline.ts — destination for the shared formatter

Resolution

Completed: 2026-05-21

Branch: `claude/update-adapters-5CJgQ`

What was done

  • Added `packages/content/src/format.ts` with `formatPipelineSummary(stats, warnings): string`. Pure formatter; takes the same shape `Site` exposes, returns the multi-line summary block.
  • `@refrakt-md/content` exports it from the public API.
  • SvelteKit plugin's inline formatter (15 lines) replaced with a single `process.stderr.write(formatPipelineSummary(...))` call. Site output verified byte-identical to pre-extraction.
  • Astro integration's runes-Vite-plugin `getUsedBlocks` callback also prints the summary (once per build via a `summaryPrinted` flag) after loading the site.
  • Nuxt module: same as Astro.
  • Eleventy `createDataFile` writes the summary to stderr after `loadContent`.
  • Next.js exports `printPipelineSummary(site: Site)` — consumers call from their layout / setup module.
  • HTML template's `build.ts` writes the summary after `loadContent`.

Notes

The summary is now emitted by every adapter on every full build. The site's existing 5-warning output now prints twice during `npm run build` (once for the dev server pre-build, once for the actual build) — pre-existing behaviour matching the SvelteKit plugin's lifecycle.

Per-adapter end-to-end output verification deferred to SPEC-059.

Full workspace build + all 2652 tests pass.