@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.
Files changed (384) hide show
  1. package/README.md +75 -932
  2. package/package.json +26 -27
  3. package/src/api/anchor-conversion.ts +43 -0
  4. package/src/api/editor-state-types.ts +2 -1
  5. package/src/api/public-types.ts +504 -101
  6. package/src/api/session-state.ts +4 -0
  7. package/src/api/v3/README.md +91 -0
  8. package/src/api/v3/_create.ts +146 -0
  9. package/src/api/v3/_layer-metadata.ts +362 -0
  10. package/src/api/v3/_mocks.ts +84 -0
  11. package/src/api/v3/_runtime-handle.ts +162 -0
  12. package/src/api/v3/_ux-response.ts +73 -0
  13. package/src/api/v3/ai/_metadata-audit.ts +225 -0
  14. package/src/api/v3/ai/attach.ts +235 -0
  15. package/src/api/v3/ai/bundle.ts +132 -0
  16. package/src/api/v3/ai/explain.ts +144 -0
  17. package/src/api/v3/ai/export.ts +54 -0
  18. package/src/api/v3/ai/inspect.ts +118 -0
  19. package/src/api/v3/ai/policy.ts +77 -0
  20. package/src/api/v3/ai/replacement.ts +341 -0
  21. package/src/api/v3/ai/resolve.ts +133 -0
  22. package/src/api/v3/index.ts +79 -0
  23. package/src/api/v3/runtime/chart.ts +310 -0
  24. package/src/api/v3/runtime/clipboard.ts +81 -0
  25. package/src/api/v3/runtime/collab.ts +331 -0
  26. package/src/api/v3/runtime/content.ts +236 -0
  27. package/src/api/v3/runtime/document.ts +282 -0
  28. package/src/api/v3/runtime/formatting.ts +186 -0
  29. package/src/api/v3/runtime/geometry.ts +349 -0
  30. package/src/api/v3/runtime/layout.ts +108 -0
  31. package/src/api/v3/runtime/review.ts +129 -0
  32. package/src/api/v3/runtime/search.ts +74 -0
  33. package/src/api/v3/runtime/table.ts +63 -0
  34. package/src/api/v3/runtime/workflow.ts +434 -0
  35. package/src/api/v3/ui/_context.ts +86 -0
  36. package/src/api/v3/ui/_create.ts +65 -0
  37. package/src/api/v3/ui/_types.ts +520 -0
  38. package/src/api/v3/ui/chrome-composition.ts +342 -0
  39. package/src/{ui-tailwind/chrome → api/v3/ui}/chrome-preset-model.ts +11 -1
  40. package/src/api/v3/ui/chrome.ts +476 -0
  41. package/src/api/v3/ui/debug.ts +124 -0
  42. package/src/api/v3/ui/index.ts +64 -0
  43. package/src/api/v3/ui/overlays-visibility.ts +170 -0
  44. package/src/api/v3/ui/overlays.ts +427 -0
  45. package/src/api/v3/ui/scope.ts +71 -0
  46. package/src/api/v3/ui/session.ts +100 -0
  47. package/src/api/v3/ui/surface.ts +170 -0
  48. package/src/api/v3/ui/viewport.ts +303 -0
  49. package/src/core/commands/index.ts +28 -6
  50. package/src/core/commands/list-commands.ts +3 -2
  51. package/src/core/commands/section-layout-commands.ts +9 -8
  52. package/src/core/schema/text-schema.ts +16 -0
  53. package/src/core/selection/mapping.ts +33 -72
  54. package/src/core/state/editor-state.ts +96 -189
  55. package/src/index.ts +23 -4
  56. package/src/io/chart-preview-resolver.ts +1 -1
  57. package/src/io/docx-session.ts +36 -4797
  58. package/src/io/export/build-app-properties-xml.ts +1 -1
  59. package/src/io/export/serialize-comments.ts +1 -1
  60. package/src/io/export/serialize-headers-footers.ts +6 -1
  61. package/src/io/export/serialize-main-document.ts +45 -0
  62. package/src/io/export/serialize-run-formatting.ts +17 -2
  63. package/src/io/export/twip.ts +1 -1
  64. package/src/io/normalize/normalize-text.ts +27 -20
  65. package/src/io/ooxml/chart/parse-series.ts +1 -1
  66. package/src/io/ooxml/chart/resolve-color.ts +2 -2
  67. package/src/io/ooxml/chart/types.ts +1 -1
  68. package/src/io/ooxml/classify-embedding.ts +83 -33
  69. package/src/io/ooxml/parse-fill.ts +1 -1
  70. package/src/io/ooxml/parse-main-document.ts +71 -1
  71. package/src/io/ooxml/parse-object.ts +14 -10
  72. package/src/io/ooxml/parse-run-formatting.ts +47 -1
  73. package/src/io/ooxml/property-grab-bag.ts +2 -2
  74. package/src/io/ooxml/units.ts +11 -0
  75. package/src/io/ooxml/workflow-payload.ts +282 -7
  76. package/src/model/anchor.ts +85 -0
  77. package/src/model/canonical-document.ts +351 -15
  78. package/src/model/chart-types.ts +1 -1
  79. package/src/model/layout/index.ts +83 -0
  80. package/src/model/layout/page-graph-types.ts +181 -0
  81. package/src/model/layout/page-layout-snapshot.ts +105 -0
  82. package/src/model/layout/resolved-layout-types.ts +47 -0
  83. package/src/model/layout/runtime-page-graph-types.ts +102 -0
  84. package/src/model/paragraph-scope-ids.ts +72 -0
  85. package/src/model/review/comment-types.ts +112 -0
  86. package/src/model/review/index.ts +2 -0
  87. package/src/model/review/revision-types.ts +215 -0
  88. package/src/model/snapshot.ts +32 -0
  89. package/src/review/store/comment-store.ts +21 -47
  90. package/src/review/store/revision-types.ts +40 -198
  91. package/src/runtime/collab/base-doc-fingerprint.ts +6 -1
  92. package/src/runtime/collab/runtime-collab-sync.ts +13 -3
  93. package/src/runtime/collab-session.ts +1 -1
  94. package/src/runtime/debug/build-debug-inspector-snapshot.ts +686 -0
  95. package/src/runtime/debug/event-ring-buffer.ts +64 -0
  96. package/src/runtime/debug/probability-sampler.ts +18 -0
  97. package/src/runtime/debug/runtime-debug-facet.ts +67 -0
  98. package/src/runtime/debug/stage-tokens.ts +31 -0
  99. package/src/runtime/debug/telemetry-bus.ts +271 -0
  100. package/src/runtime/debug/types.ts +275 -0
  101. package/src/runtime/debug/wrap-ref-for-telemetry.ts +118 -0
  102. package/src/runtime/document-layout.ts +8 -6
  103. package/src/runtime/document-runtime.ts +843 -1141
  104. package/src/runtime/document-search.ts +1 -1
  105. package/src/runtime/edit-ops/index.ts +1 -1
  106. package/src/runtime/external-send-runtime.ts +1 -1
  107. package/src/runtime/formatting/document-lookup.ts +235 -0
  108. package/src/runtime/formatting/field/registry.ts +41 -0
  109. package/src/runtime/{field-resolver.ts → formatting/field/resolver.ts} +27 -2
  110. package/src/runtime/formatting/font-resolution.ts +83 -0
  111. package/src/runtime/formatting/formatting-context.ts +903 -0
  112. package/src/runtime/formatting/formatting-types.ts +157 -0
  113. package/src/runtime/{hyperlink-color-resolver.ts → formatting/hyperlink-color.ts} +2 -2
  114. package/src/runtime/formatting/index.ts +125 -0
  115. package/src/runtime/{resolved-numbering-geometry.ts → formatting/numbering/geometry.ts} +1 -1
  116. package/src/runtime/{numbering-prefix.ts → formatting/numbering/prefix.ts} +170 -3
  117. package/src/runtime/formatting/paragraph-style-resolver.ts +92 -0
  118. package/src/runtime/formatting/projector.ts +75 -0
  119. package/src/runtime/formatting/resolve-effective.ts +407 -0
  120. package/src/runtime/formatting/revision-display.ts +105 -0
  121. package/src/runtime/{paragraph-style-resolver.ts → formatting/style-cascade.ts} +84 -141
  122. package/src/runtime/{table-style-resolver.ts → formatting/table-style-resolver.ts} +1 -1
  123. package/src/runtime/formatting/telemetry-bridge.ts +106 -0
  124. package/src/runtime/{theme-color-resolver.ts → formatting/theme-color.ts} +2 -30
  125. package/src/runtime/geometry/caret-geometry.ts +164 -0
  126. package/src/runtime/geometry/geometry-facet.ts +364 -0
  127. package/src/runtime/geometry/geometry-types.ts +256 -0
  128. package/src/runtime/geometry/hit-test.ts +125 -0
  129. package/src/runtime/geometry/index.ts +71 -0
  130. package/src/runtime/geometry/inert-geometry-facet.ts +43 -0
  131. package/src/runtime/geometry/invalidation.ts +35 -0
  132. package/src/runtime/geometry/object-handles.ts +77 -0
  133. package/src/runtime/geometry/overlay-rects.ts +85 -0
  134. package/src/runtime/geometry/project-anchors.ts +100 -0
  135. package/src/runtime/geometry/project-fragments.ts +216 -0
  136. package/src/runtime/geometry/projector.ts +129 -0
  137. package/src/runtime/geometry/replacement-envelope.ts +130 -0
  138. package/src/runtime/geometry/viewport.ts +218 -0
  139. package/src/runtime/layout/compat-input-ledger.ts +211 -0
  140. package/src/runtime/layout/index.ts +6 -1
  141. package/src/runtime/layout/inert-layout-facet.ts +12 -7
  142. package/src/runtime/layout/layout-engine-instance.ts +189 -11
  143. package/src/runtime/layout/layout-engine-version.ts +450 -1
  144. package/src/runtime/layout/layout-facet-types.ts +60 -0
  145. package/src/runtime/layout/layout-measurement-provider.ts +13 -0
  146. package/src/runtime/layout/measurement-backend-canvas.ts +14 -2
  147. package/src/runtime/layout/measurement-backend-empirical.ts +23 -4
  148. package/src/runtime/layout/page-graph.ts +62 -209
  149. package/src/runtime/layout/page-story-resolver.ts +7 -12
  150. package/src/runtime/layout/paginated-layout-engine.ts +186 -11
  151. package/src/runtime/layout/project-block-fragments.ts +11 -0
  152. package/src/runtime/layout/projector.ts +90 -0
  153. package/src/runtime/layout/public-facet.ts +187 -442
  154. package/src/runtime/layout/resolved-formatting-state.ts +158 -26
  155. package/src/runtime/layout/table-render-plan.ts +1 -1
  156. package/src/runtime/prerender/cache-envelope.ts +6 -1
  157. package/src/runtime/prerender/prerender-document.ts +18 -23
  158. package/src/runtime/render/decoration-resolver.ts +1 -1
  159. package/src/runtime/render/render-frame-types.ts +20 -0
  160. package/src/runtime/render/render-kernel.ts +94 -25
  161. package/src/runtime/scopes/_formatting-seam.ts +262 -0
  162. package/src/runtime/scopes/_scope-dependencies.ts +49 -0
  163. package/src/runtime/scopes/action-validation.ts +356 -0
  164. package/src/runtime/scopes/attach-explanation.ts +102 -0
  165. package/src/runtime/scopes/audit-bundle.ts +71 -0
  166. package/src/runtime/scopes/compile-scope-bundle.ts +163 -0
  167. package/src/runtime/scopes/compile-scope.ts +262 -0
  168. package/src/runtime/scopes/compiler-service.ts +431 -0
  169. package/src/runtime/scopes/create-issue.ts +107 -0
  170. package/src/runtime/scopes/enumerate-scopes.ts +543 -0
  171. package/src/runtime/scopes/evidence.ts +233 -0
  172. package/src/runtime/scopes/index.ts +150 -0
  173. package/src/runtime/scopes/position-map.ts +214 -0
  174. package/src/runtime/scopes/preservation-boundary.ts +91 -0
  175. package/src/runtime/scopes/projector.ts +49 -0
  176. package/src/runtime/scopes/replaceability.ts +87 -0
  177. package/src/runtime/scopes/replacement/apply.ts +228 -0
  178. package/src/runtime/scopes/replacement/compile.ts +59 -0
  179. package/src/runtime/scopes/replacement/propose.ts +42 -0
  180. package/src/runtime/scopes/resolve-reference.ts +347 -0
  181. package/src/runtime/scopes/review-bundle.ts +141 -0
  182. package/src/runtime/scopes/scope-kinds/_paragraph-text.ts +57 -0
  183. package/src/runtime/scopes/scope-kinds/_table-text.ts +42 -0
  184. package/src/runtime/scopes/scope-kinds/comment-thread.ts +59 -0
  185. package/src/runtime/scopes/scope-kinds/field.ts +65 -0
  186. package/src/runtime/scopes/scope-kinds/heading.ts +84 -0
  187. package/src/runtime/scopes/scope-kinds/list-item.ts +77 -0
  188. package/src/runtime/scopes/scope-kinds/paragraph.ts +182 -0
  189. package/src/runtime/scopes/scope-kinds/revision.ts +62 -0
  190. package/src/runtime/scopes/scope-kinds/table-cell.ts +57 -0
  191. package/src/runtime/scopes/scope-kinds/table-row.ts +61 -0
  192. package/src/runtime/scopes/scope-kinds/table.ts +55 -0
  193. package/src/runtime/scopes/scope-range.ts +208 -0
  194. package/src/runtime/scopes/semantic-scope-types.ts +454 -0
  195. package/src/runtime/scopes/workflow-overlap.ts +92 -0
  196. package/src/runtime/selection/index.ts +1 -1
  197. package/src/runtime/structure-ops/fragment-insert.ts +1 -1
  198. package/src/runtime/structure-ops/index.ts +1 -1
  199. package/src/runtime/surface-projection.ts +232 -262
  200. package/src/runtime/units.ts +4 -2
  201. package/src/runtime/workflow/coordinator.ts +1348 -0
  202. package/src/runtime/workflow/derived-scope-resolver.ts +125 -0
  203. package/src/runtime/workflow/index.ts +25 -0
  204. package/src/runtime/workflow/markup-mode-policy.ts +98 -0
  205. package/src/runtime/{workflow-markup.ts → workflow/markup.ts} +6 -6
  206. package/src/runtime/workflow/metadata-persistence.ts +306 -0
  207. package/src/runtime/workflow/metadata-writer.ts +123 -0
  208. package/src/runtime/workflow/overlay-store.ts +690 -0
  209. package/src/runtime/workflow/projector.ts +127 -0
  210. package/src/runtime/{query-scopes.ts → workflow/query-scopes.ts} +3 -3
  211. package/src/runtime/{workflow-rail-segments.ts → workflow/rail/compose.ts} +60 -165
  212. package/src/runtime/workflow/rail/types.ts +198 -0
  213. package/src/runtime/workflow/scope-rail-composer.ts +39 -0
  214. package/src/runtime/{scope-resolver.ts → workflow/scope-resolver.ts} +3 -3
  215. package/src/runtime/workflow/scope-writer.ts +188 -0
  216. package/src/runtime/{tamper-gate.ts → workflow/tamper-gate.ts} +1 -1
  217. package/src/runtime/workflow/visibility-policy.ts +129 -0
  218. package/src/session/_sync-legacy.ts +66 -0
  219. package/src/session/export/embedded-reconstitute.ts +104 -0
  220. package/src/session/export/export-diagnostics.ts +85 -0
  221. package/src/session/export/export-validation.ts +110 -0
  222. package/src/session/export/index.ts +34 -0
  223. package/src/session/export/preservation-reattach.ts +30 -0
  224. package/src/session/export/serialize-dispatch.ts +165 -0
  225. package/src/session/export/stateful-export-pipeline.ts +432 -0
  226. package/src/session/export/stateful-export.ts +684 -0
  227. package/src/session/import/canonical-assembly.ts +227 -0
  228. package/src/session/import/diagnostics-session.ts +54 -0
  229. package/src/session/import/embedded-discovery.ts +225 -0
  230. package/src/session/import/embedded-offload.ts +337 -0
  231. package/src/session/import/import-diagnostics.ts +69 -0
  232. package/src/session/import/loader-types.ts +313 -0
  233. package/src/session/import/loader.ts +1834 -0
  234. package/src/session/import/normalize.ts +195 -0
  235. package/src/session/import/package-parts.ts +217 -0
  236. package/src/session/import/package-read.ts +195 -0
  237. package/src/session/import/parse-orchestration.ts +105 -0
  238. package/src/session/import/part-constants.ts +70 -0
  239. package/src/session/import/part-discovery.ts +94 -0
  240. package/src/session/import/preservation-index.ts +46 -0
  241. package/src/{runtime/read-only-diagnostics-runtime.ts → session/import/read-only-diagnostics.ts} +24 -3
  242. package/src/session/import/review-import.ts +508 -0
  243. package/src/session/import/styles-consolidation.ts +281 -0
  244. package/src/session/import/workflow-scope-import.ts +256 -0
  245. package/src/session/index.ts +37 -0
  246. package/src/session/session-state.ts +69 -0
  247. package/src/session/session.ts +532 -0
  248. package/src/session/shared/protection.ts +228 -0
  249. package/src/session/shared/session-utils.ts +82 -0
  250. package/src/session/types.ts +499 -0
  251. package/src/shell/chart-snapshots.ts +96 -0
  252. package/src/shell/media-previews.ts +85 -0
  253. package/src/shell/overlay-anchor-bridge.ts +53 -0
  254. package/src/shell/paste-adapter.ts +23 -0
  255. package/src/shell/ref-commands.ts +1697 -0
  256. package/src/shell/ref-utilities.ts +48 -0
  257. package/src/shell/search.ts +51 -0
  258. package/src/{ui/editor-runtime-boundary.ts → shell/session-bootstrap.ts} +243 -67
  259. package/src/shell/ui-subscriber-channels.ts +81 -0
  260. package/src/shell/use-collab-sync.ts +116 -0
  261. package/src/ui/WordReviewEditor.tsx +496 -2051
  262. package/src/ui/editor-shell-view.tsx +30 -1
  263. package/src/ui/editor-surface-controller.tsx +49 -1
  264. package/src/ui/headless/revision-decoration-model.ts +83 -0
  265. package/src/{ui-tailwind/chrome → ui/headless}/role-action-sets.ts +1 -1
  266. package/src/ui/headless/scoped-chrome-policy.ts +2 -2
  267. package/src/ui/headless/selection-tool-context.ts +1 -1
  268. package/src/ui/headless/selection-tool-resolver.ts +1 -1
  269. package/src/ui/runtime-shortcut-dispatch.ts +46 -1
  270. package/src/ui/ui-controller-factory.ts +221 -0
  271. package/src/ui-tailwind/chart/ChartSurface.tsx +2 -2
  272. package/src/ui-tailwind/chart/layout/legend-layout.ts +1 -1
  273. package/src/ui-tailwind/chart/layout/plot-area.ts +2 -2
  274. package/src/ui-tailwind/chart/layout/title-layout.ts +1 -1
  275. package/src/ui-tailwind/chart/render/area.tsx +3 -3
  276. package/src/ui-tailwind/chart/render/bar-column.tsx +3 -3
  277. package/src/ui-tailwind/chart/render/bubble.tsx +3 -3
  278. package/src/ui-tailwind/chart/render/combo.tsx +2 -2
  279. package/src/ui-tailwind/chart/render/data-labels.tsx +2 -2
  280. package/src/ui-tailwind/chart/render/font-metrics.ts +2 -2
  281. package/src/ui-tailwind/chart/render/line.tsx +3 -3
  282. package/src/ui-tailwind/chart/render/pie.tsx +6 -6
  283. package/src/ui-tailwind/chart/render/scatter.tsx +3 -3
  284. package/src/ui-tailwind/chart/render/svg-primitives.ts +3 -3
  285. package/src/ui-tailwind/chart/render/unsupported.tsx +2 -2
  286. package/src/ui-tailwind/chrome/build-context-menu-entries.ts +88 -0
  287. package/src/ui-tailwind/chrome/chrome-preset-toolbar.tsx +1 -1
  288. package/src/ui-tailwind/chrome/collab-send-to-supplier-button.tsx +1 -1
  289. package/src/ui-tailwind/chrome/collab-tamper-banner.tsx +1 -1
  290. package/src/ui-tailwind/chrome/collab-top-nav-container.tsx +1 -1
  291. package/src/ui-tailwind/chrome/editor-action-registry.ts +553 -0
  292. package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +182 -0
  293. package/src/ui-tailwind/chrome/local-surface-arbiter.ts +534 -0
  294. package/src/ui-tailwind/chrome/resolve-target-kind.ts +226 -0
  295. package/src/ui-tailwind/chrome/tw-alert-banner.tsx +38 -4
  296. package/src/ui-tailwind/chrome/tw-context-band.tsx +125 -0
  297. package/src/ui-tailwind/chrome/tw-context-menu-portal.tsx +248 -0
  298. package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +42 -1
  299. package/src/ui-tailwind/chrome/tw-selection-anchor-resolver.ts +8 -7
  300. package/src/ui-tailwind/chrome/tw-selection-tool-blocked.tsx +38 -4
  301. package/src/ui-tailwind/chrome/tw-selection-tool-comment.tsx +104 -6
  302. package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +66 -7
  303. package/src/ui-tailwind/chrome/tw-selection-tool-workflow.tsx +54 -8
  304. package/src/ui-tailwind/chrome/tw-shortcut-hint.tsx +7 -1
  305. package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +33 -0
  306. package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +78 -1
  307. package/src/ui-tailwind/chrome/tw-table-grip-layer.tsx +16 -8
  308. package/src/ui-tailwind/chrome/tw-workspace-chrome-host.tsx +276 -0
  309. package/src/ui-tailwind/chrome/use-context-menu-controller.ts +201 -0
  310. package/src/ui-tailwind/chrome-overlay/chrome-overlay-projector.ts +1 -1
  311. package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +22 -4
  312. package/src/ui-tailwind/chrome-overlay/tw-comment-balloon-layer.tsx +1 -1
  313. package/src/ui-tailwind/chrome-overlay/tw-locked-block-layer.tsx +1 -1
  314. package/src/ui-tailwind/chrome-overlay/tw-object-selection-overlay.tsx +11 -5
  315. package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +197 -3
  316. package/src/ui-tailwind/chrome-overlay/tw-revision-margin-bar-layer.tsx +1 -1
  317. package/src/ui-tailwind/chrome-overlay/tw-scope-card-layer.tsx +35 -6
  318. package/src/ui-tailwind/chrome-overlay/tw-scope-rail-layer.tsx +24 -16
  319. package/src/ui-tailwind/chrome-overlay/tw-table-continuation-header.tsx +1 -1
  320. package/src/ui-tailwind/debug/README.md +57 -0
  321. package/src/ui-tailwind/debug/index.ts +3 -0
  322. package/src/ui-tailwind/debug/tw-debug-overlay.tsx +186 -0
  323. package/src/ui-tailwind/debug/tw-debug-presentation.tsx +80 -0
  324. package/src/ui-tailwind/debug/tw-debug-top-bar.tsx +83 -0
  325. package/src/ui-tailwind/editor-surface/chart-node-view.tsx +2 -2
  326. package/src/ui-tailwind/editor-surface/float-wrap-resolver.ts +1 -1
  327. package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +135 -10
  328. package/src/ui-tailwind/editor-surface/pm-decorations.ts +40 -13
  329. package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +1 -1
  330. package/src/ui-tailwind/editor-surface/pm-schema.ts +1 -1
  331. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +3 -3
  332. package/src/ui-tailwind/editor-surface/predicted-tag-preflight.ts +1 -1
  333. package/src/ui-tailwind/editor-surface/remote-cursor-plugin.ts +2 -2
  334. package/src/ui-tailwind/editor-surface/scroll-anchor.ts +91 -9
  335. package/src/ui-tailwind/editor-surface/shape-renderer.ts +1 -1
  336. package/src/ui-tailwind/editor-surface/surface-layer.ts +1 -1
  337. package/src/ui-tailwind/editor-surface/tw-opaque-block.tsx +1 -1
  338. package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +23 -6
  339. package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +132 -22
  340. package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +1 -1
  341. package/src/ui-tailwind/index.ts +0 -5
  342. package/src/ui-tailwind/overlay-anchor-bridge-context.tsx +33 -0
  343. package/src/ui-tailwind/page-stack/floating-image-overlay-model.ts +66 -29
  344. package/src/ui-tailwind/page-stack/tw-floating-image-layer.tsx +25 -2
  345. package/src/ui-tailwind/review/comment-markdown-renderer.tsx +15 -0
  346. package/src/ui-tailwind/review/tw-review-rail.tsx +92 -4
  347. package/src/ui-tailwind/review/tw-workflow-tab.tsx +1 -1
  348. package/src/ui-tailwind/review-workspace/page-chrome.ts +210 -0
  349. package/src/ui-tailwind/review-workspace/page-shell-metrics.ts +101 -0
  350. package/src/ui-tailwind/review-workspace/paragraph-layout.ts +115 -0
  351. package/src/ui-tailwind/review-workspace/selection-toolbar-placement.ts +97 -0
  352. package/src/ui-tailwind/review-workspace/tw-review-workspace-navigator.tsx +130 -0
  353. package/src/ui-tailwind/review-workspace/tw-review-workspace-page-toolbar.tsx +240 -0
  354. package/src/ui-tailwind/review-workspace/tw-review-workspace-rail.tsx +59 -0
  355. package/src/ui-tailwind/review-workspace/types.ts +408 -0
  356. package/src/ui-tailwind/review-workspace/use-chrome-policy.ts +104 -0
  357. package/src/ui-tailwind/review-workspace/use-derived-view-state.ts +151 -0
  358. package/src/ui-tailwind/review-workspace/use-diagnostics-signal.ts +70 -0
  359. package/src/ui-tailwind/review-workspace/use-grabbed-segment-offsets.ts +40 -0
  360. package/src/ui-tailwind/review-workspace/use-layout-facet-render-signal.ts +55 -0
  361. package/src/ui-tailwind/review-workspace/use-page-markers.ts +130 -0
  362. package/src/ui-tailwind/review-workspace/use-pm-surface-capture.ts +60 -0
  363. package/src/ui-tailwind/review-workspace/use-review-rail-state.ts +63 -0
  364. package/src/ui-tailwind/review-workspace/use-scope-card-state.ts +170 -0
  365. package/src/ui-tailwind/review-workspace/use-scroll-root-capture.ts +28 -0
  366. package/src/ui-tailwind/review-workspace/use-selection-toolbar-placement.ts +113 -0
  367. package/src/ui-tailwind/review-workspace/use-shell-selection-anchor-bridge.ts +120 -0
  368. package/src/ui-tailwind/review-workspace/use-status-bar-page-facts.ts +55 -0
  369. package/src/ui-tailwind/review-workspace/use-viewport-dimensions.ts +43 -0
  370. package/src/ui-tailwind/review-workspace/use-workspace-arbiter.ts +25 -0
  371. package/src/ui-tailwind/review-workspace/use-workspace-composition.ts +86 -0
  372. package/src/ui-tailwind/review-workspace/use-workspace-side-effects.ts +150 -0
  373. package/src/ui-tailwind/theme/editor-theme.css +25 -0
  374. package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +2 -2
  375. package/src/ui-tailwind/toolbar/tw-toolbar.tsx +61 -98
  376. package/src/ui-tailwind/tw-review-workspace.tsx +521 -1802
  377. package/src/ui-tailwind/ui-api-context.tsx +43 -0
  378. package/src/ui-tailwind/ui-shell-channels-context.tsx +49 -0
  379. package/src/validation/compatibility-engine.ts +6 -6
  380. package/src/runtime/styles-cascade.ts +0 -33
  381. package/src/ui-tailwind/chrome/tw-mode-dock.tsx +0 -85
  382. /package/src/runtime/{page-number-format.ts → formatting/field/page-number-format.ts} +0 -0
  383. /package/src/runtime/{ai-action-policy.ts → workflow/ai-action-policy.ts} +0 -0
  384. /package/src/runtime/{scope-tag-registry.ts → workflow/scope-tag-registry.ts} +0 -0
@@ -0,0 +1,337 @@
1
+ /**
2
+ * P8 Step 7 — load-time offload of `offloadable` embedded documents
3
+ * to host storage.
4
+ *
5
+ * Contract summary (architecture §P8):
6
+ * - Runs once per `open()`. Iterates the embedded-document manifest
7
+ * list produced by `collectEmbeddedDocuments`. Filters to entries
8
+ * whose classifier-assigned `kind === "offloadable"`.
9
+ * - If `hostAdapter.storeEmbeddedDocument` is present: materialise
10
+ * each offloadable entry's bytes via the manifest's lazy `bytes()`
11
+ * accessor, compute sha-256, call the adapter, and emit an
12
+ * `EmbeddingOffloadEntry` record carrying everything needed for
13
+ * export-time reconstitution (storage reference + inline-bytes
14
+ * P3 fallback).
15
+ * - If the adapter is absent, OR if `storeEmbeddedDocument` rejects /
16
+ * throws for a specific entry, that entry silently degrades to
17
+ * `store-only` semantics — no record is emitted, bytes stay on
18
+ * the parent package via the existing opaque-preservation path.
19
+ * - On reopen of a previously-offloaded package, the entries are
20
+ * instead rehydrated from `customXml/item1.xml` under the
21
+ * `bw:embeddings` namespace; see `hydrateOffloadEntriesFromPayload`.
22
+ *
23
+ * Scope of this module: load-side only. The export-side mirror
24
+ * (writes customXml namespace, calls `loadEmbeddedDocument`, rebuilds
25
+ * package parts) lives at `src/session/export/embedded-reconstitute.ts`.
26
+ *
27
+ * P6 clean — imports from api/**, io/** (opc + ooxml), model/**,
28
+ * preservation/**, shared session utilities only.
29
+ */
30
+
31
+ import type {
32
+ EditorHostAdapter,
33
+ EmbeddedDocumentManifestLike,
34
+ StorageReference,
35
+ } from "../../api/public-types.ts";
36
+ import {
37
+ decodeBytesBase64,
38
+ encodeBytesBase64,
39
+ sha256Hex,
40
+ } from "../../io/source-package-provenance.ts";
41
+ import type { EmbeddedDocumentManifest } from "../types.ts";
42
+ import type { EditorStatePayload } from "../../io/ooxml/workflow-payload.ts";
43
+
44
+ /**
45
+ * Full record for a single offloaded embedded document. Carries the
46
+ * metadata the export path needs to rebuild the package part when
47
+ * the host's `loadEmbeddedDocument` succeeds, AND the inline-bytes
48
+ * base64 fallback that keeps export byte-identical when the host
49
+ * returns null / throws.
50
+ */
51
+ export interface EmbeddingOffloadEntry {
52
+ /** Manifest id — stable across open/export (content-fingerprint). */
53
+ readonly embeddedDocId: string;
54
+ /** Relationship id the source document uses for this embedding. */
55
+ readonly relationshipId: string;
56
+ /** Absolute OPC part path the embedding was extracted from. */
57
+ readonly sourcePartPath: string;
58
+ /** OPC content type. Preserved verbatim across round-trip. */
59
+ readonly contentType: string;
60
+ /** SHA-256 hex digest of the embedding bytes. */
61
+ readonly sha256: string;
62
+ /** Opaque storage handle the host returned. */
63
+ readonly storageReference: StorageReference;
64
+ /**
65
+ * Base64-encoded copy of the embedding bytes. Authoritative P3
66
+ * fallback — every entry carries this regardless of whether the
67
+ * host implemented `storeEmbeddedDocument`, so export reconstitution
68
+ * never fails on storage unavailability.
69
+ */
70
+ readonly inlineBytes: string;
71
+ }
72
+
73
+ /**
74
+ * Output of `processEmbeddedOffload`. `entries` is empty when no
75
+ * adapter is available OR when zero offloadable manifests were found
76
+ * OR when every offloadable adapter call failed.
77
+ */
78
+ export interface EmbeddedOffloadResult {
79
+ readonly entries: readonly EmbeddingOffloadEntry[];
80
+ /**
81
+ * Absolute part paths of every successfully offloaded embedding.
82
+ * Passed into `buildImportPreservation`'s `ownedPartPaths` list so
83
+ * those parts are EXCLUDED from preservation — the export
84
+ * reconstitute path is the sole writer for them.
85
+ */
86
+ readonly ownedPartPaths: readonly string[];
87
+ }
88
+
89
+ /**
90
+ * Parameters accepted by `processEmbeddedOffload`.
91
+ */
92
+ export interface ProcessEmbeddedOffloadParams {
93
+ /** Document id passed to the host adapter. */
94
+ readonly parentDocumentId: string;
95
+ /** Full manifest list from `collectEmbeddedDocuments`. */
96
+ readonly manifests: readonly EmbeddedDocumentManifest[];
97
+ /** Host adapter; `undefined` skips offload entirely. */
98
+ readonly hostAdapter: EditorHostAdapter | undefined;
99
+ /**
100
+ * Lookup from manifest relationship id → absolute OPC part path
101
+ * (as resolved via `resolveRelationshipTarget`). Allows this module
102
+ * to stay decoupled from `part-manifest.ts` resolution logic —
103
+ * the loader already resolved every relationship it walked.
104
+ */
105
+ readonly resolvePartPath: (relationshipId: string) => string | undefined;
106
+ /** OPC content type for each part path. */
107
+ readonly resolveContentType: (partPath: string) => string | undefined;
108
+ }
109
+
110
+ /**
111
+ * Run the load-time offload pass. Safe to call with any of the
112
+ * parameters in a "disabling" shape — no adapter, empty manifests,
113
+ * zero offloadable entries — all return `{ entries: [], ownedPartPaths: [] }`.
114
+ *
115
+ * Swallowed diagnostics: `storeEmbeddedDocument` rejections / throws
116
+ * are caught per-entry. The offending manifest silently falls back to
117
+ * `store-only` semantics. Callers that want visibility should scan
118
+ * the returned entry list against the input manifests and diff.
119
+ */
120
+ export async function processEmbeddedOffload(
121
+ params: ProcessEmbeddedOffloadParams,
122
+ ): Promise<EmbeddedOffloadResult> {
123
+ const { parentDocumentId, manifests, hostAdapter, resolvePartPath, resolveContentType } = params;
124
+ if (!hostAdapter?.storeEmbeddedDocument) {
125
+ return EMPTY_RESULT;
126
+ }
127
+ const offloadables = manifests.filter((m) => m.kind === "offloadable");
128
+ if (offloadables.length === 0) {
129
+ return EMPTY_RESULT;
130
+ }
131
+
132
+ const entries: EmbeddingOffloadEntry[] = [];
133
+ const ownedPartPaths: string[] = [];
134
+ for (const manifest of offloadables) {
135
+ const sourcePartPath = resolvePartPath(manifest.relationshipId);
136
+ if (!sourcePartPath) continue; // Shouldn't happen — defensive.
137
+ let bytes: Uint8Array;
138
+ try {
139
+ bytes = manifest.bytes();
140
+ } catch {
141
+ // Lazy accessor failed — fall back to store-only. The
142
+ // preservation path will still carry the bytes (the source
143
+ // package part is untouched).
144
+ continue;
145
+ }
146
+ const contentType = resolveContentType(sourcePartPath) ?? "application/octet-stream";
147
+ const sha = sha256Hex(bytes);
148
+ const manifestLike: EmbeddedDocumentManifestLike = {
149
+ id: manifest.id,
150
+ kind: manifest.kind,
151
+ size: manifest.size,
152
+ relationshipId: manifest.relationshipId,
153
+ ...(manifest.progId !== undefined ? { progId: manifest.progId } : {}),
154
+ ...(manifest.mimeType !== undefined ? { mimeType: manifest.mimeType } : {}),
155
+ ...(manifest.filename !== undefined ? { filename: manifest.filename } : {}),
156
+ };
157
+ let hostRef: StorageReference;
158
+ try {
159
+ hostRef = await hostAdapter.storeEmbeddedDocument({
160
+ parentDocumentId,
161
+ embedded: manifestLike,
162
+ bytes,
163
+ });
164
+ } catch {
165
+ // Host rejected — this specific entry falls back to store-only.
166
+ // Other offloadable entries in the same package are unaffected.
167
+ continue;
168
+ }
169
+ // Defensive: validate the adapter's return shape. A host could
170
+ // return `undefined`, `null`, or a malformed object; TypeScript's
171
+ // `Promise<StorageReference>` annotation is a compile-time
172
+ // contract, not a runtime check. On malformed returns, fall back
173
+ // to store-only for this entry.
174
+ if (
175
+ typeof hostRef !== "object" ||
176
+ hostRef === null ||
177
+ typeof hostRef.providerId !== "string" ||
178
+ typeof hostRef.handle !== "string"
179
+ ) {
180
+ continue;
181
+ }
182
+ // Per the `StorageReference.sha256` contract in `public-types.ts`:
183
+ // the session computes the sha; the reference round-trips it
184
+ // unchanged. Override whatever the host returned with the value
185
+ // we computed from the authoritative bytes so tamper-detection at
186
+ // rehydrate time compares against the session's own measurement.
187
+ const storageReference: StorageReference = {
188
+ providerId: hostRef.providerId,
189
+ handle: hostRef.handle,
190
+ sha256: sha,
191
+ };
192
+ entries.push({
193
+ embeddedDocId: manifest.id,
194
+ relationshipId: manifest.relationshipId,
195
+ sourcePartPath,
196
+ contentType,
197
+ sha256: sha,
198
+ storageReference,
199
+ inlineBytes: encodeBytesBase64(bytes),
200
+ });
201
+ ownedPartPaths.push(sourcePartPath);
202
+ }
203
+ return { entries, ownedPartPaths };
204
+ }
205
+
206
+ /**
207
+ * Rehydrate offload entries from a `bw:embeddings` customXml payload
208
+ * the session read during `parseWorkflowPayloadEnvelopeFromPackage`.
209
+ * Returns an empty result when the payload has no `embeddings`
210
+ * namespace entry, or when the entry's inline JSON is malformed.
211
+ *
212
+ * Used on REOPEN: when a previously-offloaded package is opened
213
+ * again, we don't re-run the adapter — we trust the customXml record.
214
+ * The reconstitute pass at export uses these entries exactly as if
215
+ * they had come from a fresh offload pass.
216
+ */
217
+ export function hydrateOffloadEntriesFromPayload(
218
+ payload: EditorStatePayload | undefined,
219
+ ): EmbeddedOffloadResult {
220
+ if (!payload) return EMPTY_RESULT;
221
+ const entry = payload.entries.find((e) => e.namespace === "embeddings");
222
+ if (!entry || entry.inline === undefined || entry.malformedInline) {
223
+ return EMPTY_RESULT;
224
+ }
225
+ const parsed = parseEmbeddingsInline(entry.inline);
226
+ if (!parsed) return EMPTY_RESULT;
227
+ return {
228
+ entries: parsed,
229
+ ownedPartPaths: parsed.map((e) => e.sourcePartPath),
230
+ };
231
+ }
232
+
233
+ /**
234
+ * Schema the `bw:embeddings` inline JSON uses. Versioned so future
235
+ * field additions remain non-breaking. Current version: `1`.
236
+ */
237
+ export interface EmbeddingsInlineSchema {
238
+ readonly version: 1;
239
+ readonly entries: readonly EmbeddingOffloadEntry[];
240
+ }
241
+
242
+ /**
243
+ * Serialise the collected offload entries into the JSON shape the
244
+ * customXml `bw:embeddings` inline block expects.
245
+ */
246
+ export function buildEmbeddingsInlinePayload(
247
+ entries: readonly EmbeddingOffloadEntry[],
248
+ ): EmbeddingsInlineSchema {
249
+ return { version: 1, entries };
250
+ }
251
+
252
+ // ---------------------------------------------------------------------------
253
+ // Internals
254
+ // ---------------------------------------------------------------------------
255
+
256
+ const EMPTY_RESULT: EmbeddedOffloadResult = Object.freeze({
257
+ entries: Object.freeze([]) as readonly EmbeddingOffloadEntry[],
258
+ ownedPartPaths: Object.freeze([]) as readonly string[],
259
+ });
260
+
261
+ // Base64 encode/decode reach the cross-runtime helpers in
262
+ // `src/io/source-package-provenance.ts` — those handle both Node
263
+ // (Buffer) and browser (btoa/atob) contexts. Direct call; the earlier
264
+ // local `encodeBase64` alias was unnecessary indirection.
265
+
266
+ function parseEmbeddingsInline(
267
+ inline: unknown,
268
+ ): EmbeddingOffloadEntry[] | undefined {
269
+ if (
270
+ typeof inline !== "object" ||
271
+ inline === null ||
272
+ !("entries" in inline) ||
273
+ !Array.isArray((inline as { entries: unknown }).entries)
274
+ ) {
275
+ return undefined;
276
+ }
277
+ // Forward-compat: reject unknown schema versions rather than
278
+ // attempting a best-effort parse that could silently drop fields a
279
+ // future schema depends on. `version` is absent in a malformed
280
+ // payload (parseEmbeddingsInline rejects below via entry-shape
281
+ // checks anyway); a non-1 version is a genuine forward-compat
282
+ // break that should surface as "no offload entries available"
283
+ // rather than a quiet partial rehydration.
284
+ const version = (inline as { version?: unknown }).version;
285
+ if (version !== undefined && version !== 1) {
286
+ return undefined;
287
+ }
288
+ const raw = (inline as { entries: unknown[] }).entries;
289
+ const out: EmbeddingOffloadEntry[] = [];
290
+ for (const item of raw) {
291
+ if (typeof item !== "object" || item === null) continue;
292
+ const r = item as Record<string, unknown>;
293
+ if (
294
+ typeof r.embeddedDocId !== "string" ||
295
+ typeof r.relationshipId !== "string" ||
296
+ typeof r.sourcePartPath !== "string" ||
297
+ typeof r.contentType !== "string" ||
298
+ typeof r.sha256 !== "string" ||
299
+ typeof r.inlineBytes !== "string" ||
300
+ typeof r.storageReference !== "object" ||
301
+ r.storageReference === null
302
+ ) {
303
+ continue;
304
+ }
305
+ const ref = r.storageReference as Record<string, unknown>;
306
+ if (
307
+ typeof ref.providerId !== "string" ||
308
+ typeof ref.handle !== "string" ||
309
+ typeof ref.sha256 !== "string"
310
+ ) {
311
+ continue;
312
+ }
313
+ out.push({
314
+ embeddedDocId: r.embeddedDocId,
315
+ relationshipId: r.relationshipId,
316
+ sourcePartPath: r.sourcePartPath,
317
+ contentType: r.contentType,
318
+ sha256: r.sha256,
319
+ inlineBytes: r.inlineBytes,
320
+ storageReference: {
321
+ providerId: ref.providerId,
322
+ handle: ref.handle,
323
+ sha256: ref.sha256,
324
+ },
325
+ });
326
+ }
327
+ return out;
328
+ }
329
+
330
+ /**
331
+ * Decode the base64 inline-bytes fallback back into raw bytes. Used
332
+ * by the export reconstitute path when `loadEmbeddedDocument` is
333
+ * unavailable or returns null.
334
+ */
335
+ export function decodeInlineBytes(base64: string): Uint8Array {
336
+ return decodeBytesBase64(base64);
337
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Typed warning-record builders for the session import layer.
3
+ *
4
+ * Slice 3b of refactor/01 package-session. Extracted from
5
+ * src/io/docx-session.ts (duplicate inline `.map()` transforms at
6
+ * the diagnostics assembly site in both the sync and async load paths).
7
+ *
8
+ * Each function maps a parse-layer diagnostic array into the
9
+ * `CanonicalDocument.diagnostics.warnings` record shape so call sites
10
+ * stay concise and IDs stay consistent.
11
+ *
12
+ * Contract P6 clean. Depends only on model types and the two parser
13
+ * modules that define the input diagnostic shapes.
14
+ */
15
+
16
+ import type { CanonicalDocument } from "../../model/canonical-document.ts";
17
+ import type { RevisionImportDiagnostic } from "../../io/ooxml/parse-revisions.ts";
18
+ import type { CommentImportDiagnostic } from "../../io/ooxml/parse-comments.ts";
19
+
20
+ /** Warning shape carried on `CanonicalDocument.diagnostics.warnings`. */
21
+ type CanonicalWarning = CanonicalDocument["diagnostics"]["warnings"][number];
22
+
23
+ /**
24
+ * Map main-document revision diagnostics into stable warning records.
25
+ * Uses `diagnostic:revision-import-N` / `warning:revision-import-<id>`
26
+ * naming so IDs are deterministic across serialization round-trips.
27
+ */
28
+ export function mapRevisionDiagnosticsToWarnings(
29
+ diagnostics: readonly RevisionImportDiagnostic[],
30
+ ): CanonicalWarning[] {
31
+ return diagnostics.map((diagnostic, index) => ({
32
+ diagnosticId: `diagnostic:revision-import-${index + 1}`,
33
+ warningId: `warning:revision-import-${diagnostic.revisionId}`,
34
+ source: "review" as const,
35
+ message: diagnostic.message,
36
+ }));
37
+ }
38
+
39
+ /**
40
+ * Map story-part (header / footer) revision diagnostics into stable
41
+ * warning records. Uses `diagnostic:story-revision-import-N` /
42
+ * `warning:story-revision-import-<id>` naming to avoid colliding with
43
+ * the main-document revision warnings above.
44
+ */
45
+ export function mapStoryRevisionDiagnosticsToWarnings(
46
+ diagnostics: readonly RevisionImportDiagnostic[],
47
+ ): CanonicalWarning[] {
48
+ return diagnostics.map((diagnostic, index) => ({
49
+ diagnosticId: `diagnostic:story-revision-import-${index + 1}`,
50
+ warningId: `warning:story-revision-import-${diagnostic.revisionId}`,
51
+ source: "review" as const,
52
+ message: diagnostic.message,
53
+ }));
54
+ }
55
+
56
+ /**
57
+ * Map comment-parse diagnostics into stable warning records. Uses
58
+ * `diagnostic:comment-import-N` / `warning:comment-import-<id>` naming.
59
+ */
60
+ export function mapCommentDiagnosticsToWarnings(
61
+ diagnostics: readonly CommentImportDiagnostic[],
62
+ ): CanonicalWarning[] {
63
+ return diagnostics.map((diagnostic, index) => ({
64
+ diagnosticId: `diagnostic:comment-import-${index + 1}`,
65
+ warningId: `warning:comment-import-${diagnostic.commentId}`,
66
+ source: "review" as const,
67
+ message: diagnostic.message,
68
+ }));
69
+ }