The umbrella's DOM tests vi.mock the single @anchor/index barrel (spreading the original and overriding PdfSpikeViewer). To keep the cutover a mechanical specifier swap and preserve those mocks, the evidence-anchor root re-exports the full surface (pure core + PDF adapter), matching the prior @anchor/index. evidence-anchor/pdf remains a focused viewer entry. Viewer code still lives only under src/pdf/ (eslint-enforced). Repo stays green: 30 tests, tc, lint. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
88 lines
4.2 KiB
Markdown
88 lines
4.2 KiB
Markdown
# evidence-anchor
|
|
|
|
Selector creation, resolution, and the `DocumentViewerAdapter` contract that
|
|
every document viewer in the citation-evidence workspace implements. This repo
|
|
turns annotations from static marks into durable, reopenable source references.
|
|
|
|
- **Owns:** selector *behavior* — `createSelectors`, `resolveSelectors`, PDF
|
|
selector math, the viewer-adapter contract, and highlight/scroll helpers.
|
|
- **Does not own:** selector *type interfaces* — those live in `citation-engine`
|
|
(`shared/selector`). See `ADR-0006` and `SharedContracts.md` §8.
|
|
- **May depend on:** `citation-engine` only (DependencyMap §4). Nothing from
|
|
`binder/`, `source/`, or `work/` may flow back into it.
|
|
|
|
See `SCOPE.md` for the boundary and `INTENT.md` for the long-range intent.
|
|
|
|
## Status: extracting from the umbrella
|
|
|
|
The concrete anchor slice currently lives upstream in
|
|
[`../citation-evidence/src/anchor/`](../citation-evidence/src/anchor/). Workplan
|
|
`EANCH-WP-0001` moves it here as a standalone TypeScript package, wires the
|
|
umbrella to consume this package, and verifies the round-trip. Shared-contract
|
|
changes still happen in the umbrella (`citation-evidence/wiki/`), not here.
|
|
|
|
## Install model
|
|
|
|
Sibling-checkout, linked-package model — this repo is checked out next to its
|
|
consumers and consumed via a local link (e.g. `link:../evidence-anchor`), not
|
|
published to a registry during MVP. Its only shared-type dependency is
|
|
`citation-engine`, imported through the engine's public `shared` entrypoint
|
|
(`@citation-evidence/engine/shared`) rather than umbrella-only `@shared/*`
|
|
aliases.
|
|
|
|
## Package layout (initial extracted version)
|
|
|
|
```text
|
|
src/
|
|
index.ts public entrypoint — pure surface only
|
|
types.ts adapter-side types: SelectionCapture,
|
|
ResolvedAnchorTarget, AnchorResolution,
|
|
HighlightRenderOptions, DocumentViewerAdapter
|
|
css.d.ts ambient decl for side-effect .css imports
|
|
selectors/ pure core — no viewer/UI deps
|
|
index.ts createSelectors, resolveSelectors, DEFAULT_CONTEXT_CHARS
|
|
create.ts selector creation from a captured selection
|
|
resolve.ts resolution + the exact-match confidence ladder
|
|
create.test.ts
|
|
resolve.test.ts
|
|
pdf/ adapter boundary — the only place viewer libs live
|
|
index.ts subpath entry `evidence-anchor/pdf`
|
|
pdf-selector-math.ts pure page + normalized-rect math (capture↔selectors)
|
|
pdf-selector-math.test.ts
|
|
pdf-viewer-adapter-spike.tsx concrete PDF adapter (PdfSpikeViewer)
|
|
scroll-job.ts retryable scroll-to-highlight helper
|
|
scroll-job.test.ts
|
|
highlight-styles.css highlight rendering styles
|
|
debug-textlayer.css optional text-layer debugging styles
|
|
```
|
|
|
|
Boundary rules for the layout (enforced by `eslint.config.js`):
|
|
|
|
- viewer-library imports (`pdfjs-dist`, `react`, `react-pdf-highlighter-plus`)
|
|
are confined to `src/pdf/` — the pure zone (`src/selectors/**`, `src/types.ts`)
|
|
may not import them;
|
|
- `src/selectors/` is pure and depends only on `citation-engine` shared types;
|
|
- the **root** entrypoint (`evidence-anchor`) is the full barrel — selector
|
|
creation/resolution, the adapter types/contract, and the PDF adapter — so
|
|
consumers resolve every anchor symbol (and their test `vi.mock(...)` calls)
|
|
from a single specifier, matching the umbrella's prior `@anchor/index`;
|
|
- a focused, viewer-free entry is also published at **`evidence-anchor/pdf`**
|
|
for consumers that want the PDF surface explicitly. The concrete adapter is
|
|
still the explicitly-named `PdfSpikeViewer` spike; promoting it to a
|
|
production `PDFViewerAdapter` is registered follow-on work (T06).
|
|
|
|
## Public API (target surface)
|
|
|
|
```ts
|
|
import {
|
|
createSelectors,
|
|
resolveSelectors,
|
|
type DocumentViewerAdapter,
|
|
type AnchorResolution,
|
|
} from "evidence-anchor";
|
|
```
|
|
|
|
Resolution is explicit about uncertainty — `AnchorResolution.status` is one of
|
|
`resolved` / `ambiguous` / `unresolved` / `stale` with a `0..1` confidence, so a
|
|
caller can highlight, ask the user to confirm, or mark a citation stale rather
|
|
than silently highlight the wrong passage.
|