@beyondwork/docx-react-component 1.0.29 → 1.0.31

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 (383) hide show
  1. package/package.json +65 -96
  2. package/src/README.md +85 -0
  3. package/src/api/README.md +26 -0
  4. package/src/api/public-types.ts +1952 -0
  5. package/src/api/session-state.ts +62 -0
  6. package/src/compare/diff-engine.ts +623 -0
  7. package/src/compare/export-redlines.ts +280 -0
  8. package/src/compare/index.ts +25 -0
  9. package/src/compare/snapshot.ts +97 -0
  10. package/src/component-inventory.md +99 -0
  11. package/src/core/README.md +10 -0
  12. package/src/core/commands/README.md +3 -0
  13. package/{dist/chunk-TJBP2K4T.js → src/core/commands/formatting-commands.ts} +536 -196
  14. package/src/core/commands/image-commands.ts +373 -0
  15. package/src/core/commands/index.ts +1879 -0
  16. package/src/core/commands/list-commands.ts +565 -0
  17. package/src/core/commands/paragraph-layout-commands.ts +339 -0
  18. package/src/core/commands/review-commands.ts +108 -0
  19. package/{dist/core/commands/section-layout-commands.cjs → src/core/commands/section-layout-commands.ts} +340 -137
  20. package/src/core/commands/structural-helpers.ts +309 -0
  21. package/{dist/core/commands/style-commands.cjs → src/core/commands/style-commands.ts} +113 -65
  22. package/src/core/commands/table-structure-commands.ts +854 -0
  23. package/{dist/chunk-UZXBISGO.js → src/core/commands/text-commands.ts} +142 -86
  24. package/src/core/schema/README.md +3 -0
  25. package/src/core/schema/text-schema.ts +516 -0
  26. package/src/core/search/search-text.ts +357 -0
  27. package/src/core/selection/README.md +3 -0
  28. package/src/core/selection/mapping.ts +289 -0
  29. package/src/core/selection/review-anchors.ts +183 -0
  30. package/src/core/state/README.md +3 -0
  31. package/src/core/state/editor-state.ts +892 -0
  32. package/src/core/state/text-transaction.ts +869 -0
  33. package/src/formats/xlsx/io/parse-shared-strings.ts +41 -0
  34. package/src/formats/xlsx/io/parse-sheet.ts +459 -0
  35. package/src/formats/xlsx/io/parse-styles.ts +59 -0
  36. package/src/formats/xlsx/io/parse-workbook.ts +75 -0
  37. package/src/formats/xlsx/io/serialize-shared-strings.ts +72 -0
  38. package/src/formats/xlsx/io/serialize-sheet.ts +333 -0
  39. package/src/formats/xlsx/io/serialize-styles.ts +98 -0
  40. package/src/formats/xlsx/io/serialize-workbook.ts +429 -0
  41. package/src/formats/xlsx/io/xlsx-session.ts +314 -0
  42. package/src/formats/xlsx/model/cell.ts +189 -0
  43. package/src/formats/xlsx/model/sheet.ts +326 -0
  44. package/src/formats/xlsx/model/styles.ts +118 -0
  45. package/src/formats/xlsx/model/workbook.ts +453 -0
  46. package/src/formats/xlsx/runtime/cell-commands.ts +567 -0
  47. package/src/formats/xlsx/runtime/sheet-commands.ts +206 -0
  48. package/src/formats/xlsx/runtime/workbook-runtime.ts +177 -0
  49. package/src/formats/xlsx/runtime/workbook-transaction.ts +822 -0
  50. package/src/index.ts +142 -0
  51. package/src/io/README.md +10 -0
  52. package/src/io/docx-session.ts +3175 -0
  53. package/src/io/export/README.md +3 -0
  54. package/src/io/export/export-session.ts +220 -0
  55. package/src/io/export/minimal-docx.ts +115 -0
  56. package/src/io/export/reattach-preserved-parts.ts +54 -0
  57. package/src/io/export/serialize-comments.ts +947 -0
  58. package/src/io/export/serialize-footnotes.ts +394 -0
  59. package/src/io/export/serialize-headers-footers.ts +368 -0
  60. package/src/io/export/serialize-main-document.ts +1342 -0
  61. package/src/io/export/serialize-numbering.ts +218 -0
  62. package/src/io/export/serialize-revisions.ts +389 -0
  63. package/src/io/export/serialize-runtime-revisions.ts +463 -0
  64. package/src/io/export/serialize-tables.ts +174 -0
  65. package/src/io/export/split-review-boundaries.ts +356 -0
  66. package/src/io/export/split-story-blocks-for-runtime-revisions.ts +252 -0
  67. package/src/io/export/table-properties-xml.ts +318 -0
  68. package/src/io/normalize/README.md +3 -0
  69. package/src/io/normalize/normalize-text.ts +670 -0
  70. package/src/io/ooxml/README.md +3 -0
  71. package/src/io/ooxml/highlight-colors.ts +39 -0
  72. package/src/io/ooxml/numbering-sentinels.ts +44 -0
  73. package/src/io/ooxml/parse-comments.ts +852 -0
  74. package/src/io/ooxml/parse-complex-content.ts +287 -0
  75. package/src/io/ooxml/parse-fields.ts +834 -0
  76. package/src/io/ooxml/parse-footnotes.ts +952 -0
  77. package/src/io/ooxml/parse-headers-footers.ts +1212 -0
  78. package/src/io/ooxml/parse-inline-media.ts +461 -0
  79. package/src/io/ooxml/parse-main-document.ts +2947 -0
  80. package/src/io/ooxml/parse-numbering.ts +747 -0
  81. package/src/io/ooxml/parse-revisions.ts +1045 -0
  82. package/src/io/ooxml/parse-settings.ts +184 -0
  83. package/src/io/ooxml/parse-shapes.ts +296 -0
  84. package/src/io/ooxml/parse-styles.ts +639 -0
  85. package/src/io/ooxml/parse-tables.ts +627 -0
  86. package/src/io/ooxml/parse-theme.ts +346 -0
  87. package/src/io/ooxml/part-manifest.ts +136 -0
  88. package/src/io/ooxml/revision-boundaries.ts +475 -0
  89. package/src/io/ooxml/workflow-payload.ts +544 -0
  90. package/src/io/opc/README.md +3 -0
  91. package/src/io/opc/corrupt-package.ts +166 -0
  92. package/src/io/opc/docx-package.ts +74 -0
  93. package/src/io/opc/package-reader.ts +325 -0
  94. package/src/io/opc/package-writer.ts +273 -0
  95. package/src/io/source-package-provenance.ts +241 -0
  96. package/{dist/chunk-RMH72RZI.js → src/legal/bookmarks.ts} +130 -44
  97. package/src/legal/cross-references.ts +414 -0
  98. package/src/legal/defined-terms.ts +203 -0
  99. package/src/legal/index.ts +32 -0
  100. package/src/legal/signature-blocks.ts +259 -0
  101. package/src/model/README.md +3 -0
  102. package/src/model/canonical-document.ts +2722 -0
  103. package/src/model/cds-1.0.0.ts +212 -0
  104. package/src/model/snapshot.ts +760 -0
  105. package/src/preservation/README.md +3 -0
  106. package/src/preservation/markup-compatibility.ts +48 -0
  107. package/src/preservation/opaque-fragment-store.ts +89 -0
  108. package/src/preservation/opaque-region.ts +233 -0
  109. package/src/preservation/package-preservation.ts +113 -0
  110. package/src/preservation/preserved-part-manifest.ts +56 -0
  111. package/src/preservation/relationship-retention.ts +57 -0
  112. package/src/preservation/store.ts +255 -0
  113. package/src/review/README.md +16 -0
  114. package/src/review/store/README.md +3 -0
  115. package/src/review/store/comment-anchors.ts +70 -0
  116. package/src/review/store/comment-remapping.ts +154 -0
  117. package/src/review/store/comment-store.ts +349 -0
  118. package/src/review/store/comment-thread.ts +109 -0
  119. package/src/review/store/revision-actions.ts +423 -0
  120. package/src/review/store/revision-store.ts +323 -0
  121. package/src/review/store/revision-types.ts +182 -0
  122. package/src/review/store/runtime-comment-store.ts +43 -0
  123. package/src/runtime/README.md +3 -0
  124. package/src/runtime/ai-action-policy.ts +764 -0
  125. package/src/runtime/context-analytics.ts +824 -0
  126. package/src/runtime/document-layout.ts +332 -0
  127. package/src/runtime/document-locations.ts +521 -0
  128. package/src/runtime/document-navigation.ts +616 -0
  129. package/src/runtime/document-outline.ts +440 -0
  130. package/src/runtime/document-runtime.ts +4055 -0
  131. package/src/runtime/document-search.ts +145 -0
  132. package/src/runtime/event-refresh-hints.ts +137 -0
  133. package/src/runtime/numbering-prefix.ts +244 -0
  134. package/src/runtime/page-layout-estimation.ts +305 -0
  135. package/src/runtime/read-only-diagnostics-runtime.ts +241 -0
  136. package/src/runtime/resolved-numbering-geometry.ts +293 -0
  137. package/src/runtime/review-runtime.ts +44 -0
  138. package/src/runtime/revision-runtime.ts +107 -0
  139. package/src/runtime/session-capabilities.ts +192 -0
  140. package/src/runtime/story-context.ts +164 -0
  141. package/src/runtime/story-targeting.ts +162 -0
  142. package/src/runtime/suggestions-snapshot.ts +137 -0
  143. package/src/runtime/surface-projection.ts +1553 -0
  144. package/src/runtime/table-commands.ts +173 -0
  145. package/src/runtime/table-schema.ts +309 -0
  146. package/src/runtime/table-style-resolver.ts +409 -0
  147. package/src/runtime/view-state.ts +493 -0
  148. package/src/runtime/virtualized-rendering.ts +258 -0
  149. package/src/runtime/workflow-markup.ts +393 -0
  150. package/src/ui/README.md +30 -0
  151. package/src/ui/WordReviewEditor.tsx +5268 -0
  152. package/src/ui/browser-export.ts +52 -0
  153. package/src/ui/comments/README.md +3 -0
  154. package/src/ui/compatibility/README.md +3 -0
  155. package/src/ui/editor-command-bag.ts +127 -0
  156. package/src/ui/editor-runtime-boundary.ts +1558 -0
  157. package/src/ui/editor-shell-view.tsx +144 -0
  158. package/src/ui/editor-surface/README.md +3 -0
  159. package/src/ui/editor-surface-controller.tsx +66 -0
  160. package/src/ui/headless/comment-decoration-model.ts +124 -0
  161. package/src/ui/headless/preserve-editor-selection.ts +5 -0
  162. package/src/ui/headless/revision-decoration-model.ts +128 -0
  163. package/src/ui/headless/selection-helpers.ts +54 -0
  164. package/src/ui/headless/selection-tool-context.ts +19 -0
  165. package/src/ui/headless/selection-tool-resolver.ts +752 -0
  166. package/src/ui/headless/selection-tool-types.ts +129 -0
  167. package/src/ui/headless/selection-toolbar-model.ts +11 -0
  168. package/src/ui/headless/use-editor-keyboard.ts +103 -0
  169. package/src/ui/review/README.md +3 -0
  170. package/src/ui/runtime-shortcut-dispatch.ts +365 -0
  171. package/src/ui/runtime-snapshot-selectors.ts +197 -0
  172. package/src/ui/shared/revision-filters.ts +31 -0
  173. package/src/ui/status/README.md +3 -0
  174. package/src/ui/theme/README.md +3 -0
  175. package/src/ui/toolbar/README.md +3 -0
  176. package/src/ui/workflow-surface-blocked-rails.ts +94 -0
  177. package/src/ui-tailwind/chrome/chrome-preset-model.ts +107 -0
  178. package/src/ui-tailwind/chrome/chrome-preset-toolbar.tsx +15 -0
  179. package/src/ui-tailwind/chrome/responsive-chrome.ts +46 -0
  180. package/src/ui-tailwind/chrome/review-queue-bar.tsx +97 -0
  181. package/src/ui-tailwind/chrome/tw-alert-banner.tsx +64 -0
  182. package/src/ui-tailwind/chrome/tw-context-analytics-summary.tsx +122 -0
  183. package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +121 -0
  184. package/src/ui-tailwind/chrome/tw-layout-panel.tsx +114 -0
  185. package/src/ui-tailwind/chrome/tw-object-context-toolbar.tsx +30 -0
  186. package/src/ui-tailwind/chrome/tw-page-ruler.tsx +365 -0
  187. package/src/ui-tailwind/chrome/tw-selection-tool-blocked.tsx +23 -0
  188. package/src/ui-tailwind/chrome/tw-selection-tool-comment.tsx +35 -0
  189. package/src/ui-tailwind/chrome/tw-selection-tool-formatting.tsx +37 -0
  190. package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +303 -0
  191. package/src/ui-tailwind/chrome/tw-selection-tool-structure.tsx +116 -0
  192. package/src/ui-tailwind/chrome/tw-selection-tool-suggestion.tsx +29 -0
  193. package/src/ui-tailwind/chrome/tw-selection-tool-workflow.tsx +27 -0
  194. package/src/ui-tailwind/chrome/tw-selection-toolbar.tsx +186 -0
  195. package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +139 -0
  196. package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +250 -0
  197. package/src/ui-tailwind/chrome/tw-unsaved-modal.tsx +58 -0
  198. package/src/ui-tailwind/chrome/use-before-unload.ts +20 -0
  199. package/src/ui-tailwind/editor-surface/perf-probe.ts +179 -0
  200. package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +189 -0
  201. package/src/ui-tailwind/editor-surface/pm-contextual-ui.ts +31 -0
  202. package/src/ui-tailwind/editor-surface/pm-decorations.ts +411 -0
  203. package/src/ui-tailwind/editor-surface/pm-position-map.ts +123 -0
  204. package/src/ui-tailwind/editor-surface/pm-schema.ts +927 -0
  205. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +567 -0
  206. package/src/ui-tailwind/editor-surface/search-plugin.ts +168 -0
  207. package/src/ui-tailwind/editor-surface/surface-build-keys.ts +63 -0
  208. package/src/ui-tailwind/editor-surface/tw-caret.tsx +12 -0
  209. package/src/ui-tailwind/editor-surface/tw-editor-surface.tsx +150 -0
  210. package/src/ui-tailwind/editor-surface/tw-inline-token.tsx +129 -0
  211. package/src/ui-tailwind/editor-surface/tw-opaque-block.tsx +58 -0
  212. package/src/ui-tailwind/editor-surface/tw-paragraph-block.tsx +151 -0
  213. package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +1047 -0
  214. package/src/ui-tailwind/editor-surface/tw-segment-view.tsx +111 -0
  215. package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +503 -0
  216. package/src/ui-tailwind/index.ts +62 -0
  217. package/src/ui-tailwind/page-chrome-model.ts +27 -0
  218. package/src/ui-tailwind/review/tw-comment-sidebar.tsx +406 -0
  219. package/src/ui-tailwind/review/tw-health-panel.tsx +149 -0
  220. package/src/ui-tailwind/review/tw-review-rail.tsx +130 -0
  221. package/src/ui-tailwind/review/tw-revision-sidebar.tsx +164 -0
  222. package/src/ui-tailwind/status/tw-status-bar.tsx +65 -0
  223. package/{dist → src}/ui-tailwind/theme/editor-theme.css +58 -40
  224. package/src/ui-tailwind/toolbar/toolbar-layout.ts +47 -0
  225. package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +52 -0
  226. package/src/ui-tailwind/toolbar/tw-toolbar.tsx +1478 -0
  227. package/src/ui-tailwind/tw-review-workspace.tsx +1587 -0
  228. package/src/validation/README.md +3 -0
  229. package/src/validation/compatibility-engine.ts +878 -0
  230. package/src/validation/compatibility-report.ts +161 -0
  231. package/src/validation/diagnostics.ts +204 -0
  232. package/src/validation/docx-comment-proof.ts +720 -0
  233. package/src/validation/import-diagnostics.ts +128 -0
  234. package/src/validation/low-priority-word-surfaces.ts +373 -0
  235. package/dist/canonical-document-BLEbzL2J.d.cts +0 -844
  236. package/dist/canonical-document-BLEbzL2J.d.ts +0 -844
  237. package/dist/chunk-2FJS5GZM.js +0 -763
  238. package/dist/chunk-2FJS5GZM.js.map +0 -1
  239. package/dist/chunk-2OQBZS3F.js +0 -446
  240. package/dist/chunk-2OQBZS3F.js.map +0 -1
  241. package/dist/chunk-2S7W4KFO.js +0 -127
  242. package/dist/chunk-2S7W4KFO.js.map +0 -1
  243. package/dist/chunk-2TG72QSW.js +0 -3874
  244. package/dist/chunk-2TG72QSW.js.map +0 -1
  245. package/dist/chunk-36QNIZBO.js +0 -532
  246. package/dist/chunk-36QNIZBO.js.map +0 -1
  247. package/dist/chunk-4AQOYAW4.js +0 -3069
  248. package/dist/chunk-4AQOYAW4.js.map +0 -1
  249. package/dist/chunk-4D5EWJ3P.js +0 -77
  250. package/dist/chunk-4D5EWJ3P.js.map +0 -1
  251. package/dist/chunk-5FN54NDH.js +0 -2257
  252. package/dist/chunk-5FN54NDH.js.map +0 -1
  253. package/dist/chunk-BOYGQYRQ.js +0 -7306
  254. package/dist/chunk-BOYGQYRQ.js.map +0 -1
  255. package/dist/chunk-CN3XMECL.js +0 -212
  256. package/dist/chunk-CN3XMECL.js.map +0 -1
  257. package/dist/chunk-EBI3BX6U.js +0 -164
  258. package/dist/chunk-EBI3BX6U.js.map +0 -1
  259. package/dist/chunk-EILUG3VB.js +0 -1275
  260. package/dist/chunk-EILUG3VB.js.map +0 -1
  261. package/dist/chunk-FUDY333O.js +0 -70
  262. package/dist/chunk-FUDY333O.js.map +0 -1
  263. package/dist/chunk-GBVOWFIK.js +0 -1237
  264. package/dist/chunk-GBVOWFIK.js.map +0 -1
  265. package/dist/chunk-H4TQ3H3Y.js +0 -262
  266. package/dist/chunk-H4TQ3H3Y.js.map +0 -1
  267. package/dist/chunk-JGB3IXZO.js +0 -189
  268. package/dist/chunk-JGB3IXZO.js.map +0 -1
  269. package/dist/chunk-KD2QRQPY.js +0 -4342
  270. package/dist/chunk-KD2QRQPY.js.map +0 -1
  271. package/dist/chunk-KLMXQVYK.js +0 -369
  272. package/dist/chunk-KLMXQVYK.js.map +0 -1
  273. package/dist/chunk-KZUG5KFQ.js +0 -214
  274. package/dist/chunk-KZUG5KFQ.js.map +0 -1
  275. package/dist/chunk-QDAQ4CJU.js +0 -345
  276. package/dist/chunk-QDAQ4CJU.js.map +0 -1
  277. package/dist/chunk-RMH72RZI.js.map +0 -1
  278. package/dist/chunk-SWKWQZXM.js +0 -117
  279. package/dist/chunk-SWKWQZXM.js.map +0 -1
  280. package/dist/chunk-TJBP2K4T.js.map +0 -1
  281. package/dist/chunk-TLCEAQDQ.js +0 -542
  282. package/dist/chunk-TLCEAQDQ.js.map +0 -1
  283. package/dist/chunk-UZXBISGO.js.map +0 -1
  284. package/dist/chunk-WGBAKP3Q.js +0 -3220
  285. package/dist/chunk-WGBAKP3Q.js.map +0 -1
  286. package/dist/compare/index.cjs +0 -5475
  287. package/dist/compare/index.cjs.map +0 -1
  288. package/dist/compare/index.d.cts +0 -114
  289. package/dist/compare/index.d.ts +0 -114
  290. package/dist/compare/index.js +0 -731
  291. package/dist/compare/index.js.map +0 -1
  292. package/dist/core/commands/formatting-commands.cjs +0 -828
  293. package/dist/core/commands/formatting-commands.cjs.map +0 -1
  294. package/dist/core/commands/formatting-commands.d.cts +0 -63
  295. package/dist/core/commands/formatting-commands.d.ts +0 -63
  296. package/dist/core/commands/formatting-commands.js +0 -37
  297. package/dist/core/commands/formatting-commands.js.map +0 -1
  298. package/dist/core/commands/image-commands.cjs +0 -2023
  299. package/dist/core/commands/image-commands.cjs.map +0 -1
  300. package/dist/core/commands/image-commands.d.cts +0 -58
  301. package/dist/core/commands/image-commands.d.ts +0 -58
  302. package/dist/core/commands/image-commands.js +0 -18
  303. package/dist/core/commands/image-commands.js.map +0 -1
  304. package/dist/core/commands/section-layout-commands.cjs.map +0 -1
  305. package/dist/core/commands/section-layout-commands.d.cts +0 -62
  306. package/dist/core/commands/section-layout-commands.d.ts +0 -62
  307. package/dist/core/commands/section-layout-commands.js +0 -21
  308. package/dist/core/commands/section-layout-commands.js.map +0 -1
  309. package/dist/core/commands/style-commands.cjs.map +0 -1
  310. package/dist/core/commands/style-commands.d.cts +0 -13
  311. package/dist/core/commands/style-commands.d.ts +0 -13
  312. package/dist/core/commands/style-commands.js +0 -9
  313. package/dist/core/commands/style-commands.js.map +0 -1
  314. package/dist/core/commands/table-structure-commands.cjs +0 -1883
  315. package/dist/core/commands/table-structure-commands.cjs.map +0 -1
  316. package/dist/core/commands/table-structure-commands.d.cts +0 -59
  317. package/dist/core/commands/table-structure-commands.d.ts +0 -59
  318. package/dist/core/commands/table-structure-commands.js +0 -12
  319. package/dist/core/commands/table-structure-commands.js.map +0 -1
  320. package/dist/core/commands/text-commands.cjs +0 -2391
  321. package/dist/core/commands/text-commands.cjs.map +0 -1
  322. package/dist/core/commands/text-commands.d.cts +0 -24
  323. package/dist/core/commands/text-commands.d.ts +0 -24
  324. package/dist/core/commands/text-commands.js +0 -28
  325. package/dist/core/commands/text-commands.js.map +0 -1
  326. package/dist/core/selection/mapping.cjs +0 -200
  327. package/dist/core/selection/mapping.cjs.map +0 -1
  328. package/dist/core/selection/mapping.d.cts +0 -2
  329. package/dist/core/selection/mapping.d.ts +0 -2
  330. package/dist/core/selection/mapping.js +0 -31
  331. package/dist/core/selection/mapping.js.map +0 -1
  332. package/dist/core/state/editor-state.cjs +0 -2278
  333. package/dist/core/state/editor-state.cjs.map +0 -1
  334. package/dist/core/state/editor-state.d.cts +0 -2
  335. package/dist/core/state/editor-state.d.ts +0 -2
  336. package/dist/core/state/editor-state.js +0 -26
  337. package/dist/core/state/editor-state.js.map +0 -1
  338. package/dist/index.cjs +0 -38553
  339. package/dist/index.cjs.map +0 -1
  340. package/dist/index.d.cts +0 -15
  341. package/dist/index.d.ts +0 -15
  342. package/dist/index.js +0 -7856
  343. package/dist/index.js.map +0 -1
  344. package/dist/io/docx-session.cjs +0 -16236
  345. package/dist/io/docx-session.cjs.map +0 -1
  346. package/dist/io/docx-session.d.cts +0 -21
  347. package/dist/io/docx-session.d.ts +0 -21
  348. package/dist/io/docx-session.js +0 -18
  349. package/dist/io/docx-session.js.map +0 -1
  350. package/dist/legal/index.cjs +0 -3900
  351. package/dist/legal/index.cjs.map +0 -1
  352. package/dist/legal/index.d.cts +0 -86
  353. package/dist/legal/index.d.ts +0 -86
  354. package/dist/legal/index.js +0 -616
  355. package/dist/legal/index.js.map +0 -1
  356. package/dist/public-types-7ZL_94cz.d.ts +0 -1573
  357. package/dist/public-types-CeMaDueh.d.cts +0 -1573
  358. package/dist/public-types.cjs +0 -19
  359. package/dist/public-types.cjs.map +0 -1
  360. package/dist/public-types.d.cts +0 -2
  361. package/dist/public-types.d.ts +0 -2
  362. package/dist/public-types.js +0 -1
  363. package/dist/public-types.js.map +0 -1
  364. package/dist/runtime/document-runtime.cjs +0 -11140
  365. package/dist/runtime/document-runtime.cjs.map +0 -1
  366. package/dist/runtime/document-runtime.d.cts +0 -231
  367. package/dist/runtime/document-runtime.d.ts +0 -231
  368. package/dist/runtime/document-runtime.js +0 -21
  369. package/dist/runtime/document-runtime.js.map +0 -1
  370. package/dist/structural-helpers-CilgOVhh.d.cts +0 -10
  371. package/dist/structural-helpers-q0Gd-eBN.d.ts +0 -10
  372. package/dist/ui-tailwind/editor-surface/search-plugin.cjs +0 -313
  373. package/dist/ui-tailwind/editor-surface/search-plugin.cjs.map +0 -1
  374. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +0 -67
  375. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +0 -67
  376. package/dist/ui-tailwind/editor-surface/search-plugin.js +0 -23
  377. package/dist/ui-tailwind/editor-surface/search-plugin.js.map +0 -1
  378. package/dist/ui-tailwind/index.cjs +0 -4833
  379. package/dist/ui-tailwind/index.cjs.map +0 -1
  380. package/dist/ui-tailwind/index.d.cts +0 -617
  381. package/dist/ui-tailwind/index.d.ts +0 -617
  382. package/dist/ui-tailwind/index.js +0 -575
  383. package/dist/ui-tailwind/index.js.map +0 -1
@@ -0,0 +1,139 @@
1
+ import React from "react";
2
+ import type { FocusEventHandler } from "react";
3
+ import * as Tooltip from "@radix-ui/react-tooltip";
4
+ import { Check, MessageSquare, Pencil, X } from "lucide-react";
5
+
6
+ import type { SuggestionCardModel } from "../../ui/headless/selection-toolbar-model";
7
+ import { preserveEditorSelectionMouseDown } from "../../ui/headless/preserve-editor-selection";
8
+
9
+ export interface TwSuggestionCardProps {
10
+ model: SuggestionCardModel;
11
+ onFocusCapture?: FocusEventHandler<HTMLDivElement>;
12
+ onBlurCapture?: FocusEventHandler<HTMLDivElement>;
13
+ onAccept?: () => void;
14
+ onReject?: () => void;
15
+ onEditSuggestion?: () => void;
16
+ onAddComment?: () => void;
17
+ }
18
+
19
+ const focusRingClass =
20
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-canvas";
21
+
22
+ export function TwSuggestionCard(props: TwSuggestionCardProps) {
23
+ const contextLabel = summarizeSuggestionContext(props.model);
24
+ const commentDisabled = !props.model.canAddComment;
25
+ const tooltipLabel = commentDisabled
26
+ ? props.model.disabledReason ?? "Commenting is unavailable for this selection"
27
+ : "Comment on suggestion";
28
+
29
+ return (
30
+ <div
31
+ data-testid="suggestion-card"
32
+ className="inline-flex max-w-[min(24rem,calc(100vw-1.5rem))] flex-col gap-1.5 rounded-xl border border-border/80 bg-canvas px-2.5 py-1.5 shadow-lg ring-1 ring-border/75"
33
+ onFocusCapture={props.onFocusCapture}
34
+ onBlurCapture={props.onBlurCapture}
35
+ role="group"
36
+ aria-label="Suggestion actions"
37
+ >
38
+ <div className="flex items-start justify-between gap-2">
39
+ <div className="min-w-0">
40
+ <div className="text-[10px] font-semibold uppercase tracking-[0.12em] text-warning">
41
+ {props.model.kindLabel}
42
+ </div>
43
+ <div className="mt-0.5 max-w-[14rem] truncate text-[13px] text-primary">
44
+ {props.model.previewText}
45
+ </div>
46
+ </div>
47
+ {contextLabel ? (
48
+ <div className="shrink-0 rounded-full bg-canvas px-1.5 py-0.5 text-[9px] font-medium uppercase tracking-[0.08em] text-comment ring-1 ring-comment/20">
49
+ {contextLabel}
50
+ </div>
51
+ ) : null}
52
+ </div>
53
+
54
+ <div className="flex flex-wrap items-center gap-1">
55
+ <SuggestionActionButton
56
+ icon={<Check className="h-3.5 w-3.5" />}
57
+ label="Accept suggestion"
58
+ disabled={!props.model.canAccept}
59
+ tone="accept"
60
+ onClick={props.onAccept}
61
+ />
62
+ <SuggestionActionButton
63
+ icon={<X className="h-3.5 w-3.5" />}
64
+ label="Reject suggestion"
65
+ disabled={!props.model.canReject}
66
+ tone="reject"
67
+ onClick={props.onReject}
68
+ />
69
+ <SuggestionActionButton
70
+ icon={<Pencil className="h-3.5 w-3.5" />}
71
+ label="Edit suggestion"
72
+ disabled={!props.model.canEditSuggestion}
73
+ tone="neutral"
74
+ onClick={props.onEditSuggestion}
75
+ />
76
+ <Tooltip.Root>
77
+ <Tooltip.Trigger asChild>
78
+ <button
79
+ type="button"
80
+ aria-label="Comment on suggestion"
81
+ disabled={commentDisabled}
82
+ onMouseDown={preserveEditorSelectionMouseDown}
83
+ onClick={props.onAddComment}
84
+ className={`inline-flex h-7 items-center gap-1 rounded-md border border-border px-2 text-[11px] font-medium text-secondary transition-colors hover:bg-surface disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}
85
+ >
86
+ <MessageSquare className="h-3 w-3" />
87
+ Comment
88
+ </button>
89
+ </Tooltip.Trigger>
90
+ <Tooltip.Portal>
91
+ <Tooltip.Content
92
+ className="rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50"
93
+ sideOffset={6}
94
+ >
95
+ {tooltipLabel}
96
+ </Tooltip.Content>
97
+ </Tooltip.Portal>
98
+ </Tooltip.Root>
99
+ </div>
100
+ </div>
101
+ );
102
+ }
103
+
104
+ function summarizeSuggestionContext(model: SuggestionCardModel): string | null {
105
+ const labels = model.badges.map((badge) => badge.label.trim()).filter(Boolean);
106
+ if (labels.length === 0) {
107
+ return null;
108
+ }
109
+ const summary = labels.slice(0, 2).join(" · ");
110
+ return summary.length > 36 ? `${summary.slice(0, 33)}...` : summary;
111
+ }
112
+
113
+ function SuggestionActionButton(props: {
114
+ icon: React.ReactNode;
115
+ label: string;
116
+ disabled: boolean;
117
+ tone: "accept" | "reject" | "neutral";
118
+ onClick?: () => void;
119
+ }) {
120
+ const toneClass = props.tone === "accept"
121
+ ? "border-success/35 bg-canvas text-success hover:bg-surface"
122
+ : props.tone === "reject"
123
+ ? "border-danger/35 bg-canvas text-danger hover:bg-surface"
124
+ : "border-border text-secondary hover:bg-surface";
125
+
126
+ return (
127
+ <button
128
+ type="button"
129
+ aria-label={props.label}
130
+ disabled={props.disabled}
131
+ onMouseDown={preserveEditorSelectionMouseDown}
132
+ onClick={props.onClick}
133
+ className={`inline-flex h-7 items-center gap-1 rounded-md border px-2 text-[11px] font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${toneClass} ${focusRingClass}`}
134
+ >
135
+ {props.icon}
136
+ {props.label.replace(" suggestion", "").replace(" on suggestion", "")}
137
+ </button>
138
+ );
139
+ }
@@ -0,0 +1,250 @@
1
+ import React from "react";
2
+
3
+ import type {
4
+ StyleCatalogSnapshot,
5
+ TableOperationCapabilitySnapshot,
6
+ TableStructureContextSnapshot,
7
+ } from "../../api/public-types";
8
+ import { preserveEditorSelectionMouseDown } from "../../ui/headless/preserve-editor-selection";
9
+
10
+ export interface TwTableContextToolbarProps {
11
+ disabled: boolean;
12
+ tableContext: TableStructureContextSnapshot | null;
13
+ tableStyles: StyleCatalogSnapshot["tables"];
14
+ onSetTableStyle?: (styleId: string) => void;
15
+ onAddRowBefore?: () => void;
16
+ onAddRowAfter?: () => void;
17
+ onAddColumnBefore?: () => void;
18
+ onAddColumnAfter?: () => void;
19
+ onDeleteRow?: () => void;
20
+ onDeleteColumn?: () => void;
21
+ onMergeCells?: () => void;
22
+ onSplitCell?: () => void;
23
+ onSetCellBackground?: (color: string) => void;
24
+ onDeleteTable?: () => void;
25
+ }
26
+
27
+ const CELL_COLORS = [
28
+ "#ffffff",
29
+ "#f0f0ee",
30
+ "#dbeafe",
31
+ "#fef3c7",
32
+ "#dcfce7",
33
+ "#fce7f3",
34
+ ] as const;
35
+
36
+ export function TwTableContextToolbar(props: TwTableContextToolbarProps) {
37
+ const tableContext = props.tableContext;
38
+ const tableSizeLabel = tableContext ? `${tableContext.rowCount} x ${tableContext.columnCount}` : null;
39
+ const selectionLabel = tableContext
40
+ ? tableContext.selectedCellCount > 1
41
+ ? `${tableContext.selectedCellCount} cells`
42
+ : `R${tableContext.currentCell.rowIndex + 1} C${tableContext.currentCell.columnIndex + 1}`
43
+ : null;
44
+
45
+ return (
46
+ <div
47
+ data-testid="table-context-toolbar"
48
+ className="flex max-w-[min(30rem,calc(100vw-1.5rem))] flex-wrap items-start gap-1.5 rounded-lg border border-border bg-canvas px-2.5 py-1.5 shadow-sm"
49
+ >
50
+ <span className="text-[9px] font-semibold uppercase tracking-[0.12em] text-tertiary">
51
+ Table
52
+ </span>
53
+ {tableSizeLabel ? <ToolbarBadge>{tableSizeLabel}</ToolbarBadge> : null}
54
+ {selectionLabel ? <ToolbarBadge>{selectionLabel}</ToolbarBadge> : null}
55
+ {tableContext?.currentCell.isHeader ? <ToolbarBadge tone="accent">Header row</ToolbarBadge> : null}
56
+
57
+ <ToolbarSection label="Style">
58
+ <select
59
+ aria-label="Table style"
60
+ className="h-7 min-w-[9rem] rounded-md border border-border bg-canvas px-2 text-[11px] text-primary disabled:opacity-40"
61
+ disabled={
62
+ props.disabled ||
63
+ props.tableStyles.length === 0 ||
64
+ !props.onSetTableStyle ||
65
+ !tableContext?.operations.setTableStyle.enabled
66
+ }
67
+ onMouseDown={preserveEditorSelectionMouseDown}
68
+ onChange={(event) => props.onSetTableStyle?.(event.target.value)}
69
+ value={tableContext?.currentStyleId ?? ""}
70
+ title={tableContext?.operations.setTableStyle.reason}
71
+ >
72
+ <option value="" disabled>Table style</option>
73
+ {props.tableStyles.map((style) => (
74
+ <option key={style.styleId} value={style.styleId}>
75
+ {style.displayName}
76
+ </option>
77
+ ))}
78
+ </select>
79
+ </ToolbarSection>
80
+
81
+ <ToolbarSection label="Rows">
82
+ <ToolbarButton
83
+ ariaLabel="Add row above"
84
+ capability={tableContext?.operations.addRowBefore}
85
+ disabled={props.disabled}
86
+ onClick={props.onAddRowBefore}
87
+ >
88
+ Above
89
+ </ToolbarButton>
90
+ <ToolbarButton
91
+ ariaLabel="Add row below"
92
+ capability={tableContext?.operations.addRowAfter}
93
+ disabled={props.disabled}
94
+ onClick={props.onAddRowAfter}
95
+ >
96
+ Below
97
+ </ToolbarButton>
98
+ <ToolbarButton
99
+ ariaLabel="Delete row"
100
+ capability={tableContext?.operations.deleteRow}
101
+ disabled={props.disabled}
102
+ onClick={props.onDeleteRow}
103
+ >
104
+ Delete row
105
+ </ToolbarButton>
106
+ </ToolbarSection>
107
+
108
+ <ToolbarSection label="Columns">
109
+ <ToolbarButton
110
+ ariaLabel="Add column left"
111
+ capability={tableContext?.operations.addColumnBefore}
112
+ disabled={props.disabled}
113
+ onClick={props.onAddColumnBefore}
114
+ >
115
+ Left
116
+ </ToolbarButton>
117
+ <ToolbarButton
118
+ ariaLabel="Add column right"
119
+ capability={tableContext?.operations.addColumnAfter}
120
+ disabled={props.disabled}
121
+ onClick={props.onAddColumnAfter}
122
+ >
123
+ Right
124
+ </ToolbarButton>
125
+ <ToolbarButton
126
+ ariaLabel="Delete column"
127
+ capability={tableContext?.operations.deleteColumn}
128
+ disabled={props.disabled}
129
+ onClick={props.onDeleteColumn}
130
+ >
131
+ Delete column
132
+ </ToolbarButton>
133
+ </ToolbarSection>
134
+
135
+ <ToolbarSection label="Cells">
136
+ <ToolbarButton
137
+ ariaLabel="Merge cells"
138
+ capability={tableContext?.operations.mergeCells}
139
+ disabled={props.disabled}
140
+ onClick={props.onMergeCells}
141
+ >
142
+ Merge
143
+ </ToolbarButton>
144
+ <ToolbarButton
145
+ ariaLabel="Split cell"
146
+ capability={tableContext?.operations.splitCell}
147
+ disabled={props.disabled}
148
+ onClick={props.onSplitCell}
149
+ >
150
+ Split
151
+ </ToolbarButton>
152
+ </ToolbarSection>
153
+
154
+ <ToolbarSection label="Fill">
155
+ <div className="flex items-center gap-1">
156
+ {CELL_COLORS.map((color) => (
157
+ <button
158
+ key={color}
159
+ type="button"
160
+ aria-label={`Set cell fill ${color}`}
161
+ disabled={
162
+ props.disabled ||
163
+ !props.onSetCellBackground ||
164
+ !tableContext?.operations.setCellBackground.enabled
165
+ }
166
+ onMouseDown={preserveEditorSelectionMouseDown}
167
+ onClick={() => props.onSetCellBackground?.(color)}
168
+ className="h-5 w-5 rounded border border-border disabled:opacity-40"
169
+ style={{ backgroundColor: color }}
170
+ title={tableContext?.operations.setCellBackground.reason}
171
+ />
172
+ ))}
173
+ </div>
174
+ </ToolbarSection>
175
+
176
+ <ToolbarSection label="Table">
177
+ <ToolbarButton
178
+ ariaLabel="Delete table"
179
+ capability={tableContext?.operations.deleteTable}
180
+ danger
181
+ disabled={props.disabled}
182
+ onClick={props.onDeleteTable}
183
+ >
184
+ Delete table
185
+ </ToolbarButton>
186
+ </ToolbarSection>
187
+ </div>
188
+ );
189
+ }
190
+
191
+ function ToolbarBadge(props: {
192
+ children: React.ReactNode;
193
+ tone?: "neutral" | "accent";
194
+ }) {
195
+ return (
196
+ <span
197
+ className={[
198
+ "rounded-full px-1.5 py-0.5 text-[9px] font-medium uppercase tracking-[0.08em]",
199
+ props.tone === "accent"
200
+ ? "bg-accent-soft text-accent"
201
+ : "bg-surface text-secondary",
202
+ ].join(" ")}
203
+ >
204
+ {props.children}
205
+ </span>
206
+ );
207
+ }
208
+
209
+ function ToolbarSection(props: {
210
+ label: string;
211
+ children: React.ReactNode;
212
+ }) {
213
+ return (
214
+ <div className="flex flex-wrap items-center gap-1 rounded-md bg-surface/60 px-1.5 py-1 ring-1 ring-border/35">
215
+ <span className="text-[9px] font-semibold uppercase tracking-[0.08em] text-tertiary">
216
+ {props.label}
217
+ </span>
218
+ <div className="flex flex-wrap items-center gap-1">{props.children}</div>
219
+ </div>
220
+ );
221
+ }
222
+
223
+ function ToolbarButton(props: {
224
+ ariaLabel: string;
225
+ capability?: TableOperationCapabilitySnapshot;
226
+ children: React.ReactNode;
227
+ danger?: boolean;
228
+ disabled: boolean;
229
+ onClick?: () => void;
230
+ }) {
231
+ const capabilityEnabled = props.capability?.enabled ?? true;
232
+ const title = !capabilityEnabled ? props.capability?.reason : undefined;
233
+ return (
234
+ <button
235
+ type="button"
236
+ aria-label={props.ariaLabel}
237
+ disabled={props.disabled || !props.onClick || !capabilityEnabled}
238
+ onMouseDown={preserveEditorSelectionMouseDown}
239
+ onClick={props.onClick}
240
+ title={title}
241
+ className={`inline-flex h-7 items-center rounded-md px-2 text-[11px] font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${
242
+ props.danger
243
+ ? "text-danger hover:bg-danger/10"
244
+ : "text-primary hover:bg-surface"
245
+ }`}
246
+ >
247
+ {props.children}
248
+ </button>
249
+ );
250
+ }
@@ -0,0 +1,58 @@
1
+ import React from "react";
2
+ import { AlertTriangle } from "lucide-react";
3
+
4
+ export interface TwUnsavedModalProps {
5
+ open: boolean;
6
+ message?: string;
7
+ onDiscard: () => void;
8
+ onCancel: () => void;
9
+ }
10
+
11
+ export function TwUnsavedModal(props: TwUnsavedModalProps) {
12
+ if (!props.open) return null;
13
+
14
+ return (
15
+ <div className="fixed inset-0 z-50 flex items-center justify-center">
16
+ {/* Backdrop */}
17
+ <div
18
+ className="absolute inset-0 bg-black/30 backdrop-blur-sm"
19
+ onClick={props.onCancel}
20
+ />
21
+
22
+ {/* Modal */}
23
+ <div className="relative mx-4 w-full max-w-md rounded-xl bg-canvas p-6 shadow-lg ring-1 ring-border">
24
+ <div className="flex items-start gap-3">
25
+ <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-warning-soft">
26
+ <AlertTriangle className="h-5 w-5 text-warning" />
27
+ </div>
28
+ <div className="flex-1">
29
+ <h3 className="text-base font-semibold text-primary">
30
+ Unsaved changes
31
+ </h3>
32
+ <p className="mt-1.5 text-sm text-secondary leading-relaxed">
33
+ {props.message ??
34
+ "You have unsaved changes that will be lost. Your work is being autosaved, but the latest edits may not be saved yet."}
35
+ </p>
36
+ </div>
37
+ </div>
38
+
39
+ <div className="mt-5 flex justify-end gap-2">
40
+ <button
41
+ type="button"
42
+ onClick={props.onCancel}
43
+ className="rounded-lg px-4 py-2 text-sm font-medium text-secondary hover:bg-surface transition-colors"
44
+ >
45
+ Keep editing
46
+ </button>
47
+ <button
48
+ type="button"
49
+ onClick={props.onDiscard}
50
+ className="rounded-lg bg-danger px-4 py-2 text-sm font-medium text-white hover:bg-danger/90 transition-colors"
51
+ >
52
+ Discard changes
53
+ </button>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ );
58
+ }
@@ -0,0 +1,20 @@
1
+ import { useEffect } from "react";
2
+
3
+ /**
4
+ * Prompts the browser's native "unsaved changes" dialog when the user
5
+ * tries to close the tab or navigate away while `shouldWarn` is true.
6
+ */
7
+ export function useBeforeUnload(shouldWarn: boolean): void {
8
+ useEffect(() => {
9
+ if (!shouldWarn) return;
10
+
11
+ function handleBeforeUnload(event: BeforeUnloadEvent) {
12
+ event.preventDefault();
13
+ // Modern browsers ignore custom messages and show their own.
14
+ event.returnValue = "";
15
+ }
16
+
17
+ window.addEventListener("beforeunload", handleBeforeUnload);
18
+ return () => window.removeEventListener("beforeunload", handleBeforeUnload);
19
+ }, [shouldWarn]);
20
+ }
@@ -0,0 +1,179 @@
1
+ export type PerfProbeKind =
2
+ | "typing"
3
+ | "selection"
4
+ | "runtime.create"
5
+ | "snapshot.surface"
6
+ | "snapshot.compatibility"
7
+ | "snapshot.navigation"
8
+ | "pm.rebuild"
9
+ | "pm.decorations"
10
+ | "pm.mount"
11
+ | "shell.render"
12
+ | "workspace.chrome"
13
+ | "selection.sync";
14
+
15
+ export interface PerfProbeSample {
16
+ token: string;
17
+ kind: PerfProbeKind;
18
+ durationMs: number;
19
+ recordedAt: number;
20
+ }
21
+
22
+ interface PendingProbe {
23
+ kind: PerfProbeKind;
24
+ startedAt: number;
25
+ }
26
+
27
+ interface PerfProbeState {
28
+ enabled?: boolean;
29
+ nextToken?: number;
30
+ pending?: Record<string, PendingProbe>;
31
+ samples?: PerfProbeSample[];
32
+ maxSamples?: number;
33
+ invalidationCounts?: Record<string, number>;
34
+ }
35
+
36
+ export interface PerfProbeSummary {
37
+ samples: PerfProbeSample[];
38
+ latest: Partial<Record<PerfProbeKind, PerfProbeSample | null>>;
39
+ invalidationCounts: Record<string, number>;
40
+ }
41
+
42
+ declare global {
43
+ interface Window {
44
+ __DOCX_REACT_PERF_PROBE__?: PerfProbeState;
45
+ }
46
+ }
47
+
48
+ export function startPerfProbe(kind: PerfProbeKind): string | null {
49
+ const state = getEnabledState();
50
+ if (!state) {
51
+ return null;
52
+ }
53
+
54
+ const token = `${kind}-${state.nextToken ?? 0}`;
55
+ state.nextToken = (state.nextToken ?? 0) + 1;
56
+ state.pending ??= {};
57
+ state.pending[token] = {
58
+ kind,
59
+ startedAt: performance.now(),
60
+ };
61
+ return token;
62
+ }
63
+
64
+ export function finishPerfProbe(token: string | null | undefined): PerfProbeSample | null {
65
+ if (!token) {
66
+ return null;
67
+ }
68
+ const state = getEnabledState();
69
+ if (!state?.pending?.[token]) {
70
+ return null;
71
+ }
72
+
73
+ const pending = state.pending[token];
74
+ delete state.pending[token];
75
+
76
+ const sample: PerfProbeSample = {
77
+ token,
78
+ kind: pending.kind,
79
+ durationMs: performance.now() - pending.startedAt,
80
+ recordedAt: Date.now(),
81
+ };
82
+
83
+ pushSample(state, sample);
84
+
85
+ return sample;
86
+ }
87
+
88
+ export function recordPerfSample(
89
+ kind: PerfProbeKind,
90
+ durationMs = 0,
91
+ ): PerfProbeSample | null {
92
+ const state = getEnabledState();
93
+ if (!state) {
94
+ return null;
95
+ }
96
+
97
+ const token = `${kind}-${state.nextToken ?? 0}`;
98
+ state.nextToken = (state.nextToken ?? 0) + 1;
99
+ const sample: PerfProbeSample = {
100
+ token,
101
+ kind,
102
+ durationMs,
103
+ recordedAt: Date.now(),
104
+ };
105
+ pushSample(state, sample);
106
+ return sample;
107
+ }
108
+
109
+ export function incrementInvalidationCounter(
110
+ counter: string,
111
+ amount = 1,
112
+ ): number {
113
+ const state = getEnabledState();
114
+ if (!state) {
115
+ return 0;
116
+ }
117
+
118
+ state.invalidationCounts ??= {};
119
+ state.invalidationCounts[counter] =
120
+ (state.invalidationCounts[counter] ?? 0) + amount;
121
+ return state.invalidationCounts[counter]!;
122
+ }
123
+
124
+ export function getLatestPerfSummary(): PerfProbeSummary | null {
125
+ const state = getEnabledState();
126
+ const samples = state?.samples ?? [];
127
+ if (!state || samples.length === 0) {
128
+ return null;
129
+ }
130
+
131
+ return {
132
+ samples: [...samples],
133
+ latest: buildLatestSampleMap(samples),
134
+ invalidationCounts: { ...(state.invalidationCounts ?? {}) },
135
+ };
136
+ }
137
+
138
+ export function resetPerfProbeState(): void {
139
+ const state = getEnabledState();
140
+ if (!state) {
141
+ return;
142
+ }
143
+ state.nextToken = 0;
144
+ state.pending = {};
145
+ state.samples = [];
146
+ state.invalidationCounts = {};
147
+ }
148
+
149
+ function getEnabledState(): PerfProbeState | null {
150
+ if (typeof window === "undefined") {
151
+ return null;
152
+ }
153
+ const state = window.__DOCX_REACT_PERF_PROBE__;
154
+ if (!state?.enabled) {
155
+ return null;
156
+ }
157
+ return state;
158
+ }
159
+
160
+ function pushSample(state: PerfProbeState, sample: PerfProbeSample): void {
161
+ state.samples ??= [];
162
+ state.samples.push(sample);
163
+ const maxSamples = state.maxSamples ?? 20;
164
+ if (state.samples.length > maxSamples) {
165
+ state.samples.splice(0, state.samples.length - maxSamples);
166
+ }
167
+ }
168
+
169
+ function buildLatestSampleMap(
170
+ samples: PerfProbeSample[],
171
+ ): Partial<Record<PerfProbeKind, PerfProbeSample | null>> {
172
+ const latest: Partial<Record<PerfProbeKind, PerfProbeSample | null>> = {};
173
+ for (const sample of [...samples].reverse()) {
174
+ if (latest[sample.kind] === undefined) {
175
+ latest[sample.kind] = sample;
176
+ }
177
+ }
178
+ return latest;
179
+ }