@beyondwork/docx-react-component 1.0.67 → 1.0.70
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 -932
- 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 -4797
- 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
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
import type {
|
|
16
16
|
CanonicalDocument as CanonicalDocumentEnvelope,
|
|
17
17
|
ColumnProperties,
|
|
18
|
+
MutableCanonicalDocument,
|
|
18
19
|
PageMargins,
|
|
19
20
|
PageNumbering,
|
|
20
21
|
PageSize,
|
|
@@ -128,7 +129,7 @@ export function insertSectionBreak(
|
|
|
128
129
|
breakType: SectionBreakType,
|
|
129
130
|
_context: SectionLayoutCommandContext,
|
|
130
131
|
): SectionLayoutMutationResult {
|
|
131
|
-
const cloned = structuredClone(document) as
|
|
132
|
+
const cloned = structuredClone(document) as MutableCanonicalDocument;
|
|
132
133
|
const surface = snapshot.surface;
|
|
133
134
|
|
|
134
135
|
if (!surface) {
|
|
@@ -168,7 +169,7 @@ export function insertSectionBreakAfterSectionIndex(
|
|
|
168
169
|
breakType: SectionBreakType,
|
|
169
170
|
context: SectionLayoutCommandContext,
|
|
170
171
|
): SectionLayoutMutationResult {
|
|
171
|
-
const cloned = structuredClone(document) as
|
|
172
|
+
const cloned = structuredClone(document) as MutableCanonicalDocument;
|
|
172
173
|
const insertionIndex = findSectionInsertionIndex(cloned, sectionIndex);
|
|
173
174
|
if (insertionIndex < 0) {
|
|
174
175
|
return noopResult(document, createSelectionSnapshot(0, 0));
|
|
@@ -207,7 +208,7 @@ export function deleteSectionBreak(
|
|
|
207
208
|
snapshot: RuntimeRenderSnapshot,
|
|
208
209
|
_context: SectionLayoutCommandContext,
|
|
209
210
|
): SectionLayoutMutationResult {
|
|
210
|
-
const cloned = structuredClone(document) as
|
|
211
|
+
const cloned = structuredClone(document) as MutableCanonicalDocument;
|
|
211
212
|
|
|
212
213
|
const breakIndex = findNearestSectionBreak(cloned, snapshot);
|
|
213
214
|
if (breakIndex < 0) {
|
|
@@ -240,7 +241,7 @@ export function deleteSectionBreakAtSectionIndex(
|
|
|
240
241
|
return noopResult(document, createSelectionSnapshot(0, 0));
|
|
241
242
|
}
|
|
242
243
|
|
|
243
|
-
const cloned = structuredClone(document) as
|
|
244
|
+
const cloned = structuredClone(document) as MutableCanonicalDocument;
|
|
244
245
|
const breakIndex = findSectionBreakNodeIndexForSection(cloned, sectionIndex);
|
|
245
246
|
if (breakIndex < 0) {
|
|
246
247
|
return noopResult(document, createSelectionSnapshot(0, 0));
|
|
@@ -269,7 +270,7 @@ export function updateSectionLayout(
|
|
|
269
270
|
patch: SectionLayoutPatch,
|
|
270
271
|
_context: SectionLayoutCommandContext,
|
|
271
272
|
): SectionLayoutMutationResult {
|
|
272
|
-
const cloned = structuredClone(document) as
|
|
273
|
+
const cloned = structuredClone(document) as MutableCanonicalDocument;
|
|
273
274
|
const surface = snapshot.surface;
|
|
274
275
|
|
|
275
276
|
if (!surface) {
|
|
@@ -317,7 +318,7 @@ export function updateSectionLayoutAtSectionIndex(
|
|
|
317
318
|
patch: SectionLayoutPatch,
|
|
318
319
|
context: SectionLayoutCommandContext,
|
|
319
320
|
): SectionLayoutMutationResult {
|
|
320
|
-
const cloned = structuredClone(document) as
|
|
321
|
+
const cloned = structuredClone(document) as MutableCanonicalDocument;
|
|
321
322
|
const target = resolveSectionPropertiesOwner(cloned, sectionIndex);
|
|
322
323
|
if (!target) {
|
|
323
324
|
return noopResult(document, createSelectionSnapshot(0, 0));
|
|
@@ -355,7 +356,7 @@ export function setSectionPageNumberingAtSectionIndex(
|
|
|
355
356
|
pageNumbering: Partial<PageNumbering> | null,
|
|
356
357
|
context: SectionLayoutCommandContext,
|
|
357
358
|
): SectionLayoutMutationResult {
|
|
358
|
-
const cloned = structuredClone(document) as
|
|
359
|
+
const cloned = structuredClone(document) as MutableCanonicalDocument;
|
|
359
360
|
const target = resolveSectionPropertiesOwner(cloned, sectionIndex);
|
|
360
361
|
if (!target) {
|
|
361
362
|
return noopResult(document, createSelectionSnapshot(0, 0));
|
|
@@ -402,7 +403,7 @@ export function setHeaderFooterLinkAtSectionIndex(
|
|
|
402
403
|
patch: SectionLinkPatch,
|
|
403
404
|
context: SectionLayoutCommandContext,
|
|
404
405
|
): SectionLayoutMutationResult {
|
|
405
|
-
const cloned = structuredClone(document) as
|
|
406
|
+
const cloned = structuredClone(document) as MutableCanonicalDocument;
|
|
406
407
|
const target = resolveSectionPropertiesOwner(cloned, sectionIndex);
|
|
407
408
|
if (!target) {
|
|
408
409
|
return noopResult(document, createSelectionSnapshot(0, 0));
|
|
@@ -11,6 +11,13 @@ import type {
|
|
|
11
11
|
export interface ParagraphProperties {
|
|
12
12
|
styleId?: string;
|
|
13
13
|
numbering?: ParagraphNode["numbering"];
|
|
14
|
+
/**
|
|
15
|
+
* w14:paraId / w14:textId — stable across reopen. Must round-trip
|
|
16
|
+
* through the text-transaction rebuild so paragraph-kind scope ids
|
|
17
|
+
* (see `src/runtime/scopes/enumerate-scopes.ts:204`) survive a text
|
|
18
|
+
* replace. Fix for coord-08 §11 / harness finding B2.
|
|
19
|
+
*/
|
|
20
|
+
wordExtensionIds?: ParagraphNode["wordExtensionIds"];
|
|
14
21
|
}
|
|
15
22
|
|
|
16
23
|
export interface TextStory {
|
|
@@ -451,6 +458,9 @@ export function cloneParagraphProperties(
|
|
|
451
458
|
},
|
|
452
459
|
}
|
|
453
460
|
: {}),
|
|
461
|
+
...(properties.wordExtensionIds
|
|
462
|
+
? { wordExtensionIds: { ...properties.wordExtensionIds } }
|
|
463
|
+
: {}),
|
|
454
464
|
};
|
|
455
465
|
}
|
|
456
466
|
|
|
@@ -553,6 +563,9 @@ function extractParagraphProperties(paragraph: ParagraphNode): ParagraphProperti
|
|
|
553
563
|
},
|
|
554
564
|
}
|
|
555
565
|
: {}),
|
|
566
|
+
...(paragraph.wordExtensionIds
|
|
567
|
+
? { wordExtensionIds: { ...paragraph.wordExtensionIds } }
|
|
568
|
+
: {}),
|
|
556
569
|
};
|
|
557
570
|
}
|
|
558
571
|
|
|
@@ -568,6 +581,9 @@ function createParagraph(properties: ParagraphProperties): ParagraphNode {
|
|
|
568
581
|
},
|
|
569
582
|
}
|
|
570
583
|
: {}),
|
|
584
|
+
...(properties.wordExtensionIds
|
|
585
|
+
? { wordExtensionIds: { ...properties.wordExtensionIds } }
|
|
586
|
+
: {}),
|
|
571
587
|
children: [],
|
|
572
588
|
};
|
|
573
589
|
}
|
|
@@ -1,54 +1,37 @@
|
|
|
1
1
|
import type { EditorStoryTarget } from "../../api/public-types";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* Internal representation of an anchor projection — uses `DocRange` so
|
|
36
|
-
* mapping helpers compose ranges independently of assoc semantics. The
|
|
37
|
-
* public-facing shape lives at `src/api/public-types.ts` (same simple name
|
|
38
|
-
* `EditorAnchorProjection`) and is flat (`{ kind: "range", from, to, assoc }`).
|
|
39
|
-
* Conversion between the two goes through `src/core/selection/anchor-conversion.ts`.
|
|
40
|
-
*/
|
|
41
|
-
export type InternalEditorAnchorProjection = RangeAnchor | NodeAnchor | DetachedAnchor;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @deprecated X3 Phase 5 — prefer `InternalEditorAnchorProjection` to avoid
|
|
45
|
-
* name-collision with the public `EditorAnchorProjection` from
|
|
46
|
-
* `src/api/public-types.ts`. Internal call-sites have migrated (via
|
|
47
|
-
* `import type { EditorAnchorProjection as InternalEditorAnchorProjection }`
|
|
48
|
-
* aliasing in `document-runtime.ts`). This alias stays for one release cycle
|
|
49
|
-
* so third-party internal consumers don't break. Remove in v2.1+.
|
|
50
|
-
*/
|
|
51
|
-
export type EditorAnchorProjection = InternalEditorAnchorProjection;
|
|
2
|
+
import {
|
|
3
|
+
createDetachedAnchor,
|
|
4
|
+
DEFAULT_BOUNDARY_ASSOC,
|
|
5
|
+
normalizeRange,
|
|
6
|
+
type Assoc,
|
|
7
|
+
type BoundaryAssoc,
|
|
8
|
+
type DetachedAnchor,
|
|
9
|
+
type DocRange,
|
|
10
|
+
type EditorAnchorProjection,
|
|
11
|
+
type InternalEditorAnchorProjection,
|
|
12
|
+
type NodeAnchor,
|
|
13
|
+
type Position,
|
|
14
|
+
type RangeAnchor,
|
|
15
|
+
} from "../../model/anchor.ts";
|
|
16
|
+
|
|
17
|
+
// Anchor data shapes + pure factories live at `src/model/anchor.ts`.
|
|
18
|
+
// Re-exported here for back-compat with every site that already imports
|
|
19
|
+
// anchor types / createDetachedAnchor from `core/selection/mapping`. The
|
|
20
|
+
// mapping machinery below operates on them.
|
|
21
|
+
export {
|
|
22
|
+
createDetachedAnchor,
|
|
23
|
+
DEFAULT_BOUNDARY_ASSOC,
|
|
24
|
+
normalizeRange,
|
|
25
|
+
type Assoc,
|
|
26
|
+
type BoundaryAssoc,
|
|
27
|
+
type DetachedAnchor,
|
|
28
|
+
type DocRange,
|
|
29
|
+
type EditorAnchorProjection,
|
|
30
|
+
type InternalEditorAnchorProjection,
|
|
31
|
+
type NodeAnchor,
|
|
32
|
+
type Position,
|
|
33
|
+
type RangeAnchor,
|
|
34
|
+
};
|
|
52
35
|
|
|
53
36
|
export interface MappingStep {
|
|
54
37
|
from: Position;
|
|
@@ -78,11 +61,6 @@ export interface TransactionMapping {
|
|
|
78
61
|
};
|
|
79
62
|
}
|
|
80
63
|
|
|
81
|
-
export const DEFAULT_BOUNDARY_ASSOC: BoundaryAssoc = {
|
|
82
|
-
start: 1,
|
|
83
|
-
end: -1,
|
|
84
|
-
};
|
|
85
|
-
|
|
86
64
|
export function createRangeAnchor(
|
|
87
65
|
from: Position,
|
|
88
66
|
to = from,
|
|
@@ -103,29 +81,12 @@ export function createNodeAnchor(at: Position, assoc: Assoc = 1): NodeAnchor {
|
|
|
103
81
|
};
|
|
104
82
|
}
|
|
105
83
|
|
|
106
|
-
export function createDetachedAnchor(
|
|
107
|
-
lastKnownRange: DocRange,
|
|
108
|
-
reason: DetachedAnchor["reason"],
|
|
109
|
-
): DetachedAnchor {
|
|
110
|
-
return {
|
|
111
|
-
kind: "detached",
|
|
112
|
-
lastKnownRange: normalizeRange(lastKnownRange),
|
|
113
|
-
reason,
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
84
|
export function createEmptyMapping(): TransactionMapping {
|
|
118
85
|
return {
|
|
119
86
|
steps: [],
|
|
120
87
|
};
|
|
121
88
|
}
|
|
122
89
|
|
|
123
|
-
export function normalizeRange(range: DocRange): DocRange {
|
|
124
|
-
return range.from <= range.to
|
|
125
|
-
? { from: range.from, to: range.to }
|
|
126
|
-
: { from: range.to, to: range.from };
|
|
127
|
-
}
|
|
128
|
-
|
|
129
90
|
export function getEffectiveRange(anchor: EditorAnchorProjection): DocRange {
|
|
130
91
|
if (anchor.kind === "range") {
|
|
131
92
|
return anchor.range;
|
|
@@ -3,9 +3,14 @@ import {
|
|
|
3
3
|
createDetachedAnchor,
|
|
4
4
|
createNodeAnchor,
|
|
5
5
|
createRangeAnchor,
|
|
6
|
-
type EditorAnchorProjection,
|
|
6
|
+
type EditorAnchorProjection as InternalEditorAnchorProjection,
|
|
7
7
|
} from "../selection/mapping.ts";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
createPublicDetachedAnchor,
|
|
10
|
+
createPublicNodeAnchor,
|
|
11
|
+
createPublicRangeAnchor,
|
|
12
|
+
} from "../selection/anchor-conversion.ts";
|
|
13
|
+
import type { EditorAnchorProjection } from "../../api/public-types.ts";
|
|
9
14
|
import {
|
|
10
15
|
assertPersistedEditorSnapshot as assertModelPersistedEditorSnapshot,
|
|
11
16
|
createPersistedEditorSnapshot as createModelPersistedEditorSnapshot,
|
|
@@ -15,6 +20,9 @@ import {
|
|
|
15
20
|
} from "../../model/snapshot.ts";
|
|
16
21
|
import {
|
|
17
22
|
assertCanonicalDocument,
|
|
23
|
+
createCanonicalDocumentId,
|
|
24
|
+
createEmptyCanonicalDocument as createEmptyCanonicalDocumentModel,
|
|
25
|
+
repairCanonicalDocumentEnvelope,
|
|
18
26
|
type CanonicalDocument,
|
|
19
27
|
type CommentEntry as ModelCommentEntry,
|
|
20
28
|
type CommentResolution as ModelCommentResolution,
|
|
@@ -23,75 +31,53 @@ import {
|
|
|
23
31
|
type RevisionRecord as ModelRevisionRecord,
|
|
24
32
|
} from "../../model/canonical-document.ts";
|
|
25
33
|
|
|
34
|
+
export { createCanonicalDocumentId };
|
|
35
|
+
|
|
26
36
|
export type RuntimePhase = "loading" | "ready" | "error";
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export type CompatibilityFeatureClass =
|
|
74
|
-
| "supported-roundtrip"
|
|
75
|
-
| "preserve-only"
|
|
76
|
-
| "unsupported-fatal";
|
|
77
|
-
|
|
78
|
-
export interface CompatibilityFeatureEntry {
|
|
79
|
-
featureEntryId: string;
|
|
80
|
-
featureKey: string;
|
|
81
|
-
featureClass: CompatibilityFeatureClass;
|
|
82
|
-
message: string;
|
|
83
|
-
affectedAnchor?: EditorAnchorProjection;
|
|
84
|
-
details?: Record<string, unknown>;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export interface CompatibilityReport {
|
|
88
|
-
reportVersion: "compatibility-report/1";
|
|
89
|
-
generatedAt: string;
|
|
90
|
-
blockExport: boolean;
|
|
91
|
-
featureEntries: CompatibilityFeatureEntry[];
|
|
92
|
-
warnings: EditorWarning[];
|
|
93
|
-
errors: EditorError[];
|
|
94
|
-
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Review-record types — `EditorWarning`, `EditorError`,
|
|
40
|
+
* `CompatibilityFeatureEntry`, `CompatibilityReport`,
|
|
41
|
+
* `CompatibilityFeatureClass`, and the code enums — are re-exports of
|
|
42
|
+
* the public shapes in `src/api/public-types.ts`. Until 2026-04-22 the
|
|
43
|
+
* runtime held distinct `Internal*`-flavored copies that differed from
|
|
44
|
+
* the public types *only* on `affectedAnchor` (nested
|
|
45
|
+
* `{range: {from, to}}` vs flat `{from, to}`). That drift forced
|
|
46
|
+
* `src/api/diagnostic-conversion.ts` at every boundary between the
|
|
47
|
+
* runtime and the public API.
|
|
48
|
+
*
|
|
49
|
+
* Resolution: flatten at the **record-attachment boundary**. Internal
|
|
50
|
+
* code that constructs records with nested anchors now wraps with
|
|
51
|
+
* `createPublicRangeAnchor` / `toPublicAnchorProjection` at the
|
|
52
|
+
* construction site — the resulting record carries a flat anchor
|
|
53
|
+
* end-to-end. The nested shape remains the authoritative mapping-
|
|
54
|
+
* composition format inside `src/core/selection/mapping.ts`; the flat
|
|
55
|
+
* shape is the record-attachment format. `src/core/selection/anchor-
|
|
56
|
+
* conversion.ts` is kept as the named seam; `src/api/diagnostic-
|
|
57
|
+
* conversion.ts` was deleted because the record-type conversion
|
|
58
|
+
* became identity.
|
|
59
|
+
*
|
|
60
|
+
* See `docs/plans/cross-layer-coord-02.md §8`.
|
|
61
|
+
*/
|
|
62
|
+
import type {
|
|
63
|
+
EditorWarning,
|
|
64
|
+
EditorError,
|
|
65
|
+
EditorWarningCode,
|
|
66
|
+
EditorErrorCode,
|
|
67
|
+
CompatibilityFeatureClass,
|
|
68
|
+
CompatibilityFeatureEntry,
|
|
69
|
+
CompatibilityReport,
|
|
70
|
+
} from "../../api/public-types.ts";
|
|
71
|
+
|
|
72
|
+
export type {
|
|
73
|
+
EditorWarning,
|
|
74
|
+
EditorError,
|
|
75
|
+
EditorWarningCode,
|
|
76
|
+
EditorErrorCode,
|
|
77
|
+
CompatibilityFeatureClass,
|
|
78
|
+
CompatibilityFeatureEntry,
|
|
79
|
+
CompatibilityReport,
|
|
80
|
+
};
|
|
95
81
|
|
|
96
82
|
export type CommentEntryRecord = ModelCommentEntry;
|
|
97
83
|
export type CommentResolutionRecord = ModelCommentResolution;
|
|
@@ -105,7 +91,15 @@ export interface SelectionSnapshot {
|
|
|
105
91
|
anchor: number;
|
|
106
92
|
head: number;
|
|
107
93
|
isCollapsed: boolean;
|
|
108
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Internal nested-range shape (`{kind:"range", range:{from,to}, assoc}`).
|
|
96
|
+
* SelectionSnapshot is runtime-internal state used for mapping composition
|
|
97
|
+
* through `src/core/selection/mapping.ts`; the nested shape is load-bearing
|
|
98
|
+
* for `DocRange`-unit remap helpers. Public surfaces that expose a
|
|
99
|
+
* selection convert to the public flat shape via `toPublicAnchorProjection`
|
|
100
|
+
* at the boundary.
|
|
101
|
+
*/
|
|
102
|
+
activeRange: InternalEditorAnchorProjection;
|
|
109
103
|
}
|
|
110
104
|
|
|
111
105
|
export interface DocumentStats {
|
|
@@ -218,40 +212,16 @@ export function createDefaultCanonicalDocument(
|
|
|
218
212
|
documentId: string,
|
|
219
213
|
timestamp: string,
|
|
220
214
|
): CanonicalDocumentEnvelope {
|
|
221
|
-
|
|
222
|
-
|
|
215
|
+
// Thin wrapper around the model-layer factory. The canonical shape of
|
|
216
|
+
// "an empty document" belongs to Layer 02 so every construction path
|
|
217
|
+
// agrees on the default envelope; this file's remaining responsibility
|
|
218
|
+
// is to derive a stable per-session `docId` from the host's
|
|
219
|
+
// `documentId` (not a model concern — the hash is a session-layer
|
|
220
|
+
// convention that happens to resolve to a UUID-shaped string).
|
|
221
|
+
return createEmptyCanonicalDocumentModel({
|
|
223
222
|
docId: createCanonicalDocumentId(documentId),
|
|
224
223
|
createdAt: timestamp,
|
|
225
|
-
|
|
226
|
-
metadata: {
|
|
227
|
-
customProperties: {},
|
|
228
|
-
},
|
|
229
|
-
styles: {
|
|
230
|
-
paragraphs: {},
|
|
231
|
-
characters: {},
|
|
232
|
-
tables: {},
|
|
233
|
-
},
|
|
234
|
-
numbering: {
|
|
235
|
-
abstractDefinitions: {},
|
|
236
|
-
instances: {},
|
|
237
|
-
},
|
|
238
|
-
media: {
|
|
239
|
-
items: {},
|
|
240
|
-
},
|
|
241
|
-
content: {
|
|
242
|
-
type: "doc",
|
|
243
|
-
children: [{ type: "paragraph", children: [] }],
|
|
244
|
-
},
|
|
245
|
-
review: createEmptyReviewStore(),
|
|
246
|
-
preservation: {
|
|
247
|
-
opaqueFragments: {},
|
|
248
|
-
packageParts: {},
|
|
249
|
-
},
|
|
250
|
-
diagnostics: {
|
|
251
|
-
warnings: [],
|
|
252
|
-
errors: [],
|
|
253
|
-
},
|
|
254
|
-
};
|
|
224
|
+
});
|
|
255
225
|
}
|
|
256
226
|
|
|
257
227
|
export function createSelectionSnapshot(anchor = 0, head = anchor): SelectionSnapshot {
|
|
@@ -385,63 +355,16 @@ function normalizeCanonicalDocumentEnvelope(
|
|
|
385
355
|
documentId: string,
|
|
386
356
|
timestamp: string,
|
|
387
357
|
): CanonicalDocumentEnvelope {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
typeof record.createdAt === "string" && record.createdAt.length > 0
|
|
399
|
-
? record.createdAt
|
|
400
|
-
: base.createdAt,
|
|
401
|
-
updatedAt:
|
|
402
|
-
typeof record.updatedAt === "string" && record.updatedAt.length > 0
|
|
403
|
-
? record.updatedAt
|
|
404
|
-
: base.updatedAt,
|
|
405
|
-
metadata: {
|
|
406
|
-
...base.metadata,
|
|
407
|
-
...metadata,
|
|
408
|
-
customProperties: isRecord(metadata.customProperties)
|
|
409
|
-
? (Object.fromEntries(
|
|
410
|
-
Object.entries(metadata.customProperties).filter(([, entry]) => typeof entry === "string"),
|
|
411
|
-
) as Record<string, string>)
|
|
412
|
-
: {},
|
|
413
|
-
},
|
|
414
|
-
styles:
|
|
415
|
-
record.styles === undefined
|
|
416
|
-
? base.styles
|
|
417
|
-
: (record.styles as CanonicalDocumentEnvelope["styles"]),
|
|
418
|
-
numbering:
|
|
419
|
-
record.numbering === undefined
|
|
420
|
-
? base.numbering
|
|
421
|
-
: (record.numbering as CanonicalDocumentEnvelope["numbering"]),
|
|
422
|
-
media:
|
|
423
|
-
record.media === undefined
|
|
424
|
-
? base.media
|
|
425
|
-
: (record.media as CanonicalDocumentEnvelope["media"]),
|
|
426
|
-
content: isRecord(record.content)
|
|
427
|
-
? (record.content as unknown as CanonicalDocumentEnvelope["content"])
|
|
428
|
-
: base.content,
|
|
429
|
-
review:
|
|
430
|
-
record.review === undefined
|
|
431
|
-
? base.review
|
|
432
|
-
: (record.review as CanonicalDocumentEnvelope["review"]),
|
|
433
|
-
preservation:
|
|
434
|
-
record.preservation === undefined
|
|
435
|
-
? base.preservation
|
|
436
|
-
: (record.preservation as CanonicalDocumentEnvelope["preservation"]),
|
|
437
|
-
diagnostics:
|
|
438
|
-
record.diagnostics === undefined
|
|
439
|
-
? base.diagnostics
|
|
440
|
-
: (record.diagnostics as CanonicalDocumentEnvelope["diagnostics"]),
|
|
441
|
-
...(isRecord(record.subParts)
|
|
442
|
-
? { subParts: record.subParts as unknown as CanonicalDocumentEnvelope["subParts"] }
|
|
443
|
-
: {}),
|
|
444
|
-
};
|
|
358
|
+
// Delegated to the model layer so the repair path recognises every
|
|
359
|
+
// optional field the canonical envelope actually owns — `subParts`,
|
|
360
|
+
// `fieldRegistry`, and `fontTable`. The previous local copy dropped
|
|
361
|
+
// `fieldRegistry` and `fontTable`, which silently lost canonical data
|
|
362
|
+
// on any load-persist-reload cycle.
|
|
363
|
+
return repairCanonicalDocumentEnvelope(value, {
|
|
364
|
+
fallbackDocId: createCanonicalDocumentId(documentId),
|
|
365
|
+
fallbackCreatedAt: timestamp,
|
|
366
|
+
fallbackUpdatedAt: timestamp,
|
|
367
|
+
});
|
|
445
368
|
}
|
|
446
369
|
|
|
447
370
|
function coerceCompatibilityReport(
|
|
@@ -692,6 +615,14 @@ function normalizeCompatibilityReport(report: CompatibilityReport): Compatibilit
|
|
|
692
615
|
};
|
|
693
616
|
}
|
|
694
617
|
|
|
618
|
+
/**
|
|
619
|
+
* Defensive anchor-projection normalizer — accepts either shape
|
|
620
|
+
* (public flat `{kind:"range", from, to, assoc}` *or* legacy nested
|
|
621
|
+
* `{kind:"range", range:{from,to}, assoc}` from pre-2026-04-22
|
|
622
|
+
* snapshots) and returns the canonical public flat shape. Records
|
|
623
|
+
* carry flat anchors by contract, but this normalizer still copes with
|
|
624
|
+
* the nested shape from older persisted snapshots.
|
|
625
|
+
*/
|
|
695
626
|
function normalizeAnchorProjection(anchor: EditorAnchorProjection): EditorAnchorProjection {
|
|
696
627
|
switch (anchor.kind) {
|
|
697
628
|
case "range": {
|
|
@@ -702,13 +633,13 @@ function normalizeAnchorProjection(anchor: EditorAnchorProjection): EditorAnchor
|
|
|
702
633
|
assoc: { start: -1 | 1; end: -1 | 1 };
|
|
703
634
|
};
|
|
704
635
|
return rangeAnchor.range
|
|
705
|
-
?
|
|
706
|
-
:
|
|
636
|
+
? createPublicRangeAnchor(rangeAnchor.range.from, rangeAnchor.range.to, rangeAnchor.assoc)
|
|
637
|
+
: createPublicRangeAnchor(rangeAnchor.from ?? 0, rangeAnchor.to ?? 0, rangeAnchor.assoc);
|
|
707
638
|
}
|
|
708
639
|
case "node":
|
|
709
|
-
return
|
|
640
|
+
return createPublicNodeAnchor(anchor.at, anchor.assoc);
|
|
710
641
|
case "detached":
|
|
711
|
-
return
|
|
642
|
+
return createPublicDetachedAnchor(anchor.lastKnownRange, anchor.reason);
|
|
712
643
|
}
|
|
713
644
|
}
|
|
714
645
|
|
|
@@ -735,30 +666,6 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
735
666
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
736
667
|
}
|
|
737
668
|
|
|
738
|
-
export function createCanonicalDocumentId(documentId: string): string {
|
|
739
|
-
const hashWord = (seed: string): string => {
|
|
740
|
-
let hash = 0x811c9dc5;
|
|
741
|
-
for (const char of seed) {
|
|
742
|
-
hash ^= char.charCodeAt(0);
|
|
743
|
-
hash = Math.imul(hash, 0x01000193);
|
|
744
|
-
}
|
|
745
|
-
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
746
|
-
};
|
|
747
|
-
|
|
748
|
-
const raw =
|
|
749
|
-
hashWord(`${documentId}:0`) +
|
|
750
|
-
hashWord(`${documentId}:1`) +
|
|
751
|
-
hashWord(`${documentId}:2`) +
|
|
752
|
-
hashWord(`${documentId}:3`);
|
|
753
|
-
|
|
754
|
-
return [
|
|
755
|
-
raw.slice(0, 8),
|
|
756
|
-
raw.slice(8, 12),
|
|
757
|
-
`4${raw.slice(13, 16)}`,
|
|
758
|
-
`8${raw.slice(17, 20)}`,
|
|
759
|
-
raw.slice(20, 32),
|
|
760
|
-
].join("-");
|
|
761
|
-
}
|
|
762
669
|
|
|
763
670
|
export function normalizeCommentThreadRecord(value: unknown): CommentThreadRecord {
|
|
764
671
|
const record = isRecord(value) ? value : {};
|
|
@@ -858,7 +765,7 @@ export function normalizeCommentThreadRecord(value: unknown): CommentThreadRecor
|
|
|
858
765
|
: "comment-generated",
|
|
859
766
|
anchor:
|
|
860
767
|
isRecord(record.anchor) && typeof record.anchor.kind === "string"
|
|
861
|
-
? (record.anchor as unknown as
|
|
768
|
+
? (record.anchor as unknown as InternalEditorAnchorProjection)
|
|
862
769
|
: createDetachedAnchor({ from: 0, to: 0 }, "importAmbiguity"),
|
|
863
770
|
createdAt,
|
|
864
771
|
createdBy: authorId,
|
package/src/index.ts
CHANGED
|
@@ -7,19 +7,38 @@ export {
|
|
|
7
7
|
validateEditorSessionState,
|
|
8
8
|
EDITOR_SESSION_STATE_VERSION,
|
|
9
9
|
} from "./api/session-state.ts";
|
|
10
|
+
|
|
11
|
+
// Layer 01 — package/session seam. Host consumers open documents
|
|
12
|
+
// through this class rather than reaching into `src/io/docx-session.ts`.
|
|
13
|
+
// See `docs/architecture/01-package-session.md` § Public entry points.
|
|
14
|
+
export {
|
|
15
|
+
DocxSession,
|
|
16
|
+
SessionNotOpenError,
|
|
17
|
+
SessionNotWiredError,
|
|
18
|
+
} from "./session/index.ts";
|
|
19
|
+
export type {
|
|
20
|
+
OpenOptions,
|
|
21
|
+
OpenResult,
|
|
22
|
+
ExportOptions,
|
|
23
|
+
ValidateOptions,
|
|
24
|
+
ValidationReport,
|
|
25
|
+
ValidationFinding,
|
|
26
|
+
PreservationSnapshot,
|
|
27
|
+
EmbeddedDocumentManifest,
|
|
28
|
+
} from "./session/index.ts";
|
|
10
29
|
// R2 — issue metadata id for scope-card-overlay P1.
|
|
11
30
|
// K1-light — review-action metadata id for scope-card-overlay P2.
|
|
12
31
|
export { ISSUE_METADATA_ID, REVIEW_ACTION_METADATA_ID } from "./api/public-types.ts";
|
|
13
32
|
// P17 — metadata persistence error class.
|
|
14
33
|
export { MetadataResolverMissingError } from "./api/public-types.ts";
|
|
15
34
|
|
|
16
|
-
// Collab substrate (P1 – P8f + P14). See
|
|
35
|
+
// Collab substrate (P1 – P8f + P14). See CLAUDE.md (lane status table)
|
|
17
36
|
// for the shipped-slice table. Surfaces are stable for host integration;
|
|
18
37
|
// the chrome preset + markdown renderer land in P9 / P10.
|
|
19
38
|
export { createCollabSession } from "./runtime/collab-session.ts";
|
|
20
39
|
export { createCollabSessionBridge } from "./runtime/collab-session-bridge.ts";
|
|
21
40
|
export { createCollabSessionFacet } from "./runtime/collab-session-facet.ts";
|
|
22
|
-
export { createTamperGate } from "./runtime/tamper-gate.ts";
|
|
41
|
+
export { createTamperGate } from "./runtime/workflow/tamper-gate.ts";
|
|
23
42
|
export { resignPayload } from "./runtime/resign-payload.ts";
|
|
24
43
|
export {
|
|
25
44
|
setLocalIdentity,
|
|
@@ -61,7 +80,7 @@ export type {
|
|
|
61
80
|
TamperGateArgs,
|
|
62
81
|
AttachArgs as TamperGateAttachArgs,
|
|
63
82
|
GuardResult as TamperGateGuardResult,
|
|
64
|
-
} from "./runtime/tamper-gate.ts";
|
|
83
|
+
} from "./runtime/workflow/tamper-gate.ts";
|
|
65
84
|
export type {
|
|
66
85
|
RuntimeSendToExternalArgs,
|
|
67
86
|
RuntimeSendToExternalResult,
|
|
@@ -309,7 +328,7 @@ export type {
|
|
|
309
328
|
// L7 Phase 2.5 — prerender cache public API. Platforms / ingest workers
|
|
310
329
|
// call `prerenderDocument(buffer)` on template upload to populate the
|
|
311
330
|
// cache; end-user opens read the cache and skip the layout pass. See
|
|
312
|
-
//
|
|
331
|
+
// CLAUDE.md (lane status table) §Phase 2.5.
|
|
313
332
|
export { prerenderDocument } from "./runtime/prerender/prerender-document.ts";
|
|
314
333
|
export type {
|
|
315
334
|
PrerenderOptions,
|