@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,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell re-export module — the seam that hosts substrate-reach-through
|
|
3
|
+
* helpers `WordReviewEditor` still consumes after the Track A
|
|
4
|
+
* ref-bridge carve-out. Layer 11 presentation code (`src/ui/**` +
|
|
5
|
+
* `src/ui-tailwind/**`) imports from this module instead of reaching
|
|
6
|
+
* directly into `src/core/**` or `src/runtime/**`, which retires
|
|
7
|
+
* those imports from the L11 boundary register.
|
|
8
|
+
*
|
|
9
|
+
* The shell layer is an allowed substrate consumer (handoff §3,
|
|
10
|
+
* designsystem.md §8.8 "Mounted shell" stratum); presentation
|
|
11
|
+
* reads through it.
|
|
12
|
+
*
|
|
13
|
+
* Each binding below is a straight re-export — no runtime wrapping,
|
|
14
|
+
* no behavioral change, no perf cost. Hot-path consumers
|
|
15
|
+
* (`dispatchTextCommand` called on every keystroke) retain identity
|
|
16
|
+
* stability; the ESM re-export binding is folded at module load.
|
|
17
|
+
*
|
|
18
|
+
* Track D + G · refactor/11 — closes the WRE-side substrate leakage
|
|
19
|
+
* that Track A (ref-bridge carve-out) did not touch. After this
|
|
20
|
+
* module ships, `WordReviewEditor.tsx` still holds ~2 direct
|
|
21
|
+
* substrate imports for trivial type-only use that routes cleanly
|
|
22
|
+
* through `src/api/public-types.ts`; the rest travel through here.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
export { storyTargetsEqual } from "../core/selection/mapping.ts";
|
|
26
|
+
export { getFormattingStateFromRenderSnapshot } from "../core/commands/formatting-commands.ts";
|
|
27
|
+
export {
|
|
28
|
+
dispatchTextCommand,
|
|
29
|
+
type DispatchTextCommand,
|
|
30
|
+
} from "../runtime/edit-dispatch/index.ts";
|
|
31
|
+
export { getTableStructureContext } from "../core/commands/table-structure-commands.ts";
|
|
32
|
+
export { getStoryBlocks } from "../runtime/story-targeting.ts";
|
|
33
|
+
export { deriveCapabilities } from "../runtime/session-capabilities";
|
|
34
|
+
export {
|
|
35
|
+
resolveCurrentContextAnalyticsQuery,
|
|
36
|
+
runtimeContextAnalyticsSnapshotsEqual,
|
|
37
|
+
} from "../runtime/context-analytics.ts";
|
|
38
|
+
export {
|
|
39
|
+
createEditorViewStateSnapshot,
|
|
40
|
+
createViewState,
|
|
41
|
+
} from "../runtime/view-state.ts";
|
|
42
|
+
export { wrapRefForTelemetry } from "../runtime/debug/wrap-ref-for-telemetry.ts";
|
|
43
|
+
export {
|
|
44
|
+
conflictKey,
|
|
45
|
+
convertScopesToInternal,
|
|
46
|
+
convertScopesToExternal,
|
|
47
|
+
type PendingConflict,
|
|
48
|
+
} from "../runtime/workflow/metadata-persistence.ts";
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell helper — document search projections.
|
|
3
|
+
*
|
|
4
|
+
* Two thin projections used by the React editor ref (`findText`,
|
|
5
|
+
* `searchDocument`) plus the in-component search effects. Both take
|
|
6
|
+
* the mounted runtime and return public-API shapes.
|
|
7
|
+
*
|
|
8
|
+
* Lives in `src/shell/` rather than `src/ui/` so the underlying
|
|
9
|
+
* `src/runtime/document-search.ts` value import is a consumer
|
|
10
|
+
* relationship rather than an L11 register offender.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { EditorAnchorProjection, SearchOptions, SearchResultSnapshot } from "../api/public-types.ts";
|
|
14
|
+
import { findTextMatches, searchDocument } from "../runtime/document-search.ts";
|
|
15
|
+
import type { WordReviewEditorRuntime } from "./session-bootstrap.ts";
|
|
16
|
+
import type { TwProseMirrorSurfaceRef } from "../ui-tailwind/editor-surface/tw-prosemirror-surface";
|
|
17
|
+
|
|
18
|
+
export function findTextMatchesForRuntime(
|
|
19
|
+
runtime: WordReviewEditorRuntime,
|
|
20
|
+
query: string,
|
|
21
|
+
options: SearchOptions | undefined,
|
|
22
|
+
): EditorAnchorProjection[] {
|
|
23
|
+
const snapshot = runtime.getRenderSnapshot();
|
|
24
|
+
return findTextMatches(
|
|
25
|
+
runtime.getSessionState().canonicalDocument,
|
|
26
|
+
snapshot.selection,
|
|
27
|
+
query,
|
|
28
|
+
options ?? {},
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function searchRuntimeDocument(
|
|
33
|
+
runtime: WordReviewEditorRuntime,
|
|
34
|
+
mountedSurface: TwProseMirrorSurfaceRef | null,
|
|
35
|
+
query: string,
|
|
36
|
+
options: SearchOptions = {},
|
|
37
|
+
): SearchResultSnapshot[] {
|
|
38
|
+
if (mountedSurface) {
|
|
39
|
+
return mountedSurface.search(query, options);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const snapshot = runtime.getRenderSnapshot();
|
|
43
|
+
return searchDocument(
|
|
44
|
+
runtime.getSessionState().canonicalDocument,
|
|
45
|
+
snapshot.selection,
|
|
46
|
+
snapshot.activeStory,
|
|
47
|
+
runtime.getDocumentNavigationSnapshot(),
|
|
48
|
+
query,
|
|
49
|
+
options,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -29,7 +29,11 @@ import {
|
|
|
29
29
|
editorSessionStateFromPersistedSnapshot,
|
|
30
30
|
persistedSnapshotFromEditorSessionState,
|
|
31
31
|
} from "../api/session-state.ts";
|
|
32
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
createCanonicalDocumentId,
|
|
34
|
+
createDefaultCanonicalDocument,
|
|
35
|
+
createSelectionSnapshot,
|
|
36
|
+
} from "../core/state/editor-state.ts";
|
|
33
37
|
import {
|
|
34
38
|
createDocumentRuntime,
|
|
35
39
|
type DocumentRuntimeEvent,
|
|
@@ -41,15 +45,31 @@ import {
|
|
|
41
45
|
type RuntimeCommandAppliedBridge,
|
|
42
46
|
} from "../runtime/collab/runtime-collab-sync.ts";
|
|
43
47
|
import { createInertLayoutFacet } from "../runtime/layout/index.ts";
|
|
48
|
+
import { createInertGeometryFacet } from "../runtime/geometry/index.ts";
|
|
49
|
+
import { TelemetryBus } from "../runtime/debug/telemetry-bus.ts";
|
|
44
50
|
import {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
} from "../
|
|
51
|
+
createRuntimeDebugFacet,
|
|
52
|
+
type RuntimeDebugFacet,
|
|
53
|
+
} from "../runtime/debug/runtime-debug-facet.ts";
|
|
54
|
+
// Slice 5c flipped the async DOM warm path to `DocxSession.open()`.
|
|
55
|
+
// The two remaining sync call sites (SSR/Node `createRuntime`
|
|
56
|
+
// fallback + `resolvePackageBackedExportSession`) were isolated
|
|
57
|
+
// behind `src/session/_sync-legacy.ts` in Slice 5e-3 so the UI layer
|
|
58
|
+
// no longer imports directly from the legacy file. The shim + its
|
|
59
|
+
// debt exception in `ci-check-session-layer-purity.mjs` go away at
|
|
60
|
+
// Slice 5e-9 together with the legacy file.
|
|
61
|
+
import type { CacheEnvelope } from "../runtime/prerender/cache-envelope.ts";
|
|
48
62
|
import { tryReadLaycacheEnvelope } from "../runtime/prerender/customxml-probe.ts";
|
|
49
|
-
import {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
} from "../
|
|
63
|
+
import { createEditorSurfaceSnapshot } from "../runtime/surface-projection.ts";
|
|
64
|
+
import { MAIN_STORY_TARGET } from "../core/selection/mapping.ts";
|
|
65
|
+
import type { ProgressiveSurfaceProjector } from "../session/types.ts";
|
|
66
|
+
import { DocxSession } from "../session/index.ts";
|
|
67
|
+
// Slice 5e-11 item-4: `_internal-legacy.ts` retired. All fields that
|
|
68
|
+
// were reached through `getLegacyOpenView` are now public on
|
|
69
|
+
// `OpenResult` directly; a tiny local adapter maps `OpenResult` into
|
|
70
|
+
// the `LoadedDocxEditorSession` shape the downstream shell code
|
|
71
|
+
// still expects.
|
|
72
|
+
import { openDocxSync } from "../session/_sync-legacy.ts";
|
|
53
73
|
import {
|
|
54
74
|
decodePersistedSourcePackageBytes,
|
|
55
75
|
hasValidPersistedSourcePackageDigest,
|
|
@@ -65,7 +85,7 @@ import {
|
|
|
65
85
|
import {
|
|
66
86
|
downloadExportResult,
|
|
67
87
|
withExportDelivery,
|
|
68
|
-
} from "
|
|
88
|
+
} from "../ui/browser-export";
|
|
69
89
|
|
|
70
90
|
export interface ResolvedSource {
|
|
71
91
|
source: "docx" | "session" | "snapshot";
|
|
@@ -80,7 +100,7 @@ export interface ResolvedSource {
|
|
|
80
100
|
* load. Undefined in SSR / Node test fallback — `createRuntime` then
|
|
81
101
|
* does the classic synchronous load.
|
|
82
102
|
*/
|
|
83
|
-
preloadedDocxSession?: ReturnType<typeof
|
|
103
|
+
preloadedDocxSession?: ReturnType<typeof openDocxSync>;
|
|
84
104
|
/**
|
|
85
105
|
* L7 Phase 2.7 — when the editor-runtime-boundary probe finds a
|
|
86
106
|
* laycache envelope in `/customXml/item1.xml`, its `graph` is stashed
|
|
@@ -128,7 +148,7 @@ type InternalWordReviewEditorRuntime = WordReviewEditorRuntime & {
|
|
|
128
148
|
) => boolean;
|
|
129
149
|
};
|
|
130
150
|
|
|
131
|
-
type PackageBackedDocxSession = ReturnType<typeof
|
|
151
|
+
type PackageBackedDocxSession = ReturnType<typeof openDocxSync>;
|
|
132
152
|
|
|
133
153
|
interface SnapshotExportBarrier {
|
|
134
154
|
reason:
|
|
@@ -324,9 +344,11 @@ export function useEditorRuntimeBoundary(
|
|
|
324
344
|
useRef<EditorSessionState["canonicalDocument"] | null>(null);
|
|
325
345
|
const autosaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
326
346
|
const lastSavedRevisionTokenRef = useRef<string | null>(null);
|
|
327
|
-
// Fastload P6: scheduler
|
|
328
|
-
//
|
|
329
|
-
|
|
347
|
+
// Fastload P6: load-scheduler disposer handed back from
|
|
348
|
+
// `DocxSession.open()` via `LegacyOpenView.dispose`. Held here so
|
|
349
|
+
// unmount / source-change can cancel pending idle chart-preview
|
|
350
|
+
// callbacks (CLAUDE.md Performance Invariant 9).
|
|
351
|
+
const loadDisposeRef = useRef<(() => void) | null>(null);
|
|
330
352
|
const hostAdapterRef = useRef(hostAdapter);
|
|
331
353
|
const datastoreRef = useRef(datastore);
|
|
332
354
|
const onEventRef = useRef(onEvent);
|
|
@@ -407,8 +429,8 @@ export function useEditorRuntimeBoundary(
|
|
|
407
429
|
runtimeRef.current = null;
|
|
408
430
|
// Fastload P6: dispose any scheduler held from a previous mount /
|
|
409
431
|
// source cycle before allocating a fresh one for this load.
|
|
410
|
-
|
|
411
|
-
|
|
432
|
+
loadDisposeRef.current?.();
|
|
433
|
+
loadDisposeRef.current = null;
|
|
412
434
|
setRuntime(null);
|
|
413
435
|
|
|
414
436
|
try {
|
|
@@ -429,37 +451,28 @@ export function useEditorRuntimeBoundary(
|
|
|
429
451
|
return;
|
|
430
452
|
}
|
|
431
453
|
|
|
432
|
-
// Fastload P6: in a DOM environment, preload the docx via
|
|
433
|
-
//
|
|
434
|
-
// can paint the skeleton while the rest of the parse
|
|
435
|
-
// SSR / Node tests fall through to the synchronous
|
|
436
|
-
// `createRuntime`.
|
|
454
|
+
// Fastload P6: in a DOM environment, preload the docx via
|
|
455
|
+
// `DocxSession.open()` so normalize-body yields mid-walk and the
|
|
456
|
+
// browser can paint the skeleton while the rest of the parse
|
|
457
|
+
// finishes. SSR / Node tests fall through to the synchronous
|
|
458
|
+
// load inside `createRuntime`.
|
|
437
459
|
//
|
|
438
|
-
// L7 Phase 2.7 — Plan B read-path wiring.
|
|
439
|
-
//
|
|
440
|
-
//
|
|
441
|
-
//
|
|
442
|
-
//
|
|
443
|
-
//
|
|
444
|
-
//
|
|
445
|
-
//
|
|
446
|
-
// `
|
|
447
|
-
//
|
|
448
|
-
//
|
|
460
|
+
// L7 Phase 2.7 — Plan B read-path wiring. `tryLaycacheEnvelope:
|
|
461
|
+
// true` tells the session to probe `/customXml/item1.xml` for a
|
|
462
|
+
// cached envelope and short-circuit the five expensive parse
|
|
463
|
+
// stages on a hit (CLAUDE.md Performance Invariant 10 — probe
|
|
464
|
+
// and loader are now colocated inside the session; no blocking
|
|
465
|
+
// work between them). Measured win on 138-pp extra-large CCEP:
|
|
466
|
+
// ~947 ms cold → ~590 ms warm (Δ 376 ms).
|
|
467
|
+
//
|
|
468
|
+
// `onProgressiveSnapshot` is passed unconditionally — the
|
|
469
|
+
// loader gates it on `laycacheEnvelope === undefined`, so the
|
|
470
|
+
// warm-path short-circuit skips the synthesis automatically.
|
|
449
471
|
if (
|
|
450
472
|
source.initialDocx !== undefined &&
|
|
451
473
|
source.preloadedDocxSession === undefined &&
|
|
452
474
|
typeof document !== "undefined"
|
|
453
475
|
) {
|
|
454
|
-
const scheduler = createLoadScheduler();
|
|
455
|
-
loadSchedulerRef.current = scheduler;
|
|
456
|
-
const probeResult = await tryReadLaycacheEnvelope(source.initialDocx);
|
|
457
|
-
if (cancelled) {
|
|
458
|
-
scheduler.dispose();
|
|
459
|
-
loadSchedulerRef.current = null;
|
|
460
|
-
return;
|
|
461
|
-
}
|
|
462
|
-
recordPerfSample("loadSession.laycacheProbe");
|
|
463
476
|
const handleChartPreviewsReady = (
|
|
464
477
|
resolvedDocument: EditorSessionState["canonicalDocument"],
|
|
465
478
|
): void => {
|
|
@@ -481,34 +494,89 @@ export function useEditorRuntimeBoundary(
|
|
|
481
494
|
runtimeRef.current as InternalWordReviewEditorRuntime | null
|
|
482
495
|
)?.hydrateChartPreviews?.(resolvedDocument);
|
|
483
496
|
};
|
|
484
|
-
|
|
497
|
+
// Slice 5e-7.b — runtime-side port that lets the session
|
|
498
|
+
// layer synthesize the progressive surface without importing
|
|
499
|
+
// `src/runtime/surface-projection.ts` directly. The adapter
|
|
500
|
+
// binds in a default collapsed selection + `MAIN_STORY_TARGET`
|
|
501
|
+
// + a provisional canonical envelope so the session only
|
|
502
|
+
// passes the body-stage root content + viewport counts.
|
|
503
|
+
const surfaceProjector: ProgressiveSurfaceProjector = ({
|
|
504
|
+
rootContent,
|
|
505
|
+
documentId: providedDocumentId,
|
|
506
|
+
blocksRealized,
|
|
507
|
+
blocksTotal,
|
|
508
|
+
}) => {
|
|
509
|
+
const provisionalDoc = {
|
|
510
|
+
...createDefaultCanonicalDocument(
|
|
511
|
+
providedDocumentId,
|
|
512
|
+
new Date().toISOString(),
|
|
513
|
+
),
|
|
514
|
+
content: rootContent,
|
|
515
|
+
};
|
|
516
|
+
return createEditorSurfaceSnapshot(
|
|
517
|
+
provisionalDoc,
|
|
518
|
+
createSelectionSnapshot(0, 0),
|
|
519
|
+
MAIN_STORY_TARGET,
|
|
520
|
+
blocksRealized < blocksTotal
|
|
521
|
+
? { viewportBlockRange: { start: 0, end: blocksRealized } }
|
|
522
|
+
: undefined,
|
|
523
|
+
);
|
|
524
|
+
};
|
|
525
|
+
const openResult = await new DocxSession().open(source.initialDocx, {
|
|
485
526
|
documentId,
|
|
486
527
|
sourceLabel: source.sourceLabel,
|
|
487
|
-
bytes: source.initialDocx,
|
|
488
528
|
editorBuild: "dev",
|
|
489
|
-
|
|
529
|
+
tryLaycacheEnvelope: true,
|
|
530
|
+
// Slice 5e-11 item-1: probe injection. Session no longer
|
|
531
|
+
// imports from `src/runtime/prerender/**`; the shell
|
|
532
|
+
// supplies the probe. See `cross-layer-coord-01 §1`.
|
|
533
|
+
laycacheProbe: tryReadLaycacheEnvelope,
|
|
490
534
|
onChartPreviewsReady: handleChartPreviewsReady,
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
},
|
|
504
|
-
}),
|
|
535
|
+
surfaceProjector,
|
|
536
|
+
// C2c: on the cold path the loader fires this once after
|
|
537
|
+
// body-normalize with a viewport-windowed surface; on the
|
|
538
|
+
// warm path (envelope resolved) it is silently skipped.
|
|
539
|
+
// Performance Invariant 8: MUST be wrapped in
|
|
540
|
+
// `startTransition` so React treats it as low-priority;
|
|
541
|
+
// the full `setRuntime` commit preempts it.
|
|
542
|
+
onProgressiveSnapshot: (partial) => {
|
|
543
|
+
React.startTransition(() => {
|
|
544
|
+
setProgressiveSurface(partial.surface ?? null);
|
|
545
|
+
});
|
|
546
|
+
},
|
|
505
547
|
});
|
|
548
|
+
// Slice 5e-11 item-4: adapter maps `OpenResult` → the
|
|
549
|
+
// `LoadedDocxEditorSession` shape the downstream shell
|
|
550
|
+
// code expects. Two field-name mismatches exist:
|
|
551
|
+
// `sessionState` / `initialSessionState`, and
|
|
552
|
+
// `embeddedDocuments` / `embeddedDocumentManifests`.
|
|
553
|
+
const preloadView: ReturnType<typeof openDocxSync> = {
|
|
554
|
+
initialSessionState: openResult.sessionState,
|
|
555
|
+
initialSnapshot: openResult.initialSnapshot,
|
|
556
|
+
readOnly: openResult.readOnly,
|
|
557
|
+
...(openResult.fatalError !== undefined
|
|
558
|
+
? { fatalError: openResult.fatalError }
|
|
559
|
+
: {}),
|
|
560
|
+
protectionSnapshot: openResult.protectionSnapshot,
|
|
561
|
+
exportDocx: openResult.exportDocx,
|
|
562
|
+
embeddedDocumentManifests: openResult.embeddedDocuments,
|
|
563
|
+
...(openResult.initialEditorStatePayload !== undefined
|
|
564
|
+
? {
|
|
565
|
+
initialEditorStatePayload:
|
|
566
|
+
openResult.initialEditorStatePayload as NonNullable<
|
|
567
|
+
ReturnType<typeof openDocxSync>["initialEditorStatePayload"]
|
|
568
|
+
>,
|
|
569
|
+
}
|
|
570
|
+
: {}),
|
|
571
|
+
};
|
|
572
|
+
loadDisposeRef.current = openResult.dispose ?? null;
|
|
506
573
|
if (cancelled) {
|
|
507
|
-
|
|
508
|
-
|
|
574
|
+
openResult.dispose?.();
|
|
575
|
+
loadDisposeRef.current = null;
|
|
509
576
|
return;
|
|
510
577
|
}
|
|
511
|
-
|
|
578
|
+
recordPerfSample("loadSession.laycacheProbe");
|
|
579
|
+
source.preloadedDocxSession = preloadView;
|
|
512
580
|
if (pendingChartPreviewDocRef.current) {
|
|
513
581
|
source.preloadedDocxSession.initialSessionState = {
|
|
514
582
|
...source.preloadedDocxSession.initialSessionState,
|
|
@@ -519,8 +587,10 @@ export function useEditorRuntimeBoundary(
|
|
|
519
587
|
canonicalDocument: pendingChartPreviewDocRef.current,
|
|
520
588
|
};
|
|
521
589
|
}
|
|
522
|
-
if (
|
|
523
|
-
source.preloadedLaycacheGraph =
|
|
590
|
+
if (openResult.laycacheEnvelope) {
|
|
591
|
+
source.preloadedLaycacheGraph = (
|
|
592
|
+
openResult.laycacheEnvelope as CacheEnvelope
|
|
593
|
+
).graph;
|
|
524
594
|
}
|
|
525
595
|
}
|
|
526
596
|
|
|
@@ -643,8 +713,8 @@ export function useEditorRuntimeBoundary(
|
|
|
643
713
|
// Fastload P6: release any pending idle callbacks the load scheduler
|
|
644
714
|
// registered so React unmount doesn't leak setTimeout/IdleCallback
|
|
645
715
|
// handles.
|
|
646
|
-
|
|
647
|
-
|
|
716
|
+
loadDisposeRef.current?.();
|
|
717
|
+
loadDisposeRef.current = null;
|
|
648
718
|
};
|
|
649
719
|
}, []);
|
|
650
720
|
|
|
@@ -740,7 +810,7 @@ function createRuntime(
|
|
|
740
810
|
const docxSession =
|
|
741
811
|
args.source.preloadedDocxSession ??
|
|
742
812
|
(args.source.initialDocx
|
|
743
|
-
?
|
|
813
|
+
? openDocxSync({
|
|
744
814
|
documentId: args.documentId,
|
|
745
815
|
sourceLabel: args.source.sourceLabel,
|
|
746
816
|
bytes: args.source.initialDocx,
|
|
@@ -985,6 +1055,7 @@ function createLoadingRuntimeBridge(input: {
|
|
|
985
1055
|
progressiveSurfaceRef?: React.RefObject<EditorSurfaceSnapshot | null>;
|
|
986
1056
|
}): WordReviewEditorRuntime {
|
|
987
1057
|
const inertLayoutFacet = createInertLayoutFacet();
|
|
1058
|
+
const inertGeometryFacet = createInertGeometryFacet();
|
|
988
1059
|
const emptyFieldSnapshot: FieldSnapshot = {
|
|
989
1060
|
totalCount: 0,
|
|
990
1061
|
supportedCount: 0,
|
|
@@ -1027,6 +1098,7 @@ function createLoadingRuntimeBridge(input: {
|
|
|
1027
1098
|
getFontEntry: (name: string) =>
|
|
1028
1099
|
input.sessionState.canonicalDocument.fontTable?.fonts[name],
|
|
1029
1100
|
replaceText: () => undefined,
|
|
1101
|
+
applyScopeReplacement: () => undefined,
|
|
1030
1102
|
insertFragment: () => undefined,
|
|
1031
1103
|
copy: () => undefined,
|
|
1032
1104
|
cut: () => undefined,
|
|
@@ -1066,6 +1138,9 @@ function createLoadingRuntimeBridge(input: {
|
|
|
1066
1138
|
throw createLoadingBoundaryError(input.snapshot.documentId, "scope");
|
|
1067
1139
|
},
|
|
1068
1140
|
getScope: () => null,
|
|
1141
|
+
compileScopeBundleById: () => null,
|
|
1142
|
+
getMarkerBackedScopeIds: () => new Set<string>(),
|
|
1143
|
+
debug: createLoadingDebugFacet(),
|
|
1069
1144
|
removeScope: () => undefined,
|
|
1070
1145
|
acceptChange: () => undefined,
|
|
1071
1146
|
rejectChange: () => undefined,
|
|
@@ -1086,6 +1161,13 @@ function createLoadingRuntimeBridge(input: {
|
|
|
1086
1161
|
getPageLayoutSnapshot: () => null,
|
|
1087
1162
|
getDocumentNavigationSnapshot: () => input.navigation,
|
|
1088
1163
|
layout: inertLayoutFacet,
|
|
1164
|
+
workflow: {
|
|
1165
|
+
getRailSegments: () => [],
|
|
1166
|
+
getAllRailSegments: () => [],
|
|
1167
|
+
getAllScopeCardModels: () => [],
|
|
1168
|
+
},
|
|
1169
|
+
geometry: inertGeometryFacet,
|
|
1170
|
+
getLayoutFacet: () => inertLayoutFacet,
|
|
1089
1171
|
getCurrentLocation: () => null,
|
|
1090
1172
|
getLocationForSelection: () => null,
|
|
1091
1173
|
getLocationForAnchor: () => null,
|
|
@@ -1156,6 +1238,18 @@ function createLoadingRuntimeBridge(input: {
|
|
|
1156
1238
|
definitions: [],
|
|
1157
1239
|
entries: [],
|
|
1158
1240
|
}),
|
|
1241
|
+
// W10 — class-A overlay-visibility policy. Loading bridge: no
|
|
1242
|
+
// authored policy until the real runtime mounts.
|
|
1243
|
+
getVisibilityPolicy: () => null,
|
|
1244
|
+
getVisibilityPolicies: () => [],
|
|
1245
|
+
setVisibilityPolicy: () => false,
|
|
1246
|
+
clearVisibilityPolicy: () => false,
|
|
1247
|
+
subscribeVisibilityPolicy: () => () => undefined,
|
|
1248
|
+
getMarkupModePolicy: () => null,
|
|
1249
|
+
setMarkupModePolicy: () => false,
|
|
1250
|
+
subscribeMarkupModePolicy: () => () => undefined,
|
|
1251
|
+
setEffectiveMarkupModeProvider: () => undefined,
|
|
1252
|
+
invalidateForMarkupModeChange: () => undefined,
|
|
1159
1253
|
queryScopes: () => [],
|
|
1160
1254
|
findScopesAt: () => [],
|
|
1161
1255
|
findScopesIntersecting: () => [],
|
|
@@ -1200,6 +1294,88 @@ function createLoadingRuntimeBridge(input: {
|
|
|
1200
1294
|
};
|
|
1201
1295
|
}
|
|
1202
1296
|
|
|
1297
|
+
/**
|
|
1298
|
+
* Loading-bridge debug facet. Exposes an all-off `TelemetryBus` and a
|
|
1299
|
+
* projector that only renders the current loading state. Consumers that
|
|
1300
|
+
* connect the debug facet before the runtime is live (e.g. the Phase 2
|
|
1301
|
+
* service during cold-open) see an honest empty bundle, not an error.
|
|
1302
|
+
*/
|
|
1303
|
+
function createLoadingDebugFacet(): RuntimeDebugFacet {
|
|
1304
|
+
const bus = new TelemetryBus();
|
|
1305
|
+
return {
|
|
1306
|
+
bus,
|
|
1307
|
+
getSnapshot() {
|
|
1308
|
+
return {
|
|
1309
|
+
schemaVersion: 1,
|
|
1310
|
+
generatedAtUtc: new Date().toISOString(),
|
|
1311
|
+
session: {
|
|
1312
|
+
documentId: "",
|
|
1313
|
+
sessionId: "",
|
|
1314
|
+
dirty: false,
|
|
1315
|
+
exportBlocked: true,
|
|
1316
|
+
activeStory: { kind: "main" },
|
|
1317
|
+
workspaceMode: "canvas",
|
|
1318
|
+
viewMode: "loading",
|
|
1319
|
+
documentMode: "loading",
|
|
1320
|
+
measurementFidelity: null,
|
|
1321
|
+
currentPage: null,
|
|
1322
|
+
},
|
|
1323
|
+
health: {
|
|
1324
|
+
compatibility: {
|
|
1325
|
+
exportAllowed: false,
|
|
1326
|
+
exportPlan: "full",
|
|
1327
|
+
featureBlocked: false,
|
|
1328
|
+
warnings: [],
|
|
1329
|
+
features: [],
|
|
1330
|
+
summary: { blockedCount: 0, preserveOnlyCount: 0, warningCount: 0 },
|
|
1331
|
+
generatedAt: new Date().toISOString(),
|
|
1332
|
+
blockedFeatureKeys: [],
|
|
1333
|
+
preserveOnlyFeatureKeys: [],
|
|
1334
|
+
} as never,
|
|
1335
|
+
warnings: [],
|
|
1336
|
+
blockedReasons: [],
|
|
1337
|
+
fatalError: null,
|
|
1338
|
+
readOnly: false,
|
|
1339
|
+
},
|
|
1340
|
+
context: null,
|
|
1341
|
+
selection: { anchor: null, location: null },
|
|
1342
|
+
workflow: {
|
|
1343
|
+
overlay: null,
|
|
1344
|
+
activeWorkItemId: null,
|
|
1345
|
+
metadataPersistenceMode: null,
|
|
1346
|
+
candidateCount: 0,
|
|
1347
|
+
scopeCount: 0,
|
|
1348
|
+
markerBackedCount: 0,
|
|
1349
|
+
overlayOnlyCount: 0,
|
|
1350
|
+
detachedCount: 0,
|
|
1351
|
+
},
|
|
1352
|
+
scopes: [],
|
|
1353
|
+
review: {
|
|
1354
|
+
unresolvedCommentCount: 0,
|
|
1355
|
+
pendingRevisionCount: 0,
|
|
1356
|
+
detachedCommentCount: 0,
|
|
1357
|
+
detachedRevisionCount: 0,
|
|
1358
|
+
},
|
|
1359
|
+
layout: { pageCount: null, sectionCount: null, storyCount: 0 },
|
|
1360
|
+
channels: bus.getChannels(),
|
|
1361
|
+
};
|
|
1362
|
+
},
|
|
1363
|
+
tail(n = 64) {
|
|
1364
|
+
return bus.tailAll(n);
|
|
1365
|
+
},
|
|
1366
|
+
tailChannel(channel, n = 64) {
|
|
1367
|
+
return bus.tail(channel, n);
|
|
1368
|
+
},
|
|
1369
|
+
setChannels(flags) {
|
|
1370
|
+
bus.setChannels(flags);
|
|
1371
|
+
return bus.getChannels();
|
|
1372
|
+
},
|
|
1373
|
+
getChannels() {
|
|
1374
|
+
return bus.getChannels();
|
|
1375
|
+
},
|
|
1376
|
+
};
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1203
1379
|
function createLoadingBoundaryError(
|
|
1204
1380
|
documentId: string,
|
|
1205
1381
|
target: "comment" | "session" | "snapshot" | "export" | "scope",
|
|
@@ -1717,7 +1893,7 @@ function resolvePackageBackedExportSession(args: CreateRuntimeArgs): {
|
|
|
1717
1893
|
};
|
|
1718
1894
|
}
|
|
1719
1895
|
|
|
1720
|
-
const session =
|
|
1896
|
+
const session = openDocxSync({
|
|
1721
1897
|
documentId: args.documentId,
|
|
1722
1898
|
sourceLabel: sourcePackage.sourceLabel ?? args.source.sourceLabel,
|
|
1723
1899
|
bytes,
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell-side subscriber-emitter channels for the mounted UI API
|
|
3
|
+
* controller hooks (`subscribeChrome`, `subscribeViewport`,
|
|
4
|
+
* `subscribeOverlays`).
|
|
5
|
+
*
|
|
6
|
+
* Why this exists
|
|
7
|
+
*
|
|
8
|
+
* `ui.chrome.subscribe` / `ui.viewport.subscribe` / `ui.overlays.subscribe`
|
|
9
|
+
* delegate to their respective controller hooks. Until 2026-04-23 those
|
|
10
|
+
* hooks were `undefined` on the mounted path, causing each subscribe to
|
|
11
|
+
* throw with a configuration-clear error. That's fine for consumer
|
|
12
|
+
* discovery but it means Playwright drivers, the debug service, and any
|
|
13
|
+
* non-React consumer that wants to observe posture / viewport /
|
|
14
|
+
* overlay-invalidation over time couldn't actually do it on the mounted
|
|
15
|
+
* editor.
|
|
16
|
+
*
|
|
17
|
+
* The three channels here are **stable per-mount** emitter triples:
|
|
18
|
+
*
|
|
19
|
+
* - `subscribe(listener) → unsubscribe`
|
|
20
|
+
* - `emit(value)` — called by the shell at event time
|
|
21
|
+
* - `size` — count of current listeners (test + telemetry hook)
|
|
22
|
+
*
|
|
23
|
+
* The shell creates one of each via `useRef` at mount, wires `subscribeX`
|
|
24
|
+
* on the UI controller factory to the emitter's `subscribe`, and calls
|
|
25
|
+
* `.emit(value)` from the appropriate React effect / DOM listener when
|
|
26
|
+
* the underlying state changes. The factory's controller identity stays
|
|
27
|
+
* stable because the emitter object identity is stable (a ref box).
|
|
28
|
+
*
|
|
29
|
+
* U7 compliance: viewport and overlay emitters are **rAF-coalesced at
|
|
30
|
+
* the shell-call-site level**, not inside the emitter. The emitter is a
|
|
31
|
+
* dumb fan-out; coalescing is the responsibility of whatever is calling
|
|
32
|
+
* `.emit()`. Posture is microtask-coalesced because the posture sources
|
|
33
|
+
* are synchronous React state / props and batching is React's default.
|
|
34
|
+
*
|
|
35
|
+
* Isolation: each emitter holds its own listener set. Teardown at
|
|
36
|
+
* unmount clears the set so a stale listener can't leak across remounts.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
export interface UiSubscriberChannel<T> {
|
|
40
|
+
/** Register a listener; returns an unsubscribe fn. Idempotent add. */
|
|
41
|
+
readonly subscribe: (listener: (value: T) => void) => () => void;
|
|
42
|
+
/** Fire every registered listener with `value`. Errors isolated. */
|
|
43
|
+
readonly emit: (value: T) => void;
|
|
44
|
+
/** Clear the listener set (call on unmount). Subsequent emits no-op. */
|
|
45
|
+
readonly dispose: () => void;
|
|
46
|
+
/** Current listener count (test / telemetry). */
|
|
47
|
+
readonly size: () => number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Build a stable emitter channel. Listeners are held in a Set so
|
|
52
|
+
* registration is idempotent (adding the same fn twice leaves one
|
|
53
|
+
* entry). Removal is O(1). Emission isolates listener throws so one
|
|
54
|
+
* broken consumer can't break the fan-out.
|
|
55
|
+
*/
|
|
56
|
+
export function createUiSubscriberChannel<T>(): UiSubscriberChannel<T> {
|
|
57
|
+
const listeners = new Set<(value: T) => void>();
|
|
58
|
+
return {
|
|
59
|
+
subscribe(listener) {
|
|
60
|
+
listeners.add(listener);
|
|
61
|
+
return () => {
|
|
62
|
+
listeners.delete(listener);
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
emit(value) {
|
|
66
|
+
for (const listener of listeners) {
|
|
67
|
+
try {
|
|
68
|
+
listener(value);
|
|
69
|
+
} catch {
|
|
70
|
+
// One broken listener must not break the fan-out.
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
dispose() {
|
|
75
|
+
listeners.clear();
|
|
76
|
+
},
|
|
77
|
+
size() {
|
|
78
|
+
return listeners.size;
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|