v1.0.0 — Stable API + the engine 1.5.0 authoring features - #15
Merged
Conversation
Mark the public API stable under semver and integrate the document-authoring features pdfnative added through 1.5.0, plus the conveniences planned for 0.4.0. Breaking: pdfnative is now a peer dependency (^1.5.0), not bundled. Added: - Bookmarks/outline & page labels on <Document> (and DocSpec) - <Section> composite (heading + grouped content) - Nested lists (child <List>, nested <Item>, or items data prop) - Table cellBorders / cellVAlign (+ ColumnDef vAlign/kind via type re-export) - inspectDocument / inspectSpec (layout geometry, no render) + layout.debug - layout.viewerPreferences - renderToFileStream / renderSpecToFileStream (constant memory, keeps outline) - resolveFonts + options.fonts; fromUrl / fromBase64 image helpers - SVG <text> renders as native selectable PDF text (no API change) - 11 new samples; tests extended to 71 passing; CITATION.cff version pin Docs: README (peer-dep install, migration 0.2→1.0, feature sections, scope), KNOWLEDGE_BASE, llms.txt, ROADMAP (React 18 → non-goal), CHANGELOG, SECURITY, release notes. Migrate AI instructions to Claude Code: add CLAUDE.md, update AGENTS.md + Copilot instructions, fix CODEOWNERS globs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Governance (aligned with the pdfnative monorepo contract): - .github/ai-governance.json — machine-readable draftsman/HITL policy (no autonomous GitHub writes, minimal-dependency, required issue fields) - .github/AGENT_RULES.md — human/agent protocol - .github/drafts/ — local draft staging area (git-ignored except README) - scripts/verify-issue.mjs + `npm run verify:issue` — local draft verifier - docs/AI_GOVERNANCE.md — narrative guide - tests/governance.test.ts — CLI black-box + artifact assertions - draftsman rule added to AGENTS.md, CLAUDE.md, copilot-instructions The package ships no code path that writes to GitHub or makes network calls; AI agents act strictly as draftsmen and a human submits under their identity. validateFontData: - re-export validateFontData + FontValidationResult (opt-in font check before embedding a custom font); wired into core-bridge/types/index, fonts-prop sample, and tests; documented in README/llms.txt/KNOWLEDGE_BASE. 79 tests passing; typecheck:all, lint, coverage (thresholds met), and build all clean. pdfnative stays external in the bundle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v1.0.0 — Stable API + the engine 1.5.0 authoring features
Summary
v1.0.0 marks the public API of pdfnative-react as stable under semantic
versioning. It integrates the document-authoring features the
pdfnativeengine added through1.5.0 and ships the conveniences originally planned for 0.4.0. Three themes:
<Document>, viewer preferences and a layout debug overlay vialayout,inspectDocument/inspectSpec, nested lists, tablecellBorders/cellVAlign, and SVG<text>as native selectable text.<Section>,resolveFonts/options.fonts, and thefromUrl/fromBase64image helpers, plusrenderToFileStream.pdfnativebecomes a peer dependency; thepackage's scope is stated explicitly (authoring, not byte-level
post-processing); and the
pdfnativefamily's AI human-in-the-loop governancecontract is adopted here (draftsman-only,
npm run verify:issue).Breaking change
pdfnativemoved fromdependenciestopeerDependencies(^1.5.0), andis also a
devDependencyfor local tests. Consumers install it themselves(
npm install pdfnative-react pdfnative react). Matches how the engine isalready external in the tsup build; lets apps control the engine version.
Changes
src/core-bridge/index.tsinspectDocumentLayoutandstreamToFile(runtime), plus the newengine types (
OutlineItem,PageLabelRange,PageLabelStyle,ViewerPreferences,LayoutDebugOptions,LayoutInspection,InspectedPage/InspectedBlock,CellBorders,ListItem,StreamToFileResult,FontData). Still the only runtimepdfnativeimport.src/components.tsx<Document>gainsoutline(OutlineItem[] | 'auto') andpageLabels.<Section>— the one composite component (heading + children;level,color,break), resolved before the reconciler runs.<List>/<Item>accept nested items (child<List>, nested<Item>, or theitemsdata prop with{ text, items }).<Table>gainscellBordersandcellVAlign.src/reconciler/serialize.tsoutline/pageLabelspass through; tablecellBorders/cellVAlignforwarded. NewtoListItem/subItemsOfrecursion emits a plainstringfor leaf items (byte-identical to the flat case) or{ text, items }for nested ones — collecting the item's own text from non-
item/listchildren so sub-item text is never swallowed into the parent label.
src/render.ts+ newsrc/fonts.ts+ newsrc/assets.tsinspectDocument(node, options?)andrenderToFileStream(node, path, options?)(constant memory; verified to preserve
/Outlines).resolveFonts(map)registers loaders and returnsFontEntry[]; internaloptionsWithFontsresolvesoptions.fontsfor the async entries.RenderOptions.fonts+FontsMap/FontLoadertypes added.validateFontData(data)re-exported (opt-in font check) +FontValidationResult.fromUrl(url, init?)/fromBase64(payload)produce<Image>bytes.src/spec/(DocSpec parity)DocSpecgainsoutline/pageLabels;ul/olitems accept nestedListItems;TableSpecBodygainscellBorders/cellVAlign. NewinspectSpecand
renderSpecToFileStream.schema.tsadds recursivelistItem/outlineItem$defs,outline/pageLabelstop-level props, and thepreviously-missing table body fields. No
['sec']tuple (sugar only).src/hooks.tsusePdf/usePdfStreamresolveoptions.fontsasynchronously (memoized perfonts-object identity), preserving the microtask defer + cancellation contract.
Samples & tests
cell-borders, math, svg-text, section, fonts-prop, image-helpers,
stream-to-file);
samples/README.mdupdated.flat-list regression guard, the streaming-
/Outlinescheck, and aCITATION.cffversion pin).New: AI-governance / human-in-the-loop contract
pdfnativefamily's governance contract for this repo:.github/ai-governance.json(draftsman role, HITL-mandatory, no autonomousGitHub writes, minimal-dependency policy),
.github/AGENT_RULES.md, a.github/drafts/staging area (git-ignored except the README/releaseartifacts),
docs/AI_GOVERNANCE.md, and a dependency-freescripts/verify-issue.mjsCLI wired asnpm run verify:issue.tests/governance.test.tsexercises the CLI (pass / dependency-violation /missing-repro) and asserts the
ai-governance.jsonpolicy +AGENT_RULES.mdAGENTS.md,CLAUDE.md,and
.github/copilot-instructions.md.Docs & governance
README.md(peer-dep install, new feature sections, a "Migrating 0.2 → 1.0"note, the post-processing boundary, and an AI-governance doc link),
docs/KNOWLEDGE_BASE.md,llms.txt,ROADMAP.md(React 18 → non-goal;0.2.x/0.4.0 shipped),
CHANGELOG.md(1.0.0 with Breaking Changes),SECURITY.md(1.x table),CITATION.cff.CLAUDE.mdadded (points toAGENTS.md);AGENTS.mdand the Copilotinstruction files updated;
.github/CODEOWNERSglobs fixed to real paths.Validation
npm run typecheck:all→ clean (src + tests + samples).npm run lint→ clean.npm run test:coverage→ 79 / 79 passing (8 files); statements 92.5 %,branches 85.3 %, functions 96.2 %, lines 94.3 % (thresholds met).
npm run verify:issue→ the governance CLI validates a draft (pass / fail).npm run build→ dual ESM + CJS + types;pdfnativestays external.fromUrldegrades gracefully offline).Backward compatibility
pdfnativeis now a peer dependency. Everything else isadditive — new components/props/functions and type re-exports; the existing
component/render/hook/spec surface is unchanged and flat lists still serialize
to
string[].Out of scope (by design)
react-reconcilercontract.<View>— declarative block flow.font compilation) — use the
pdfnativeengine directly; deliberately notre-exported.
Self-review checklist
src/core-bridge/index.tsimportspdfnativeat runtime;src/types.tskeeps its sanctioned type-only import.<View>; new blocks map 1:1 onto pdfnative (Section ispure sugar, no host tag).
DocSpec↔ JSX parity preserved; nested lists/outline/pageLabels/tablestyling forwarded and tested.
'use client'.$idderived fromsrc/version.ts; version pinned topackage.jsonandCITATION.cff.any(one containedaswidening inresolveFontsfor the engine's over-strict font-loader type);
type-only imports.renderToFileStreamverified to preserve/Outlines; flat-list outputunchanged (regression test).
verify:issueCLI+
tests/governance.test.tsgreen; the library makes no GitHub/network calls.typecheck:all, lint, build all clean.