Skip to content

docs(design): the v7 public api plan - #831

Merged
andiwand merged 1 commit into
mainfrom
docs/api-v7-plan
Sep 6, 2026
Merged

docs(design): the v7 public api plan#831
andiwand merged 1 commit into
mainfrom
docs/api-v7-plan

Conversation

@andiwand

@andiwand andiwand commented Sep 6, 2026

Copy link
Copy Markdown
Member

🤖 Generated with Claude Code

We cut a major soon. This records what it should change in src/odr/*.hpp, why,
and in which pull requests — so the eight code PRs behind it can each be small
and reviewed against a stated target rather than a vibe.

No code. docs/design/api-v7.md plus its line in the design index.

The premise

The public API grew several ways to do each thing, and the count is
uncomfortable once you actually take it:

ways to decode a file 22
ways to ask what a file is 12
html::translate overloads 20
roads into editing 2

Three of those are not merely redundant, they are the same code twice:

  • odr::open is a pure forward. odr.cpp:203-230 is six one-line
    return DecodedFile(...). The split leaked into the bindings — JNI exposes
    both (jni_core.cpp:227 vs jni_file.cpp:93), Python binds all six open
    overloads and the DocumentFile factories.
  • DocumentFile::type/::meta decode the whole file to read one field, and
    throw for anything that is not a document.
  • open_strategy::open_document_file repeats open_file's cascade engine
    for engine for zip and cfb, and both ends throw NoDocumentFile — which
    as_document_file() throws too. open(f).as_document_file() is a drop-in,
    so ~90 of the 737 lines in open_strategy.cpp say the same thing twice.

Underneath the noise sits one real asymmetry: CsvFile::from_file bypasses
open_strategy entirely, so DecodePreference and CsvOptions are two
"how to decode" knobs on different roads and a caller who wants to name a
separator cannot get there through open. The overload count is the symptom;
that is the bug.

The wasm binding already converged on the shape we want — odr.open(bytes, { name }),
openAs, detect. C++ is the layer that never got the cleanup.

What the plan proposes

Two open functions where there were twenty-two, four translate overloads
where there were twenty, one editing entry point, and the removals
docs/design/README.md already flagged as "the breaking change this
deliberately is not".

It also argues against two things worth arguing against: renumbering the
enums (cosmetic payoff, silent failure in a stale binding — pin the values and
test them instead), and regrouping HtmlConfig (breaking in five bindings for
readability, and #764 changes the field list anyway).

The nine PRs

  1. this one
  2. refactor(api)!: drop the inert globals
  3. refactor(api)!: drop the inert config and charset surface
  4. refactor(html)!: cut translate to its four inputs
  5. refactor(api)!: one way to ask what a file is
  6. refactor(api)!: one way to open a file
  7. feat(api)!: fold the decode options into one struct
  8. refactor(document)!: one way to edit a document
  9. test(api): pin the enum ordinals

Ordered so each compiles alone, and so bindings move in the same PR as the
header they mirror — a lagging binding is a build break, not a deprecation.

Records what the next major changes in the public headers and why: one road
per operation instead of the several we grew, the removals the design doc
deferred until a major, and the enum-ordinal constraint only a major can lift.

Counts the duplication rather than asserting it - twenty-two ways to decode a
file, twelve to ask what one is, twenty translate overloads - and names the
three cases that are the same code twice, including open_document_file, which
repeats open_file's cascade engine for engine.

Splits the work into nine pull requests in an order where each compiles alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hxDa2rev11eLUEJZJ5nmz
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant