@beyondwork/docx-react-component 1.0.106 → 1.0.108
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +19 -5
- package/src/api/geometry-overlay-rects.ts +5 -0
- package/src/api/package-version.ts +1 -1
- package/src/api/page-anchor-id.ts +5 -0
- package/src/api/public-types.ts +16 -9
- package/src/api/table-node-specs.ts +6 -0
- package/src/api/v3/_create.ts +2 -1
- package/src/api/v3/_page-anchor-id.ts +52 -0
- package/src/api/v3/_runtime-handle.ts +92 -1
- package/src/api/v3/ai/_audit-time.ts +5 -0
- package/src/api/v3/ai/_pe2-evidence.ts +38 -0
- package/src/api/v3/ai/attach.ts +7 -2
- package/src/api/v3/ai/replacement.ts +101 -18
- package/src/api/v3/ai/resolve.ts +2 -2
- package/src/api/v3/ai/review.ts +177 -3
- package/src/api/v3/index.ts +1 -0
- package/src/api/v3/runtime/collab.ts +462 -0
- package/src/api/v3/runtime/document.ts +503 -20
- package/src/api/v3/runtime/geometry.ts +97 -0
- package/src/api/v3/runtime/layout.ts +744 -0
- package/src/api/v3/runtime/perf-probe.ts +14 -0
- package/src/api/v3/runtime/viewport.ts +9 -8
- package/src/api/v3/ui/_types.ts +149 -55
- package/src/api/v3/ui/chrome-preset-model.ts +5 -5
- package/src/api/v3/ui/debug.ts +115 -2
- package/src/api/v3/ui/index.ts +13 -0
- package/src/api/v3/ui/overlays.ts +0 -8
- package/src/api/v3/ui/surface.ts +56 -0
- package/src/api/v3/ui/viewport.ts +22 -9
- package/src/core/commands/image-commands.ts +1 -0
- package/src/core/commands/index.ts +6 -0
- package/src/core/schema/text-schema.ts +43 -5
- package/src/core/selection/mapping.ts +8 -1
- package/src/core/selection/review-anchors.ts +5 -1
- package/src/core/state/text-transaction.ts +8 -2
- package/src/io/export/serialize-revisions.ts +149 -1
- package/src/io/normalize/normalize-text.ts +6 -0
- package/src/io/ooxml/parse-bookmark-references.ts +55 -0
- package/src/io/ooxml/parse-fields.ts +24 -2
- package/src/io/ooxml/parse-headers-footers.ts +38 -5
- package/src/io/ooxml/parse-main-document.ts +153 -9
- package/src/io/ooxml/parse-numbering.ts +20 -0
- package/src/io/ooxml/parse-revisions.ts +19 -8
- package/src/io/opc/package-reader.ts +98 -8
- package/src/model/anchor.ts +4 -3
- package/src/model/canonical-document.ts +220 -2
- package/src/model/canonical-hash.ts +221 -0
- package/src/model/canonical-layout-inputs.ts +245 -6
- package/src/model/layout/index.ts +1 -0
- package/src/model/layout/page-graph-types.ts +118 -1
- package/src/model/review/revision-types.ts +14 -3
- package/src/preservation/store.ts +20 -4
- package/src/review/README.md +1 -1
- package/src/review/store/revision-actions.ts +14 -2
- package/src/runtime/collab/event-types.ts +67 -1
- package/src/runtime/collab/runtime-collab-sync.ts +177 -5
- package/src/runtime/diagnostics/layout-guard-warning.ts +18 -0
- package/src/runtime/document-heading-outline.ts +147 -0
- package/src/runtime/document-navigation.ts +8 -243
- package/src/runtime/document-runtime.ts +240 -97
- package/src/runtime/edit-dispatch/dispatch-text-command.ts +11 -0
- package/src/runtime/formatting/layout-inputs.ts +38 -5
- package/src/runtime/formatting/numbering/geometry.ts +28 -2
- package/src/runtime/geometry/adjacent-geometry-intake.ts +835 -0
- package/src/runtime/geometry/caret-geometry.ts +5 -6
- package/src/runtime/geometry/geometry-facet.ts +60 -10
- package/src/runtime/geometry/geometry-index.ts +591 -20
- package/src/runtime/geometry/geometry-types.ts +59 -0
- package/src/runtime/geometry/hit-test.ts +11 -1
- package/src/runtime/geometry/overlay-rects.ts +5 -3
- package/src/runtime/geometry/project-anchors.ts +1 -1
- package/src/runtime/geometry/word-layout-v2-line-intake.ts +323 -0
- package/src/runtime/layout/index.ts +6 -0
- package/src/runtime/layout/layout-engine-instance.ts +6 -1
- package/src/runtime/layout/layout-engine-version.ts +181 -16
- package/src/runtime/layout/layout-facet-types.ts +6 -0
- package/src/runtime/layout/page-graph.ts +21 -4
- package/src/runtime/layout/paginated-layout-engine.ts +139 -15
- package/src/runtime/layout/project-block-fragments.ts +265 -7
- package/src/runtime/layout/public-facet.ts +78 -24
- package/src/runtime/layout/table-row-continuation-contract.ts +107 -0
- package/src/runtime/layout/table-row-split.ts +92 -35
- package/src/runtime/prerender/cache-envelope.ts +2 -2
- package/src/runtime/prerender/cache-key.ts +5 -4
- package/src/runtime/prerender/customxml-cache.ts +0 -1
- package/src/runtime/render/render-kernel.ts +1 -1
- package/src/runtime/revision-runtime.ts +112 -10
- package/src/runtime/scopes/_scope-dependencies.ts +1 -0
- package/src/runtime/scopes/action-validation.ts +22 -2
- package/src/runtime/scopes/capabilities.ts +316 -0
- package/src/runtime/scopes/compile-scope-bundle.ts +14 -0
- package/src/runtime/scopes/compiler-service.ts +108 -4
- package/src/runtime/scopes/content-control-evidence.ts +79 -0
- package/src/runtime/scopes/create-issue.ts +5 -5
- package/src/runtime/scopes/evidence.ts +91 -0
- package/src/runtime/scopes/formatting/apply.ts +2 -0
- package/src/runtime/scopes/geometry-evidence.ts +130 -0
- package/src/runtime/scopes/index.ts +54 -0
- package/src/runtime/scopes/issue-lifecycle.ts +224 -0
- package/src/runtime/scopes/layout-evidence.ts +374 -0
- package/src/runtime/scopes/multi-paragraph-refusal.ts +37 -0
- package/src/runtime/scopes/preservation-boundary.ts +7 -1
- package/src/runtime/scopes/replacement/apply.ts +97 -34
- package/src/runtime/scopes/scope-kinds/paragraph.ts +108 -12
- package/src/runtime/scopes/semantic-scope-types.ts +242 -3
- package/src/runtime/scopes/visualization.ts +28 -0
- package/src/runtime/surface-projection.ts +44 -5
- package/src/runtime/telemetry/perf-probe.ts +216 -0
- package/src/runtime/virtualized-rendering.ts +36 -1
- package/src/runtime/workflow/ai-issue-lifecycle.ts +253 -0
- package/src/runtime/workflow/coordinator.ts +39 -11
- package/src/runtime/workflow/derived-scope-resolver.ts +63 -9
- package/src/runtime/workflow/index.ts +3 -0
- package/src/runtime/workflow/overlay-lane-types.ts +58 -0
- package/src/runtime/workflow/overlay-lanes.ts +168 -10
- package/src/runtime/workflow/overlay-store.ts +2 -2
- package/src/runtime/workflow/redline-posture-calibration.ts +257 -0
- package/src/runtime/workflow/word-field-matrix-calibration.ts +231 -0
- package/src/session/_sync-legacy.ts +17 -27
- package/src/session/import/loader.ts +6 -4
- package/src/session/import/source-package-evidence.ts +186 -2
- package/src/session/index.ts +5 -6
- package/src/session/session.ts +30 -56
- package/src/session/types.ts +8 -13
- package/src/shell/session-bootstrap.ts +155 -81
- package/src/ui/WordReviewEditor.tsx +520 -12
- package/src/ui/editor-shell-view.tsx +14 -4
- package/src/ui/editor-surface-controller.tsx +5 -3
- package/src/ui/headless/selection-tool-resolver.ts +1 -2
- package/src/ui/presence-overlay-lane.ts +0 -1
- package/src/ui/ui-controller-factory.ts +7 -0
- package/src/ui-tailwind/chrome/build-context-menu-entries.ts +5 -1
- package/src/ui-tailwind/chrome/editor-action-registry.ts +105 -5
- package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +7 -0
- package/src/ui-tailwind/chrome/layer-debug-contracts.ts +208 -0
- package/src/ui-tailwind/chrome/resolve-target-kind.ts +13 -0
- package/src/ui-tailwind/chrome/tw-alert-banner.tsx +11 -3
- package/src/ui-tailwind/chrome/tw-command-palette.tsx +36 -6
- package/src/ui-tailwind/chrome/tw-context-menu.tsx +6 -1
- package/src/ui-tailwind/chrome/tw-display-mode-selector.tsx +42 -109
- package/src/ui-tailwind/chrome/tw-inline-find-bar.tsx +26 -6
- package/src/ui-tailwind/chrome/tw-navigation-command-bar.tsx +328 -0
- package/src/ui-tailwind/chrome/tw-object-context-toolbar.tsx +8 -4
- package/src/ui-tailwind/chrome/tw-runtime-repl-dialog.tsx +129 -1
- package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +19 -5
- package/src/ui-tailwind/chrome/tw-selection-tool-structure.tsx +5 -1
- package/src/ui-tailwind/chrome/tw-workspace-chrome-host.tsx +28 -12
- package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +30 -3
- package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +116 -10
- package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +223 -94
- package/src/ui-tailwind/chrome-overlay/tw-presence-overlay-lane.tsx +157 -0
- package/src/ui-tailwind/chrome-overlay/tw-review-overlay-lane-markers.tsx +259 -0
- package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +5 -2
- package/src/ui-tailwind/chrome-overlay/tw-substrate-overlay-lanes.tsx +314 -0
- package/src/ui-tailwind/debug/README.md +4 -1
- package/src/ui-tailwind/debug/layer11-consumer-readiness.ts +272 -0
- package/src/ui-tailwind/debug/layer11-word-field-matrix-evidence.ts +160 -0
- package/src/ui-tailwind/editor-surface/perf-probe.ts +14 -215
- package/src/ui-tailwind/editor-surface/pm-decorations.ts +42 -0
- package/src/ui-tailwind/editor-surface/pm-position-map.ts +38 -2
- package/src/ui-tailwind/editor-surface/pm-schema.ts +14 -4
- package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +34 -5
- package/src/ui-tailwind/editor-surface/runtime-decoration-plugin.ts +9 -19
- package/src/ui-tailwind/editor-surface/surface-build-keys.ts +2 -2
- package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +145 -0
- package/src/ui-tailwind/editor-surface/tw-page-block-view.tsx +16 -11
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +8 -10
- package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +3 -0
- package/src/ui-tailwind/page-stack/tw-page-chrome-entry.tsx +4 -2
- package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +60 -20
- package/src/ui-tailwind/page-stack/tw-region-block-renderer.tsx +16 -11
- package/src/ui-tailwind/review/tw-health-panel.tsx +36 -17
- package/src/ui-tailwind/review/tw-review-rail.tsx +7 -4
- package/src/ui-tailwind/review-workspace/diagnostics-visibility.ts +44 -0
- package/src/ui-tailwind/review-workspace/page-shell-metrics.ts +11 -0
- package/src/ui-tailwind/review-workspace/tw-review-workspace-rail.tsx +16 -1
- package/src/ui-tailwind/review-workspace/types.ts +26 -12
- package/src/ui-tailwind/review-workspace/use-diagnostics-signal.ts +40 -11
- package/src/ui-tailwind/review-workspace/use-layout-facet-render-signal.ts +2 -1
- package/src/ui-tailwind/review-workspace/use-page-markers.ts +15 -26
- package/src/ui-tailwind/review-workspace/use-scope-card-state.ts +35 -18
- package/src/ui-tailwind/review-workspace/use-selection-toolbar-placement.ts +41 -32
- package/src/ui-tailwind/review-workspace/use-status-bar-page-facts.ts +2 -1
- package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +2 -1
- package/src/ui-tailwind/status/tw-status-bar.tsx +6 -5
- package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +52 -80
- package/src/ui-tailwind/toolbar/tw-shell-header.tsx +12 -48
- package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +9 -4
- package/src/ui-tailwind/toolbar/tw-toolbar.tsx +328 -361
- package/src/ui-tailwind/tw-review-workspace.tsx +152 -286
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
import type { EditorStoryTarget } from "../../api/public-types";
|
|
27
27
|
import type {
|
|
28
28
|
PublicMeasurementFidelity,
|
|
29
|
+
PublicPageFrame,
|
|
29
30
|
PublicPageRegion,
|
|
30
31
|
} from "../layout/public-facet.ts";
|
|
31
32
|
|
|
@@ -119,17 +120,28 @@ export interface GeometryPrecisionCounts {
|
|
|
119
120
|
export interface GeometryIndexCoverage {
|
|
120
121
|
status: GeometryRehydrationStatus;
|
|
121
122
|
pageCount: number;
|
|
123
|
+
pageFrameCompleteness: GeometryPageFrameCompletenessCounts;
|
|
122
124
|
regionCount: number;
|
|
123
125
|
sliceCount: number;
|
|
124
126
|
lineCount: number;
|
|
125
127
|
anchorCount: number;
|
|
126
128
|
hitTargetCount: number;
|
|
127
129
|
semanticEntryCount: number;
|
|
130
|
+
pageLocalFieldLedgerCount: number;
|
|
128
131
|
replacementEnvelopeCount: number;
|
|
129
132
|
objectHandleCount: number;
|
|
133
|
+
layoutDivergenceObjectCount: number;
|
|
134
|
+
splitRowCarryCount: number;
|
|
130
135
|
precision: GeometryPrecisionCounts;
|
|
131
136
|
}
|
|
132
137
|
|
|
138
|
+
export type GeometryPageFrameCompleteness = PublicPageFrame["completeness"];
|
|
139
|
+
|
|
140
|
+
export type GeometryPageFrameCompletenessCounts = Record<
|
|
141
|
+
GeometryPageFrameCompleteness,
|
|
142
|
+
number
|
|
143
|
+
>;
|
|
144
|
+
|
|
133
145
|
export type GeometrySourceIdentityJoinKind = "direct" | "block-scoped";
|
|
134
146
|
|
|
135
147
|
/**
|
|
@@ -183,6 +195,10 @@ export interface GeometryIndexPage {
|
|
|
183
195
|
pageIndex: number;
|
|
184
196
|
rect: GeometryRect;
|
|
185
197
|
regionIds: readonly string[];
|
|
198
|
+
frameCompleteness: GeometryPageFrameCompleteness;
|
|
199
|
+
displayPageNumber?: number;
|
|
200
|
+
layoutDivergenceIds?: readonly string[];
|
|
201
|
+
layoutDivergenceObjectIds?: readonly string[];
|
|
186
202
|
}
|
|
187
203
|
|
|
188
204
|
export interface GeometryIndexRegion {
|
|
@@ -255,6 +271,8 @@ export interface GeometryHitTarget {
|
|
|
255
271
|
|
|
256
272
|
export type SemanticDisplayEntryKind =
|
|
257
273
|
| "text-line"
|
|
274
|
+
| "field-region"
|
|
275
|
+
| "page-local-field-ledger"
|
|
258
276
|
| "numbering-marker"
|
|
259
277
|
| "table-frame"
|
|
260
278
|
| "table-row"
|
|
@@ -269,6 +287,34 @@ export type SemanticDisplayEntryKind =
|
|
|
269
287
|
| "border"
|
|
270
288
|
| "debug-classification";
|
|
271
289
|
|
|
290
|
+
export interface GeometryTableRowRange {
|
|
291
|
+
from: number;
|
|
292
|
+
to: number;
|
|
293
|
+
totalRows: number;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export interface GeometryTableSplitRowCarry {
|
|
297
|
+
rowIndex: number;
|
|
298
|
+
continuesFromPreviousPage: boolean;
|
|
299
|
+
continuesToNextPage: boolean;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export interface GeometryTableVerticalMergeCarry {
|
|
303
|
+
columnIndex: number;
|
|
304
|
+
restartRowIndex: number;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export interface GeometryTableContinuation {
|
|
308
|
+
sequenceIndex?: number;
|
|
309
|
+
sliceCount?: number;
|
|
310
|
+
rowRange?: GeometryTableRowRange;
|
|
311
|
+
continuesFromPreviousPage?: boolean;
|
|
312
|
+
continuesToNextPage?: boolean;
|
|
313
|
+
repeatedHeaderRowIndexes?: readonly number[];
|
|
314
|
+
splitRowCarry?: readonly GeometryTableSplitRowCarry[];
|
|
315
|
+
verticalMergeCarry?: readonly GeometryTableVerticalMergeCarry[];
|
|
316
|
+
}
|
|
317
|
+
|
|
272
318
|
export interface SemanticDisplayEntry {
|
|
273
319
|
entryId: string;
|
|
274
320
|
kind: SemanticDisplayEntryKind;
|
|
@@ -282,6 +328,18 @@ export interface SemanticDisplayEntry {
|
|
|
282
328
|
fragmentId?: string;
|
|
283
329
|
rowIndex?: number;
|
|
284
330
|
columnIndex?: number;
|
|
331
|
+
tableContinuation?: GeometryTableContinuation;
|
|
332
|
+
layoutObjectId?: string;
|
|
333
|
+
fieldFamilies?: readonly string[];
|
|
334
|
+
pageLocalStoryId?: string;
|
|
335
|
+
pageLocalStoryKind?: "header" | "footer";
|
|
336
|
+
pageLocalStoryVariant?: string;
|
|
337
|
+
resolvedFieldId?: string;
|
|
338
|
+
resolvedFieldFamily?: string;
|
|
339
|
+
resolvedFieldDisplayText?: string;
|
|
340
|
+
frameCompleteness?: GeometryPageFrameCompleteness;
|
|
341
|
+
layoutDivergenceIds?: readonly string[];
|
|
342
|
+
layoutDivergenceObjectIds?: readonly string[];
|
|
285
343
|
rect: GeometryRect;
|
|
286
344
|
status: GeometryRehydrationStatus;
|
|
287
345
|
precision: GeometryPrecision;
|
|
@@ -303,6 +361,7 @@ export interface GeometryObjectHandleEntry {
|
|
|
303
361
|
rects: readonly GeometryRect[];
|
|
304
362
|
status: GeometryRehydrationStatus;
|
|
305
363
|
precision: GeometryPrecision;
|
|
364
|
+
layoutDivergenceIds?: readonly string[];
|
|
306
365
|
sourceIdentity?: GeometrySourceIdentity;
|
|
307
366
|
}
|
|
308
367
|
|
|
@@ -32,7 +32,17 @@ export function resolveHitTest(
|
|
|
32
32
|
if (!frame) return null;
|
|
33
33
|
for (const page of frame.pages) {
|
|
34
34
|
if (!containsPoint(page.frame, point)) continue;
|
|
35
|
-
//
|
|
35
|
+
// Column regions are explicit L04 projection facts nested inside
|
|
36
|
+
// the body band. Check them before the broad body region so the
|
|
37
|
+
// body's between-block snap cannot steal clicks from a populated
|
|
38
|
+
// column.
|
|
39
|
+
if (page.regions.columns) {
|
|
40
|
+
for (const columnRegion of page.regions.columns) {
|
|
41
|
+
const hit = hitTestStoryRegion(page, point, columnRegion);
|
|
42
|
+
if (hit) return hit;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Check body next — it owns the bulk of the page. Header /
|
|
36
46
|
// footer / footnotes are secondary stories and only matter when
|
|
37
47
|
// the point falls outside the body.
|
|
38
48
|
const bodyHit = hitTestStoryRegion(page, point, page.regions.body);
|
|
@@ -48,8 +48,10 @@ function normalizeVisibleRange(
|
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* Build the `PageOverlayRect` list from a `GeometryFacet`. Returns
|
|
51
|
-
* `null` when the facet
|
|
52
|
-
* caller can fall back to
|
|
51
|
+
* `null` when the facet cannot resolve every requested visible page
|
|
52
|
+
* (cold-open or partial frame) so the caller can fall back to an
|
|
53
|
+
* explicitly degraded DOM-measurement path instead of painting a
|
|
54
|
+
* partial page stack.
|
|
53
55
|
*/
|
|
54
56
|
export function resolvePageOverlayRectsFromGeometry(
|
|
55
57
|
geometryFacet: GeometryFacet,
|
|
@@ -69,7 +71,7 @@ export function resolvePageOverlayRectsFromGeometry(
|
|
|
69
71
|
if (i < normalizedVisible.start || i >= normalizedVisible.end) continue;
|
|
70
72
|
}
|
|
71
73
|
const page = geometryFacet.getPage(i);
|
|
72
|
-
if (!page)
|
|
74
|
+
if (!page) return null;
|
|
73
75
|
rects.push({
|
|
74
76
|
pageId: page.pageId,
|
|
75
77
|
pageIndex: page.pageIndex,
|
|
@@ -21,7 +21,7 @@ import type {
|
|
|
21
21
|
RenderFrame,
|
|
22
22
|
RenderFrameRect,
|
|
23
23
|
} from "../render/index.ts";
|
|
24
|
-
import { emitLayoutGuardWarning } from "../layout
|
|
24
|
+
import { emitLayoutGuardWarning } from "../diagnostics/layout-guard-warning.ts";
|
|
25
25
|
|
|
26
26
|
export function resolveAnchorRects(
|
|
27
27
|
frame: RenderFrame | null,
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
export type WordLayoutV2LineIntakeLane = "ccep" | "ccep-redline";
|
|
2
|
+
|
|
3
|
+
export interface WordLayoutV2LineIntakeDocumentInput {
|
|
4
|
+
readonly lane: WordLayoutV2LineIntakeLane;
|
|
5
|
+
readonly runId: string;
|
|
6
|
+
readonly docId: string;
|
|
7
|
+
readonly recordPath?: string;
|
|
8
|
+
readonly artifact: unknown;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface WordLayoutV2LineGeometryRect {
|
|
12
|
+
readonly x: number;
|
|
13
|
+
readonly y: number;
|
|
14
|
+
readonly width: number;
|
|
15
|
+
readonly height: number;
|
|
16
|
+
readonly unit: "screenPx" | string;
|
|
17
|
+
readonly approxTwips?: {
|
|
18
|
+
readonly x?: number;
|
|
19
|
+
readonly y?: number;
|
|
20
|
+
readonly width?: number;
|
|
21
|
+
readonly height?: number;
|
|
22
|
+
readonly unit?: "twipsApproxFromScreen" | string;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface WordLayoutV2LineGeometryRow {
|
|
27
|
+
readonly lineId?: string;
|
|
28
|
+
readonly textHash?: string;
|
|
29
|
+
readonly charLength?: number;
|
|
30
|
+
readonly rectCount: number;
|
|
31
|
+
readonly rects: readonly WordLayoutV2LineGeometryRect[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface WordLayoutV2LineGeometryDocumentSummary {
|
|
35
|
+
readonly lane: WordLayoutV2LineIntakeLane;
|
|
36
|
+
readonly runId: string;
|
|
37
|
+
readonly docId: string;
|
|
38
|
+
readonly recordPath?: string;
|
|
39
|
+
readonly source?: {
|
|
40
|
+
readonly fileName?: string;
|
|
41
|
+
readonly sha256?: string;
|
|
42
|
+
readonly bytes?: number;
|
|
43
|
+
};
|
|
44
|
+
readonly tuple: {
|
|
45
|
+
readonly zoom?: number;
|
|
46
|
+
readonly viewportWidth?: number;
|
|
47
|
+
readonly markupMode?: string;
|
|
48
|
+
readonly dpi?: number;
|
|
49
|
+
};
|
|
50
|
+
readonly word?: {
|
|
51
|
+
readonly version?: string;
|
|
52
|
+
readonly build?: string;
|
|
53
|
+
readonly activePrinter?: string;
|
|
54
|
+
};
|
|
55
|
+
readonly comSummary: {
|
|
56
|
+
readonly pageCount?: number | null;
|
|
57
|
+
readonly paragraphCount?: number;
|
|
58
|
+
readonly revisionCount?: number;
|
|
59
|
+
readonly commentCount?: number;
|
|
60
|
+
};
|
|
61
|
+
readonly lineBoxSummary: {
|
|
62
|
+
readonly status?: string;
|
|
63
|
+
readonly lineCount: number;
|
|
64
|
+
readonly lineRows: number;
|
|
65
|
+
readonly linesWithTextHash: number;
|
|
66
|
+
readonly linesWithRects: number;
|
|
67
|
+
readonly rectCount: number;
|
|
68
|
+
readonly approxTwipsRectCount: number;
|
|
69
|
+
readonly documentRangeRectCount?: number;
|
|
70
|
+
readonly firstLineId?: string;
|
|
71
|
+
readonly lastLineId?: string;
|
|
72
|
+
readonly coordinateSpace: "screen-px";
|
|
73
|
+
readonly precision: "screen-space-approximate";
|
|
74
|
+
readonly normalizationStatus: "awaiting-l04-page-frame-join";
|
|
75
|
+
};
|
|
76
|
+
readonly lineRows: readonly WordLayoutV2LineGeometryRow[];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface WordLayoutV2LineGeometryIntakeSummary {
|
|
80
|
+
readonly schemaVersion: "layer-05-word-layout-v2-line-geometry-intake/v0";
|
|
81
|
+
readonly generatedAtUtc: string;
|
|
82
|
+
readonly sourceRuns: readonly {
|
|
83
|
+
readonly runId: string;
|
|
84
|
+
readonly lane: WordLayoutV2LineIntakeLane;
|
|
85
|
+
readonly documents: number;
|
|
86
|
+
readonly lineRows: number;
|
|
87
|
+
readonly linesWithRects: number;
|
|
88
|
+
readonly rectCount: number;
|
|
89
|
+
readonly markupModes: readonly string[];
|
|
90
|
+
}[];
|
|
91
|
+
readonly totals: {
|
|
92
|
+
readonly documents: number;
|
|
93
|
+
readonly lineRows: number;
|
|
94
|
+
readonly linesWithRects: number;
|
|
95
|
+
readonly rectCount: number;
|
|
96
|
+
readonly approxTwipsRectCount: number;
|
|
97
|
+
readonly cleanDocuments: number;
|
|
98
|
+
readonly redlineDocuments: number;
|
|
99
|
+
readonly cleanLineRows: number;
|
|
100
|
+
readonly redlineLineRows: number;
|
|
101
|
+
};
|
|
102
|
+
readonly routing: {
|
|
103
|
+
readonly routedTo: "L05";
|
|
104
|
+
readonly axis: "line-geometry";
|
|
105
|
+
readonly sourceId: "word-layout-v2.uia.lineBoxes.lines";
|
|
106
|
+
readonly coordinateSpace: "screen-px";
|
|
107
|
+
readonly precision: "screen-space-approximate";
|
|
108
|
+
readonly requiredUpstreamFact: "L04 page/frame mapping";
|
|
109
|
+
};
|
|
110
|
+
readonly documents: readonly WordLayoutV2LineGeometryDocumentSummary[];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function summarizeWordLayoutV2LineGeometryIntake(input: {
|
|
114
|
+
readonly generatedAtUtc: string;
|
|
115
|
+
readonly documents: readonly WordLayoutV2LineIntakeDocumentInput[];
|
|
116
|
+
}): WordLayoutV2LineGeometryIntakeSummary {
|
|
117
|
+
const documents = input.documents
|
|
118
|
+
.map(summarizeDocument)
|
|
119
|
+
.sort((a, b) =>
|
|
120
|
+
a.lane.localeCompare(b.lane) ||
|
|
121
|
+
a.docId.localeCompare(b.docId) ||
|
|
122
|
+
a.recordPath?.localeCompare(b.recordPath ?? "") ||
|
|
123
|
+
0,
|
|
124
|
+
);
|
|
125
|
+
const sourceRuns = summarizeRuns(documents);
|
|
126
|
+
return {
|
|
127
|
+
schemaVersion: "layer-05-word-layout-v2-line-geometry-intake/v0",
|
|
128
|
+
generatedAtUtc: input.generatedAtUtc,
|
|
129
|
+
sourceRuns,
|
|
130
|
+
totals: {
|
|
131
|
+
documents: documents.length,
|
|
132
|
+
lineRows: sum(documents, (doc) => doc.lineBoxSummary.lineRows),
|
|
133
|
+
linesWithRects: sum(documents, (doc) => doc.lineBoxSummary.linesWithRects),
|
|
134
|
+
rectCount: sum(documents, (doc) => doc.lineBoxSummary.rectCount),
|
|
135
|
+
approxTwipsRectCount: sum(documents, (doc) => doc.lineBoxSummary.approxTwipsRectCount),
|
|
136
|
+
cleanDocuments: documents.filter((doc) => doc.lane === "ccep").length,
|
|
137
|
+
redlineDocuments: documents.filter((doc) => doc.lane === "ccep-redline").length,
|
|
138
|
+
cleanLineRows: sum(
|
|
139
|
+
documents.filter((doc) => doc.lane === "ccep"),
|
|
140
|
+
(doc) => doc.lineBoxSummary.lineRows,
|
|
141
|
+
),
|
|
142
|
+
redlineLineRows: sum(
|
|
143
|
+
documents.filter((doc) => doc.lane === "ccep-redline"),
|
|
144
|
+
(doc) => doc.lineBoxSummary.lineRows,
|
|
145
|
+
),
|
|
146
|
+
},
|
|
147
|
+
routing: {
|
|
148
|
+
routedTo: "L05",
|
|
149
|
+
axis: "line-geometry",
|
|
150
|
+
sourceId: "word-layout-v2.uia.lineBoxes.lines",
|
|
151
|
+
coordinateSpace: "screen-px",
|
|
152
|
+
precision: "screen-space-approximate",
|
|
153
|
+
requiredUpstreamFact: "L04 page/frame mapping",
|
|
154
|
+
},
|
|
155
|
+
documents,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function summarizeDocument(
|
|
160
|
+
input: WordLayoutV2LineIntakeDocumentInput,
|
|
161
|
+
): WordLayoutV2LineGeometryDocumentSummary {
|
|
162
|
+
const artifact = record(input.artifact);
|
|
163
|
+
const source = record(artifact.source);
|
|
164
|
+
const tuple = record(artifact.tuple);
|
|
165
|
+
const word = record(artifact.word);
|
|
166
|
+
const comProbe = record(artifact.comProbe);
|
|
167
|
+
const uia = record(artifact.uia);
|
|
168
|
+
const lineBoxes = record(uia.lineBoxes);
|
|
169
|
+
const documentRange = record(lineBoxes.documentRange);
|
|
170
|
+
const lines = array(lineBoxes.lines);
|
|
171
|
+
const lineRows = lines.map(normalizeLineRow);
|
|
172
|
+
const lineCount = numberValue(lineBoxes.lineCount) ?? lineRows.length;
|
|
173
|
+
const rectCount = sum(lineRows, (line) => line.rects.length);
|
|
174
|
+
return {
|
|
175
|
+
lane: input.lane,
|
|
176
|
+
runId: input.runId,
|
|
177
|
+
docId: input.docId,
|
|
178
|
+
recordPath: input.recordPath,
|
|
179
|
+
source: {
|
|
180
|
+
fileName: stringValue(source.fileName),
|
|
181
|
+
sha256: stringValue(source.sha256),
|
|
182
|
+
bytes: numberValue(source.bytes),
|
|
183
|
+
},
|
|
184
|
+
tuple: {
|
|
185
|
+
zoom: numberValue(tuple.zoom),
|
|
186
|
+
viewportWidth: numberValue(tuple.viewportWidth),
|
|
187
|
+
markupMode: stringValue(tuple.markupMode),
|
|
188
|
+
dpi: numberValue(tuple.dpi),
|
|
189
|
+
},
|
|
190
|
+
word: {
|
|
191
|
+
version: stringValue(word.version),
|
|
192
|
+
build: stringValue(word.build),
|
|
193
|
+
activePrinter: stringValue(word.activePrinter),
|
|
194
|
+
},
|
|
195
|
+
comSummary: {
|
|
196
|
+
pageCount: nullableNumberValue(comProbe.pageCount),
|
|
197
|
+
paragraphCount: numberValue(comProbe.paragraphs),
|
|
198
|
+
revisionCount: numberValue(comProbe.revisions),
|
|
199
|
+
commentCount: numberValue(comProbe.comments),
|
|
200
|
+
},
|
|
201
|
+
lineBoxSummary: {
|
|
202
|
+
status: stringValue(lineBoxes.status),
|
|
203
|
+
lineCount,
|
|
204
|
+
lineRows: lineRows.length,
|
|
205
|
+
linesWithTextHash: lineRows.filter((line) => line.textHash !== undefined).length,
|
|
206
|
+
linesWithRects: lineRows.filter((line) => line.rects.length > 0).length,
|
|
207
|
+
rectCount,
|
|
208
|
+
approxTwipsRectCount: sum(
|
|
209
|
+
lineRows,
|
|
210
|
+
(line) => line.rects.filter((rect) => rect.approxTwips !== undefined).length,
|
|
211
|
+
),
|
|
212
|
+
documentRangeRectCount: Array.isArray(documentRange.rects)
|
|
213
|
+
? documentRange.rects.length
|
|
214
|
+
: undefined,
|
|
215
|
+
firstLineId: lineRows[0]?.lineId,
|
|
216
|
+
lastLineId: lineRows[lineRows.length - 1]?.lineId,
|
|
217
|
+
coordinateSpace: "screen-px",
|
|
218
|
+
precision: "screen-space-approximate",
|
|
219
|
+
normalizationStatus: "awaiting-l04-page-frame-join",
|
|
220
|
+
},
|
|
221
|
+
lineRows,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function summarizeRuns(
|
|
226
|
+
documents: readonly WordLayoutV2LineGeometryDocumentSummary[],
|
|
227
|
+
): WordLayoutV2LineGeometryIntakeSummary["sourceRuns"] {
|
|
228
|
+
const keys = [...new Set(documents.map((doc) => `${doc.lane}\0${doc.runId}`))].sort();
|
|
229
|
+
return keys.map((key) => {
|
|
230
|
+
const [lane, runId] = key.split("\0") as [WordLayoutV2LineIntakeLane, string];
|
|
231
|
+
const docs = documents.filter((doc) => doc.lane === lane && doc.runId === runId);
|
|
232
|
+
const markupModes = [
|
|
233
|
+
...new Set(docs.map((doc) => doc.tuple.markupMode).filter((mode): mode is string => !!mode)),
|
|
234
|
+
].sort();
|
|
235
|
+
return {
|
|
236
|
+
runId,
|
|
237
|
+
lane,
|
|
238
|
+
documents: docs.length,
|
|
239
|
+
lineRows: sum(docs, (doc) => doc.lineBoxSummary.lineRows),
|
|
240
|
+
linesWithRects: sum(docs, (doc) => doc.lineBoxSummary.linesWithRects),
|
|
241
|
+
rectCount: sum(docs, (doc) => doc.lineBoxSummary.rectCount),
|
|
242
|
+
markupModes,
|
|
243
|
+
};
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function normalizeLineRow(raw: unknown): WordLayoutV2LineGeometryRow {
|
|
248
|
+
const line = record(raw);
|
|
249
|
+
const rects = normalizeRects(line.rects);
|
|
250
|
+
return {
|
|
251
|
+
lineId: stringValue(line.lineId),
|
|
252
|
+
textHash: stringValue(line.textHash),
|
|
253
|
+
charLength: numberValue(line.charLength),
|
|
254
|
+
rectCount: numberValue(line.rectCount) ?? rects.length,
|
|
255
|
+
rects,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function normalizeRects(raw: unknown): readonly WordLayoutV2LineGeometryRect[] {
|
|
260
|
+
if (Array.isArray(raw)) return raw.map(normalizeRect).filter(isRect);
|
|
261
|
+
const maybeRect = normalizeRect(raw);
|
|
262
|
+
return isRect(maybeRect) ? [maybeRect] : [];
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function normalizeRect(raw: unknown): WordLayoutV2LineGeometryRect | undefined {
|
|
266
|
+
const rect = record(raw);
|
|
267
|
+
const x = numberValue(rect.x);
|
|
268
|
+
const y = numberValue(rect.y);
|
|
269
|
+
const width = numberValue(rect.width);
|
|
270
|
+
const height = numberValue(rect.height);
|
|
271
|
+
if (x === undefined || y === undefined || width === undefined || height === undefined) {
|
|
272
|
+
return undefined;
|
|
273
|
+
}
|
|
274
|
+
const approxTwips = record(rect.approxTwips);
|
|
275
|
+
const normalizedApproxTwips = {
|
|
276
|
+
x: numberValue(approxTwips.x),
|
|
277
|
+
y: numberValue(approxTwips.y),
|
|
278
|
+
width: numberValue(approxTwips.width),
|
|
279
|
+
height: numberValue(approxTwips.height),
|
|
280
|
+
unit: stringValue(approxTwips.unit),
|
|
281
|
+
};
|
|
282
|
+
const hasApproxTwips = Object.values(normalizedApproxTwips).some(
|
|
283
|
+
(value) => value !== undefined,
|
|
284
|
+
);
|
|
285
|
+
return {
|
|
286
|
+
x,
|
|
287
|
+
y,
|
|
288
|
+
width,
|
|
289
|
+
height,
|
|
290
|
+
unit: stringValue(rect.unit) ?? "screenPx",
|
|
291
|
+
approxTwips: hasApproxTwips ? normalizedApproxTwips : undefined,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function isRect(value: WordLayoutV2LineGeometryRect | undefined): value is WordLayoutV2LineGeometryRect {
|
|
296
|
+
return value !== undefined;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function record(value: unknown): Record<string, unknown> {
|
|
300
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
301
|
+
? value as Record<string, unknown>
|
|
302
|
+
: {};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function array(value: unknown): readonly unknown[] {
|
|
306
|
+
return Array.isArray(value) ? value : [];
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function stringValue(value: unknown): string | undefined {
|
|
310
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function numberValue(value: unknown): number | undefined {
|
|
314
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function nullableNumberValue(value: unknown): number | null | undefined {
|
|
318
|
+
return value === null ? null : numberValue(value);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function sum<T>(items: readonly T[], read: (item: T) => number): number {
|
|
322
|
+
return items.reduce((total, item) => total + read(item), 0);
|
|
323
|
+
}
|
|
@@ -183,14 +183,20 @@ export {
|
|
|
183
183
|
type PublicLineBox,
|
|
184
184
|
type PublicNoteAllocation,
|
|
185
185
|
type PublicPageAnchor,
|
|
186
|
+
type PublicPageFrame,
|
|
187
|
+
type PublicPageLocalStoryInstance,
|
|
186
188
|
type PublicPageSpan,
|
|
187
189
|
type PublicSectionNode,
|
|
188
190
|
type PublicResolvedPageStories,
|
|
191
|
+
type PublicResolvedStoryField,
|
|
189
192
|
type PublicResolvedParagraphFormatting,
|
|
190
193
|
type PublicResolvedRunFormatting,
|
|
194
|
+
type PublicStoryAnchoredObject,
|
|
195
|
+
type PublicTwipsRect,
|
|
191
196
|
type PublicBlockMeasurement,
|
|
192
197
|
type PublicMeasurementFidelity,
|
|
193
198
|
type PublicFieldDirtinessReport,
|
|
199
|
+
type PublicLayoutDivergence,
|
|
194
200
|
type LayoutFacetEvent,
|
|
195
201
|
type LayoutFacetInvalidationReason,
|
|
196
202
|
type RenderZoomSummary,
|
|
@@ -27,6 +27,7 @@ import type {
|
|
|
27
27
|
import type {
|
|
28
28
|
CanonicalDocumentEnvelope,
|
|
29
29
|
} from "../../core/state/editor-state.ts";
|
|
30
|
+
import { collectCanonicalFieldRegionIdentities } from "../../model/canonical-layout-inputs.ts";
|
|
30
31
|
import { MAIN_STORY_TARGET } from "../../core/selection/mapping.ts";
|
|
31
32
|
import { createSelectionSnapshot } from "../../core/state/editor-state.ts";
|
|
32
33
|
import {
|
|
@@ -36,7 +37,7 @@ import {
|
|
|
36
37
|
} from "../document-layout.ts";
|
|
37
38
|
import { findNoteReferencePosition } from "../view-state.ts";
|
|
38
39
|
import { createEditorSurfaceSnapshot } from "../surface-projection.ts";
|
|
39
|
-
import { buildHeadingOutline } from "../document-
|
|
40
|
+
import { buildHeadingOutline } from "../document-heading-outline.ts";
|
|
40
41
|
import {
|
|
41
42
|
analyzeInvalidation,
|
|
42
43
|
computeFieldDirtiness,
|
|
@@ -456,6 +457,7 @@ export function createLayoutEngine(
|
|
|
456
457
|
MAIN_STORY_TARGET,
|
|
457
458
|
);
|
|
458
459
|
const sections = buildResolvedSections(document);
|
|
460
|
+
const fieldRegions = collectCanonicalFieldRegionIdentities(document);
|
|
459
461
|
const pageStack = buildPageStackWithSplits(
|
|
460
462
|
document,
|
|
461
463
|
sections,
|
|
@@ -470,6 +472,7 @@ export function createLayoutEngine(
|
|
|
470
472
|
pageStack.splits,
|
|
471
473
|
pageStack.columnByBlockIdByPageIndex,
|
|
472
474
|
pageStack.fragmentMeasurementsByPageIndex,
|
|
475
|
+
fieldRegions,
|
|
473
476
|
);
|
|
474
477
|
const lineBoxesByPageIndex = projectLineBoxesForPageFragments(
|
|
475
478
|
pages,
|
|
@@ -642,6 +645,7 @@ export function createLayoutEngine(
|
|
|
642
645
|
: undefined;
|
|
643
646
|
|
|
644
647
|
const freshStories = resolvePageStories(freshSnapshotsToRebuild);
|
|
648
|
+
const fieldRegions = collectCanonicalFieldRegionIdentities(document);
|
|
645
649
|
// Project fragments for the fresh tail pages, threading paragraph
|
|
646
650
|
// line-range splits produced by intra-paragraph pagination.
|
|
647
651
|
const freshBodyFragmentsByPageIndex = projectSurfaceBlocksToPageFragments(
|
|
@@ -650,6 +654,7 @@ export function createLayoutEngine(
|
|
|
650
654
|
freshResult.splits,
|
|
651
655
|
freshResult.columnByBlockIdByPageIndex,
|
|
652
656
|
freshResult.fragmentMeasurementsByPageIndex,
|
|
657
|
+
fieldRegions,
|
|
653
658
|
);
|
|
654
659
|
const freshLineBoxesByPageIndex = projectLineBoxesForPageFragments(
|
|
655
660
|
freshSnapshotsToRebuild,
|