@temelj/mdx 0.14.0 → 0.16.0

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 (381) hide show
  1. package/README.md +470 -82
  2. package/dist/character-entities.d.mts +4 -0
  3. package/dist/character-entities.d.mts.map +1 -0
  4. package/dist/character-entities.mjs +2132 -0
  5. package/dist/character-entities.mjs.map +1 -0
  6. package/dist/character-reference.d.mts +6 -0
  7. package/dist/character-reference.d.mts.map +1 -0
  8. package/dist/character-reference.mjs +18 -0
  9. package/dist/character-reference.mjs.map +1 -0
  10. package/dist/compile-analysis.d.mts +28 -0
  11. package/dist/compile-analysis.d.mts.map +1 -0
  12. package/dist/compile-analysis.mjs +74 -0
  13. package/dist/compile-analysis.mjs.map +1 -0
  14. package/dist/compile-emit.d.mts +9 -0
  15. package/dist/compile-emit.d.mts.map +1 -0
  16. package/dist/compile-emit.mjs +187 -0
  17. package/dist/compile-emit.mjs.map +1 -0
  18. package/dist/compile-esm.d.mts +34 -0
  19. package/dist/compile-esm.d.mts.map +1 -0
  20. package/dist/compile-esm.mjs +187 -0
  21. package/dist/compile-esm.mjs.map +1 -0
  22. package/dist/compile-names.d.mts +13 -0
  23. package/dist/compile-names.d.mts.map +1 -0
  24. package/dist/compile-names.mjs +32 -0
  25. package/dist/compile-names.mjs.map +1 -0
  26. package/dist/compiler.d.mts +69 -85
  27. package/dist/compiler.d.mts.map +1 -1
  28. package/dist/compiler.mjs +167 -420
  29. package/dist/compiler.mjs.map +1 -1
  30. package/dist/diagnostics.d.mts +37 -0
  31. package/dist/diagnostics.d.mts.map +1 -0
  32. package/dist/diagnostics.mjs +57 -0
  33. package/dist/diagnostics.mjs.map +1 -0
  34. package/dist/errors.d.mts +157 -0
  35. package/dist/errors.d.mts.map +1 -0
  36. package/dist/errors.mjs +263 -0
  37. package/dist/errors.mjs.map +1 -0
  38. package/dist/footnote-numbering.d.mts +27 -0
  39. package/dist/footnote-numbering.d.mts.map +1 -0
  40. package/dist/footnote-numbering.mjs +49 -0
  41. package/dist/footnote-numbering.mjs.map +1 -0
  42. package/dist/format-context.d.mts +46 -0
  43. package/dist/format-context.d.mts.map +1 -0
  44. package/dist/format-context.mjs +26 -0
  45. package/dist/format-context.mjs.map +1 -0
  46. package/dist/format-directive.d.mts +9 -0
  47. package/dist/format-directive.d.mts.map +1 -0
  48. package/dist/format-directive.mjs +99 -0
  49. package/dist/format-directive.mjs.map +1 -0
  50. package/dist/format-jsx.d.mts +8 -0
  51. package/dist/format-jsx.d.mts.map +1 -0
  52. package/dist/format-jsx.mjs +47 -0
  53. package/dist/format-jsx.mjs.map +1 -0
  54. package/dist/format-math.d.mts +9 -0
  55. package/dist/format-math.d.mts.map +1 -0
  56. package/dist/format-math.mjs +79 -0
  57. package/dist/format-math.mjs.map +1 -0
  58. package/dist/format-safe.d.mts +25 -0
  59. package/dist/format-safe.d.mts.map +1 -0
  60. package/dist/format-safe.mjs +366 -0
  61. package/dist/format-safe.mjs.map +1 -0
  62. package/dist/format-table.d.mts +8 -0
  63. package/dist/format-table.d.mts.map +1 -0
  64. package/dist/format-table.mjs +55 -0
  65. package/dist/format-table.mjs.map +1 -0
  66. package/dist/format-track.d.mts +18 -0
  67. package/dist/format-track.d.mts.map +1 -0
  68. package/dist/format-track.mjs +34 -0
  69. package/dist/format-track.mjs.map +1 -0
  70. package/dist/format.d.mts +7 -0
  71. package/dist/format.d.mts.map +1 -0
  72. package/dist/format.mjs +549 -0
  73. package/dist/format.mjs.map +1 -0
  74. package/dist/frontmatter-decode.d.mts +15 -0
  75. package/dist/frontmatter-decode.d.mts.map +1 -0
  76. package/dist/frontmatter-decode.mjs +187 -0
  77. package/dist/frontmatter-decode.mjs.map +1 -0
  78. package/dist/frontmatter-schema.d.mts +8 -0
  79. package/dist/frontmatter-schema.d.mts.map +1 -0
  80. package/dist/frontmatter-schema.mjs +28 -0
  81. package/dist/frontmatter-schema.mjs.map +1 -0
  82. package/dist/frontmatter.d.mts +40 -0
  83. package/dist/frontmatter.d.mts.map +1 -0
  84. package/dist/frontmatter.mjs +109 -0
  85. package/dist/frontmatter.mjs.map +1 -0
  86. package/dist/heading.d.mts +6 -0
  87. package/dist/heading.d.mts.map +1 -0
  88. package/dist/heading.mjs +19 -0
  89. package/dist/heading.mjs.map +1 -0
  90. package/dist/html-format.d.mts +32 -0
  91. package/dist/html-format.d.mts.map +1 -0
  92. package/dist/html-format.mjs +127 -0
  93. package/dist/html-format.mjs.map +1 -0
  94. package/dist/html-lower.d.mts +78 -0
  95. package/dist/html-lower.d.mts.map +1 -0
  96. package/dist/html-lower.mjs +583 -0
  97. package/dist/html-lower.mjs.map +1 -0
  98. package/dist/html-stream.d.mts +13 -0
  99. package/dist/html-stream.d.mts.map +1 -0
  100. package/dist/html-stream.mjs +32 -0
  101. package/dist/html-stream.mjs.map +1 -0
  102. package/dist/html.d.mts +120 -0
  103. package/dist/html.d.mts.map +1 -0
  104. package/dist/html.mjs +77 -0
  105. package/dist/html.mjs.map +1 -0
  106. package/dist/identifier.d.mts +4 -0
  107. package/dist/identifier.d.mts.map +1 -0
  108. package/dist/identifier.mjs +8 -0
  109. package/dist/identifier.mjs.map +1 -0
  110. package/dist/javascript-ast.d.mts +16 -0
  111. package/dist/javascript-ast.d.mts.map +1 -0
  112. package/dist/javascript-ast.mjs +39 -0
  113. package/dist/javascript-ast.mjs.map +1 -0
  114. package/dist/javascript-jsx.d.mts +24 -0
  115. package/dist/javascript-jsx.d.mts.map +1 -0
  116. package/dist/javascript-jsx.mjs +189 -0
  117. package/dist/javascript-jsx.mjs.map +1 -0
  118. package/dist/javascript.d.mts +9 -0
  119. package/dist/javascript.d.mts.map +1 -0
  120. package/dist/javascript.mjs +31 -0
  121. package/dist/javascript.mjs.map +1 -0
  122. package/dist/jsx-reference.d.mts +15 -0
  123. package/dist/jsx-reference.d.mts.map +1 -0
  124. package/dist/jsx-reference.mjs +31 -0
  125. package/dist/jsx-reference.mjs.map +1 -0
  126. package/dist/mod.d.mts +26 -9
  127. package/dist/mod.mjs +20 -8
  128. package/dist/model.d.mts +196 -0
  129. package/dist/model.d.mts.map +1 -0
  130. package/dist/model.mjs +113 -0
  131. package/dist/model.mjs.map +1 -0
  132. package/dist/parser/block-container-recognizers.d.mts +40 -0
  133. package/dist/parser/block-container-recognizers.d.mts.map +1 -0
  134. package/dist/parser/block-container-recognizers.mjs +90 -0
  135. package/dist/parser/block-container-recognizers.mjs.map +1 -0
  136. package/dist/parser/block-directive-recognizers.d.mts +22 -0
  137. package/dist/parser/block-directive-recognizers.d.mts.map +1 -0
  138. package/dist/parser/block-directive-recognizers.mjs +77 -0
  139. package/dist/parser/block-directive-recognizers.mjs.map +1 -0
  140. package/dist/parser/block-leaf-recognizers.d.mts +53 -0
  141. package/dist/parser/block-leaf-recognizers.d.mts.map +1 -0
  142. package/dist/parser/block-leaf-recognizers.mjs +386 -0
  143. package/dist/parser/block-leaf-recognizers.mjs.map +1 -0
  144. package/dist/parser/block-parser.d.mts +38 -0
  145. package/dist/parser/block-parser.d.mts.map +1 -0
  146. package/dist/parser/block-parser.mjs +895 -0
  147. package/dist/parser/block-parser.mjs.map +1 -0
  148. package/dist/parser/block-syntax.d.mts +240 -0
  149. package/dist/parser/block-syntax.d.mts.map +1 -0
  150. package/dist/parser/characters.d.mts +19 -0
  151. package/dist/parser/characters.d.mts.map +1 -0
  152. package/dist/parser/characters.mjs +52 -0
  153. package/dist/parser/characters.mjs.map +1 -0
  154. package/dist/parser/config.d.mts +16 -0
  155. package/dist/parser/config.d.mts.map +1 -0
  156. package/dist/parser/config.mjs +25 -0
  157. package/dist/parser/config.mjs.map +1 -0
  158. package/dist/parser/directive-attributes.d.mts +9 -0
  159. package/dist/parser/directive-attributes.d.mts.map +1 -0
  160. package/dist/parser/directive-attributes.mjs +24 -0
  161. package/dist/parser/directive-attributes.mjs.map +1 -0
  162. package/dist/parser/embedded-scanner.d.mts +18 -0
  163. package/dist/parser/embedded-scanner.d.mts.map +1 -0
  164. package/dist/parser/embedded-scanner.mjs +199 -0
  165. package/dist/parser/embedded-scanner.mjs.map +1 -0
  166. package/dist/parser/inline-autolink.d.mts +7 -0
  167. package/dist/parser/inline-autolink.d.mts.map +1 -0
  168. package/dist/parser/inline-autolink.mjs +42 -0
  169. package/dist/parser/inline-autolink.mjs.map +1 -0
  170. package/dist/parser/inline-character-reference.d.mts +7 -0
  171. package/dist/parser/inline-character-reference.d.mts.map +1 -0
  172. package/dist/parser/inline-character-reference.mjs +22 -0
  173. package/dist/parser/inline-character-reference.mjs.map +1 -0
  174. package/dist/parser/inline-code.d.mts +7 -0
  175. package/dist/parser/inline-code.d.mts.map +1 -0
  176. package/dist/parser/inline-code.mjs +29 -0
  177. package/dist/parser/inline-code.mjs.map +1 -0
  178. package/dist/parser/inline-directive.d.mts +9 -0
  179. package/dist/parser/inline-directive.d.mts.map +1 -0
  180. package/dist/parser/inline-directive.mjs +45 -0
  181. package/dist/parser/inline-directive.mjs.map +1 -0
  182. package/dist/parser/inline-embedded.d.mts +19 -0
  183. package/dist/parser/inline-embedded.d.mts.map +1 -0
  184. package/dist/parser/inline-embedded.mjs +92 -0
  185. package/dist/parser/inline-embedded.mjs.map +1 -0
  186. package/dist/parser/inline-emphasis.d.mts +11 -0
  187. package/dist/parser/inline-emphasis.d.mts.map +1 -0
  188. package/dist/parser/inline-emphasis.mjs +79 -0
  189. package/dist/parser/inline-emphasis.mjs.map +1 -0
  190. package/dist/parser/inline-input.d.mts +46 -0
  191. package/dist/parser/inline-input.d.mts.map +1 -0
  192. package/dist/parser/inline-input.mjs +137 -0
  193. package/dist/parser/inline-input.mjs.map +1 -0
  194. package/dist/parser/inline-link.d.mts +12 -0
  195. package/dist/parser/inline-link.d.mts.map +1 -0
  196. package/dist/parser/inline-link.mjs +187 -0
  197. package/dist/parser/inline-link.mjs.map +1 -0
  198. package/dist/parser/inline-math.d.mts +10 -0
  199. package/dist/parser/inline-math.d.mts.map +1 -0
  200. package/dist/parser/inline-math.mjs +46 -0
  201. package/dist/parser/inline-math.mjs.map +1 -0
  202. package/dist/parser/inline-output.d.mts +34 -0
  203. package/dist/parser/inline-output.d.mts.map +1 -0
  204. package/dist/parser/inline-output.mjs +62 -0
  205. package/dist/parser/inline-output.mjs.map +1 -0
  206. package/dist/parser/inline-parser.d.mts +14 -0
  207. package/dist/parser/inline-parser.d.mts.map +1 -0
  208. package/dist/parser/inline-parser.mjs +328 -0
  209. package/dist/parser/inline-parser.mjs.map +1 -0
  210. package/dist/parser/inline-pending.d.mts +23 -0
  211. package/dist/parser/inline-pending.d.mts.map +1 -0
  212. package/dist/parser/inline-pending.mjs +100 -0
  213. package/dist/parser/inline-pending.mjs.map +1 -0
  214. package/dist/parser/inline-syntax.d.mts +118 -0
  215. package/dist/parser/inline-syntax.d.mts.map +1 -0
  216. package/dist/parser/inline-syntax.mjs +1 -0
  217. package/dist/parser/javascript-boundary.d.mts +16 -0
  218. package/dist/parser/javascript-boundary.d.mts.map +1 -0
  219. package/dist/parser/javascript-boundary.mjs +42 -0
  220. package/dist/parser/javascript-boundary.mjs.map +1 -0
  221. package/dist/parser/javascript-scanner.d.mts +22 -0
  222. package/dist/parser/javascript-scanner.d.mts.map +1 -0
  223. package/dist/parser/javascript-scanner.mjs +122 -0
  224. package/dist/parser/javascript-scanner.mjs.map +1 -0
  225. package/dist/parser/materialize-cache.d.mts +34 -0
  226. package/dist/parser/materialize-cache.d.mts.map +1 -0
  227. package/dist/parser/materialize-cache.mjs +12 -0
  228. package/dist/parser/materialize-cache.mjs.map +1 -0
  229. package/dist/parser/materialize-jsx.d.mts +14 -0
  230. package/dist/parser/materialize-jsx.d.mts.map +1 -0
  231. package/dist/parser/materialize-jsx.mjs +76 -0
  232. package/dist/parser/materialize-jsx.mjs.map +1 -0
  233. package/dist/parser/materialize.d.mts +61 -0
  234. package/dist/parser/materialize.d.mts.map +1 -0
  235. package/dist/parser/materialize.mjs +736 -0
  236. package/dist/parser/materialize.mjs.map +1 -0
  237. package/dist/parser/recognizer.d.mts +20 -0
  238. package/dist/parser/recognizer.d.mts.map +1 -0
  239. package/dist/parser/recognizer.mjs +24 -0
  240. package/dist/parser/recognizer.mjs.map +1 -0
  241. package/dist/parser/session.d.mts +42 -0
  242. package/dist/parser/session.d.mts.map +1 -0
  243. package/dist/parser/session.mjs +89 -0
  244. package/dist/parser/session.mjs.map +1 -0
  245. package/dist/parser.d.mts +25 -0
  246. package/dist/parser.d.mts.map +1 -0
  247. package/dist/parser.mjs +37 -0
  248. package/dist/parser.mjs.map +1 -0
  249. package/dist/plugin-internal.d.mts +25 -0
  250. package/dist/plugin-internal.d.mts.map +1 -0
  251. package/dist/plugin-internal.mjs +99 -0
  252. package/dist/plugin-internal.mjs.map +1 -0
  253. package/dist/plugin.d.mts +37 -0
  254. package/dist/plugin.d.mts.map +1 -0
  255. package/dist/plugin.mjs +1 -0
  256. package/dist/plugins/code-block-metadata.d.mts +42 -0
  257. package/dist/plugins/code-block-metadata.d.mts.map +1 -0
  258. package/dist/plugins/code-block-metadata.mjs +133 -0
  259. package/dist/plugins/code-block-metadata.mjs.map +1 -0
  260. package/dist/plugins/heading-id.d.mts +15 -0
  261. package/dist/plugins/heading-id.d.mts.map +1 -0
  262. package/dist/plugins/heading-id.mjs +45 -0
  263. package/dist/plugins/heading-id.mjs.map +1 -0
  264. package/dist/plugins/lower-heading.d.mts +16 -0
  265. package/dist/plugins/lower-heading.d.mts.map +1 -0
  266. package/dist/plugins/lower-heading.mjs +28 -0
  267. package/dist/plugins/lower-heading.mjs.map +1 -0
  268. package/dist/plugins/math-render.d.mts +26 -0
  269. package/dist/plugins/math-render.d.mts.map +1 -0
  270. package/dist/plugins/math-render.mjs +51 -0
  271. package/dist/plugins/math-render.mjs.map +1 -0
  272. package/dist/plugins/mod.d.mts +9 -6
  273. package/dist/plugins/mod.mjs +8 -6
  274. package/dist/plugins/remove-esm.d.mts +10 -0
  275. package/dist/plugins/remove-esm.d.mts.map +1 -0
  276. package/dist/plugins/remove-esm.mjs +12 -0
  277. package/dist/plugins/remove-esm.mjs.map +1 -0
  278. package/dist/plugins/shiki.d.mts +21 -0
  279. package/dist/plugins/shiki.d.mts.map +1 -0
  280. package/dist/plugins/shiki.mjs +144 -0
  281. package/dist/plugins/shiki.mjs.map +1 -0
  282. package/dist/plugins/syntax-highlight.d.mts +38 -0
  283. package/dist/plugins/syntax-highlight.d.mts.map +1 -0
  284. package/dist/plugins/syntax-highlight.mjs +106 -0
  285. package/dist/plugins/syntax-highlight.mjs.map +1 -0
  286. package/dist/processor.d.mts +60 -0
  287. package/dist/processor.d.mts.map +1 -0
  288. package/dist/processor.mjs +106 -0
  289. package/dist/processor.mjs.map +1 -0
  290. package/dist/ranges.d.mts +10 -0
  291. package/dist/ranges.d.mts.map +1 -0
  292. package/dist/ranges.mjs +22 -0
  293. package/dist/ranges.mjs.map +1 -0
  294. package/dist/source-map.d.mts +28 -0
  295. package/dist/source-map.d.mts.map +1 -0
  296. package/dist/source-map.mjs +90 -0
  297. package/dist/source-map.mjs.map +1 -0
  298. package/dist/source-text.d.mts +35 -0
  299. package/dist/source-text.d.mts.map +1 -0
  300. package/dist/source-text.mjs +136 -0
  301. package/dist/source-text.mjs.map +1 -0
  302. package/dist/source.d.mts +86 -0
  303. package/dist/source.d.mts.map +1 -0
  304. package/dist/source.mjs +264 -0
  305. package/dist/source.mjs.map +1 -0
  306. package/dist/stream-events.d.mts +59 -0
  307. package/dist/stream-events.d.mts.map +1 -0
  308. package/dist/stream-events.mjs +115 -0
  309. package/dist/stream-events.mjs.map +1 -0
  310. package/dist/stream-session.d.mts +79 -0
  311. package/dist/stream-session.d.mts.map +1 -0
  312. package/dist/stream-session.mjs +904 -0
  313. package/dist/stream-session.mjs.map +1 -0
  314. package/dist/stream-tail.d.mts +84 -0
  315. package/dist/stream-tail.d.mts.map +1 -0
  316. package/dist/stream-tail.mjs +359 -0
  317. package/dist/stream-tail.mjs.map +1 -0
  318. package/dist/stream-types.d.mts +89 -0
  319. package/dist/stream-types.d.mts.map +1 -0
  320. package/dist/stream-types.mjs +1 -0
  321. package/dist/stream.d.mts +28 -0
  322. package/dist/stream.d.mts.map +1 -0
  323. package/dist/stream.mjs +68 -0
  324. package/dist/stream.mjs.map +1 -0
  325. package/dist/syntax-options.d.mts +21 -0
  326. package/dist/syntax-options.d.mts.map +1 -0
  327. package/dist/syntax-options.mjs +26 -0
  328. package/dist/syntax-options.mjs.map +1 -0
  329. package/dist/traversal.d.mts +25 -0
  330. package/dist/traversal.d.mts.map +1 -0
  331. package/dist/traversal.mjs +136 -0
  332. package/dist/traversal.mjs.map +1 -0
  333. package/dist/tree.d.mts +18 -0
  334. package/dist/tree.d.mts.map +1 -0
  335. package/dist/tree.mjs +43 -0
  336. package/dist/tree.mjs.map +1 -0
  337. package/dist/unified/adapter.d.mts +24 -0
  338. package/dist/unified/adapter.d.mts.map +1 -0
  339. package/dist/unified/adapter.mjs +44 -0
  340. package/dist/unified/adapter.mjs.map +1 -0
  341. package/dist/unified/mod.d.mts +2 -0
  342. package/dist/unified/mod.mjs +1 -0
  343. package/dist/unified/runtime.d.mts +10 -0
  344. package/dist/unified/runtime.d.mts.map +1 -0
  345. package/dist/unified/runtime.mjs +115 -0
  346. package/dist/unified/runtime.mjs.map +1 -0
  347. package/dist/unified/tree-bridge.d.mts +63 -0
  348. package/dist/unified/tree-bridge.d.mts.map +1 -0
  349. package/dist/unified/tree-bridge.mjs +876 -0
  350. package/dist/unified/tree-bridge.mjs.map +1 -0
  351. package/dist/uri.d.mts +5 -0
  352. package/dist/uri.d.mts.map +1 -0
  353. package/dist/uri.mjs +32 -0
  354. package/dist/uri.mjs.map +1 -0
  355. package/package.json +56 -30
  356. package/dist/plugins/heading-id/plugin.d.mts +0 -17
  357. package/dist/plugins/heading-id/plugin.d.mts.map +0 -1
  358. package/dist/plugins/heading-id/plugin.mjs +0 -23
  359. package/dist/plugins/heading-id/plugin.mjs.map +0 -1
  360. package/dist/plugins/katex/plugin.d.mts +0 -39
  361. package/dist/plugins/katex/plugin.d.mts.map +0 -1
  362. package/dist/plugins/katex/plugin.mjs +0 -107
  363. package/dist/plugins/katex/plugin.mjs.map +0 -1
  364. package/dist/plugins/remove-imports-exports.d.mts +0 -10
  365. package/dist/plugins/remove-imports-exports.d.mts.map +0 -1
  366. package/dist/plugins/remove-imports-exports.mjs +0 -15
  367. package/dist/plugins/remove-imports-exports.mjs.map +0 -1
  368. package/dist/plugins/syntax-highlight/code-meta.d.mts +0 -22
  369. package/dist/plugins/syntax-highlight/code-meta.d.mts.map +0 -1
  370. package/dist/plugins/syntax-highlight/code-meta.mjs +0 -38
  371. package/dist/plugins/syntax-highlight/code-meta.mjs.map +0 -1
  372. package/dist/plugins/syntax-highlight/plugin.d.mts +0 -57
  373. package/dist/plugins/syntax-highlight/plugin.d.mts.map +0 -1
  374. package/dist/plugins/syntax-highlight/plugin.mjs +0 -93
  375. package/dist/plugins/syntax-highlight/plugin.mjs.map +0 -1
  376. package/dist/plugins/tree-processor/plugin.d.mts +0 -19
  377. package/dist/plugins/tree-processor/plugin.d.mts.map +0 -1
  378. package/dist/plugins/tree-processor/plugin.mjs +0 -21
  379. package/dist/plugins/tree-processor/plugin.mjs.map +0 -1
  380. package/dist/types.d.mts +0 -2
  381. /package/dist/{types.mjs → parser/block-syntax.mjs} +0 -0
@@ -0,0 +1,904 @@
1
+ import { createDiagnostic } from "./diagnostics.mjs";
2
+ import { LimitError, ParseError } from "./errors.mjs";
3
+ import { FootnoteNumbering } from "./footnote-numbering.mjs";
4
+ import { mdxChildren } from "./model.mjs";
5
+ import { rangesIntersect, shiftRange } from "./ranges.mjs";
6
+ import { SourceBuffer, sourceText } from "./source.mjs";
7
+ import { createHtmlLoweringCache, lowerFootnoteSection, lowerNodes } from "./html-lower.mjs";
8
+ import { createMaterializeCache } from "./parser/materialize-cache.mjs";
9
+ import { materializeDocument } from "./parser/materialize.mjs";
10
+ import { ParserSession } from "./parser/session.mjs";
11
+ import { FenceText, OpenParagraph, lowerOpenLeaf, trimOpenTail } from "./stream-tail.mjs";
12
+ import { rewriteMdx } from "./traversal.mjs";
13
+ //#region src/stream-session.ts
14
+ const EMPTY_DEFINITIONS = {
15
+ links: /* @__PURE__ */ new Map(),
16
+ footnotes: /* @__PURE__ */ new Map()
17
+ };
18
+ const NO_OCCURRENCES = Object.freeze([]);
19
+ const NO_DEPENDENCIES = Object.freeze({
20
+ definitions: Object.freeze([]),
21
+ footnotes: Object.freeze([])
22
+ });
23
+ /**
24
+ * Owns the parser and the rendered blocks of one stream. A top-level block
25
+ * settles once later input cannot change it, and then materializes and lowers
26
+ * once. Each append renders only the open tail; a settled block renders again
27
+ * only when a definition or footnote number it uses changes.
28
+ */
29
+ var StreamSession = class {
30
+ #limits;
31
+ #maximumPendingBlockLength;
32
+ #parser;
33
+ /** The stream owns its source; each version is an immutable file. */
34
+ #source;
35
+ #file;
36
+ /** Settled parser output that has not been rendered yet. */
37
+ #queue = [];
38
+ #settled = [];
39
+ /** The settled blocks' renderings, kept beside the entries so a snapshot copies one array. */
40
+ #blocks = [];
41
+ #tail = [];
42
+ #definitions = EMPTY_DEFINITIONS;
43
+ #dependents = /* @__PURE__ */ new Map();
44
+ #nodes = 0;
45
+ #diagnostics = [];
46
+ #limited;
47
+ #referenceLimits = /* @__PURE__ */ new Map();
48
+ #numbering = new FootnoteNumbering();
49
+ #occurrences = /* @__PURE__ */ new WeakMap();
50
+ #tailDefinitions = EMPTY_DEFINITIONS;
51
+ #tailNumbering = new FootnoteNumbering();
52
+ #tailOccurrences = /* @__PURE__ */ new WeakMap();
53
+ #definitionsVersion = 0;
54
+ #footnotes;
55
+ #footnotesKey = [];
56
+ #materializeCache = createMaterializeCache();
57
+ #loweringCache = createHtmlLoweringCache();
58
+ #fence = new FenceText();
59
+ #paragraph = new OpenParagraph();
60
+ #phrasing = /* @__PURE__ */ new WeakMap();
61
+ #nextId = 0;
62
+ #current;
63
+ #lastValid;
64
+ /** The settled numbering must restart, because settled blocks were dropped. */
65
+ #renumber = false;
66
+ #limitedPreview = false;
67
+ constructor(options) {
68
+ this.#limits = options.limits;
69
+ this.#maximumPendingBlockLength = options.maximumPendingBlockLength;
70
+ this.#source = new SourceBuffer({
71
+ name: options.name,
72
+ text: options.source
73
+ });
74
+ this.#file = this.#source.file;
75
+ this.#parser = new ParserSession({
76
+ source: this.#file,
77
+ syntax: options.syntax,
78
+ onSettled: (syntax, index) => this.#queue.push({
79
+ syntax,
80
+ index
81
+ })
82
+ });
83
+ this.#current = this.update(0);
84
+ }
85
+ /** The latest change, whose snapshot is the current preview. */
86
+ get current() {
87
+ return this.#current;
88
+ }
89
+ append(text) {
90
+ const start = this.#settled.length;
91
+ this.#file = this.#source.append(text);
92
+ this.#parser.append(text, sourceText(this.#file));
93
+ this.#current = this.update(start);
94
+ return this.#current;
95
+ }
96
+ edit(edit) {
97
+ const retired = this.retiredIds(edit);
98
+ this.#file = this.#source.replace(edit.start, edit.end, edit.text);
99
+ this.#parser.edit(edit);
100
+ this.#current = this.update(this.#settled.length, retired);
101
+ return this.#current;
102
+ }
103
+ /**
104
+ * Finishes the tail strictly and assembles the document from the settled
105
+ * blocks' nodes, so only the tail materializes again.
106
+ */
107
+ complete() {
108
+ const limited = this.limitState();
109
+ if (limited !== void 0 && limited.limit !== "maximumPendingBlockLength") throw this.limitError(limited);
110
+ const tail = this.#parser.tailDraft().blocks;
111
+ const settled = this.#settled;
112
+ const diagnostics = [];
113
+ const errors = [];
114
+ const parts = [];
115
+ let nodes = 1 + this.#nodes;
116
+ for (const entry of settled) if (entry.materialized.kind === "invalid") errors.push(...entry.materialized.diagnostics);
117
+ else if (entry.materialized.kind === "ok") {
118
+ diagnostics.push(...entry.materialized.diagnostics);
119
+ parts.push({
120
+ id: entry.id,
121
+ origin: entry.origin,
122
+ node: entry.materialized.node
123
+ });
124
+ }
125
+ const tailIds = new Map(this.#tail.map((entry) => [entry.origin.start, entry.id]));
126
+ for (const syntax of tail) {
127
+ const origin = blockOrigin(sourceText(this.#file), syntax);
128
+ const materialized = materializeDocument(this.#file, [syntax], this.#parser.syntax, {
129
+ ...this.#limits,
130
+ maximumNodes: Math.max(1, this.#limits.maximumNodes - nodes + 1)
131
+ }, {
132
+ keepReferences: true,
133
+ cache: this.#materializeCache,
134
+ definitionLookup: this.effectiveDefinitions().links
135
+ });
136
+ if (materialized.kind === "limitExceeded") throw this.limitError({
137
+ limit: materialized.limit,
138
+ offset: origin.end
139
+ });
140
+ if (materialized.kind === "invalid") {
141
+ errors.push(...materialized.diagnostics);
142
+ continue;
143
+ }
144
+ diagnostics.push(...materialized.diagnostics);
145
+ for (const block of materialized.blocks) {
146
+ nodes += block.nodeCount;
147
+ parts.push({
148
+ id: tailIds.get(origin.start) ?? this.newId(),
149
+ origin,
150
+ node: block.node
151
+ });
152
+ }
153
+ }
154
+ const [firstError, ...otherErrors] = errors;
155
+ if (firstError !== void 0) throw ParseError.invalidSyntax(this.#file, [firstError, ...otherErrors]);
156
+ if (nodes > this.#limits.maximumNodes) throw this.limitError({
157
+ limit: "maximumNodes",
158
+ offset: this.#file.length
159
+ });
160
+ const definitions = collectDefinitions(parts.map((part) => part.node));
161
+ const document = {
162
+ kind: "document",
163
+ children: parts.map((part) => resolveReferences(part.node, definitions, this.#file)),
164
+ origin: {
165
+ start: 0,
166
+ end: this.#file.length
167
+ }
168
+ };
169
+ return Object.freeze({
170
+ kind: "complete",
171
+ file: this.#file,
172
+ document,
173
+ blocks: Object.freeze(parts.map((part) => Object.freeze({
174
+ id: part.id,
175
+ origin: part.origin
176
+ }))),
177
+ diagnostics: Object.freeze(diagnostics)
178
+ });
179
+ }
180
+ /**
181
+ * Settles queued blocks, renders the blocks whose definitions or footnote
182
+ * numbers changed, renders the open tail, and assembles the snapshot.
183
+ */
184
+ update(previousSettled, retired) {
185
+ if (this.#file.length > this.#limits.maximumSourceLength) return this.limitChange({
186
+ limit: "maximumSourceLength",
187
+ offset: this.#file.length
188
+ });
189
+ const before = this.effectiveDefinitions();
190
+ const previousTail = this.#tail;
191
+ const start = Math.min(previousSettled, this.dropChangedSettled());
192
+ const firstAdded = this.#settled.length;
193
+ const adopted = this.settleQueued(previousTail, retired);
194
+ const draft = this.#parser.tailDraft();
195
+ const parts = draft.blocks.map((syntax) => this.materializeTail(syntax, draft.pending));
196
+ this.#tailDefinitions = collectDefinitions(parts.flatMap(materializedNodes));
197
+ const after = this.effectiveDefinitions();
198
+ const changed = changedDefinitions(before, after);
199
+ const refreshed = this.refreshSettled(changed, after, firstAdded, adopted, start);
200
+ const settledDefinitions = this.effectiveDefinitions();
201
+ const resolvedParts = parts.map((part) => {
202
+ if (part.materialized.kind !== "ok" || !part.materialized.references.some((id) => changed.links.has(id))) return part;
203
+ return {
204
+ ...part,
205
+ materialized: this.materialize(part.syntax, this.#limits.maximumNodes - 1 - this.#nodes, part.pending !== void 0 && containsRange(part.syntax.range, part.pending.range) ? part.pending.range : void 0, settledDefinitions.links)
206
+ };
207
+ });
208
+ this.#tailDefinitions = collectDefinitions(resolvedParts.flatMap(materializedNodes));
209
+ const resolvedDefinitions = this.effectiveDefinitions();
210
+ this.renderTail(resolvedParts, previousTail, retired, resolvedDefinitions, changed.links);
211
+ const footnotes = this.footnoteSection(resolvedDefinitions);
212
+ const limited = this.limitState(draft.pending);
213
+ if (limited !== void 0) return this.limitChange(limited);
214
+ const snapshot = Object.freeze({
215
+ kind: "preview",
216
+ file: this.#file,
217
+ blocks: Object.freeze([...this.#blocks, ...this.#tail.map((entry) => entry.block)]),
218
+ footnotes,
219
+ diagnostics: Object.freeze([...this.#diagnostics, ...this.#tail.flatMap((entry) => entry.block.diagnostics)]),
220
+ limit: void 0
221
+ });
222
+ const continuous = !this.#limitedPreview;
223
+ this.#limitedPreview = false;
224
+ const previous = this.#lastValid;
225
+ this.#lastValid = snapshot;
226
+ return Object.freeze({
227
+ snapshot,
228
+ start: previous !== void 0 && continuous ? start : 0,
229
+ refreshed: Object.freeze(continuous ? refreshed : []),
230
+ footnotesChanged: footnotes !== previous?.footnotes
231
+ });
232
+ }
233
+ /**
234
+ * Drops settled blocks that an edit replaced, which settle again from the
235
+ * queue, and returns how many settled blocks remain.
236
+ */
237
+ dropChangedSettled() {
238
+ const keep = Math.min(this.#settled.length, this.#parser.settledCount, this.#queue[0]?.index ?? Infinity);
239
+ if (keep < this.#settled.length) this.truncate(keep);
240
+ return this.#settled.length;
241
+ }
242
+ /** Settles queued parser output and returns the indexes of blocks adopted from the tail. */
243
+ settleQueued(previousTail, retired) {
244
+ const adopted = /* @__PURE__ */ new Set();
245
+ for (const settlement of this.#queue) {
246
+ if (settlement.index !== this.#settled.length) continue;
247
+ const entry = this.settle(settlement.syntax, previousTail, retired);
248
+ if (entry.block !== void 0) adopted.add(this.#settled.length);
249
+ this.addSettled(entry);
250
+ }
251
+ this.#queue = [];
252
+ return adopted;
253
+ }
254
+ /**
255
+ * Renders newly settled blocks, and settled blocks whose definitions or
256
+ * footnote numbers changed. Returns the re-rendered blocks before `start`.
257
+ */
258
+ refreshSettled(changed, definitions, firstAdded, adopted, start) {
259
+ const dirty = /* @__PURE__ */ new Set();
260
+ if (changed.links.size > 0) {
261
+ this.#loweringCache = createHtmlLoweringCache();
262
+ this.#materializeCache = createMaterializeCache();
263
+ this.#definitionsVersion++;
264
+ for (const identifier of changed.links) for (const index of this.#dependents.get(identifier) ?? []) dirty.add(index);
265
+ }
266
+ for (let index = firstAdded; index < this.#settled.length; index++) if (!adopted.has(index)) dirty.add(index);
267
+ let rematerializedFootnotes = false;
268
+ for (const index of this.#referenceLimits.keys()) dirty.add(index);
269
+ for (const index of dirty) {
270
+ const entry = this.#settled[index];
271
+ if (entry.materialized.kind === "ok" && (entry.materialized.references.some((id) => changed.links.has(id)) || this.#referenceLimits.has(index))) {
272
+ const old = entry.materialized;
273
+ const oldCount = old.nodeCount;
274
+ const materialized = this.materialize(entry.syntax, this.#limits.maximumNodes - 1 - this.#nodes + oldCount, void 0, definitions.links);
275
+ if (materialized.kind === "limitExceeded") {
276
+ this.#referenceLimits.set(index, {
277
+ limit: materialized.limit,
278
+ offset: entry.origin.end
279
+ });
280
+ continue;
281
+ }
282
+ this.#referenceLimits.delete(index);
283
+ if (materialized.kind === "ok") this.#definitions = {
284
+ links: replaceDefinitions(this.#definitions.links, old.contents.definitions, materialized.contents.definitions),
285
+ footnotes: replaceDefinitions(this.#definitions.footnotes, old.contents.footnotes, materialized.contents.footnotes)
286
+ };
287
+ this.#nodes += (materialized.kind === "ok" ? materialized.nodeCount : 0) - oldCount;
288
+ for (const identifier of old.contents.definitionReferences) this.#dependents.get(identifier)?.delete(index);
289
+ if (materialized.kind === "ok") for (const identifier of materialized.contents.definitionReferences) {
290
+ const dependents = this.#dependents.get(identifier) ?? /* @__PURE__ */ new Set();
291
+ dependents.add(index);
292
+ this.#dependents.set(identifier, dependents);
293
+ }
294
+ this.#settled[index] = {
295
+ ...entry,
296
+ materialized
297
+ };
298
+ rematerializedFootnotes ||= old.contents.footnoteReferences.length > 0;
299
+ }
300
+ }
301
+ definitions = this.effectiveDefinitions();
302
+ const renumberAll = changed.footnotes || this.#renumber || rematerializedFootnotes;
303
+ this.#renumber = false;
304
+ for (const index of this.renumber(renumberAll ? 0 : firstAdded)) dirty.add(index);
305
+ const refreshed = [];
306
+ for (const index of dirty) {
307
+ this.#settled[index] = this.render(this.#settled[index], definitions, this.#occurrences, true);
308
+ this.#blocks[index] = renderedBlock(this.#settled[index]);
309
+ if (index < start) refreshed.push(renderedBlock(this.#settled[index]));
310
+ }
311
+ for (const index of adopted) {
312
+ const entry = this.#settled[index];
313
+ const block = renderedBlock(entry);
314
+ if (!dirty.has(index) && !block.settled) {
315
+ this.#settled[index] = {
316
+ ...entry,
317
+ block: Object.freeze({
318
+ ...block,
319
+ settled: true
320
+ })
321
+ };
322
+ this.#blocks[index] = renderedBlock(this.#settled[index]);
323
+ }
324
+ }
325
+ return refreshed;
326
+ }
327
+ /** Adopts the tail's rendering for a block that settled unchanged, or queues it to render. */
328
+ settle(syntax, previousTail, retired) {
329
+ const adopted = previousTail.find((entry) => entry.syntax === syntax && entry.pending === void 0);
330
+ if (adopted !== void 0) return adopted;
331
+ const origin = blockOrigin(sourceText(this.#file), syntax);
332
+ return {
333
+ syntax,
334
+ id: this.blockId(origin, previousTail, retired),
335
+ origin,
336
+ materialized: this.materialize(syntax, this.#limits.maximumNodes - 1 - this.#nodes),
337
+ pending: void 0,
338
+ pendingNodes: 0,
339
+ occurrences: NO_OCCURRENCES,
340
+ block: void 0
341
+ };
342
+ }
343
+ materializeTail(syntax, pending) {
344
+ const open = pending !== void 0 && containsRange(syntax.range, pending.range) ? pending : void 0;
345
+ return {
346
+ syntax,
347
+ origin: blockOrigin(sourceText(this.#file), syntax),
348
+ materialized: this.materialize(syntax, this.#limits.maximumNodes - 1 - this.#nodes, open?.range),
349
+ pending: open
350
+ };
351
+ }
352
+ materialize(syntax, budget, open, definitions = this.effectiveDefinitions().links) {
353
+ if (budget < 1) return {
354
+ kind: "limitExceeded",
355
+ limit: "maximumNodes"
356
+ };
357
+ const result = materializeDocument(this.#file, [syntax], this.#parser.syntax, {
358
+ ...this.#limits,
359
+ maximumNodes: budget + 1
360
+ }, {
361
+ keepReferences: true,
362
+ allowIncomplete: true,
363
+ cache: this.#materializeCache,
364
+ open,
365
+ definitionLookup: definitions
366
+ });
367
+ if (result.kind === "limitExceeded") return {
368
+ kind: "limitExceeded",
369
+ limit: result.limit
370
+ };
371
+ if (result.kind === "invalid") return {
372
+ kind: "invalid",
373
+ diagnostics: result.diagnostics
374
+ };
375
+ const [block] = result.blocks;
376
+ if (block === void 0) throw new Error("A stream block materialized to no node");
377
+ const contents = blockContents(block.node);
378
+ return {
379
+ kind: "ok",
380
+ node: block.node,
381
+ nodeCount: block.nodeCount,
382
+ references: block.references,
383
+ diagnostics: result.diagnostics,
384
+ contents: {
385
+ ...contents,
386
+ definitionReferences: [.../* @__PURE__ */ new Set([...contents.definitionReferences, ...block.references])]
387
+ }
388
+ };
389
+ }
390
+ /** Adds one settled block to the running totals. Its rendering may still be pending. */
391
+ addSettled(entry) {
392
+ const index = this.#settled.length;
393
+ this.#settled.push(entry);
394
+ this.#blocks.push(entry.block ?? unrendered);
395
+ const { materialized } = entry;
396
+ if (materialized.kind === "limitExceeded") {
397
+ this.#limited ??= {
398
+ limit: materialized.limit,
399
+ offset: entry.origin.end
400
+ };
401
+ return;
402
+ }
403
+ this.#diagnostics.push(...materialized.diagnostics);
404
+ if (materialized.kind === "invalid") return;
405
+ const { contents } = materialized;
406
+ this.#nodes += materialized.nodeCount;
407
+ if (contents.definitions.length > 0 || contents.footnotes.length > 0) {
408
+ const links = new Map(this.#definitions.links);
409
+ const footnotes = new Map(this.#definitions.footnotes);
410
+ addFirst(links, contents.definitions);
411
+ addFirst(footnotes, contents.footnotes);
412
+ this.#definitions = {
413
+ links,
414
+ footnotes
415
+ };
416
+ }
417
+ for (const identifier of contents.definitionReferences) {
418
+ let dependents = this.#dependents.get(identifier);
419
+ if (dependents === void 0) {
420
+ dependents = /* @__PURE__ */ new Set();
421
+ this.#dependents.set(identifier, dependents);
422
+ }
423
+ dependents.add(index);
424
+ }
425
+ }
426
+ /** Drops the settled blocks from `length` on, after an edit before them. */
427
+ truncate(length) {
428
+ const kept = this.#settled.slice(0, length);
429
+ this.#settled = [];
430
+ this.#blocks = [];
431
+ this.#definitions = EMPTY_DEFINITIONS;
432
+ this.#dependents = /* @__PURE__ */ new Map();
433
+ this.#nodes = 0;
434
+ this.#diagnostics = [];
435
+ this.#limited = void 0;
436
+ for (const index of this.#referenceLimits.keys()) if (index >= length) this.#referenceLimits.delete(index);
437
+ for (const entry of kept) this.addSettled(entry);
438
+ this.#renumber = true;
439
+ }
440
+ /**
441
+ * Numbers footnote references in settled blocks from `from` on, continuing
442
+ * the numbering before them, and returns the blocks whose numbers changed.
443
+ */
444
+ renumber(from) {
445
+ if (from === 0) {
446
+ this.#numbering = new FootnoteNumbering();
447
+ this.#occurrences = /* @__PURE__ */ new WeakMap();
448
+ }
449
+ const changed = [];
450
+ for (let index = from; index < this.#settled.length; index++) {
451
+ const entry = this.#settled[index];
452
+ const occurrences = numberReferences(entry.materialized, this.#numbering, this.#occurrences, (identifier) => this.isFootnoteDefined(identifier));
453
+ if (!sameOccurrences(entry.occurrences, occurrences)) {
454
+ changed.push(index);
455
+ this.#settled[index] = {
456
+ ...entry,
457
+ occurrences
458
+ };
459
+ }
460
+ }
461
+ return changed;
462
+ }
463
+ renderTail(parts, previousTail, retired, definitions, changedLinks) {
464
+ this.#tailNumbering = this.#numbering.fork();
465
+ this.#tailOccurrences = /* @__PURE__ */ new WeakMap();
466
+ this.#tail = parts.map((part) => {
467
+ const occurrences = numberReferences(part.materialized, this.#tailNumbering, this.#tailOccurrences, (identifier) => this.isFootnoteDefined(identifier));
468
+ const reusable = previousTail.find((entry) => entry.syntax === part.syntax && entry.pending === void 0 && part.pending === void 0 && sameOccurrences(entry.occurrences, occurrences) && !dependsOn(entry, changedLinks));
469
+ if (reusable !== void 0) return reusable;
470
+ return this.render({
471
+ ...part,
472
+ id: this.blockId(part.origin, previousTail, retired),
473
+ pendingNodes: 0,
474
+ occurrences,
475
+ block: void 0
476
+ }, definitions, this.#tailOccurrences, false);
477
+ });
478
+ const last = this.#tail.at(-1);
479
+ if (last !== void 0) {
480
+ const nodes = trimOpenTail(last.block.nodes);
481
+ if (nodes !== last.block.nodes) this.#tail[this.#tail.length - 1] = {
482
+ ...last,
483
+ block: Object.freeze({
484
+ ...last.block,
485
+ nodes: Object.freeze(nodes)
486
+ })
487
+ };
488
+ }
489
+ }
490
+ /** Lowers one block in the stream's scope. */
491
+ render(entry, definitions, occurrences, settled) {
492
+ const { materialized, pending } = entry;
493
+ if (materialized.kind !== "ok") {
494
+ const invalid = materialized.kind === "invalid";
495
+ return {
496
+ ...entry,
497
+ block: Object.freeze({
498
+ id: entry.id,
499
+ origin: entry.origin,
500
+ nodes: Object.freeze(invalid ? inertSource(this.#file, entry.origin) : []),
501
+ status: invalid ? "invalid" : "valid",
502
+ settled,
503
+ diagnostics: invalid ? materialized.diagnostics : Object.freeze([]),
504
+ dependencies: NO_DEPENDENCIES
505
+ })
506
+ };
507
+ }
508
+ let pendingNodes = 0;
509
+ const references = new Set(materialized.references);
510
+ const scope = {
511
+ definition: (identifier) => definitions.links.get(identifier),
512
+ footnote: (identifier) => definitions.footnotes.get(identifier),
513
+ occurrence: (node) => occurrences.get(node),
514
+ options: { source: this.#file },
515
+ provisional: true,
516
+ cache: this.#loweringCache
517
+ };
518
+ const nodes = lowerNodes([materialized.node], pending === void 0 ? scope : {
519
+ ...scope,
520
+ replace: (node) => {
521
+ const open = lowerOpenLeaf(node, pending, {
522
+ file: this.#file,
523
+ definitions: definitions.links,
524
+ references,
525
+ syntax: this.#parser.syntax,
526
+ limits: this.#limits,
527
+ fence: this.#fence,
528
+ paragraph: this.#paragraph,
529
+ phrasing: this.#phrasing,
530
+ lowering: this.#loweringCache
531
+ }, (children, previous) => lowerNodes(children, scope, previous));
532
+ pendingNodes += open?.nodeCount ?? 0;
533
+ return open?.nodes;
534
+ }
535
+ });
536
+ const contents = {
537
+ ...materialized.contents,
538
+ definitionReferences: [.../* @__PURE__ */ new Set([...materialized.contents.definitionReferences, ...references])]
539
+ };
540
+ return {
541
+ ...entry,
542
+ materialized: {
543
+ ...materialized,
544
+ contents,
545
+ references: [...references]
546
+ },
547
+ pendingNodes,
548
+ block: Object.freeze({
549
+ id: entry.id,
550
+ origin: entry.origin,
551
+ nodes: Object.freeze(nodes),
552
+ status: "valid",
553
+ settled,
554
+ diagnostics: materialized.diagnostics,
555
+ dependencies: dependenciesOf(contents)
556
+ })
557
+ };
558
+ }
559
+ isFootnoteDefined(identifier) {
560
+ return this.#definitions.footnotes.has(identifier) || this.#tailDefinitions.footnotes.has(identifier);
561
+ }
562
+ effectiveDefinitions() {
563
+ const tail = this.#tailDefinitions;
564
+ if (tail.links.size === 0 && tail.footnotes.size === 0) return this.#definitions;
565
+ const links = new Map(this.#definitions.links);
566
+ const footnotes = new Map(this.#definitions.footnotes);
567
+ addFirst(links, [...tail.links.values()]);
568
+ addFirst(footnotes, [...tail.footnotes.values()]);
569
+ return {
570
+ links,
571
+ footnotes
572
+ };
573
+ }
574
+ /** The footnote section, rebuilt only when its numbering or definitions change. */
575
+ footnoteSection(definitions) {
576
+ const numbering = this.#tailNumbering;
577
+ const key = [this.#definitionsVersion, ...numbering.order.flatMap((identifier) => [
578
+ identifier,
579
+ numbering.count(identifier),
580
+ definitions.footnotes.get(identifier)
581
+ ])];
582
+ if (key.length === this.#footnotesKey.length && key.every((value, index) => value === this.#footnotesKey[index])) return this.#footnotes;
583
+ this.#footnotesKey = key;
584
+ this.#footnotes = lowerFootnoteSection(numbering, {
585
+ definition: (identifier) => definitions.links.get(identifier),
586
+ footnote: (identifier) => definitions.footnotes.get(identifier),
587
+ occurrence: (node) => this.#occurrences.get(node) ?? this.#tailOccurrences.get(node),
588
+ options: { source: this.#file },
589
+ provisional: true
590
+ });
591
+ return this.#footnotes;
592
+ }
593
+ /** The first limit the stream exceeds, if any. */
594
+ limitState(pending) {
595
+ if (this.#file.length > this.#limits.maximumSourceLength) return {
596
+ limit: "maximumSourceLength",
597
+ offset: this.#file.length
598
+ };
599
+ if (this.#limited !== void 0) return this.#limited;
600
+ const referenceLimit = this.#referenceLimits.values().next().value;
601
+ if (referenceLimit !== void 0) return referenceLimit;
602
+ let nodes = 1 + this.#nodes;
603
+ for (const entry of this.#tail) {
604
+ if (entry.materialized.kind === "limitExceeded") return {
605
+ limit: entry.materialized.limit,
606
+ offset: entry.origin.end
607
+ };
608
+ nodes += (entry.materialized.kind === "ok" ? entry.materialized.nodeCount : 0) + entry.pendingNodes;
609
+ }
610
+ if (nodes > this.#limits.maximumNodes) return {
611
+ limit: "maximumNodes",
612
+ offset: this.#tail.at(-1)?.origin.end ?? 0
613
+ };
614
+ const owner = pending === void 0 ? void 0 : this.#tail.find((entry) => entry.pending !== void 0);
615
+ if (owner !== void 0 && owner.syntax.range.end - owner.syntax.range.start > this.#maximumPendingBlockLength) return {
616
+ limit: "maximumPendingBlockLength",
617
+ offset: owner.syntax.range.end
618
+ };
619
+ }
620
+ /** Keeps the last preview within limits, with its block identities. */
621
+ limitChange(state) {
622
+ this.#limitedPreview = true;
623
+ const snapshot = Object.freeze({
624
+ kind: "preview",
625
+ file: this.#file,
626
+ blocks: this.#lastValid?.blocks ?? Object.freeze([]),
627
+ footnotes: this.#lastValid?.footnotes,
628
+ diagnostics: Object.freeze([limitDiagnostic(this.#file, state)]),
629
+ limit: state.limit
630
+ });
631
+ return Object.freeze({
632
+ snapshot,
633
+ start: snapshot.blocks.length,
634
+ refreshed: Object.freeze([]),
635
+ footnotesChanged: false
636
+ });
637
+ }
638
+ limitError(state) {
639
+ const maximum = state.limit === "maximumPendingBlockLength" ? this.#maximumPendingBlockLength : this.#limits[state.limit];
640
+ return LimitError.exceeded(this.#file, state.limit, maximum, {
641
+ start: state.offset,
642
+ end: state.offset
643
+ }, state.limit === "maximumSourceLength" ? this.#file.length : void 0);
644
+ }
645
+ /** A block keeps its identity across appends, and across edits that do not touch it. */
646
+ blockId(origin, previousTail, retired) {
647
+ if (retired !== void 0) return retired.get(rangeKey(origin)) ?? this.newId();
648
+ return previousTail.find((entry) => entry.origin.start === origin.start)?.id ?? this.newId();
649
+ }
650
+ /** Identities of blocks an edit does not touch, keyed by their range after the edit. */
651
+ retiredIds(edit) {
652
+ const retired = /* @__PURE__ */ new Map();
653
+ const delta = edit.text.length - (edit.end - edit.start);
654
+ for (const entry of [...this.#settled, ...this.#tail]) if (!rangesIntersect(entry.origin, edit)) retired.set(rangeKey(entry.origin.start >= edit.end ? shiftRange(entry.origin, delta) : entry.origin), entry.id);
655
+ return retired;
656
+ }
657
+ newId() {
658
+ const value = `block-${this.#nextId++}`;
659
+ if (!isBlockId(value)) throw new Error("Internal block identity invariant failed");
660
+ return value;
661
+ }
662
+ };
663
+ /** Stands in for a settled block until it renders later in the same update. */
664
+ const unrendered = Object.freeze({
665
+ id: placeholderId(),
666
+ origin: Object.freeze({
667
+ start: 0,
668
+ end: 0
669
+ }),
670
+ nodes: Object.freeze([]),
671
+ status: "valid",
672
+ settled: true,
673
+ diagnostics: Object.freeze([]),
674
+ dependencies: NO_DEPENDENCIES
675
+ });
676
+ /** Every settled entry renders before an update publishes its snapshot. */
677
+ function renderedBlock(entry) {
678
+ if (entry.block === void 0) throw new Error("A settled stream block was not rendered");
679
+ return entry.block;
680
+ }
681
+ function materializedNodes(part) {
682
+ return part.materialized.kind === "ok" ? [part.materialized.node] : [];
683
+ }
684
+ const emptyContents = Object.freeze({
685
+ definitionReferences: Object.freeze([]),
686
+ footnoteReferences: Object.freeze([]),
687
+ definitions: Object.freeze([]),
688
+ footnotes: Object.freeze([])
689
+ });
690
+ /** Contents by node identity. Trees are immutable, so a reused subtree is walked once. */
691
+ const contentsCache = /* @__PURE__ */ new WeakMap();
692
+ /** The references a node makes and the definitions it contains, in document order. */
693
+ function blockContents(node) {
694
+ const hit = contentsCache.get(node);
695
+ if (hit !== void 0) return hit;
696
+ if (node.kind === "list") return listContents(node);
697
+ const parts = mdxChildren(node).map(blockContents);
698
+ switch (node.kind) {
699
+ case "linkReference":
700
+ case "imageReference":
701
+ parts.unshift({
702
+ ...emptyContents,
703
+ definitionReferences: [node.identifier]
704
+ });
705
+ break;
706
+ case "footnoteReference":
707
+ parts.unshift({
708
+ ...emptyContents,
709
+ footnoteReferences: [node]
710
+ });
711
+ break;
712
+ case "definition":
713
+ parts.unshift({
714
+ ...emptyContents,
715
+ definitions: [node]
716
+ });
717
+ break;
718
+ case "footnoteDefinition": parts.unshift({
719
+ ...emptyContents,
720
+ footnotes: [node]
721
+ });
722
+ }
723
+ const filled = parts.filter((part) => part !== emptyContents);
724
+ const contents = filled.length === 0 ? emptyContents : filled.length === 1 ? filled[0] : {
725
+ definitionReferences: [...new Set(filled.flatMap((part) => part.definitionReferences))],
726
+ footnoteReferences: filled.flatMap((part) => part.footnoteReferences),
727
+ definitions: filled.flatMap((part) => part.definitions),
728
+ footnotes: filled.flatMap((part) => part.footnotes)
729
+ };
730
+ contentsCache.set(node, contents);
731
+ return contents;
732
+ }
733
+ /** A list's contents after each of its last items, by item. */
734
+ const listContentsCache = /* @__PURE__ */ new WeakMap();
735
+ /** A growing list combines the contents of its unchanged leading items once. */
736
+ function listContents(node) {
737
+ const items = node.children;
738
+ let start = 0;
739
+ let contents = emptyContents;
740
+ for (let index = items.length - 1; index >= Math.max(0, items.length - 8); index--) {
741
+ const prefix = listContentsCache.get(items[index]);
742
+ if (prefix?.index === index) {
743
+ start = index + 1;
744
+ contents = prefix.contents;
745
+ break;
746
+ }
747
+ }
748
+ for (let index = start; index < items.length; index++) {
749
+ contents = mergeContents(contents, blockContents(items[index]));
750
+ if (index >= items.length - 8) listContentsCache.set(items[index], {
751
+ index,
752
+ contents
753
+ });
754
+ }
755
+ contentsCache.set(node, contents);
756
+ return contents;
757
+ }
758
+ function mergeContents(left, right) {
759
+ if (right === emptyContents) return left;
760
+ if (left === emptyContents) return right;
761
+ return {
762
+ definitionReferences: [.../* @__PURE__ */ new Set([...left.definitionReferences, ...right.definitionReferences])],
763
+ footnoteReferences: [...left.footnoteReferences, ...right.footnoteReferences],
764
+ definitions: [...left.definitions, ...right.definitions],
765
+ footnotes: [...left.footnotes, ...right.footnotes]
766
+ };
767
+ }
768
+ function collectDefinitions(nodes) {
769
+ const links = /* @__PURE__ */ new Map();
770
+ const footnotes = /* @__PURE__ */ new Map();
771
+ for (const node of nodes) {
772
+ const contents = blockContents(node);
773
+ addFirst(links, contents.definitions);
774
+ addFirst(footnotes, contents.footnotes);
775
+ }
776
+ return {
777
+ links,
778
+ footnotes
779
+ };
780
+ }
781
+ /** Replaces re-materialized definitions only when their old node was the winning definition. */
782
+ function replaceDefinitions(current, previous, next) {
783
+ if (previous.length === 0) return current;
784
+ const old = new Set(previous);
785
+ const updated = new Map(current);
786
+ for (const node of next) {
787
+ const winner = updated.get(node.identifier);
788
+ if (winner !== void 0 && old.has(winner)) updated.set(node.identifier, node);
789
+ }
790
+ return updated;
791
+ }
792
+ function addFirst(target, nodes) {
793
+ for (const node of nodes) if (!target.has(node.identifier)) target.set(node.identifier, node);
794
+ }
795
+ function changedDefinitions(before, after) {
796
+ const links = /* @__PURE__ */ new Set();
797
+ if (before.links !== after.links) for (const identifier of /* @__PURE__ */ new Set([...before.links.keys(), ...after.links.keys()])) {
798
+ const previous = before.links.get(identifier);
799
+ const next = after.links.get(identifier);
800
+ if (previous?.url !== next?.url || previous?.title !== next?.title) links.add(identifier);
801
+ }
802
+ let footnotes = before.footnotes.size !== after.footnotes.size;
803
+ for (const identifier of after.footnotes.keys()) footnotes ||= !before.footnotes.has(identifier);
804
+ return {
805
+ links,
806
+ footnotes
807
+ };
808
+ }
809
+ function numberReferences(materialized, numbering, occurrences, defined) {
810
+ if (materialized.kind !== "ok" || materialized.contents.footnoteReferences.length === 0) return NO_OCCURRENCES;
811
+ return materialized.contents.footnoteReferences.map((node) => {
812
+ if (!defined(node.identifier)) return;
813
+ const occurrence = numbering.reference(node.identifier);
814
+ occurrences.set(node, occurrence);
815
+ return occurrence;
816
+ });
817
+ }
818
+ function sameOccurrences(left, right) {
819
+ return left === right || left.length === right.length && left.every((occurrence, index) => occurrence?.ordinal === right[index]?.ordinal && occurrence?.occurrence === right[index]?.occurrence);
820
+ }
821
+ function dependsOn(entry, identifiers) {
822
+ return identifiers.size > 0 && entry.materialized.kind === "ok" && entry.materialized.contents.definitionReferences.some((identifier) => identifiers.has(identifier));
823
+ }
824
+ function dependenciesOf(contents) {
825
+ if (contents.definitionReferences.length === 0 && contents.footnoteReferences.length === 0) return NO_DEPENDENCIES;
826
+ return Object.freeze({
827
+ definitions: Object.freeze([...contents.definitionReferences]),
828
+ footnotes: Object.freeze([...new Set(contents.footnoteReferences.map((node) => node.identifier))])
829
+ });
830
+ }
831
+ /** Turns references without definitions into their authored text, like batch parsing. */
832
+ function resolveReferences(node, definitions, file) {
833
+ const contents = blockContents(node);
834
+ if (!(contents.definitionReferences.some((identifier) => !definitions.links.has(identifier)) || contents.footnoteReferences.some((reference) => !definitions.footnotes.has(reference.identifier)))) return node;
835
+ const authored = (reference) => reference.origin === void 0 ? void 0 : {
836
+ kind: "text",
837
+ value: file.slice(reference.origin),
838
+ origin: reference.origin
839
+ };
840
+ const [result] = rewriteMdx({
841
+ kind: "document",
842
+ children: [node]
843
+ }, {
844
+ linkReference: ({ node: reference }) => definitions.links.has(reference.identifier) ? void 0 : authored(reference),
845
+ imageReference: ({ node: reference }) => definitions.links.has(reference.identifier) ? void 0 : authored(reference),
846
+ footnoteReference: ({ node: reference }) => definitions.footnotes.has(reference.identifier) ? void 0 : authored(reference)
847
+ }).children;
848
+ if (result === void 0) throw new Error("Reference resolution removed a stream block");
849
+ return result;
850
+ }
851
+ /** Invalid authored source renders as inert text. */
852
+ function inertSource(file, origin) {
853
+ return [{
854
+ kind: "element",
855
+ tagName: "p",
856
+ attributes: {},
857
+ children: [{
858
+ kind: "text",
859
+ value: file.semanticSlice(origin).trimEnd(),
860
+ origin
861
+ }],
862
+ origin
863
+ }];
864
+ }
865
+ function limitDiagnostic(file, state) {
866
+ return createDiagnostic({
867
+ code: "mdx-limit-exceeded",
868
+ severity: "error",
869
+ message: `${state.limit} was exceeded at source offset ${state.offset}`,
870
+ span: {
871
+ file,
872
+ start: state.offset,
873
+ end: state.offset
874
+ }
875
+ });
876
+ }
877
+ /** A block starts at the start of its first physical line. */
878
+ function blockOrigin(text, syntax) {
879
+ let start = syntax.range.start;
880
+ while (start > 0 && text.char(start - 1) !== "\n" && text.char(start - 1) !== "\r") start--;
881
+ return {
882
+ start,
883
+ end: syntax.range.end
884
+ };
885
+ }
886
+ function containsRange(outer, inner) {
887
+ return outer.start <= inner.start && inner.end <= outer.end;
888
+ }
889
+ function rangeKey(range) {
890
+ return `${range.start}:${range.end}`;
891
+ }
892
+ /** The placeholder never reaches a snapshot, so its identity never meets a real block. */
893
+ function placeholderId() {
894
+ const value = "block-0";
895
+ if (!isBlockId(value)) throw new Error("Internal block identity invariant failed");
896
+ return value;
897
+ }
898
+ function isBlockId(value) {
899
+ return /^block-\d+$/u.test(value);
900
+ }
901
+ //#endregion
902
+ export { StreamSession };
903
+
904
+ //# sourceMappingURL=stream-session.mjs.map