Promote DomRange and Structural selector types for non-PDF anchoring
Define real DomRangeSelector, StructuralSelector, StructureMap, and containerPath fields so evidence-anchor can implement HTML/Markdown selector creation and resolution. Update SharedContracts.md with field shapes and DomSelectionCapture payload.
This commit is contained in:
parent
67a3d82dfa
commit
86d10e7e90
3 changed files with 111 additions and 12 deletions
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import type { DocumentId, RepresentationId } from "./ids";
|
||||
import type { DomNodePath, StructuralPathSegment } from "./selector";
|
||||
|
||||
/**
|
||||
* The kind of normalized view derived from a source document.
|
||||
|
|
@ -56,10 +57,23 @@ export interface PageOffsetRange {
|
|||
export type OffsetMap = readonly PageOffsetRange[];
|
||||
|
||||
/**
|
||||
* Reserved for `StructuralSelector` (heading/section/AST path).
|
||||
* Not implementable in MVP — type is `never` to enforce that at compile time.
|
||||
* Maps canonical-text offset ranges to structural paths for non-paginated
|
||||
* representations (`html-dom`, `markdown-rendered`).
|
||||
*
|
||||
* Entries are sorted by `globalStart`, are non-overlapping, and together
|
||||
* cover `[0, canonicalText.length)`.
|
||||
*/
|
||||
export type StructureMap = never;
|
||||
export interface StructureRange {
|
||||
/** Inclusive canonical-text offset where this block begins. */
|
||||
readonly globalStart: number;
|
||||
/** Exclusive canonical-text offset where this block ends. */
|
||||
readonly globalEnd: number;
|
||||
readonly path: readonly StructuralPathSegment[];
|
||||
/** DOM path to the block's text container, when captured from a viewer. */
|
||||
readonly containerPath?: DomNodePath;
|
||||
}
|
||||
|
||||
export type StructureMap = readonly StructureRange[];
|
||||
|
||||
/** A source document known to the system. */
|
||||
export interface Document {
|
||||
|
|
|
|||
|
|
@ -7,9 +7,8 @@
|
|||
*
|
||||
* The MVP implements the four PDF-relevant variants
|
||||
* (`TextQuoteSelector`, `TextPositionSelector`, `PdfRectSelector`,
|
||||
* `PdfPageTextSelector`). The other three kinds (DOM, structural, fragment)
|
||||
* are reserved as `never`-typed stubs so adding them later is a localised
|
||||
* change.
|
||||
* `PdfPageTextSelector`) plus DOM/structural selectors for HTML/Markdown.
|
||||
* `FragmentSelector` remains a `never`-typed stub.
|
||||
*/
|
||||
|
||||
/** Exact quote with optional surrounding context (W3C-aligned). */
|
||||
|
|
@ -54,11 +53,41 @@ export interface PdfPageTextSelector {
|
|||
readonly end: number;
|
||||
}
|
||||
|
||||
/** Reserved for HTML/Markdown viewer adapters. Not implementable in MVP. */
|
||||
export type DomRangeSelector = never;
|
||||
/**
|
||||
* Child-index path from the document root to a text container node.
|
||||
* Each entry is the 0-based index among `childNodes` at that level.
|
||||
*/
|
||||
export type DomNodePath = readonly number[];
|
||||
|
||||
/** Reserved for heading/section/AST-path locators. Not implementable in MVP. */
|
||||
export type StructuralSelector = never;
|
||||
/** DOM range for rendered HTML/Markdown (W3C Range-aligned). */
|
||||
export interface DomRangeSelector {
|
||||
readonly type: "DomRangeSelector";
|
||||
readonly startPath: DomNodePath;
|
||||
readonly startOffset: number;
|
||||
readonly endPath: DomNodePath;
|
||||
readonly endOffset: number;
|
||||
}
|
||||
|
||||
/** One segment of a structural path (heading, section, or block). */
|
||||
export interface StructuralPathSegment {
|
||||
readonly kind: "heading" | "section" | "block";
|
||||
/** 0-based index among siblings of the same kind at this level. */
|
||||
readonly index: number;
|
||||
/** Heading level (1–6) when `kind` is `heading`. */
|
||||
readonly level?: number;
|
||||
/** Snapshot of heading/section label text when known. */
|
||||
readonly label?: string;
|
||||
}
|
||||
|
||||
/** Structural locator for re-render-stable anchoring in HTML/Markdown. */
|
||||
export interface StructuralSelector {
|
||||
readonly type: "StructuralSelector";
|
||||
readonly path: readonly StructuralPathSegment[];
|
||||
/** Inclusive start offset within the resolved block's canonical text. */
|
||||
readonly startOffset: number;
|
||||
/** Exclusive end offset within the resolved block's canonical text. */
|
||||
readonly endOffset: number;
|
||||
}
|
||||
|
||||
/** Reserved for exported deep-link fragments. Not implementable in MVP. */
|
||||
export type FragmentSelector = never;
|
||||
|
|
|
|||
|
|
@ -148,6 +148,38 @@ StructuralSelector heading/section/AST path
|
|||
FragmentSelector exported fragment / deep link (export-only)
|
||||
```
|
||||
|
||||
Field shapes (non-PDF selectors, EANCH-WP-0003):
|
||||
|
||||
```ts
|
||||
type DomNodePath = readonly number[]; // child-index path from document root
|
||||
|
||||
interface DomRangeSelector {
|
||||
type: "DomRangeSelector";
|
||||
startPath: DomNodePath;
|
||||
startOffset: number;
|
||||
endPath: DomNodePath;
|
||||
endOffset: number;
|
||||
}
|
||||
|
||||
interface StructuralPathSegment {
|
||||
kind: "heading" | "section" | "block";
|
||||
index: number;
|
||||
level?: number; // headings only
|
||||
label?: string;
|
||||
}
|
||||
|
||||
interface StructuralSelector {
|
||||
type: "StructuralSelector";
|
||||
path: readonly StructuralPathSegment[];
|
||||
startOffset: number;
|
||||
endOffset: number;
|
||||
}
|
||||
```
|
||||
|
||||
`StructureMap` on `DocumentRepresentation` maps canonical-text spans to
|
||||
structural paths (sorted, non-overlapping). Ingest pipelines may omit it;
|
||||
viewer adapters populate it at selection time.
|
||||
|
||||
**Selector redundancy rule:** when an annotation is created, the system stores
|
||||
*all selector types that are available* for that document representation, not
|
||||
just one. Resolution tries them in order of expected confidence and stops at
|
||||
|
|
@ -218,8 +250,32 @@ interface DocumentViewerAdapter {
|
|||
}
|
||||
```
|
||||
|
||||
MVP delivers a single `PDFViewerAdapter`. HTML and Markdown adapters are
|
||||
deferred.
|
||||
MVP delivers a single `PDFViewerAdapter`. HTML and Markdown adapters ship in
|
||||
`evidence-anchor/dom`.
|
||||
|
||||
`SelectionCapture` is a discriminated union:
|
||||
|
||||
```ts
|
||||
interface PdfSelectionCapture {
|
||||
kind: "pdf";
|
||||
text: string;
|
||||
page: number;
|
||||
rects: readonly NormalizedRect[];
|
||||
boundingRect?: NormalizedRect;
|
||||
}
|
||||
|
||||
interface DomSelectionCapture {
|
||||
kind: "dom";
|
||||
text: string;
|
||||
startPath: DomNodePath;
|
||||
startOffset: number;
|
||||
endPath: DomNodePath;
|
||||
endOffset: number;
|
||||
structuralPath?: readonly StructuralPathSegment[];
|
||||
}
|
||||
|
||||
type SelectionCapture = PdfSelectionCapture | DomSelectionCapture;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue