feat(public-facade): re-curate root index.ts with three tiers (SD-3212 b)#3389
Conversation
…2 b)
Grows packages/superdoc/src/public/index.ts from 24 exports to 200,
organized into three tiers per the SD-3212 A1 classification artifact:
- supported-root (132): documented public API; first-class root surface.
- legacy-root (60): typed for backward compat; not the recommended path.
Per-name @deprecated JSDoc only where a real replacement exists.
- internal-candidate (8): accidental implementation leaks; kept typed
under compat re-export with @internal so a future major can remove
them. Only at root because at least one supported/legacy export
reaches them transitively.
Source map driven from src/index.js (runtime imports + JSDoc @typedef
block). All 200 names from the classification artifact accounted for.
vite-plugin-dts re-export resolution gap fixed in ensure-types.cjs:
the @superdoc/common package-root re-exports trip the plugin into
selecting the wrong file (shared/common/comments-types.js). The
existing postbuild inliner now patches dist/superdoc/src/public/index.d.ts
in addition to dist/superdoc/src/index.d.ts, stripping the private
@superdoc/* specifiers and emitting local declarations. Mirrors the
proven approach already used for src/index.js.
verify-public-facade-emit.cjs FACADE_ENTRIES['root (./index)'].expectedNames
grows to all 200 names (was 24). ui (71) preserved from SD-3204.
AGENTS.md adds a 'Contributing to the public surface' section
documenting the three tiers, the required snapshot/verifier updates
on every public-surface change, and the three CI gates that enforce
consistency.
Out of scope:
- No package.json#exports change (PR C owns the root types flip).
- No removal of any name (path-as-contract principle: if reachable,
must be typed).
Verified locally:
- pnpm --filter superdoc build:es: all build steps green, including
verify-public-facade-emit (root: 200 exports), audit-declarations
(no private @superdoc/* leak), check-export-coverage.
- typecheck-matrix.mjs: 57/57 scenarios pass.
- snapshot-superdoc-root-exports.mjs --check: matches.
- check-root-classification-closure.mjs: 0 violations.
After this lands, PR C does the mechanical
package.json#exports['.'].types flip.
Agent docs auditFound deterministic findings on 1 changed agent-doc item(s).
|
|
The |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
🎉 This PR is included in superdoc-cli v0.12.0 The release is available on GitHub release |
|
🎉 This PR is included in superdoc-sdk v1.11.0 |
|
🎉 This PR is included in @superdoc-dev/mcp v0.7.0 The release is available on GitHub release |
|
🎉 This PR is included in superdoc v1.35.0 The release is available on GitHub release |
|
🎉 This PR is included in @superdoc-dev/react v1.6.0 The release is available on GitHub release |
|
🎉 This PR is included in vscode-ext v2.7.0 |
PR B of the SD-3212 (Phase 4b) sequence. Grows
packages/superdoc/src/public/index.tsfrom 24 exports to 200, organized into three tiers per the classification artifact merged in #3380.Distribution:
The three tiers:
@deprecatedJSDoc only where a real replacement exists (e.g.editor.commands.*→editor.doc.*). Section-level framing carries "legacy compat" intent when no replacement exists.@internalso a future major can remove it. Only at root because at least one supported/legacy export reaches it transitively (enforced by the SD-3212 a1b closure gate).Load-bearing architectural decision — please scrutinize:
src/public/index.tsintentionally uses deep@superdoc/common/...imports at the source level (e.g.import { DOCX, PDF, HTML } from '@superdoc/common/document-types'). At source, deep imports are needed because the package-root re-export form (from '@superdoc/common') trips vite-plugin-dts into following theexport *chain and landing on the WRONG file (shared/common/comments-types.js, which doesn't export these names).Deep imports normally trip
audit-declarations.cjs("private@superdoc/*specifier in emitted .d.ts"). The existing postbuild inliner inensure-types.cjs— which already handles this exact problem forsrc/index.js— has been extended to also patchdist/superdoc/src/public/index.d.ts. It strips the private specifiers from the emitted declarations and inlines localdeclare const DOCX: 'application/...'declarations.Net effect:
@superdoc/*specifiers; values appear as localdeclare consts. Consumers see no behavior change vssrc/index.js's historical handling.audit-declarations.cjsno longer sees the private specifier (stripped postbuild).If a reviewer is uncomfortable with the deep-imports + strip pattern, the alternative is filing a separate ticket against vite-plugin-dts for cross-package
export *resolution. The strip-and-inline approach is the same one the codebase has been relying on forsrc/index.jssince before SD-3175 — this PR just extends it to the new facade entry point.Out of scope:
package.json#exportschange. PR C owns the root types flip.internal-candidatenames happens in a future major after deprecation cycle.Verified locally:
pnpm --filter superdoc build:es: all build steps green.verify-public-facade-emit: 10 entries clean (root: 200 exports, was 24).audit-declarations: no private@superdoc/*leak in emitted .d.ts.check-export-coverage: 12 entries OK.typecheck-matrix.mjs: 57/57 scenarios pass.snapshot-superdoc-root-exports.mjs --check: matches the locked baseline.check-root-classification-closure.mjs: 0 violations (the closure gate validates that no supported/legacy export references an internal-candidate type).AGENTS.mdupdate: new "Contributing to the public surface" section documents the three tiers, the four files every public-surface change must update, and the three CI gates that enforce consistency.Sequence:
package.json#exports['.'].typesflipRelated: