@flamingo-stack/openframe-frontend-core 0.0.498-1506.4000.1 → 0.0.498

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 (290) hide show
  1. package/dist/{chunk-ZHC2BCXK.js → chunk-2OPD6KRB.js} +4 -4
  2. package/dist/{chunk-5BQWVNRS.cjs → chunk-2R25CGSO.cjs} +62 -62
  3. package/dist/{chunk-5BQWVNRS.cjs.map → chunk-2R25CGSO.cjs.map} +1 -1
  4. package/dist/{chunk-242K7LZY.cjs → chunk-4EHQEMN4.cjs} +11 -11
  5. package/dist/{chunk-242K7LZY.cjs.map → chunk-4EHQEMN4.cjs.map} +1 -1
  6. package/dist/{chunk-4KKGHPNE.cjs → chunk-4NIBKEED.cjs} +9 -9
  7. package/dist/{chunk-4KKGHPNE.cjs.map → chunk-4NIBKEED.cjs.map} +1 -1
  8. package/dist/{chunk-5QWYIPMH.js → chunk-5ZL7PA63.js} +2 -2
  9. package/dist/{chunk-3VGRZ62V.js → chunk-6GAJETAP.js} +2 -2
  10. package/dist/{chunk-EO35UHFT.cjs → chunk-A3Z63ZL5.cjs} +60 -60
  11. package/dist/chunk-A3Z63ZL5.cjs.map +1 -0
  12. package/dist/{chunk-34C2JV2C.js → chunk-G6ARA2HD.js} +2 -2
  13. package/dist/{chunk-WNXIG6YY.js → chunk-K5HHLTSG.js} +2 -2
  14. package/dist/{chunk-42NYDEHH.js → chunk-KK4M4URN.js} +2 -2
  15. package/dist/{chunk-42SMPKGY.js → chunk-MF3VJKHT.js} +2 -2
  16. package/dist/{chunk-EORFD5WB.cjs → chunk-MSB3PEPP.cjs} +15 -15
  17. package/dist/{chunk-EORFD5WB.cjs.map → chunk-MSB3PEPP.cjs.map} +1 -1
  18. package/dist/{chunk-F7XPMG25.cjs → chunk-MVORKLWX.cjs} +27 -28
  19. package/dist/chunk-MVORKLWX.cjs.map +1 -0
  20. package/dist/{chunk-D3LUKR2Y.js → chunk-OYPUQJJ2.js} +10044 -12292
  21. package/dist/chunk-OYPUQJJ2.js.map +1 -0
  22. package/dist/{chunk-62TM2RVZ.cjs → chunk-T67MZAQJ.cjs} +26 -26
  23. package/dist/{chunk-62TM2RVZ.cjs.map → chunk-T67MZAQJ.cjs.map} +1 -1
  24. package/dist/{chunk-BUBQEZ5J.js → chunk-VLWVM6ZS.js} +2 -2
  25. package/dist/{chunk-632XJ2ZT.js → chunk-VOOEX4IZ.js} +5 -6
  26. package/dist/chunk-VOOEX4IZ.js.map +1 -0
  27. package/dist/{chunk-5ZY5JM4Z.js → chunk-W4XZ3FBZ.js} +10 -10
  28. package/dist/chunk-W4XZ3FBZ.js.map +1 -0
  29. package/dist/{chunk-2LYA3RBT.cjs → chunk-XI44QDCD.cjs} +37 -37
  30. package/dist/{chunk-2LYA3RBT.cjs.map → chunk-XI44QDCD.cjs.map} +1 -1
  31. package/dist/{chunk-WZCQW4MW.js → chunk-XSNKSMB3.js} +4 -4
  32. package/dist/{chunk-J3NHQ4JB.cjs → chunk-ZBTIN7RC.cjs} +31 -31
  33. package/dist/{chunk-J3NHQ4JB.cjs.map → chunk-ZBTIN7RC.cjs.map} +1 -1
  34. package/dist/{chunk-SS3D3DHL.cjs → chunk-ZEZTITQZ.cjs} +4886 -7134
  35. package/dist/chunk-ZEZTITQZ.cjs.map +1 -0
  36. package/dist/{chunk-44C23SSC.cjs → chunk-ZHNWWFIM.cjs} +5 -5
  37. package/dist/{chunk-44C23SSC.cjs.map → chunk-ZHNWWFIM.cjs.map} +1 -1
  38. package/dist/{chunk-H6GFQ4AO.cjs → chunk-ZTE32A7C.cjs} +7 -7
  39. package/dist/{chunk-H6GFQ4AO.cjs.map → chunk-ZTE32A7C.cjs.map} +1 -1
  40. package/dist/components/case-studies/index.cjs +8 -8
  41. package/dist/components/case-studies/index.js +2 -2
  42. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  43. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  44. package/dist/components/chat/hooks/index.d.ts +1 -0
  45. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  46. package/dist/components/chat/hooks/use-chat.d.ts.map +1 -1
  47. package/dist/components/chat/hooks/use-chunk-catchup.d.ts.map +1 -1
  48. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +48 -15
  49. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  50. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +6 -0
  51. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +1 -0
  52. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +57 -10
  53. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
  54. package/dist/components/chat/index.cjs +2 -10
  55. package/dist/components/chat/index.cjs.map +1 -1
  56. package/dist/components/chat/index.d.ts +0 -1
  57. package/dist/components/chat/index.d.ts.map +1 -1
  58. package/dist/components/chat/index.js +13 -21
  59. package/dist/components/chat/types/api.types.d.ts +81 -1
  60. package/dist/components/chat/types/api.types.d.ts.map +1 -1
  61. package/dist/components/chat/types/processing.types.d.ts +93 -2
  62. package/dist/components/chat/types/processing.types.d.ts.map +1 -1
  63. package/dist/components/chat/utils/chunk-parser.d.ts +25 -0
  64. package/dist/components/chat/utils/chunk-parser.d.ts.map +1 -0
  65. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts +6 -34
  66. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts.map +1 -1
  67. package/dist/components/chat/utils/index.d.ts +3 -2
  68. package/dist/components/chat/utils/index.d.ts.map +1 -1
  69. package/dist/components/chat/utils/process-historical-messages.d.ts +11 -59
  70. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  71. package/dist/components/contact/index.cjs +3 -3
  72. package/dist/components/contact/index.js +2 -2
  73. package/dist/components/docs/index.cjs +5 -5
  74. package/dist/components/docs/index.js +4 -4
  75. package/dist/components/embeds/index.cjs +3 -3
  76. package/dist/components/embeds/index.js +2 -2
  77. package/dist/components/faq/index.cjs +3 -3
  78. package/dist/components/faq/index.js +2 -2
  79. package/dist/components/features/index.cjs +2 -2
  80. package/dist/components/features/index.js +1 -1
  81. package/dist/components/help-center-pages/index.cjs +20 -20
  82. package/dist/components/help-center-pages/index.js +11 -11
  83. package/dist/components/index.cjs +130 -172
  84. package/dist/components/index.cjs.map +1 -1
  85. package/dist/components/index.js +21 -63
  86. package/dist/components/index.js.map +1 -1
  87. package/dist/components/navigation/header.d.ts.map +1 -1
  88. package/dist/components/navigation/index.cjs +2 -2
  89. package/dist/components/navigation/index.js +1 -1
  90. package/dist/components/navigation/mingo-ai-button.d.ts.map +1 -1
  91. package/dist/components/onboarding-guides/index.cjs +5 -5
  92. package/dist/components/onboarding-guides/index.js +4 -4
  93. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
  94. package/dist/components/related-content/index.cjs +3 -3
  95. package/dist/components/related-content/index.js +2 -2
  96. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  97. package/dist/components/tickets/index.cjs +5 -5
  98. package/dist/components/tickets/index.js +4 -4
  99. package/dist/components/ui/index.cjs +2 -44
  100. package/dist/components/ui/index.cjs.map +1 -1
  101. package/dist/components/ui/index.d.ts +2 -1
  102. package/dist/components/ui/index.d.ts.map +1 -1
  103. package/dist/components/ui/index.js +13 -55
  104. package/dist/components/ui/rich-markdown-renderer.d.ts +34 -0
  105. package/dist/components/ui/rich-markdown-renderer.d.ts.map +1 -0
  106. package/dist/components/ui/simple-markdown-renderer.d.ts +73 -0
  107. package/dist/components/ui/simple-markdown-renderer.d.ts.map +1 -0
  108. package/dist/index.cjs +2 -60
  109. package/dist/index.cjs.map +1 -1
  110. package/dist/index.js +13 -71
  111. package/dist/utils/index.cjs +40 -169
  112. package/dist/utils/index.cjs.map +1 -1
  113. package/dist/utils/index.d.ts +0 -1
  114. package/dist/utils/index.d.ts.map +1 -1
  115. package/dist/utils/index.js +41 -162
  116. package/dist/utils/index.js.map +1 -1
  117. package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
  118. package/package.json +1 -7
  119. package/src/components/chat/__tests__/chat-message-list.test.tsx +6 -381
  120. package/src/components/chat/chat-message-enhanced.tsx +20 -122
  121. package/src/components/chat/chat-message-list.tsx +132 -409
  122. package/src/components/chat/embeddable-chat.tsx +0 -6
  123. package/src/components/chat/hooks/.index.md +33 -30
  124. package/src/components/chat/hooks/.use-nats-chat-adapter.md +55 -36
  125. package/src/components/chat/hooks/.use-realtime-chunk-processor.md +77 -0
  126. package/src/components/chat/hooks/index.ts +1 -0
  127. package/src/components/chat/hooks/use-chat.ts +0 -8
  128. package/src/components/chat/hooks/use-chunk-catchup.ts +1 -26
  129. package/src/components/chat/hooks/use-nats-chat-adapter.ts +825 -254
  130. package/src/components/chat/hooks/use-realtime-chunk-processor.ts +489 -0
  131. package/src/components/chat/hooks/use-sse-chat-adapter.ts +684 -380
  132. package/src/components/chat/index.ts +0 -5
  133. package/src/components/chat/thinking-display.tsx +1 -1
  134. package/src/components/chat/types/.api.types.md +49 -39
  135. package/src/components/chat/types/.processing.types.md +58 -29
  136. package/src/components/chat/types/api.types.ts +73 -6
  137. package/src/components/chat/types/processing.types.ts +53 -11
  138. package/src/components/chat/utils/.chunk-parser.md +62 -0
  139. package/src/components/chat/utils/.index.md +40 -31
  140. package/src/components/chat/utils/__tests__/process-historical-messages-approvals.test.ts +0 -61
  141. package/src/components/chat/utils/chunk-parser.ts +262 -0
  142. package/src/components/chat/utils/extract-incomplete-message-state.ts +5 -63
  143. package/src/components/chat/utils/index.ts +8 -5
  144. package/src/components/chat/utils/process-historical-messages.ts +386 -358
  145. package/src/components/navigation/header.tsx +2 -1
  146. package/src/components/navigation/mingo-ai-button.tsx +4 -1
  147. package/src/components/navigation/mobile-nav-panel.tsx +5 -5
  148. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +4 -22
  149. package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
  150. package/src/components/shared/product-release/release-detail-page.tsx +4 -19
  151. package/src/components/ui/.simple-markdown-renderer.md +52 -0
  152. package/src/components/ui/index.ts +2 -1
  153. package/src/components/ui/release-changelog-section.tsx +1 -1
  154. package/src/components/ui/rich-markdown-renderer.tsx +1223 -0
  155. package/src/components/ui/simple-markdown-renderer.tsx +964 -0
  156. package/src/components/ui/ticket-info-section.tsx +1 -1
  157. package/src/utils/index.ts +0 -1
  158. package/src/utils/markdown-section-extractor.ts +56 -41
  159. package/dist/chat-protocol/decode.d.ts +0 -58
  160. package/dist/chat-protocol/decode.d.ts.map +0 -1
  161. package/dist/chat-protocol/encode.d.ts +0 -44
  162. package/dist/chat-protocol/encode.d.ts.map +0 -1
  163. package/dist/chat-protocol/env-flag.d.ts +0 -35
  164. package/dist/chat-protocol/env-flag.d.ts.map +0 -1
  165. package/dist/chat-protocol/events.d.ts +0 -207
  166. package/dist/chat-protocol/events.d.ts.map +0 -1
  167. package/dist/chat-protocol/frames.d.ts +0 -213
  168. package/dist/chat-protocol/frames.d.ts.map +0 -1
  169. package/dist/chat-protocol/index.cjs +0 -500
  170. package/dist/chat-protocol/index.cjs.map +0 -1
  171. package/dist/chat-protocol/index.d.ts +0 -18
  172. package/dist/chat-protocol/index.d.ts.map +0 -1
  173. package/dist/chat-protocol/index.js +0 -484
  174. package/dist/chat-protocol/index.js.map +0 -1
  175. package/dist/chat-protocol/ip-normalize.d.ts +0 -44
  176. package/dist/chat-protocol/ip-normalize.d.ts.map +0 -1
  177. package/dist/chat-protocol/nats-decoder.d.ts +0 -26
  178. package/dist/chat-protocol/nats-decoder.d.ts.map +0 -1
  179. package/dist/chunk-5ZY5JM4Z.js.map +0 -1
  180. package/dist/chunk-632XJ2ZT.js.map +0 -1
  181. package/dist/chunk-D3LUKR2Y.js.map +0 -1
  182. package/dist/chunk-EO35UHFT.cjs.map +0 -1
  183. package/dist/chunk-F7XPMG25.cjs.map +0 -1
  184. package/dist/chunk-SS3D3DHL.cjs.map +0 -1
  185. package/dist/components/chat/stream/chat-dialog-store.d.ts +0 -184
  186. package/dist/components/chat/stream/chat-dialog-store.d.ts.map +0 -1
  187. package/dist/components/chat/stream/chat-stream-reducer.d.ts +0 -367
  188. package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +0 -1
  189. package/dist/components/chat/stream/delta-batcher.d.ts +0 -51
  190. package/dist/components/chat/stream/delta-batcher.d.ts.map +0 -1
  191. package/dist/components/chat/stream/index.d.ts +0 -17
  192. package/dist/components/chat/stream/index.d.ts.map +0 -1
  193. package/dist/components/chat/stream/message-mutations.d.ts +0 -77
  194. package/dist/components/chat/stream/message-mutations.d.ts.map +0 -1
  195. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts +0 -22
  196. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts.map +0 -1
  197. package/dist/components/ui/markdown/base-components.d.ts +0 -51
  198. package/dist/components/ui/markdown/base-components.d.ts.map +0 -1
  199. package/dist/components/ui/markdown/engine.d.ts +0 -99
  200. package/dist/components/ui/markdown/engine.d.ts.map +0 -1
  201. package/dist/components/ui/markdown/heading-ids.d.ts +0 -65
  202. package/dist/components/ui/markdown/heading-ids.d.ts.map +0 -1
  203. package/dist/components/ui/markdown/index.d.ts +0 -18
  204. package/dist/components/ui/markdown/index.d.ts.map +0 -1
  205. package/dist/components/ui/markdown/mermaid-diagram.d.ts +0 -79
  206. package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +0 -1
  207. package/dist/components/ui/markdown/rich/embed-overrides.d.ts +0 -14
  208. package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +0 -1
  209. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +0 -40
  210. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +0 -1
  211. package/dist/components/ui/markdown/rich/shortcodes.d.ts +0 -8
  212. package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +0 -1
  213. package/dist/components/ui/markdown/sanitize.d.ts +0 -153
  214. package/dist/components/ui/markdown/sanitize.d.ts.map +0 -1
  215. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +0 -23
  216. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +0 -1
  217. package/dist/components/ui/markdown/streaming.d.ts +0 -78
  218. package/dist/components/ui/markdown/streaming.d.ts.map +0 -1
  219. package/dist/components/ui/markdown/text-size.d.ts +0 -34
  220. package/dist/components/ui/markdown/text-size.d.ts.map +0 -1
  221. package/dist/utils/markdown-fences.d.ts +0 -42
  222. package/dist/utils/markdown-fences.d.ts.map +0 -1
  223. package/dist/utils/markdown-heading-id.d.ts +0 -85
  224. package/dist/utils/markdown-heading-id.d.ts.map +0 -1
  225. package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +0 -317
  226. package/src/chat-protocol/__tests__/chat-protocol.test.ts +0 -516
  227. package/src/chat-protocol/__tests__/env-flag.test.ts +0 -52
  228. package/src/chat-protocol/__tests__/ip-normalize.test.ts +0 -136
  229. package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +0 -232
  230. package/src/chat-protocol/decode.ts +0 -278
  231. package/src/chat-protocol/encode.ts +0 -71
  232. package/src/chat-protocol/env-flag.ts +0 -39
  233. package/src/chat-protocol/events.ts +0 -245
  234. package/src/chat-protocol/frames.ts +0 -245
  235. package/src/chat-protocol/index.ts +0 -21
  236. package/src/chat-protocol/ip-normalize.ts +0 -146
  237. package/src/chat-protocol/nats-decoder.ts +0 -258
  238. package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +0 -207
  239. package/src/components/chat/__tests__/chat-pending-turn.test.tsx +0 -250
  240. package/src/components/chat/hooks/__tests__/__snapshots__/conversation-id-persistence-golden.test.ts.snap +0 -37
  241. package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
  242. package/src/components/chat/hooks/__tests__/chunk-catchup-dialog-staleness.test.ts +0 -92
  243. package/src/components/chat/hooks/__tests__/conversation-id-persistence-golden.test.ts +0 -438
  244. package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +0 -318
  245. package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +0 -940
  246. package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +0 -806
  247. package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +0 -467
  248. package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +0 -1248
  249. package/src/components/chat/stream/__tests__/delta-batcher.test.ts +0 -255
  250. package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +0 -105
  251. package/src/components/chat/stream/chat-dialog-store.ts +0 -536
  252. package/src/components/chat/stream/chat-stream-reducer.ts +0 -1876
  253. package/src/components/chat/stream/delta-batcher.ts +0 -168
  254. package/src/components/chat/stream/index.ts +0 -55
  255. package/src/components/chat/stream/message-mutations.ts +0 -340
  256. package/src/components/chat/stream/use-chat-stream-reducer.ts +0 -126
  257. package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +0 -420
  258. package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +0 -605
  259. package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +0 -394
  260. package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +0 -270
  261. package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +0 -2420
  262. package/src/components/ui/__tests__/markdown-parity.test.tsx +0 -2540
  263. package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +0 -176
  264. package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +0 -151
  265. package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +0 -354
  266. package/src/components/ui/markdown/__tests__/sanitize-render.test.tsx +0 -118
  267. package/src/components/ui/markdown/__tests__/streaming.test.tsx +0 -436
  268. package/src/components/ui/markdown/base-components.tsx +0 -360
  269. package/src/components/ui/markdown/engine.tsx +0 -315
  270. package/src/components/ui/markdown/heading-ids.ts +0 -239
  271. package/src/components/ui/markdown/index.ts +0 -49
  272. package/src/components/ui/markdown/mermaid-diagram.tsx +0 -323
  273. package/src/components/ui/markdown/rich/embed-overrides.tsx +0 -199
  274. package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +0 -184
  275. package/src/components/ui/markdown/rich/shortcodes.ts +0 -170
  276. package/src/components/ui/markdown/sanitize.ts +0 -3584
  277. package/src/components/ui/markdown/simple-markdown-renderer.tsx +0 -28
  278. package/src/components/ui/markdown/streaming.ts +0 -390
  279. package/src/components/ui/markdown/text-size.ts +0 -106
  280. package/src/utils/markdown-fences.ts +0 -127
  281. package/src/utils/markdown-heading-id.ts +0 -348
  282. /package/dist/{chunk-ZHC2BCXK.js.map → chunk-2OPD6KRB.js.map} +0 -0
  283. /package/dist/{chunk-5QWYIPMH.js.map → chunk-5ZL7PA63.js.map} +0 -0
  284. /package/dist/{chunk-3VGRZ62V.js.map → chunk-6GAJETAP.js.map} +0 -0
  285. /package/dist/{chunk-34C2JV2C.js.map → chunk-G6ARA2HD.js.map} +0 -0
  286. /package/dist/{chunk-WNXIG6YY.js.map → chunk-K5HHLTSG.js.map} +0 -0
  287. /package/dist/{chunk-42NYDEHH.js.map → chunk-KK4M4URN.js.map} +0 -0
  288. /package/dist/{chunk-42SMPKGY.js.map → chunk-MF3VJKHT.js.map} +0 -0
  289. /package/dist/{chunk-BUBQEZ5J.js.map → chunk-VLWVM6ZS.js.map} +0 -0
  290. /package/dist/{chunk-WZCQW4MW.js.map → chunk-XSNKSMB3.js.map} +0 -0
@@ -1,153 +0,0 @@
1
- /**
2
- * Tags the TEXT pre-pass forwards as raw HTML. Anything outside this set
3
- * (plus per-composition `extraAllowedHtmlTags`) gets its angle brackets
4
- * escaped and renders as plain text.
5
- *
6
- * `video` is deliberately NOT in the baseline: chat strips <video>
7
- * server-side and playback goes through the <Video> SSOT. The rich
8
- * composition opts back in via `extraAllowedHtmlTags={['video', 'source']}`
9
- * so authored content (blog publisher video injection) keeps working.
10
- */
11
- export declare const SAFE_HTML_TAGS: Set<string>;
12
- /**
13
- * Inline SVG element set, in the CANONICAL case parse5 produces for SVG
14
- * foreign content (`linearGradient`, `clipPath`, … are camelCase in the
15
- * HTML parser's SVG adjustment table, so the sanitize schema must match
16
- * that spelling; the text pre-pass lowercases before lookup).
17
- *
18
- * Inline `<svg>` renders in real published posts (hand-authored diagrams
19
- * and inline icon markup — NOT `<use href>` sprite references, which are
20
- * deliberately dropped; see SVG_ATTRIBUTES). The Rich renderer had NO pre-pass
21
- * and NO sanitizer, so it always rendered; without this set the unified
22
- * engine would escape it to visible source text.
23
- *
24
- * SEVERAL OF THESE NAMES ARE ALSO HTML ELEMENTS (`title`, `desc`, `text`,
25
- * `g`, `line`, `use`, `symbol`, `marker`, `mask`, `pattern`) — admitting
26
- * them UNCONSTRAINED let a post or a chat message emit a bare `<title>`,
27
- * which React 19 hoists into `<head>` (browser-tab + SEO title hijack) and
28
- * whose RAWTEXT content model swallows the rest of the document when
29
- * unclosed. They are therefore pinned to an `svg` ancestor in
30
- * `SVG_ONLY_ANCESTORS` below; outside `<svg>` the sanitizer drops them.
31
- */
32
- export declare const SVG_TAGS: Set<string>;
33
- /** Effective pre-pass tag set for a composition (lowercased for lookup). */
34
- export declare function buildEffectiveTagSet(extraAllowedHtmlTags?: string[]): Set<string>;
35
- export interface BuildSanitizeSchemaOptions {
36
- extraAllowedHtmlTags?: string[];
37
- }
38
- /**
39
- * The engine's sanitize schema: defaultSchema ∪ SAFE_HTML_TAGS ∪ extras.
40
- * - `extraAllowedHtmlTags` is unioned into tagNames here AND into the
41
- * pre-pass set (buildEffectiveTagSet) — the coupled-allowlist invariant.
42
- * - `clobberPrefix: ''` + empty `clobber`: authored raw-HTML anchors
43
- * (`<h2 id="…">`) keep their ids so `[jump](#anchor)` deep-links work.
44
- * (The renderer's own heading ids are injected at the React layer,
45
- * post-rehype, and were never affected.)
46
- * - `card`/`mention` protocols registered for href so chat markers survive
47
- * (the urlTransform below is the second gate).
48
- */
49
- export declare function buildSanitizeSchema(options?: BuildSanitizeSchemaOptions): {
50
- tagNames: string[];
51
- attributes: Record<string, (string | [string, ...unknown[]])[]>;
52
- ancestors: Record<string, string[]>;
53
- required: Record<string, Record<string, unknown>>;
54
- clobberPrefix: string;
55
- clobber: never[];
56
- protocols: {
57
- href: string[];
58
- };
59
- allowComments?: boolean | null | undefined;
60
- allowDoctypes?: boolean | null | undefined;
61
- strip?: Array<string> | null | undefined;
62
- };
63
- export declare function rehypeStripUnsafe(): (tree: any) => void;
64
- /**
65
- * PARAGRAPH SEGMENTS, NOT LINES (round 18 — SECURITY). A CommonMark code span
66
- * CROSSES LINE BREAKS: `` `foo\n</textarea>` `` is one `inlineCode` node, so
67
- * that `</textarea>` is a code sample and not a closer — yet this scan (and
68
- * `PROTECTED_SPAN_RE`, whose body class is `[^\n]`) was strictly PER LINE, so
69
- * the mask never saw the span, the closer stayed visible in the haystack,
70
- * `hasLaterCloser` returned true, and a prose `<textarea>` above it stayed LIVE
71
- * (`escapeUnknownHtmlTags` returned the input BYTE-IDENTICAL; the renderer
72
- * emitted `<code>foo </textarea></code>` — proving the closer is a code sample
73
- * — beside a live textarea swallowing the prose). This is the shape that is not
74
- * a CONTAINER at all, so no container sweep could ever have reached it.
75
- *
76
- * A code span CANNOT cross a paragraph break, so the scan unit is a maximal run
77
- * of non-blank lines. Blank lines still terminate a segment, which keeps the
78
- * fail-CLOSED direction (an unterminated opener consumes at most its own
79
- * paragraph, never the rest of the document) and keeps the bound linear — the
80
- * `suffMax` / cursor structure is unchanged, `\n` is simply an ordinary
81
- * character inside a segment.
82
- *
83
- * `PROTECTED_SPAN_RE` (the CARVE) is deliberately left per-line: it rounds the
84
- * other way, so at worst a multi-line code sample renders as escaped text.
85
- */
86
- declare function findInlineCodeRanges(source: string): Array<[number, number]>;
87
- /** Exported for the differential fuzz against the retired regex. */
88
- export declare const __findInlineCodeRangesForTest: typeof findInlineCodeRanges;
89
- /**
90
- * Build the haystack `hasLaterCloser` searches: a LENGTH-PRESERVING lowercased
91
- * copy of the document with every region that cannot contain a REAL closing
92
- * tag blanked to spaces.
93
- *
94
- * Why this exists: the escaping pass carefully carves code out, but the
95
- * closer search used to run over the RAW document. So a `</textarea>` sitting
96
- * inside a code fence, an inline-code span, or another tag's attribute string
97
- * satisfied "is closed later", the prose opener was left LIVE, and parse5's
98
- * RAWTEXT span swallowed the rest of the message anyway — the whole fix was
99
- * one code sample away from being bypassed, which is exactly what an LLM
100
- * answer about HTML looks like.
101
- *
102
- * Masking (rather than deleting) keeps every index identical to the original
103
- * string, so the caller's offset arithmetic is unchanged. THE LENGTH
104
- * INVARIANT IS LOAD-BEARING — see `foldAsciiCase`.
105
- *
106
- * CARVE DECISION (deliberate, do not "unify"): these tracker-derived regions
107
- * are NOT fed to the escaping carve, even though that would stop an authored
108
- * EOF-terminated fence body from rendering as literal `&lt;their&gt;`.
109
- *
110
- * The genuine asymmetry is the EOF-TERMINATED fence, and only that one. The
111
- * tracker protects an unclosed opener all the way to end of input, so a single
112
- * stray ``` line — mid-stream, or inside an open raw-HTML block where a ```
113
- * line is content rather than a fence — would carve the ENTIRE remainder of the
114
- * document out of the escaping pass. `PROTECTED_SPAN_RE` protects nothing at
115
- * all there (it only recognizes a fence CLOSED by a same-marker run), so its
116
- * failure mode is bounded: a code sample renders as escaped text. In the carve
117
- * an over-detected region is a region that is NOT escaped — a fail-OPEN, i.e.
118
- * exactly the swallow this module exists to prevent — so the materially larger
119
- * fail-open surface decides it.
120
- *
121
- * SHARED over-detection (e.g. a ``` line inside an HTML block — `<div>`,
122
- * `<pre>`, `<details>` — where CommonMark says the line is HTML content, not a
123
- * fence) was previously dismissed here as "not an argument either way". THAT
124
- * WAS WRONG: it is precisely the residual fail-open. The intersection guard
125
- * below only reconciles DISAGREEMENT, so when BOTH engines open the same bogus
126
- * fence the guard is a no-op and a live `<textarea>` inside it is pushed
127
- * verbatim, swallowing the rest of the message (reproduced for all three tags).
128
- * What actually closes it is the CARVE BALANCE GUARD in
129
- * `escapeUnknownHtmlTags`: a protected span may contain no UNBALANCED RAWTEXT
130
- * opener. Neither engine needs to learn about HTML blocks for that to hold.
131
- *
132
- * What makes keeping two engines SAFE is therefore the pair of guards in
133
- * `escapeUnknownHtmlTags`: a carve span the mask did not blank is escaped
134
- * rather than pushed through verbatim, and a span carrying an unbalanced
135
- * RAWTEXT opener is escaped even when both engines agree. Over-detection can
136
- * then only cost cosmetics. Before the first guard the regex's info-string-tolerant
137
- * closer let it desync and open a span from a line CommonMark treats as
138
- * ordinary text, sheltering a live `<textarea>` from escaping entirely
139
- * (`mismatched-fence-carve-does-not-shelter-opener`). The remaining tradeoff is
140
- * pinned by `unclosed-fence-body-renders-escaped` rather than left as prose.
141
- */
142
- declare function buildCloserHaystack(text: string): string;
143
- /** Exported for the length-preservation invariant test only. */
144
- export declare const __buildCloserHaystackForTest: typeof buildCloserHaystack;
145
- export declare function escapeUnknownHtmlTags(text: string, allowedTags?: Set<string>): string;
146
- /**
147
- * Extends react-markdown's default safe-protocol allowlist with the two
148
- * internal schemes the chat remark plugins emit (`card://`, `mention://`),
149
- * for `href` ONLY. All other URLs go through `defaultUrlTransform`.
150
- */
151
- export declare function cardAwareUrlTransform(url: string, key: string): string;
152
- export {};
153
- //# sourceMappingURL=sanitize.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/markdown/sanitize.ts"],"names":[],"mappings":"AA4CA;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,aAqBzB,CAAA;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,QAAQ,aAKnB,CAAA;AAqDF,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAEjF;AAkGD,MAAM,WAAW,0BAA0B;IACzC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAA;CAChC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,0BAA+B;;;;;;;;;;;;;EAgG3E;AA2DD,wBAAgB,iBAAiB,KAEvB,MAAM,GAAG,UA6ElB;AA+HD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,iBAAS,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA6ErE;AAED,oEAAoE;AACpE,eAAO,MAAM,6BAA6B,6BAAuB,CAAA;AA6/DjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,iBAAS,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA0DjD;AAED,gEAAgE;AAChE,eAAO,MAAM,4BAA4B,4BAAsB,CAAA;AAkgB/D,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,WAAW,GAAE,GAAG,CAAC,MAAM,CAAkB,GACxC,MAAM,CAgGR;AAoED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAItE"}
@@ -1,23 +0,0 @@
1
- /**
2
- * SimpleMarkdownRenderer — the chat/doc composition over the unified
3
- * `MarkdownEngine`. This IS the real component (not a compat alias): the
4
- * old 966-line standalone implementation was deleted in the unification;
5
- * its entire prop surface maps 1:1 onto the engine. Chat consumers keep
6
- * layering `additionalRemarkPlugins` (card/mention links) and
7
- * `componentOverrides` exactly as before.
8
- */
9
- import React from 'react';
10
- import { type MarkdownEngineProps } from './engine';
11
- import type { ResolveLinkResult } from '../../../types/doc-source';
12
- export type { ResolveLinkResult };
13
- export interface SimpleMarkdownRendererProps extends Omit<MarkdownEngineProps, 'extraAllowedHtmlTags'> {
14
- }
15
- /**
16
- * A type-narrowed ALIAS of the engine, not a wrapper: the composition adds
17
- * no behavior (it only hides `extraAllowedHtmlTags` from the prop surface),
18
- * and `MarkdownEngine` is already `memo`'d. Wrapping it in a second `memo`
19
- * bought nothing and cost an extra shallow-compare pass plus a fiber per
20
- * chat segment.
21
- */
22
- export declare const SimpleMarkdownRenderer: React.NamedExoticComponent<SimpleMarkdownRendererProps>;
23
- //# sourceMappingURL=simple-markdown-renderer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"simple-markdown-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/markdown/simple-markdown-renderer.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC,MAAM,WAAW,2BACf,SAAQ,IAAI,CAAC,mBAAmB,EAAE,sBAAsB,CAAC;CAAG;AAE9D;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EACf,KAAK,CAAC,oBAAoB,CAAC,2BAA2B,CAAC,CAAC"}
@@ -1,78 +0,0 @@
1
- /**
2
- * Streaming helpers for the unified markdown engine (pure, no React).
3
- *
4
- * Design contract (unification plan §D1 "Streaming rendering performance"):
5
- * - Markdown is NOT context-free across blocks. The splitter only cuts at
6
- * boundaries it can PROVE are atomic; when atomicity is unprovable the
7
- * content is left in one unit (unmemoized) — correctness beats cache hits.
8
- * - Blocks containing `card://` / `mention://` markers are never memoized:
9
- * their text is identical before/after the entity ref resolves, so a
10
- * text-keyed cache would serve the stale unresolved card mid-stream.
11
- * - On stream completion the engine discards all of this and does ONE
12
- * authoritative whole-document parse — streaming can never permanently
13
- * diverge (late reference defs, footnotes, list renumbering self-heal).
14
- * - Tail completion auto-closes ONLY unterminated fenced code blocks
15
- * (fence-count based — unambiguous). Inline emphasis/links are NOT
16
- * auto-closed: a stray `*` in "2 * 3" or a non-link `[` would be
17
- * mis-wrapped, which is worse than the brief flicker it prevents.
18
- */
19
- export interface StreamingBlock {
20
- /** Raw markdown source of this unit (including trailing blank lines). */
21
- text: string;
22
- /** Position index — cache key component so identical blocks never alias. */
23
- index: number;
24
- /**
25
- * 1-based line of this unit's first line WITHIN the whole document.
26
- * Each unit is parsed by its own `ReactMarkdown`, so hast positions are
27
- * unit-relative; the engine adds `startLine - 1` back to look ids up in
28
- * the document-wide heading-id map (see ./heading-ids.ts).
29
- */
30
- startLine: number;
31
- /**
32
- * True when this unit may be render-cached: it is complete (not the
33
- * trailing unit), atomic, and free of cross-block / late-resolving
34
- * constructs (card/mention markers, reference definitions/uses,
35
- * footnotes).
36
- */
37
- memoizable: boolean;
38
- }
39
- /**
40
- * Split streaming markdown into atomic units at blank lines that are
41
- * provably block boundaries. A blank line does NOT split when:
42
- * - inside a fenced code block,
43
- * - the next non-blank line is indented (loose-list / blockquote
44
- * continuation cannot be ruled out),
45
- * - the next non-blank line starts a list item or blockquote AND the
46
- * previous unit ended in a list item or blockquote (loose list /
47
- * multi-paragraph quote continuation).
48
- * The FINAL unit is always the live tail (never memoizable).
49
- *
50
- * BLANK LINES COME FROM `isBlankLine` (utils/markdown-fences), never from
51
- * `String.prototype.trim()`. This file is the THIRD consumer of that module
52
- * (it already instantiates `createFenceTracker`) and makes exactly the
53
- * CommonMark blank-line decision the helper was minted for, yet it kept four
54
- * hand-rolled `trim() === ''` tests — so the module's "every blank-line test"
55
- * SSOT claim was false here. `trim()` strips the full Unicode White_Space set
56
- * (U+00A0 NBSP, U+000B VT, U+000C FF, U+FEFF BOM), none of which CommonMark
57
- * treats as blank: `splitStreamingBlocks('foo\n<NBSP>\nbar\n\ntail')` returned
58
- * THREE units where the non-blank filler control (`foo\nx\nbar\n\ntail`)
59
- * returns TWO — one NBSP line cut a paragraph into two `ReactMarkdown` units on
60
- * the STREAMING path, rendering two `<p>` where the non-streaming and SEO twins
61
- * render one. Not a security hole (the fence tracker and `htmlBlocksCut` still
62
- * gate the cut), but a live divergence. It survived because the swallow sweep
63
- * drove only `SimpleMarkdownRenderer`; the sweep now drives this splitter too,
64
- * in both the exotic-blank and CRLF spellings.
65
- */
66
- export declare function splitStreamingBlocks(content: string): StreamingBlock[];
67
- /**
68
- * Auto-close an unterminated fenced code block at the streaming tail so the
69
- * half-open fence doesn't flip the rest of the message into code while
70
- * tokens arrive.
71
- *
72
- * Uses the SAME scanner as `splitStreamingBlocks` (never a parallel
73
- * fence-count heuristic — a naive count treats ``` and ~~~ as
74
- * interchangeable and appends a spurious closer to `` ```\n~~~\n``` ``),
75
- * and appends the RECORDED opener so a `~~~` block is closed with `~~~`.
76
- */
77
- export declare function completeStreamingTail(content: string): string;
78
- //# sourceMappingURL=streaming.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/markdown/streaming.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAA;IACZ,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,UAAU,EAAE,OAAO,CAAA;CACpB;AA2LD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE,CAoHtE;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAO7D"}
@@ -1,34 +0,0 @@
1
- /**
2
- * Text-size presets for the unified markdown engine.
3
- *
4
- * `default` / `compact` / `large` are carried over verbatim from the old
5
- * `SimpleMarkdownRenderer`. `article` is NEW — it reproduces the exact
6
- * typography the old `RichMarkdownRenderer` hardcoded per element, so
7
- * content surfaces (blog, case studies, releases, legal, docs) keep
8
- * byte-identical classes through the unification.
9
- *
10
- * ODS-TOKENS FLAG (ODS_TOKEN_RULES §Typography / §General): the `article`
11
- * preset carries raw px classes (`text-[32px] md:text-[40px] …`) because
12
- * ODS currently has NO composite tokens for long-form prose — `text-h1`/
13
- * `text-h2` are Azeret Mono UI-label scale and `text-h5` is uppercase,
14
- * so mapping prose headings onto them would visibly regress articles.
15
- * The `code` entry of EVERY preset (`text-[13px]` / `text-[14px]` /
16
- * `text-[16px]`), not just `article`'s, is raw px for the same reason: ODS
17
- * has no code/mono type scale. `base-components.tsx` carries the matching
18
- * flag for inline code's `text-[0.9em]` (the mono FAMILY is no longer an
19
- * exemption — both code surfaces now use `font-mono`).
20
- * Per the unification plan, the missing prose- and code-typography tokens
21
- * are FLAGGED here for addition to ODS; the raw-px carry-over is the
22
- * documented, review-gated exemption recorded in the unification PR.
23
- * Do NOT copy these px classes anywhere else.
24
- */
25
- export type TextSizeElement = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'li' | 'blockquote' | 'code' | 'th' | 'td';
26
- export type TextSizeClassMap = Partial<Record<TextSizeElement, string>>;
27
- export type TextSizePreset = 'default' | 'compact' | 'large' | 'article';
28
- export type TextSizeConfig = TextSizePreset | TextSizeClassMap | {
29
- preset: TextSizePreset;
30
- overrides: TextSizeClassMap;
31
- };
32
- export declare const TEXT_SIZE_PRESETS: Record<TextSizePreset, Record<TextSizeElement, string>>;
33
- export declare function resolveTextSizeConfig(config?: TextSizeConfig): Record<TextSizeElement, string>;
34
- //# sourceMappingURL=text-size.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"text-size.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/markdown/text-size.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,MAAM,eAAe,GACvB,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GACvC,GAAG,GAAG,IAAI,GAAG,YAAY,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;AAErD,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;AACxE,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AACzE,MAAM,MAAM,cAAc,GACtB,cAAc,GACd,gBAAgB,GAChB;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,SAAS,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE5D,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CA6DrF,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAM9F"}
@@ -1,42 +0,0 @@
1
- /**
2
- * Fenced-code tracker — THE definition of "am I inside a code fence".
3
- * Server-safe: no React, no DOM.
4
- *
5
- * Lives in its own module because it is a GENERAL CommonMark fence machine
6
- * with two unrelated consumers: the heading scanner
7
- * (`utils/markdown-heading-id`) and the streaming block splitter
8
- * (`components/ui/markdown/streaming`). It used to live inside
9
- * `markdown-heading-id`, which meant a streaming renderer imported its fence
10
- * state machine from a module named after heading slugs. `markdown-heading-id`
11
- * re-exports these names so the public `utils` surface is unchanged.
12
- */
13
- /** True when `line` is a CommonMark blank line (spaces/tabs only, `\r`-tolerant). */
14
- export declare function isBlankLine(line: string): boolean;
15
- /**
16
- * What one source line is, relative to fenced code:
17
- * - `open` — this line opened a fence
18
- * - `close` — this line closed the open fence
19
- * - `inside`— this line is fence content (including a would-be delimiter that
20
- * does NOT close the open fence: wrong marker char, too short, or
21
- * carrying an info string)
22
- * - `text` — this line is ordinary markdown outside any fence
23
- *
24
- * NOTE: no consumer discriminates the three non-`text` roles today — both the
25
- * heading scanner and the streaming splitter only test `!== 'text'`, and the
26
- * closer-haystack mask below only tests `=== 'open'` / `=== 'close'`. The
27
- * four-value union is kept because the state machine already computes the
28
- * distinction for free and a future consumer (e.g. fence-aware syntax
29
- * post-processing) would otherwise have to re-derive it.
30
- */
31
- export type FenceLineRole = 'open' | 'close' | 'inside' | 'text';
32
- export interface FenceTracker {
33
- /** Advance across one raw source line (mutates) and classify it. */
34
- push(line: string): FenceLineRole;
35
- /** Marker CHARACTER of the currently open fence (`` ` `` / `~`), or null. */
36
- openChar(): string | null;
37
- /** Run length of the currently open fence (a closer must be ≥ this). */
38
- openLength(): number;
39
- }
40
- /** A fresh fenced-code state machine. Server-safe: no React, no DOM. */
41
- export declare function createFenceTracker(): FenceTracker;
42
- //# sourceMappingURL=markdown-fences.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"markdown-fences.d.ts","sourceRoot":"","sources":["../../src/utils/markdown-fences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAoDH,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEhE,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAAA;IACjC,6EAA6E;IAC7E,QAAQ,IAAI,MAAM,GAAG,IAAI,CAAA;IACzB,wEAAwE;IACxE,UAAU,IAAI,MAAM,CAAA;CACrB;AAED,wEAAwE;AACxE,wBAAgB,kBAAkB,IAAI,YAAY,CA8BjD"}
@@ -1,85 +0,0 @@
1
- /**
2
- * Markdown heading-id slug SSOT (server-safe: no React, no DOM).
3
- *
4
- * This algorithm previously existed in THREE byte-identical copies:
5
- * - `components/ui/simple-markdown-renderer.tsx` (generateHeadingId)
6
- * - `components/ui/rich-markdown-renderer.tsx` (generateHeadingId)
7
- * - `utils/markdown-section-extractor.ts` (extractSections)
8
- *
9
- * The extractor is the PRODUCER of `sectionIds` and the renderers are the
10
- * CONSUMERS — if the two ever drift, deep-link anchors and scroll-spy
11
- * targets silently diverge. All three now call these helpers; the parity
12
- * test `components/ui/__tests__/markdown-parity.test.tsx` asserts
13
- * extractor-vs-renderer ID agreement over the fixture corpus.
14
- */
15
- /** Emoji ranges stripped from heading text before slugification. */
16
- export declare const HEADING_EMOJI_RE: RegExp;
17
- /** Remove emoji characters and trim. */
18
- export declare function stripHeadingEmojis(text: string): string;
19
- /**
20
- * Core slug chain WITHOUT the emoji strip (the extractor exposes emoji
21
- * stripping as an option, so the two steps are kept separable):
22
- * lowercase → drop non-word/space/hyphen chars → spaces to hyphens →
23
- * trim leading/trailing hyphens. May return `''` for symbol-only input —
24
- * callers apply their own fallback (`section-N`).
25
- */
26
- export declare function slugifyHeadingBase(text: string): string;
27
- /** The full default chain used by the renderers: emoji strip + slugify. */
28
- export declare function slugifyHeadingText(text: string): string;
29
- /**
30
- * Sharing the slug chain alone was not enough. The PRODUCER
31
- * (`utils/markdown-section-extractor`) and the CONSUMER
32
- * (`components/ui/markdown/heading-ids`) each carried their own copy of
33
- * "which lines are headings" and "how do duplicates get suffixed", and the
34
- * copies drifted:
35
- * - the extractor toggled its code-block state on a bare
36
- * `line.startsWith('```')`, so a `~~~`-fenced (or wider-backtick, or
37
- * indented) block containing `## Setup` produced a SECTION from the
38
- * extractor and NO id from the renderer — `sectionIdMap` then missed
39
- * silently and the deep-link anchor pointed nowhere;
40
- * - the extractor anchored ATX at column 0 while the renderer allowed the
41
- * CommonMark 0..3-space indent;
42
- * - the dedupe counter was hand-copied in both files, each with a comment
43
- * saying "the two must agree".
44
- * Both now call `scanHeadings` + `createHeadingIdDeduper`. Server-safe: no
45
- * React, no DOM.
46
- */
47
- export { createFenceTracker, isBlankLine, type FenceTracker, type FenceLineRole, } from './markdown-fences';
48
- /** A heading the renderer will emit, located in the source. */
49
- export interface ScannedHeading {
50
- /** 1-based line of the heading's FIRST line (setext: the title line). */
51
- line: number;
52
- level: number;
53
- /** Raw title text, before `stripInlineMarkdown` / slugification. */
54
- text: string;
55
- }
56
- export interface ScanHeadingsOptions {
57
- /**
58
- * Skip a leading YAML frontmatter block (`---` on line 1 through the next
59
- * `---`). Only a DOCUMENT-LEADING block counts: a bare `---` mid-document
60
- * is a thematic break or a setext underline, and treating it as a
61
- * frontmatter toggle (what the extractor used to do) silently swallowed
62
- * every heading until the next one.
63
- */
64
- skipFrontmatter?: boolean;
65
- /** Include raw-HTML headings (`<h2>Title</h2>`). Default true. */
66
- includeRawHtml?: boolean;
67
- /**
68
- * Skip fenced-code blocks. Default true — a `##` inside a code fence is
69
- * code, not a heading, and the renderer emits no id for it.
70
- */
71
- skipFences?: boolean;
72
- }
73
- /**
74
- * Collect every heading the markdown renderer will emit, in document order.
75
- * THE single definition of "which lines are headings" for both the extractor
76
- * and the renderer's id map.
77
- */
78
- export declare function scanHeadings(content: string, options?: ScanHeadingsOptions): ScannedHeading[];
79
- /**
80
- * The duplicate-id suffix counter, as ONE closure both sides instantiate.
81
- * First occurrence keeps the bare slug; the Nth gets `-N`. Extractor and
82
- * renderer MUST use the same counter or `#anchor` deep links diverge.
83
- */
84
- export declare function createHeadingIdDeduper(): (cleanId: string) => string;
85
- //# sourceMappingURL=markdown-heading-id.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"markdown-heading-id.d.ts","sourceRoot":"","sources":["../../src/utils/markdown-heading-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,oEAAoE;AACpE,eAAO,MAAM,gBAAgB,QACsC,CAAA;AAEnE,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOvD;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAKD;;;;;;;;;;;;;;;;;GAiBG;AAMH,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,aAAa,GACnB,MAAM,mBAAmB,CAAA;AAG1B,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,kEAAkE;IAClE,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAkHD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAwB,GAChC,cAAc,EAAE,CAwGlB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAUpE"}