@beyondwork/docx-react-component 1.0.66 → 1.0.69
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/README.md +75 -931
- package/package.json +26 -27
- package/src/api/anchor-conversion.ts +43 -0
- package/src/api/editor-state-types.ts +2 -1
- package/src/api/public-types.ts +504 -101
- package/src/api/session-state.ts +4 -0
- package/src/api/v3/README.md +91 -0
- package/src/api/v3/_create.ts +146 -0
- package/src/api/v3/_layer-metadata.ts +362 -0
- package/src/api/v3/_mocks.ts +84 -0
- package/src/api/v3/_runtime-handle.ts +162 -0
- package/src/api/v3/_ux-response.ts +73 -0
- package/src/api/v3/ai/_metadata-audit.ts +225 -0
- package/src/api/v3/ai/attach.ts +235 -0
- package/src/api/v3/ai/bundle.ts +132 -0
- package/src/api/v3/ai/explain.ts +144 -0
- package/src/api/v3/ai/export.ts +54 -0
- package/src/api/v3/ai/inspect.ts +118 -0
- package/src/api/v3/ai/policy.ts +77 -0
- package/src/api/v3/ai/replacement.ts +341 -0
- package/src/api/v3/ai/resolve.ts +133 -0
- package/src/api/v3/index.ts +79 -0
- package/src/api/v3/runtime/chart.ts +310 -0
- package/src/api/v3/runtime/clipboard.ts +81 -0
- package/src/api/v3/runtime/collab.ts +331 -0
- package/src/api/v3/runtime/content.ts +236 -0
- package/src/api/v3/runtime/document.ts +282 -0
- package/src/api/v3/runtime/formatting.ts +186 -0
- package/src/api/v3/runtime/geometry.ts +349 -0
- package/src/api/v3/runtime/layout.ts +108 -0
- package/src/api/v3/runtime/review.ts +129 -0
- package/src/api/v3/runtime/search.ts +74 -0
- package/src/api/v3/runtime/table.ts +63 -0
- package/src/api/v3/runtime/workflow.ts +434 -0
- package/src/api/v3/ui/_context.ts +86 -0
- package/src/api/v3/ui/_create.ts +65 -0
- package/src/api/v3/ui/_types.ts +520 -0
- package/src/api/v3/ui/chrome-composition.ts +342 -0
- package/src/{ui-tailwind/chrome → api/v3/ui}/chrome-preset-model.ts +11 -1
- package/src/api/v3/ui/chrome.ts +476 -0
- package/src/api/v3/ui/debug.ts +124 -0
- package/src/api/v3/ui/index.ts +64 -0
- package/src/api/v3/ui/overlays-visibility.ts +170 -0
- package/src/api/v3/ui/overlays.ts +427 -0
- package/src/api/v3/ui/scope.ts +71 -0
- package/src/api/v3/ui/session.ts +100 -0
- package/src/api/v3/ui/surface.ts +170 -0
- package/src/api/v3/ui/viewport.ts +303 -0
- package/src/core/commands/index.ts +28 -6
- package/src/core/commands/list-commands.ts +3 -2
- package/src/core/commands/section-layout-commands.ts +9 -8
- package/src/core/schema/text-schema.ts +16 -0
- package/src/core/selection/mapping.ts +33 -72
- package/src/core/state/editor-state.ts +96 -189
- package/src/index.ts +23 -4
- package/src/io/chart-preview-resolver.ts +1 -1
- package/src/io/docx-session.ts +36 -4795
- package/src/io/export/build-app-properties-xml.ts +1 -1
- package/src/io/export/serialize-comments.ts +1 -1
- package/src/io/export/serialize-headers-footers.ts +6 -1
- package/src/io/export/serialize-main-document.ts +45 -0
- package/src/io/export/serialize-run-formatting.ts +17 -2
- package/src/io/export/twip.ts +1 -1
- package/src/io/normalize/normalize-text.ts +27 -20
- package/src/io/ooxml/chart/parse-series.ts +1 -1
- package/src/io/ooxml/chart/resolve-color.ts +2 -2
- package/src/io/ooxml/chart/types.ts +1 -1
- package/src/io/ooxml/classify-embedding.ts +83 -33
- package/src/io/ooxml/parse-fill.ts +1 -1
- package/src/io/ooxml/parse-main-document.ts +71 -1
- package/src/io/ooxml/parse-object.ts +14 -10
- package/src/io/ooxml/parse-run-formatting.ts +47 -1
- package/src/io/ooxml/property-grab-bag.ts +2 -2
- package/src/io/ooxml/units.ts +11 -0
- package/src/io/ooxml/workflow-payload.ts +282 -7
- package/src/model/anchor.ts +85 -0
- package/src/model/canonical-document.ts +351 -15
- package/src/model/chart-types.ts +1 -1
- package/src/model/layout/index.ts +83 -0
- package/src/model/layout/page-graph-types.ts +181 -0
- package/src/model/layout/page-layout-snapshot.ts +105 -0
- package/src/model/layout/resolved-layout-types.ts +47 -0
- package/src/model/layout/runtime-page-graph-types.ts +102 -0
- package/src/model/paragraph-scope-ids.ts +72 -0
- package/src/model/review/comment-types.ts +112 -0
- package/src/model/review/index.ts +2 -0
- package/src/model/review/revision-types.ts +215 -0
- package/src/model/snapshot.ts +32 -0
- package/src/review/store/comment-store.ts +21 -47
- package/src/review/store/revision-types.ts +40 -198
- package/src/runtime/collab/base-doc-fingerprint.ts +6 -1
- package/src/runtime/collab/runtime-collab-sync.ts +13 -3
- package/src/runtime/collab-session.ts +1 -1
- package/src/runtime/debug/build-debug-inspector-snapshot.ts +686 -0
- package/src/runtime/debug/event-ring-buffer.ts +64 -0
- package/src/runtime/debug/probability-sampler.ts +18 -0
- package/src/runtime/debug/runtime-debug-facet.ts +67 -0
- package/src/runtime/debug/stage-tokens.ts +31 -0
- package/src/runtime/debug/telemetry-bus.ts +271 -0
- package/src/runtime/debug/types.ts +275 -0
- package/src/runtime/debug/wrap-ref-for-telemetry.ts +118 -0
- package/src/runtime/document-layout.ts +8 -6
- package/src/runtime/document-runtime.ts +843 -1141
- package/src/runtime/document-search.ts +1 -1
- package/src/runtime/edit-ops/index.ts +1 -1
- package/src/runtime/external-send-runtime.ts +1 -1
- package/src/runtime/formatting/document-lookup.ts +235 -0
- package/src/runtime/formatting/field/registry.ts +41 -0
- package/src/runtime/{field-resolver.ts → formatting/field/resolver.ts} +27 -2
- package/src/runtime/formatting/font-resolution.ts +83 -0
- package/src/runtime/formatting/formatting-context.ts +903 -0
- package/src/runtime/formatting/formatting-types.ts +157 -0
- package/src/runtime/{hyperlink-color-resolver.ts → formatting/hyperlink-color.ts} +2 -2
- package/src/runtime/formatting/index.ts +125 -0
- package/src/runtime/{resolved-numbering-geometry.ts → formatting/numbering/geometry.ts} +1 -1
- package/src/runtime/{numbering-prefix.ts → formatting/numbering/prefix.ts} +170 -3
- package/src/runtime/formatting/paragraph-style-resolver.ts +92 -0
- package/src/runtime/formatting/projector.ts +75 -0
- package/src/runtime/formatting/resolve-effective.ts +407 -0
- package/src/runtime/formatting/revision-display.ts +105 -0
- package/src/runtime/{paragraph-style-resolver.ts → formatting/style-cascade.ts} +84 -141
- package/src/runtime/{table-style-resolver.ts → formatting/table-style-resolver.ts} +1 -1
- package/src/runtime/formatting/telemetry-bridge.ts +106 -0
- package/src/runtime/{theme-color-resolver.ts → formatting/theme-color.ts} +2 -30
- package/src/runtime/geometry/caret-geometry.ts +164 -0
- package/src/runtime/geometry/geometry-facet.ts +364 -0
- package/src/runtime/geometry/geometry-types.ts +256 -0
- package/src/runtime/geometry/hit-test.ts +125 -0
- package/src/runtime/geometry/index.ts +71 -0
- package/src/runtime/geometry/inert-geometry-facet.ts +43 -0
- package/src/runtime/geometry/invalidation.ts +35 -0
- package/src/runtime/geometry/object-handles.ts +77 -0
- package/src/runtime/geometry/overlay-rects.ts +85 -0
- package/src/runtime/geometry/project-anchors.ts +100 -0
- package/src/runtime/geometry/project-fragments.ts +216 -0
- package/src/runtime/geometry/projector.ts +129 -0
- package/src/runtime/geometry/replacement-envelope.ts +130 -0
- package/src/runtime/geometry/viewport.ts +218 -0
- package/src/runtime/layout/compat-input-ledger.ts +211 -0
- package/src/runtime/layout/index.ts +6 -1
- package/src/runtime/layout/inert-layout-facet.ts +12 -7
- package/src/runtime/layout/layout-engine-instance.ts +189 -11
- package/src/runtime/layout/layout-engine-version.ts +450 -1
- package/src/runtime/layout/layout-facet-types.ts +60 -0
- package/src/runtime/layout/layout-measurement-provider.ts +13 -0
- package/src/runtime/layout/measurement-backend-canvas.ts +14 -2
- package/src/runtime/layout/measurement-backend-empirical.ts +23 -4
- package/src/runtime/layout/page-graph.ts +62 -209
- package/src/runtime/layout/page-story-resolver.ts +7 -12
- package/src/runtime/layout/paginated-layout-engine.ts +186 -11
- package/src/runtime/layout/project-block-fragments.ts +11 -0
- package/src/runtime/layout/projector.ts +90 -0
- package/src/runtime/layout/public-facet.ts +187 -442
- package/src/runtime/layout/resolved-formatting-state.ts +158 -26
- package/src/runtime/layout/table-render-plan.ts +1 -1
- package/src/runtime/prerender/cache-envelope.ts +6 -1
- package/src/runtime/prerender/prerender-document.ts +18 -23
- package/src/runtime/render/decoration-resolver.ts +1 -1
- package/src/runtime/render/render-frame-types.ts +20 -0
- package/src/runtime/render/render-kernel.ts +94 -25
- package/src/runtime/scopes/_formatting-seam.ts +262 -0
- package/src/runtime/scopes/_scope-dependencies.ts +49 -0
- package/src/runtime/scopes/action-validation.ts +356 -0
- package/src/runtime/scopes/attach-explanation.ts +102 -0
- package/src/runtime/scopes/audit-bundle.ts +71 -0
- package/src/runtime/scopes/compile-scope-bundle.ts +163 -0
- package/src/runtime/scopes/compile-scope.ts +262 -0
- package/src/runtime/scopes/compiler-service.ts +431 -0
- package/src/runtime/scopes/create-issue.ts +107 -0
- package/src/runtime/scopes/enumerate-scopes.ts +543 -0
- package/src/runtime/scopes/evidence.ts +233 -0
- package/src/runtime/scopes/index.ts +150 -0
- package/src/runtime/scopes/position-map.ts +214 -0
- package/src/runtime/scopes/preservation-boundary.ts +91 -0
- package/src/runtime/scopes/projector.ts +49 -0
- package/src/runtime/scopes/replaceability.ts +87 -0
- package/src/runtime/scopes/replacement/apply.ts +228 -0
- package/src/runtime/scopes/replacement/compile.ts +59 -0
- package/src/runtime/scopes/replacement/propose.ts +42 -0
- package/src/runtime/scopes/resolve-reference.ts +347 -0
- package/src/runtime/scopes/review-bundle.ts +141 -0
- package/src/runtime/scopes/scope-kinds/_paragraph-text.ts +57 -0
- package/src/runtime/scopes/scope-kinds/_table-text.ts +42 -0
- package/src/runtime/scopes/scope-kinds/comment-thread.ts +59 -0
- package/src/runtime/scopes/scope-kinds/field.ts +65 -0
- package/src/runtime/scopes/scope-kinds/heading.ts +84 -0
- package/src/runtime/scopes/scope-kinds/list-item.ts +77 -0
- package/src/runtime/scopes/scope-kinds/paragraph.ts +182 -0
- package/src/runtime/scopes/scope-kinds/revision.ts +62 -0
- package/src/runtime/scopes/scope-kinds/table-cell.ts +57 -0
- package/src/runtime/scopes/scope-kinds/table-row.ts +61 -0
- package/src/runtime/scopes/scope-kinds/table.ts +55 -0
- package/src/runtime/scopes/scope-range.ts +208 -0
- package/src/runtime/scopes/semantic-scope-types.ts +454 -0
- package/src/runtime/scopes/workflow-overlap.ts +92 -0
- package/src/runtime/selection/index.ts +1 -1
- package/src/runtime/structure-ops/fragment-insert.ts +1 -1
- package/src/runtime/structure-ops/index.ts +1 -1
- package/src/runtime/surface-projection.ts +232 -262
- package/src/runtime/units.ts +4 -2
- package/src/runtime/workflow/coordinator.ts +1348 -0
- package/src/runtime/workflow/derived-scope-resolver.ts +125 -0
- package/src/runtime/workflow/index.ts +25 -0
- package/src/runtime/workflow/markup-mode-policy.ts +98 -0
- package/src/runtime/{workflow-markup.ts → workflow/markup.ts} +6 -6
- package/src/runtime/workflow/metadata-persistence.ts +306 -0
- package/src/runtime/workflow/metadata-writer.ts +123 -0
- package/src/runtime/workflow/overlay-store.ts +690 -0
- package/src/runtime/workflow/projector.ts +127 -0
- package/src/runtime/{query-scopes.ts → workflow/query-scopes.ts} +3 -3
- package/src/runtime/{workflow-rail-segments.ts → workflow/rail/compose.ts} +60 -165
- package/src/runtime/workflow/rail/types.ts +198 -0
- package/src/runtime/workflow/scope-rail-composer.ts +39 -0
- package/src/runtime/{scope-resolver.ts → workflow/scope-resolver.ts} +3 -3
- package/src/runtime/workflow/scope-writer.ts +188 -0
- package/src/runtime/{tamper-gate.ts → workflow/tamper-gate.ts} +1 -1
- package/src/runtime/workflow/visibility-policy.ts +129 -0
- package/src/session/_sync-legacy.ts +66 -0
- package/src/session/export/embedded-reconstitute.ts +104 -0
- package/src/session/export/export-diagnostics.ts +85 -0
- package/src/session/export/export-validation.ts +110 -0
- package/src/session/export/index.ts +34 -0
- package/src/session/export/preservation-reattach.ts +30 -0
- package/src/session/export/serialize-dispatch.ts +165 -0
- package/src/session/export/stateful-export-pipeline.ts +432 -0
- package/src/session/export/stateful-export.ts +684 -0
- package/src/session/import/canonical-assembly.ts +227 -0
- package/src/session/import/diagnostics-session.ts +54 -0
- package/src/session/import/embedded-discovery.ts +225 -0
- package/src/session/import/embedded-offload.ts +337 -0
- package/src/session/import/import-diagnostics.ts +69 -0
- package/src/session/import/loader-types.ts +313 -0
- package/src/session/import/loader.ts +1834 -0
- package/src/session/import/normalize.ts +195 -0
- package/src/session/import/package-parts.ts +217 -0
- package/src/session/import/package-read.ts +195 -0
- package/src/session/import/parse-orchestration.ts +105 -0
- package/src/session/import/part-constants.ts +70 -0
- package/src/session/import/part-discovery.ts +94 -0
- package/src/session/import/preservation-index.ts +46 -0
- package/src/{runtime/read-only-diagnostics-runtime.ts → session/import/read-only-diagnostics.ts} +24 -3
- package/src/session/import/review-import.ts +508 -0
- package/src/session/import/styles-consolidation.ts +281 -0
- package/src/session/import/workflow-scope-import.ts +256 -0
- package/src/session/index.ts +37 -0
- package/src/session/session-state.ts +69 -0
- package/src/session/session.ts +532 -0
- package/src/session/shared/protection.ts +228 -0
- package/src/session/shared/session-utils.ts +82 -0
- package/src/session/types.ts +499 -0
- package/src/shell/chart-snapshots.ts +96 -0
- package/src/shell/media-previews.ts +85 -0
- package/src/shell/overlay-anchor-bridge.ts +53 -0
- package/src/shell/paste-adapter.ts +23 -0
- package/src/shell/ref-commands.ts +1697 -0
- package/src/shell/ref-utilities.ts +48 -0
- package/src/shell/search.ts +51 -0
- package/src/{ui/editor-runtime-boundary.ts → shell/session-bootstrap.ts} +243 -67
- package/src/shell/ui-subscriber-channels.ts +81 -0
- package/src/shell/use-collab-sync.ts +116 -0
- package/src/ui/WordReviewEditor.tsx +496 -2051
- package/src/ui/editor-shell-view.tsx +30 -1
- package/src/ui/editor-surface-controller.tsx +49 -1
- package/src/ui/headless/revision-decoration-model.ts +83 -0
- package/src/{ui-tailwind/chrome → ui/headless}/role-action-sets.ts +1 -1
- package/src/ui/headless/scoped-chrome-policy.ts +2 -2
- package/src/ui/headless/selection-tool-context.ts +1 -1
- package/src/ui/headless/selection-tool-resolver.ts +1 -1
- package/src/ui/runtime-shortcut-dispatch.ts +46 -1
- package/src/ui/ui-controller-factory.ts +221 -0
- package/src/ui-tailwind/chart/ChartSurface.tsx +2 -2
- package/src/ui-tailwind/chart/layout/legend-layout.ts +1 -1
- package/src/ui-tailwind/chart/layout/plot-area.ts +2 -2
- package/src/ui-tailwind/chart/layout/title-layout.ts +1 -1
- package/src/ui-tailwind/chart/render/area.tsx +3 -3
- package/src/ui-tailwind/chart/render/bar-column.tsx +3 -3
- package/src/ui-tailwind/chart/render/bubble.tsx +3 -3
- package/src/ui-tailwind/chart/render/combo.tsx +2 -2
- package/src/ui-tailwind/chart/render/data-labels.tsx +2 -2
- package/src/ui-tailwind/chart/render/font-metrics.ts +2 -2
- package/src/ui-tailwind/chart/render/line.tsx +3 -3
- package/src/ui-tailwind/chart/render/pie.tsx +6 -6
- package/src/ui-tailwind/chart/render/scatter.tsx +3 -3
- package/src/ui-tailwind/chart/render/svg-primitives.ts +3 -3
- package/src/ui-tailwind/chart/render/unsupported.tsx +2 -2
- package/src/ui-tailwind/chrome/build-context-menu-entries.ts +88 -0
- package/src/ui-tailwind/chrome/chrome-preset-toolbar.tsx +1 -1
- package/src/ui-tailwind/chrome/collab-send-to-supplier-button.tsx +1 -1
- package/src/ui-tailwind/chrome/collab-tamper-banner.tsx +1 -1
- package/src/ui-tailwind/chrome/collab-top-nav-container.tsx +1 -1
- package/src/ui-tailwind/chrome/editor-action-registry.ts +553 -0
- package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +182 -0
- package/src/ui-tailwind/chrome/local-surface-arbiter.ts +534 -0
- package/src/ui-tailwind/chrome/resolve-target-kind.ts +226 -0
- package/src/ui-tailwind/chrome/tw-alert-banner.tsx +38 -4
- package/src/ui-tailwind/chrome/tw-context-band.tsx +125 -0
- package/src/ui-tailwind/chrome/tw-context-menu-portal.tsx +248 -0
- package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +42 -1
- package/src/ui-tailwind/chrome/tw-selection-anchor-resolver.ts +8 -7
- package/src/ui-tailwind/chrome/tw-selection-tool-blocked.tsx +38 -4
- package/src/ui-tailwind/chrome/tw-selection-tool-comment.tsx +104 -6
- package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +66 -7
- package/src/ui-tailwind/chrome/tw-selection-tool-workflow.tsx +54 -8
- package/src/ui-tailwind/chrome/tw-shortcut-hint.tsx +7 -1
- package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +33 -0
- package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +78 -1
- package/src/ui-tailwind/chrome/tw-table-grip-layer.tsx +16 -8
- package/src/ui-tailwind/chrome/tw-workspace-chrome-host.tsx +276 -0
- package/src/ui-tailwind/chrome/use-context-menu-controller.ts +201 -0
- package/src/ui-tailwind/chrome-overlay/chrome-overlay-projector.ts +1 -1
- package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +22 -4
- package/src/ui-tailwind/chrome-overlay/tw-comment-balloon-layer.tsx +1 -1
- package/src/ui-tailwind/chrome-overlay/tw-locked-block-layer.tsx +1 -1
- package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +11 -5
- package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +197 -3
- package/src/ui-tailwind/chrome-overlay/tw-revision-margin-bar-layer.tsx +1 -1
- package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +35 -6
- package/src/ui-tailwind/chrome-overlay/tw-scope-rail-layer.tsx +24 -16
- package/src/ui-tailwind/chrome-overlay/tw-table-continuation-header.tsx +1 -1
- package/src/ui-tailwind/debug/README.md +57 -0
- package/src/ui-tailwind/debug/index.ts +3 -0
- package/src/ui-tailwind/debug/tw-debug-overlay.tsx +186 -0
- package/src/ui-tailwind/debug/tw-debug-presentation.tsx +80 -0
- package/src/ui-tailwind/debug/tw-debug-top-bar.tsx +83 -0
- package/src/ui-tailwind/editor-surface/chart-node-view.tsx +2 -2
- package/src/ui-tailwind/editor-surface/float-wrap-resolver.ts +1 -1
- package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +135 -10
- package/src/ui-tailwind/editor-surface/pm-decorations.ts +40 -13
- package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +1 -1
- package/src/ui-tailwind/editor-surface/pm-schema.ts +1 -1
- package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +3 -3
- package/src/ui-tailwind/editor-surface/predicted-tag-preflight.ts +1 -1
- package/src/ui-tailwind/editor-surface/remote-cursor-plugin.ts +2 -2
- package/src/ui-tailwind/editor-surface/scroll-anchor.ts +91 -9
- package/src/ui-tailwind/editor-surface/shape-renderer.ts +1 -1
- package/src/ui-tailwind/editor-surface/surface-layer.ts +1 -1
- package/src/ui-tailwind/editor-surface/tw-opaque-block.tsx +1 -1
- package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +23 -6
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +132 -22
- package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +1 -1
- package/src/ui-tailwind/index.ts +0 -5
- package/src/ui-tailwind/overlay-anchor-bridge-context.tsx +33 -0
- package/src/ui-tailwind/page-stack/floating-image-overlay-model.ts +66 -29
- package/src/ui-tailwind/page-stack/tw-floating-image-layer.tsx +25 -2
- package/src/ui-tailwind/review/comment-markdown-renderer.tsx +15 -0
- package/src/ui-tailwind/review/tw-review-rail.tsx +92 -4
- package/src/ui-tailwind/review/tw-workflow-tab.tsx +1 -1
- package/src/ui-tailwind/review-workspace/page-chrome.ts +210 -0
- package/src/ui-tailwind/review-workspace/page-shell-metrics.ts +101 -0
- package/src/ui-tailwind/review-workspace/paragraph-layout.ts +115 -0
- package/src/ui-tailwind/review-workspace/selection-toolbar-placement.ts +97 -0
- package/src/ui-tailwind/review-workspace/tw-review-workspace-navigator.tsx +130 -0
- package/src/ui-tailwind/review-workspace/tw-review-workspace-page-toolbar.tsx +240 -0
- package/src/ui-tailwind/review-workspace/tw-review-workspace-rail.tsx +59 -0
- package/src/ui-tailwind/review-workspace/types.ts +408 -0
- package/src/ui-tailwind/review-workspace/use-chrome-policy.ts +104 -0
- package/src/ui-tailwind/review-workspace/use-derived-view-state.ts +151 -0
- package/src/ui-tailwind/review-workspace/use-diagnostics-signal.ts +70 -0
- package/src/ui-tailwind/review-workspace/use-grabbed-segment-offsets.ts +40 -0
- package/src/ui-tailwind/review-workspace/use-layout-facet-render-signal.ts +55 -0
- package/src/ui-tailwind/review-workspace/use-page-markers.ts +130 -0
- package/src/ui-tailwind/review-workspace/use-pm-surface-capture.ts +60 -0
- package/src/ui-tailwind/review-workspace/use-review-rail-state.ts +63 -0
- package/src/ui-tailwind/review-workspace/use-scope-card-state.ts +170 -0
- package/src/ui-tailwind/review-workspace/use-scroll-root-capture.ts +28 -0
- package/src/ui-tailwind/review-workspace/use-selection-toolbar-placement.ts +113 -0
- package/src/ui-tailwind/review-workspace/use-shell-selection-anchor-bridge.ts +120 -0
- package/src/ui-tailwind/review-workspace/use-status-bar-page-facts.ts +55 -0
- package/src/ui-tailwind/review-workspace/use-viewport-dimensions.ts +43 -0
- package/src/ui-tailwind/review-workspace/use-workspace-arbiter.ts +25 -0
- package/src/ui-tailwind/review-workspace/use-workspace-composition.ts +86 -0
- package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +150 -0
- package/src/ui-tailwind/theme/editor-theme.css +25 -0
- package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +2 -2
- package/src/ui-tailwind/toolbar/tw-toolbar.tsx +61 -98
- package/src/ui-tailwind/tw-review-workspace.tsx +521 -1802
- package/src/ui-tailwind/ui-api-context.tsx +43 -0
- package/src/ui-tailwind/ui-shell-channels-context.tsx +49 -0
- package/src/validation/compatibility-engine.ts +6 -6
- package/src/runtime/styles-cascade.ts +0 -33
- package/src/ui-tailwind/chrome/tw-mode-dock.tsx +0 -85
- /package/src/runtime/{page-number-format.ts → formatting/field/page-number-format.ts} +0 -0
- /package/src/runtime/{ai-action-policy.ts → workflow/ai-action-policy.ts} +0 -0
- /package/src/runtime/{scope-tag-registry.ts → workflow/scope-tag-registry.ts} +0 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 02 · layout data shapes used across api / runtime / session.
|
|
3
|
+
*
|
|
4
|
+
* Pass 2 of the L04/L02 `src/model/layout/` seam (see
|
|
5
|
+
* `docs/plans/cross-layer-coord-04.md §1.12`). Previously these three
|
|
6
|
+
* types lived in `src/api/public-types.ts`; relocating them here lets
|
|
7
|
+
* the runtime-owned layout graph (`RuntimePageGraph`) reference them
|
|
8
|
+
* from a location that does not forbid transit by session / stateless
|
|
9
|
+
* services. `src/api/public-types.ts` continues to re-export these
|
|
10
|
+
* shapes so every consumer's import path remains `@beyondwork/...api`.
|
|
11
|
+
*
|
|
12
|
+
* These are pure data: no methods, no higher-layer imports. The
|
|
13
|
+
* acceptance rule at `src/model/layout/index.ts` applies.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Runtime-derived description of page layout, projected from
|
|
18
|
+
* `CanonicalDocument` `SectionProperties` + ambient defaults.
|
|
19
|
+
*/
|
|
20
|
+
export interface PageLayoutSnapshot {
|
|
21
|
+
sectionIndex: number;
|
|
22
|
+
sectionType?: "continuous" | "nextPage" | "evenPage" | "oddPage" | "nextColumn";
|
|
23
|
+
pageWidth: number;
|
|
24
|
+
pageHeight: number;
|
|
25
|
+
marginTop: number;
|
|
26
|
+
marginBottom: number;
|
|
27
|
+
marginLeft: number;
|
|
28
|
+
marginRight: number;
|
|
29
|
+
headerMargin: number;
|
|
30
|
+
footerMargin: number;
|
|
31
|
+
gutter: number;
|
|
32
|
+
orientation: "portrait" | "landscape";
|
|
33
|
+
columns: number;
|
|
34
|
+
differentFirstPage: boolean;
|
|
35
|
+
differentOddEvenPages: boolean;
|
|
36
|
+
pageNumbering?: {
|
|
37
|
+
format?: string;
|
|
38
|
+
start?: number;
|
|
39
|
+
chapterStyle?: string;
|
|
40
|
+
chapterSeparator?: string;
|
|
41
|
+
};
|
|
42
|
+
lineNumbering?: {
|
|
43
|
+
countBy?: number;
|
|
44
|
+
start?: number;
|
|
45
|
+
distance?: number;
|
|
46
|
+
restart?: "newPage" | "newSection" | "continuous";
|
|
47
|
+
};
|
|
48
|
+
pageBorders?: {
|
|
49
|
+
top?: { value?: string; size?: number; space?: number; color?: string };
|
|
50
|
+
left?: { value?: string; size?: number; space?: number; color?: string };
|
|
51
|
+
bottom?: { value?: string; size?: number; space?: number; color?: string };
|
|
52
|
+
right?: { value?: string; size?: number; space?: number; color?: string };
|
|
53
|
+
offsetFrom?: "page" | "text";
|
|
54
|
+
display?: "allPages" | "firstPage" | "notFirstPage";
|
|
55
|
+
zOrder?: "front" | "back";
|
|
56
|
+
};
|
|
57
|
+
documentGrid?: {
|
|
58
|
+
type?: "default" | "lines" | "linesAndChars" | "snapToChars";
|
|
59
|
+
linePitch?: number;
|
|
60
|
+
charSpace?: number;
|
|
61
|
+
};
|
|
62
|
+
columnDefinitions: Array<{ width: number; space?: number }>;
|
|
63
|
+
equalWidthColumns: boolean;
|
|
64
|
+
columnSeparator: boolean;
|
|
65
|
+
headerVariants: Array<{ variant: "default" | "first" | "even"; relationshipId: string }>;
|
|
66
|
+
footerVariants: Array<{ variant: "default" | "first" | "even"; relationshipId: string }>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Identifies which story / surface a read or edit addresses.
|
|
71
|
+
*/
|
|
72
|
+
export type EditorStoryTarget =
|
|
73
|
+
| { kind: "main" }
|
|
74
|
+
| {
|
|
75
|
+
kind: "header";
|
|
76
|
+
relationshipId: string;
|
|
77
|
+
variant: "default" | "first" | "even";
|
|
78
|
+
sectionIndex?: number;
|
|
79
|
+
}
|
|
80
|
+
| {
|
|
81
|
+
kind: "footer";
|
|
82
|
+
relationshipId: string;
|
|
83
|
+
variant: "default" | "first" | "even";
|
|
84
|
+
sectionIndex?: number;
|
|
85
|
+
}
|
|
86
|
+
| { kind: "footnote"; noteId: string }
|
|
87
|
+
| { kind: "endnote"; noteId: string };
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Runtime-derived descriptor for a single logical page.
|
|
91
|
+
*/
|
|
92
|
+
export interface DocumentPageSnapshot {
|
|
93
|
+
/** Zero-based page index within the whole document. */
|
|
94
|
+
pageIndex: number;
|
|
95
|
+
/** Section that owns this page (zero-based). */
|
|
96
|
+
sectionIndex: number;
|
|
97
|
+
/** Zero-based page index within its owning section. */
|
|
98
|
+
pageInSection: number;
|
|
99
|
+
/** Estimated character offset where the page begins in the main story. */
|
|
100
|
+
startOffset: number;
|
|
101
|
+
/** Estimated character offset where the page ends in the main story. */
|
|
102
|
+
endOffset: number;
|
|
103
|
+
/** Page layout properties inherited from the section. */
|
|
104
|
+
layout: PageLayoutSnapshot;
|
|
105
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 02 · resolved-layout data shapes.
|
|
3
|
+
*
|
|
4
|
+
* Pass 2 (2026-04-22) — these two types moved out of
|
|
5
|
+
* `src/runtime/layout/page-story-resolver.ts` and
|
|
6
|
+
* `src/runtime/document-layout.ts` respectively. Both are pure data
|
|
7
|
+
* shapes: no methods, no runtime-only imports. Living in the model
|
|
8
|
+
* tree lets `RuntimePageGraph` (next step) live here as well, which
|
|
9
|
+
* in turn lets `CacheEnvelope` drop its transit through
|
|
10
|
+
* `src/runtime/**` (per `docs/plans/cross-layer-coord-04.md §1.12`
|
|
11
|
+
* and Layer 01's §1 ask).
|
|
12
|
+
*
|
|
13
|
+
* The resolver function and section builder remain in their runtime
|
|
14
|
+
* homes; only the type definitions move, and those files continue to
|
|
15
|
+
* re-export them so existing consumer imports remain stable.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { SectionProperties } from "../canonical-document.ts";
|
|
19
|
+
import type { EditorStoryTarget } from "./page-layout-snapshot.ts";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Per-page story resolution — which header/footer variant applies on
|
|
23
|
+
* this page, and what the effective page number is.
|
|
24
|
+
*/
|
|
25
|
+
export interface ResolvedPageStories {
|
|
26
|
+
/** Header story target for this page, if any. */
|
|
27
|
+
header?: EditorStoryTarget;
|
|
28
|
+
/** Footer story target for this page, if any. */
|
|
29
|
+
footer?: EditorStoryTarget;
|
|
30
|
+
/** Whether this is a "first page" in its section (title page behavior). */
|
|
31
|
+
isFirstPage: boolean;
|
|
32
|
+
/** Whether this is an even-numbered page (1-indexed for display). */
|
|
33
|
+
isEvenPage: boolean;
|
|
34
|
+
/** The effective page number for display (accounting for page numbering settings). */
|
|
35
|
+
displayPageNumber: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Resolved section metadata — where a section begins and ends in the
|
|
40
|
+
* flattened offset space, plus the section-properties payload.
|
|
41
|
+
*/
|
|
42
|
+
export interface ResolvedDocumentSection {
|
|
43
|
+
index: number;
|
|
44
|
+
start: number;
|
|
45
|
+
end: number;
|
|
46
|
+
properties?: SectionProperties;
|
|
47
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 02 · runtime page-graph types.
|
|
3
|
+
*
|
|
4
|
+
* Pass 2 (2026-04-22) — `RuntimePageGraph`, `RuntimePageNode`, and
|
|
5
|
+
* `BuildPageGraphInput` moved out of `src/runtime/layout/page-graph.ts`
|
|
6
|
+
* per `docs/plans/cross-layer-coord-04.md §1.12`. Relocation unblocks
|
|
7
|
+
* Layer 01's `CacheEnvelope` transit (the type chain from
|
|
8
|
+
* `CacheEnvelope → RuntimePageGraph → PageLayoutSnapshot / ...` no
|
|
9
|
+
* longer routes through `src/runtime/**`).
|
|
10
|
+
*
|
|
11
|
+
* These are pure data shapes: no methods, no runtime-only imports.
|
|
12
|
+
* The graph's construction functions (`buildPageGraph`, `spliceGraph`)
|
|
13
|
+
* and the `graphRevision` module-local counter remain in the runtime
|
|
14
|
+
* layer (`src/runtime/layout/page-graph.ts`).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type {
|
|
18
|
+
RuntimeBlockFragment,
|
|
19
|
+
RuntimeLineBox,
|
|
20
|
+
RuntimeNoteAllocation,
|
|
21
|
+
RuntimePageAnchor,
|
|
22
|
+
RuntimePageRegions,
|
|
23
|
+
} from "./page-graph-types.ts";
|
|
24
|
+
import type {
|
|
25
|
+
DocumentPageSnapshot,
|
|
26
|
+
PageLayoutSnapshot,
|
|
27
|
+
} from "./page-layout-snapshot.ts";
|
|
28
|
+
import type {
|
|
29
|
+
ResolvedDocumentSection,
|
|
30
|
+
ResolvedPageStories,
|
|
31
|
+
} from "./resolved-layout-types.ts";
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A stable, inspectable representation of the document's paginated
|
|
35
|
+
* structure. Produced by the `PaginatedLayoutEngine` from canonical
|
|
36
|
+
* document state. External read models such as
|
|
37
|
+
* `DocumentNavigationSnapshot` and `PageLayoutSnapshot` are derived
|
|
38
|
+
* from it.
|
|
39
|
+
*/
|
|
40
|
+
export interface RuntimePageGraph {
|
|
41
|
+
/** Monotonically increasing revision stamp. */
|
|
42
|
+
revision: number;
|
|
43
|
+
/** Ordered page nodes. */
|
|
44
|
+
pages: RuntimePageNode[];
|
|
45
|
+
/** Flat list of every block fragment produced during pagination. */
|
|
46
|
+
fragments: RuntimeBlockFragment[];
|
|
47
|
+
/** Per-offset anchor index for O(log n) lookup. */
|
|
48
|
+
anchors: RuntimePageAnchor[];
|
|
49
|
+
/** Section metadata. */
|
|
50
|
+
sections: ResolvedDocumentSection[];
|
|
51
|
+
/** Total non-blank page count. */
|
|
52
|
+
contentPageCount: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface RuntimePageNode {
|
|
56
|
+
pageId: string;
|
|
57
|
+
pageIndex: number;
|
|
58
|
+
sectionIndex: number;
|
|
59
|
+
pageInSection: number;
|
|
60
|
+
startOffset: number;
|
|
61
|
+
endOffset: number;
|
|
62
|
+
layout: PageLayoutSnapshot;
|
|
63
|
+
stories: ResolvedPageStories;
|
|
64
|
+
/** Sub-regions on the page. */
|
|
65
|
+
regions: RuntimePageRegions;
|
|
66
|
+
/** Line boxes rendered in the body region. */
|
|
67
|
+
lineBoxes: RuntimeLineBox[];
|
|
68
|
+
/** Footnote allocations reserved at the bottom of the page. */
|
|
69
|
+
noteAllocations: RuntimeNoteAllocation[];
|
|
70
|
+
/** Whether this page is a blank filler (from even/odd page breaks). */
|
|
71
|
+
isBlankFiller: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface BuildPageGraphInput {
|
|
75
|
+
pages: readonly DocumentPageSnapshot[];
|
|
76
|
+
sections: readonly ResolvedDocumentSection[];
|
|
77
|
+
stories: readonly ResolvedPageStories[];
|
|
78
|
+
/** Optional block fragments pre-computed by pagination; when omitted the
|
|
79
|
+
* graph produces one fragment per page spanning its entire offset range. */
|
|
80
|
+
fragments?: readonly RuntimeBlockFragment[];
|
|
81
|
+
/**
|
|
82
|
+
* Optional block fragments keyed by pageIndex with the `pageId` omitted.
|
|
83
|
+
* `buildPageGraph` fills in the pageId using the graph's fresh revision
|
|
84
|
+
* stamp. Use this when the caller wants to emit per-block fragments but
|
|
85
|
+
* cannot know the pageId in advance.
|
|
86
|
+
*/
|
|
87
|
+
fragmentsByPageIndex?: ReadonlyMap<
|
|
88
|
+
number,
|
|
89
|
+
ReadonlyArray<Omit<RuntimeBlockFragment, "pageId">>
|
|
90
|
+
>;
|
|
91
|
+
/** Optional per-page line boxes. */
|
|
92
|
+
lineBoxes?: ReadonlyMap<string, RuntimeLineBox[]>;
|
|
93
|
+
/** Optional per-page note allocations keyed by graph-assigned pageId. */
|
|
94
|
+
noteAllocations?: ReadonlyMap<string, RuntimeNoteAllocation[]>;
|
|
95
|
+
/**
|
|
96
|
+
* P8 — per-page note allocations keyed by pageIndex (0-based).
|
|
97
|
+
* Parallel to `fragmentsByPageIndex`; `buildPageGraph` uses the index to
|
|
98
|
+
* look up allocations without requiring callers to know the graph-internal
|
|
99
|
+
* `page-${revision}-${index}` pageId in advance.
|
|
100
|
+
*/
|
|
101
|
+
noteAllocationsByPageIndex?: ReadonlyMap<number, RuntimeNoteAllocation[]>;
|
|
102
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paragraph scope-id minting — neutral home shared by L06 (workflow /
|
|
3
|
+
* metadata writer) and L08 (semantic scope enumerator).
|
|
4
|
+
*
|
|
5
|
+
* The enumerator at `src/runtime/scopes/enumerate-scopes.ts` and the
|
|
6
|
+
* derived-scope resolver at `src/runtime/workflow/derived-scope-resolver.ts`
|
|
7
|
+
* must produce identical scopeIds for the same (paragraph, blockIndex)
|
|
8
|
+
* pair — the enumerator mints them for the outward surface, the
|
|
9
|
+
* resolver matches them on the inverse path for metadata writes. Both
|
|
10
|
+
* lanes' files sit in W9-purity-guarded trees, so the logic lives here
|
|
11
|
+
* (in L02's neutral `src/model/` home) to keep both imports legal.
|
|
12
|
+
*
|
|
13
|
+
* Rules are purely shape-derived from `ParagraphNode` — no runtime,
|
|
14
|
+
* no overlay, no layout. Safe to import from anywhere.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { ParagraphNode } from "./canonical-document.ts";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Classify a paragraph as `paragraph` / `heading` / `list-item` using
|
|
21
|
+
* outlineLevel → heading style → numbering precedence. The enumerator
|
|
22
|
+
* and the derived-scope resolver both call this so their scopeIds
|
|
23
|
+
* agree on kind.
|
|
24
|
+
*/
|
|
25
|
+
export function detectParagraphKind(
|
|
26
|
+
paragraph: ParagraphNode,
|
|
27
|
+
): "paragraph" | "heading" | "list-item" {
|
|
28
|
+
if (
|
|
29
|
+
typeof paragraph.outlineLevel === "number" &&
|
|
30
|
+
paragraph.outlineLevel >= 0 &&
|
|
31
|
+
paragraph.outlineLevel <= 8
|
|
32
|
+
) {
|
|
33
|
+
return "heading";
|
|
34
|
+
}
|
|
35
|
+
if (
|
|
36
|
+
typeof paragraph.styleId === "string" &&
|
|
37
|
+
/^heading\d$/i.test(paragraph.styleId)
|
|
38
|
+
) {
|
|
39
|
+
return "heading";
|
|
40
|
+
}
|
|
41
|
+
if (paragraph.numbering) {
|
|
42
|
+
return "list-item";
|
|
43
|
+
}
|
|
44
|
+
return "paragraph";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Mint the derived scopeId for a paragraph. `wordExtensionIds.paraId`
|
|
49
|
+
* (the w14:paraId attribute) wins when present — it's stable across
|
|
50
|
+
* reopen but carries no kind information, so the kind prefix
|
|
51
|
+
* disambiguates. Kind-less bare paraIds would collide with
|
|
52
|
+
* marker-backed overlay scopeIds; the prefix prevents that.
|
|
53
|
+
*/
|
|
54
|
+
export function buildParagraphScopeId(
|
|
55
|
+
kind: "paragraph" | "heading" | "list-item",
|
|
56
|
+
blockIndex: number,
|
|
57
|
+
paragraph: ParagraphNode,
|
|
58
|
+
): string {
|
|
59
|
+
const paraId = paragraph.wordExtensionIds?.paraId;
|
|
60
|
+
if (kind === "heading") {
|
|
61
|
+
if (paraId) return `heading:${paraId}`;
|
|
62
|
+
return `heading:${paragraph.outlineLevel ?? 0}:${blockIndex}`;
|
|
63
|
+
}
|
|
64
|
+
if (kind === "list-item") {
|
|
65
|
+
if (paraId) return `li:${paraId}`;
|
|
66
|
+
const inst = paragraph.numbering?.numberingInstanceId ?? "u";
|
|
67
|
+
const lvl = paragraph.numbering?.level ?? 0;
|
|
68
|
+
return `li:${inst}:${lvl}:${blockIndex}`;
|
|
69
|
+
}
|
|
70
|
+
if (paraId) return `para:${paraId}`;
|
|
71
|
+
return `para:${blockIndex}`;
|
|
72
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure shapes for comment threads on a CanonicalDocument.
|
|
3
|
+
*
|
|
4
|
+
* Like the revision types next door, these describe what exists on the
|
|
5
|
+
* document, not the store operations that mutate them. The review layer's
|
|
6
|
+
* `src/review/store/comment-store.ts` used to own these definitions; it
|
|
7
|
+
* now re-exports from here so the session layer can consume them via the
|
|
8
|
+
* model without crossing the P6 boundary.
|
|
9
|
+
*
|
|
10
|
+
* Store constructors (`createCommentStore`, `upsertCommentThread`, ...),
|
|
11
|
+
* the remap engine, and the sidebar projection all remain in
|
|
12
|
+
* `src/review/store/comment-store.ts` — they are runtime-state operations.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { EditorAnchorProjection } from "../anchor.ts";
|
|
16
|
+
|
|
17
|
+
export type CommentAnchor = EditorAnchorProjection;
|
|
18
|
+
export type CommentAnchorState = "active" | "detached";
|
|
19
|
+
|
|
20
|
+
export interface CommentAnchorSummary {
|
|
21
|
+
anchor: CommentAnchor;
|
|
22
|
+
state: CommentAnchorState;
|
|
23
|
+
range: import("../anchor.ts").DocRange;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface CommentEntry {
|
|
27
|
+
entryId: string;
|
|
28
|
+
authorId: string;
|
|
29
|
+
body: string;
|
|
30
|
+
createdAt: string;
|
|
31
|
+
metadata?: CommentEntryMetadata;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface CommentEntryMetadata {
|
|
35
|
+
ooxmlCommentId?: string;
|
|
36
|
+
paraId?: string;
|
|
37
|
+
parentParaId?: string;
|
|
38
|
+
durableId?: string;
|
|
39
|
+
initials?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface CommentResolution {
|
|
43
|
+
resolvedAt: string;
|
|
44
|
+
resolvedBy: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type CommentThreadStatus = "open" | "resolved" | "detached";
|
|
48
|
+
|
|
49
|
+
export interface CommentThread {
|
|
50
|
+
commentId: string;
|
|
51
|
+
anchor: CommentAnchor;
|
|
52
|
+
status: CommentThreadStatus;
|
|
53
|
+
entries: CommentEntry[];
|
|
54
|
+
createdBy: string;
|
|
55
|
+
createdAt: string;
|
|
56
|
+
resolution?: CommentResolution;
|
|
57
|
+
warningIds: string[];
|
|
58
|
+
metadata?: CommentThreadMetadata;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface CommentThreadMetadata {
|
|
62
|
+
source?: "runtime" | "import";
|
|
63
|
+
rootOoxmlCommentId?: string;
|
|
64
|
+
rootParaId?: string;
|
|
65
|
+
detachedReason?: "incomplete-markers" | "multi-paragraph" | "opaque-region" | "revision-overlap";
|
|
66
|
+
actionabilityNote?: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface CommentStore {
|
|
70
|
+
version: "comment-store/1";
|
|
71
|
+
threads: Record<string, CommentThread>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Pure projection from the canonical-document's loose `CommentThread`
|
|
76
|
+
* shape (src/model/canonical-document.ts — optional entries / createdBy
|
|
77
|
+
* / body fields, status uncorrelated with anchor.kind) to the review-layer
|
|
78
|
+
* strict `CommentThread` shape defined above (required entries + status
|
|
79
|
+
* correlated with a detached anchor).
|
|
80
|
+
*
|
|
81
|
+
* Mirrors the runtime-comment-store `toCommentThread` defaults without
|
|
82
|
+
* importing from core. Session-layer code paths consume this directly so
|
|
83
|
+
* they can produce review-shape threads without reaching into
|
|
84
|
+
* `src/review/store/**`.
|
|
85
|
+
*/
|
|
86
|
+
export function toReviewCommentThread(
|
|
87
|
+
source: import("../canonical-document.ts").CommentThread,
|
|
88
|
+
): CommentThread {
|
|
89
|
+
const status: CommentThreadStatus =
|
|
90
|
+
source.anchor.kind === "detached"
|
|
91
|
+
? "detached"
|
|
92
|
+
: source.status === "resolved"
|
|
93
|
+
? "resolved"
|
|
94
|
+
: "open";
|
|
95
|
+
return {
|
|
96
|
+
commentId: source.commentId,
|
|
97
|
+
anchor: source.anchor,
|
|
98
|
+
status,
|
|
99
|
+
entries: source.entries ?? [],
|
|
100
|
+
createdBy: source.createdBy ?? source.authorId ?? "unknown",
|
|
101
|
+
createdAt: source.createdAt,
|
|
102
|
+
resolution: source.resolution,
|
|
103
|
+
warningIds: [...(source.warningIds ?? [])],
|
|
104
|
+
metadata: source.metadata,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function commentRecordsToReviewThreads(
|
|
109
|
+
comments: Record<string, import("../canonical-document.ts").CommentThread>,
|
|
110
|
+
): CommentThread[] {
|
|
111
|
+
return Object.values(comments).map(toReviewCommentThread);
|
|
112
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure shapes for tracked-change revisions on a CanonicalDocument.
|
|
3
|
+
*
|
|
4
|
+
* Revisions are model-level data (what exists on the document), not
|
|
5
|
+
* runtime state (what the review store does with them). The review
|
|
6
|
+
* layer's store at `src/review/store/revision-types.ts` used to own
|
|
7
|
+
* these types; it now re-exports from here so the session layer (which
|
|
8
|
+
* cannot import from `src/review/**`) can consume the types via the
|
|
9
|
+
* model layer.
|
|
10
|
+
*
|
|
11
|
+
* Anchor-constructor helpers (`createRevisionRangeAnchor`, `remapRevisionAnchor`,
|
|
12
|
+
* etc.) + store-oriented predicates that cross into mapping mechanics
|
|
13
|
+
* remain in review/store. Pure classifiers (`getRevisionActionability`,
|
|
14
|
+
* `isRevisionActionable`, `describeRevisionKind`) live here — they only
|
|
15
|
+
* inspect data.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { EditorAnchorProjection } from "../anchor.ts";
|
|
19
|
+
import type { RevisionStoryTargetRecord } from "../canonical-document.ts";
|
|
20
|
+
|
|
21
|
+
export type RevisionAnchor = EditorAnchorProjection;
|
|
22
|
+
|
|
23
|
+
export type SupportedRevisionKind = "insertion" | "deletion" | "property-change";
|
|
24
|
+
export type PreserveOnlyRevisionKind = "formatting" | "move";
|
|
25
|
+
export type RevisionKind = SupportedRevisionKind | PreserveOnlyRevisionKind;
|
|
26
|
+
|
|
27
|
+
export type RevisionStatus = "active" | "accepted" | "rejected" | "detached";
|
|
28
|
+
export type RevisionActionability = "actionable" | "preserve-only";
|
|
29
|
+
export type RevisionAnchorState = "active" | "detached";
|
|
30
|
+
|
|
31
|
+
export interface PropertyChangeData {
|
|
32
|
+
xmlTag: "pPrChange" | "sectPrChange" | "tblPrChange" | "rPrChange";
|
|
33
|
+
beforeXml: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface MoveData {
|
|
37
|
+
moveId: string;
|
|
38
|
+
direction: "from" | "to";
|
|
39
|
+
linkedRevisionId?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Payload for `w:cellMerge` revisions. `direction` is the `w:vMerge`
|
|
44
|
+
* attribute on the marker:
|
|
45
|
+
* `"rest"` — this cell begins a vertical merge span (restart cell).
|
|
46
|
+
* `"cont"` — this cell continues a vertical merge span.
|
|
47
|
+
*
|
|
48
|
+
* Accept commits `TableCellNode.verticalMerge` to the matching state;
|
|
49
|
+
* reject clears `verticalMerge` to undefined. No row topology changes
|
|
50
|
+
* (mirrors LibreOffice's treatment — vMerge is a rendering property, not
|
|
51
|
+
* a structural mutation).
|
|
52
|
+
*/
|
|
53
|
+
export interface CellMergeData {
|
|
54
|
+
direction: "rest" | "cont";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Ordinal coordinates of a structural table revision within the canonical
|
|
59
|
+
* document tree.
|
|
60
|
+
*
|
|
61
|
+
* Lane 7b row-insertion revisions (`<w:trPr><w:ins/></w:trPr>`) point at an
|
|
62
|
+
* entire row, not a text range — the runtime anchor position alone can't
|
|
63
|
+
* identify which row to remove on reject. This envelope carries the table's
|
|
64
|
+
* ordinal (the Nth `<w:tbl>` in the body) and the row's index within that
|
|
65
|
+
* table, both fixed at parse time. Accept/reject resolves these to a
|
|
66
|
+
* canonical-document `tableBlockIndex` by walking `doc.content.children[]`
|
|
67
|
+
* at action time.
|
|
68
|
+
*/
|
|
69
|
+
export interface TableRevisionCoordinates {
|
|
70
|
+
tableOrdinal: number;
|
|
71
|
+
rowIndex: number;
|
|
72
|
+
/**
|
|
73
|
+
* Cell index within `row.cells[]`. Present on cell-level structural
|
|
74
|
+
* revisions (`cellIns` / `cellDel` / `cellMerge`); `undefined` on
|
|
75
|
+
* row-level records (`row-ins` / `row-del`).
|
|
76
|
+
*/
|
|
77
|
+
cellIndex?: number;
|
|
78
|
+
/**
|
|
79
|
+
* For revisions inside nested tables (a `<w:tbl>` inside a cell), this
|
|
80
|
+
* carries the full ordinal path so `resolveCanonicalTableRow` can
|
|
81
|
+
* tree-walk the canonical document:
|
|
82
|
+
* `[bodyTableOrdinal, nestedTableIndex, ...]`
|
|
83
|
+
* Body-level revisions omit this field and use the flat `tableOrdinal`.
|
|
84
|
+
* Lane 7b Phase Q.
|
|
85
|
+
*/
|
|
86
|
+
tableOrdinalPath?: readonly number[];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface RevisionMetadataEnvelope {
|
|
90
|
+
source: "runtime" | "import";
|
|
91
|
+
storyTarget?: RevisionStoryTargetRecord;
|
|
92
|
+
preserveOnlyReason?: string;
|
|
93
|
+
suggestionId?: string;
|
|
94
|
+
semanticKind?:
|
|
95
|
+
| "insertion"
|
|
96
|
+
| "deletion"
|
|
97
|
+
| "replacement"
|
|
98
|
+
| "formatting-change"
|
|
99
|
+
| "paragraph-property-change"
|
|
100
|
+
| "structural-change"
|
|
101
|
+
| "object-change";
|
|
102
|
+
linkedRevisionIds?: string[];
|
|
103
|
+
predecessorSuggestionId?: string;
|
|
104
|
+
importedRevisionForm?:
|
|
105
|
+
| "run-insertion"
|
|
106
|
+
| "run-deletion"
|
|
107
|
+
| "paragraph-insertion"
|
|
108
|
+
| "paragraph-deletion";
|
|
109
|
+
originalRevisionType?: string;
|
|
110
|
+
ooxmlRevisionId?: string;
|
|
111
|
+
propertyChangeData?: PropertyChangeData;
|
|
112
|
+
moveData?: MoveData;
|
|
113
|
+
cellMergeData?: CellMergeData;
|
|
114
|
+
tableRevisionCoordinates?: TableRevisionCoordinates;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export type PropertyChangeRevision = RevisionRecord & {
|
|
118
|
+
kind: "property-change";
|
|
119
|
+
metadata: RevisionMetadataEnvelope & { propertyChangeData: PropertyChangeData };
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export type MoveRevision = RevisionRecord & {
|
|
123
|
+
kind: "move";
|
|
124
|
+
metadata: RevisionMetadataEnvelope & { moveData: MoveData };
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export interface RevisionRecord {
|
|
128
|
+
revisionId: string;
|
|
129
|
+
kind: RevisionKind;
|
|
130
|
+
anchor: RevisionAnchor;
|
|
131
|
+
authorId: string;
|
|
132
|
+
createdAt: string;
|
|
133
|
+
status: RevisionStatus;
|
|
134
|
+
warningIds: string[];
|
|
135
|
+
metadata: RevisionMetadataEnvelope;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface RevisionAnchorSummary {
|
|
139
|
+
anchor: RevisionAnchor;
|
|
140
|
+
state: RevisionAnchorState;
|
|
141
|
+
range: import("../anchor.ts").DocRange;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function getRevisionActionability(
|
|
145
|
+
revision:
|
|
146
|
+
| RevisionKind
|
|
147
|
+
| Pick<RevisionRecord, "kind" | "metadata">,
|
|
148
|
+
): RevisionActionability {
|
|
149
|
+
// Lane 7b promotions run BEFORE the preserveOnlyReason check on purpose:
|
|
150
|
+
// `createRevisionRecord` injects a default "Imported preserve-only revision."
|
|
151
|
+
// reason for any kind that `getRevisionActionability(kind)` returns as
|
|
152
|
+
// preserve-only (see revision-store.ts), which covers both `kind: "move"`
|
|
153
|
+
// and `kind: "formatting"`. The overrides below flip the default back to
|
|
154
|
+
// actionable for the specific shapes that Lane 7b promoted: cellIns
|
|
155
|
+
// structural-table revisions, and linked-pair move revisions. Do not add a
|
|
156
|
+
// `&& !preserveOnlyReason` guard here — that would re-lock these shapes
|
|
157
|
+
// against the injected default and regress 7b.
|
|
158
|
+
if (
|
|
159
|
+
typeof revision !== "string" &&
|
|
160
|
+
(revision.metadata.originalRevisionType === "cellIns" ||
|
|
161
|
+
revision.metadata.originalRevisionType === "cellDel" ||
|
|
162
|
+
revision.metadata.originalRevisionType === "cellMerge")
|
|
163
|
+
) {
|
|
164
|
+
return "actionable";
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (
|
|
168
|
+
typeof revision !== "string" &&
|
|
169
|
+
revision.kind === "move" &&
|
|
170
|
+
typeof revision.metadata.moveData?.linkedRevisionId === "string" &&
|
|
171
|
+
revision.metadata.moveData.linkedRevisionId.length > 0
|
|
172
|
+
) {
|
|
173
|
+
return "actionable";
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (
|
|
177
|
+
typeof revision !== "string" &&
|
|
178
|
+
typeof revision.metadata.preserveOnlyReason === "string" &&
|
|
179
|
+
revision.metadata.preserveOnlyReason.length > 0
|
|
180
|
+
) {
|
|
181
|
+
return "preserve-only";
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const kind = typeof revision === "string" ? revision : revision.kind;
|
|
185
|
+
switch (kind) {
|
|
186
|
+
case "insertion":
|
|
187
|
+
case "deletion":
|
|
188
|
+
case "property-change":
|
|
189
|
+
return "actionable";
|
|
190
|
+
case "formatting":
|
|
191
|
+
case "move":
|
|
192
|
+
return "preserve-only";
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export function isRevisionActionable(
|
|
197
|
+
record: Pick<RevisionRecord, "kind" | "metadata" | "status">,
|
|
198
|
+
): boolean {
|
|
199
|
+
return getRevisionActionability(record) === "actionable" && record.status === "active";
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export function describeRevisionKind(kind: RevisionKind): string {
|
|
203
|
+
switch (kind) {
|
|
204
|
+
case "insertion":
|
|
205
|
+
return "Insertion";
|
|
206
|
+
case "deletion":
|
|
207
|
+
return "Deletion";
|
|
208
|
+
case "formatting":
|
|
209
|
+
return "Formatting change";
|
|
210
|
+
case "move":
|
|
211
|
+
return "Move";
|
|
212
|
+
case "property-change":
|
|
213
|
+
return "Property change";
|
|
214
|
+
}
|
|
215
|
+
}
|