@miliastry/quasar 1.0.6 → 1.1.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 (273) hide show
  1. package/dist/Visuals/lyne.css +117 -6
  2. package/dist/Visuals/osu.css +36 -5
  3. package/dist/index.js +9664 -3282
  4. package/dist/index.mjs +9535 -3283
  5. package/dist/types/Analysis/Contracts/AnalysisReport.d.ts +22 -0
  6. package/dist/types/Analysis/Contracts/Contribution.d.ts +68 -0
  7. package/dist/types/Analysis/Contracts/Pass.d.ts +59 -0
  8. package/dist/types/Analysis/Contracts/PipelineContext.d.ts +34 -0
  9. package/dist/types/Analysis/Passes/Analysis/ColorUsageAnalyzer.d.ts +56 -0
  10. package/dist/types/Analysis/Passes/Analysis/GradientAnalyzer.d.ts +111 -0
  11. package/dist/types/Analysis/Passes/Analysis/MergeableColorAnalyzer.d.ts +26 -0
  12. package/dist/types/Analysis/Passes/Analysis/RainbowAnalyzer.d.ts +47 -0
  13. package/dist/types/Analysis/Passes/Analysis/SymbolAnalyzer.d.ts +89 -0
  14. package/dist/types/Analysis/Passes/Analysis/WaveAnalyzer.d.ts +44 -0
  15. package/dist/types/Analysis/Passes/Analysis/__tests__/GradientAnalyzer.test.d.ts +4 -0
  16. package/dist/types/Analysis/Passes/Analysis/__tests__/MergeableColorAnalyzer.test.d.ts +4 -0
  17. package/dist/types/Analysis/Passes/Analysis/__tests__/RainbowAnalyzer.test.d.ts +4 -0
  18. package/dist/types/Analysis/Passes/Analysis/__tests__/WaveAnalyzer.test.d.ts +4 -0
  19. package/dist/types/Analysis/Passes/Decision/DefaultDecision.d.ts +30 -0
  20. package/dist/types/Analysis/Passes/Decision/PaletteRemapDecision.d.ts +169 -0
  21. package/dist/types/Analysis/Passes/Decision/__tests__/DefaultDecision.test.d.ts +4 -0
  22. package/dist/types/Analysis/Passes/Transform/CollapseGradientTransform.d.ts +37 -0
  23. package/dist/types/Analysis/Passes/Transform/MergeColorsTransform.d.ts +28 -0
  24. package/dist/types/Analysis/Passes/Transform/RainbowCollapseTransform.d.ts +19 -0
  25. package/dist/types/Analysis/Passes/Transform/WaveCollapseTransform.d.ts +20 -0
  26. package/dist/types/Analysis/Passes/Utility/CharacterCountAnalyzer.d.ts +19 -0
  27. package/dist/types/Analysis/Pipeline/Pipeline.d.ts +69 -0
  28. package/dist/types/Analysis/Pipeline/PipelineBuilder.d.ts +31 -0
  29. package/dist/types/Analysis/Pipeline/PipelineStage.d.ts +17 -0
  30. package/dist/types/Analysis/Utils/color-utils.d.ts +60 -0
  31. package/dist/types/Analysis/__tests__/Integration.test.d.ts +8 -0
  32. package/dist/types/Analysis/__tests__/PaletteRemap.test.d.ts +14 -0
  33. package/dist/types/Analysis/__tests__/Pipeline.test.d.ts +10 -0
  34. package/dist/types/Analysis/__tests__/RoundTrip.test.d.ts +30 -0
  35. package/dist/types/Analysis/__tests__/SymbolAnalyzer.test.d.ts +11 -0
  36. package/dist/types/Analysis/index.d.ts +40 -0
  37. package/dist/types/BBCode/BBCodeDocumentModel.d.ts +92 -0
  38. package/dist/types/BBCode/BBCodeToGreenNode.d.ts +111 -0
  39. package/dist/types/BBCode/Parser.d.ts +78 -0
  40. package/dist/types/BBCode/index.d.ts +4 -0
  41. package/dist/types/Collab/positions.d.ts +55 -0
  42. package/dist/types/Commands/Command.d.ts +37 -0
  43. package/dist/types/Commands/CommandRegistry.d.ts +48 -0
  44. package/dist/types/Commands/DeleteNode.d.ts +7 -0
  45. package/dist/types/Commands/InsertText.d.ts +8 -0
  46. package/dist/types/Commands/SplitMerge.d.ts +9 -0
  47. package/dist/types/Commands/WrapInTag.d.ts +8 -0
  48. package/dist/types/Commands/index.d.ts +6 -0
  49. package/dist/types/Diff/TreeDiffer.d.ts +52 -0
  50. package/dist/types/Diff/__tests__/TreeDiffer.test.d.ts +1 -0
  51. package/dist/types/Diff/index.d.ts +2 -0
  52. package/dist/types/Edits/EditPlan.d.ts +144 -0
  53. package/dist/types/Edits/Optimizer.d.ts +78 -0
  54. package/dist/types/Edits/Rules/Rule.d.ts +91 -0
  55. package/dist/types/Edits/Rules/dropEmptyTags.d.ts +40 -0
  56. package/dist/types/Edits/Rules/dropRedundantNesting.d.ts +59 -0
  57. package/dist/types/Edits/Rules/index.d.ts +9 -0
  58. package/dist/types/Edits/Rules/mergeAdjacent.d.ts +93 -0
  59. package/dist/types/Edits/Rules/reorderWrappers.d.ts +42 -0
  60. package/dist/types/Edits/Rules/shortenHex.d.ts +30 -0
  61. package/dist/types/Edits/Rules/tagValue.d.ts +56 -0
  62. package/dist/types/Edits/Rules/unwrapInvisibleColor.d.ts +47 -0
  63. package/dist/types/Edits/applyEdits.d.ts +36 -0
  64. package/dist/types/Edits/index.d.ts +6 -0
  65. package/dist/types/Events/EventBus.d.ts +103 -0
  66. package/dist/types/Events/index.d.ts +2 -0
  67. package/dist/types/Formatter/Formatter.d.ts +32 -0
  68. package/dist/types/Formatter/index.d.ts +2 -0
  69. package/dist/types/HTML/HTMLDocumentModel.d.ts +13 -0
  70. package/dist/types/HTML/HTMLToGreenNode.d.ts +4 -0
  71. package/dist/types/Incremental/BracketIndex.d.ts +101 -0
  72. package/dist/types/Incremental/ChangeTracker.d.ts +69 -0
  73. package/dist/types/Incremental/IncrementalParser.d.ts +246 -0
  74. package/dist/types/Incremental/__tests__/BracketIndex.test.d.ts +1 -0
  75. package/dist/types/Incremental/__tests__/IncrementalParser.test.d.ts +1 -0
  76. package/dist/types/Incremental/index.d.ts +4 -0
  77. package/dist/types/Lexer/BBCodeLexer.d.ts +74 -0
  78. package/dist/types/Lexer/Lexer.d.ts +54 -0
  79. package/dist/types/Lexer/index.d.ts +4 -0
  80. package/dist/types/Linter/Linter.d.ts +58 -0
  81. package/dist/types/Linter/index.d.ts +2 -0
  82. package/dist/types/Markdown/MarkdownAST.d.ts +122 -0
  83. package/dist/types/Markdown/MarkdownDocumentModel.d.ts +15 -0
  84. package/dist/types/Markdown/MarkdownLexer.d.ts +155 -0
  85. package/dist/types/Markdown/MarkdownParser.d.ts +42 -0
  86. package/dist/types/Markdown/MarkdownToGreenNode.d.ts +6 -0
  87. package/dist/types/MilHibri/MilHibriDocumentModel.d.ts +21 -0
  88. package/dist/types/Model/DocumentModel.d.ts +318 -0
  89. package/dist/types/Model/NodeFactory.d.ts +29 -0
  90. package/dist/types/Model/TagRegistry.d.ts +165 -0
  91. package/dist/types/Model/index.d.ts +5 -0
  92. package/dist/types/Plugins/PluginAPI.d.ts +44 -0
  93. package/dist/types/Plugins/PluginRegistry.d.ts +81 -0
  94. package/dist/types/Plugins/index.d.ts +3 -0
  95. package/dist/types/Queries/QueryEngine.d.ts +32 -0
  96. package/dist/types/Queries/index.d.ts +1 -0
  97. package/dist/types/Reconciler/SurgicalReconciler.d.ts +23 -0
  98. package/dist/types/RenderPipeline/RenderPipeline.d.ts +46 -0
  99. package/dist/types/RenderPipeline/RenderTree.d.ts +55 -0
  100. package/dist/types/RenderPipeline/index.d.ts +4 -0
  101. package/dist/types/Repair/NestingRepair.d.ts +48 -0
  102. package/dist/types/Repair/index.d.ts +1 -0
  103. package/dist/types/Semantic/SemanticAnalyzer.d.ts +321 -0
  104. package/dist/types/Semantic/index.d.ts +2 -0
  105. package/dist/types/Symbols/SymbolTable.d.ts +47 -0
  106. package/dist/types/Symbols/index.d.ts +1 -0
  107. package/dist/types/Syntax/GreenNode.d.ts +154 -0
  108. package/dist/types/Syntax/GreenNodePool.d.ts +134 -0
  109. package/dist/types/Syntax/NodeMatcher.d.ts +75 -0
  110. package/dist/types/Syntax/RedNode.d.ts +280 -0
  111. package/dist/types/Syntax/RedNodeStore.d.ts +116 -0
  112. package/dist/types/Syntax/TreeBuilder.d.ts +54 -0
  113. package/dist/types/Syntax/__tests__/GreenNode.test.d.ts +1 -0
  114. package/dist/types/Syntax/__tests__/RedNode.test.d.ts +1 -0
  115. package/dist/types/Syntax/__tests__/RedNodeStore.test.d.ts +1 -0
  116. package/dist/types/Syntax/greenEdit.d.ts +64 -0
  117. package/dist/types/Syntax/hash.d.ts +17 -0
  118. package/dist/types/Syntax/index.d.ts +8 -0
  119. package/dist/types/Syntax/nodeAttr.d.ts +63 -0
  120. package/dist/types/Syntax/partition.d.ts +67 -0
  121. package/dist/types/Syntax/preserveNodeIds.d.ts +47 -0
  122. package/dist/types/Tokens/TokenResolver.d.ts +25 -0
  123. package/dist/types/Tokens/index.d.ts +1 -0
  124. package/dist/types/Transactions/Transaction.d.ts +36 -0
  125. package/dist/types/Transactions/UndoManager.d.ts +63 -0
  126. package/dist/types/Transactions/index.d.ts +3 -0
  127. package/dist/types/Transformers/ASTOptimizer.d.ts +34 -0
  128. package/dist/types/Transformers/GradientTransformer.d.ts +18 -0
  129. package/dist/types/Transformers/GrowTransformer.d.ts +16 -0
  130. package/dist/types/Transformers/RainbowTransformer.d.ts +17 -0
  131. package/dist/types/Transformers/SineWaveTransformer.d.ts +17 -0
  132. package/dist/types/Transformers/Transformer.d.ts +17 -0
  133. package/dist/types/Types/core.d.ts +104 -0
  134. package/dist/types/Types/diagnostics.d.ts +85 -0
  135. package/dist/types/Types/index.d.ts +11 -0
  136. package/dist/types/Types/operations.d.ts +109 -0
  137. package/dist/types/Types/queries.d.ts +67 -0
  138. package/dist/types/Types/symbols.d.ts +42 -0
  139. package/dist/types/Types/tokens.d.ts +75 -0
  140. package/dist/types/Utils/BBCodeGenerator.d.ts +21 -0
  141. package/dist/types/Utils/ColorMath.d.ts +92 -0
  142. package/dist/types/Utils/EffectMath.d.ts +643 -0
  143. package/dist/types/Utils/TagVocabulary.d.ts +104 -0
  144. package/dist/types/Utils/TagVocabulary.test.d.ts +1 -0
  145. package/dist/types/Utils/color.d.ts +29 -0
  146. package/dist/types/Utils/dom-to-svg.d.ts +28 -0
  147. package/dist/types/Utils/dom-to-svg.test.d.ts +1 -0
  148. package/dist/types/Utils/treeTransformers.d.ts +160 -0
  149. package/dist/types/Visitors/BBBlocksExporter.d.ts +27 -0
  150. package/dist/types/Visitors/BBCodeExporter.d.ts +90 -0
  151. package/dist/types/Visitors/BlockPatcher.d.ts +91 -0
  152. package/dist/types/Visitors/DOMMorpher.d.ts +13 -0
  153. package/dist/types/Visitors/HTMLRenderer.d.ts +380 -0
  154. package/dist/types/Visitors/JSONExporter.d.ts +42 -0
  155. package/dist/types/Visitors/MarkdownExporter.d.ts +28 -0
  156. package/dist/types/Visitors/SVGRenderer.d.ts +16 -0
  157. package/dist/types/Visitors/TiptapExporter.d.ts +40 -0
  158. package/dist/types/Visitors/Visitor.d.ts +35 -0
  159. package/dist/types/Visitors/index.d.ts +9 -0
  160. package/dist/types/Visuals/BoxDrawer.d.ts +49 -0
  161. package/dist/types/Visuals/index.d.ts +38 -0
  162. package/dist/types/index.d.ts +154 -0
  163. package/package.json +14 -10
  164. package/src/Analysis/Passes/Analysis/ColorUsageAnalyzer.ts +103 -0
  165. package/src/Analysis/Passes/Analysis/GradientAnalyzer.ts +294 -20
  166. package/src/Analysis/Passes/Analysis/SymbolAnalyzer.ts +257 -0
  167. package/src/Analysis/Passes/Decision/PaletteRemapDecision.ts +425 -0
  168. package/src/Analysis/Pipeline/Pipeline.ts +15 -2
  169. package/src/Analysis/index.ts +8 -2
  170. package/src/BBCode/BBCodeDocumentModel.ts +3 -0
  171. package/src/BBCode/BBCodeToGreenNode.ts +18 -12
  172. package/src/BBCode/Parser.ts +38 -1
  173. package/src/Edits/EditPlan.ts +290 -0
  174. package/src/Edits/Optimizer.ts +185 -0
  175. package/src/Edits/Rules/Rule.ts +145 -0
  176. package/src/Edits/Rules/dropEmptyTags.ts +110 -0
  177. package/src/Edits/Rules/dropRedundantNesting.ts +120 -0
  178. package/src/Edits/Rules/index.ts +28 -0
  179. package/src/Edits/Rules/mergeAdjacent.ts +224 -0
  180. package/src/Edits/Rules/reorderWrappers.ts +154 -0
  181. package/src/Edits/Rules/shortenHex.ts +79 -0
  182. package/src/Edits/Rules/tagValue.ts +105 -0
  183. package/src/Edits/Rules/unwrapInvisibleColor.ts +93 -0
  184. package/src/Edits/applyEdits.ts +54 -0
  185. package/src/Edits/index.ts +22 -0
  186. package/src/Events/EventBus.ts +18 -0
  187. package/src/HTML/HTMLToGreenNode.ts +185 -37
  188. package/src/Incremental/BracketIndex.ts +249 -0
  189. package/src/Incremental/IncrementalParser.ts +464 -41
  190. package/src/Lexer/BBCodeLexer.ts +25 -3
  191. package/src/Lexer/index.ts +1 -1
  192. package/src/Markdown/MarkdownAST.ts +65 -2
  193. package/src/Markdown/MarkdownLexer.ts +69 -14
  194. package/src/Markdown/MarkdownParser.ts +749 -62
  195. package/src/Markdown/MarkdownToGreenNode.ts +148 -27
  196. package/src/MilHibri/MilHibriDocumentModel.ts +56 -0
  197. package/src/Model/DocumentModel.ts +138 -5
  198. package/src/Model/TagRegistry.ts +129 -134
  199. package/src/Reconciler/SurgicalReconciler.ts +460 -0
  200. package/src/Repair/NestingRepair.ts +116 -0
  201. package/src/Repair/index.ts +1 -0
  202. package/src/Semantic/SemanticAnalyzer.ts +1802 -65
  203. package/src/Syntax/GreenNodePool.ts +12 -12
  204. package/src/Syntax/RedNode.ts +17 -3
  205. package/src/Syntax/RedNodeStore.ts +9 -1
  206. package/src/Syntax/nodeAttr.ts +172 -0
  207. package/src/Tokens/TokenResolver.ts +55 -0
  208. package/src/Tokens/index.ts +1 -0
  209. package/src/Types/core.ts +15 -0
  210. package/src/Utils/ColorMath.ts +276 -55
  211. package/src/Utils/EffectMath.ts +2462 -0
  212. package/src/Utils/TagVocabulary.ts +141 -0
  213. package/src/Utils/dom-to-svg.ts +28 -12
  214. package/src/Visitors/BBBlocksExporter.ts +15 -1
  215. package/src/Visitors/BBCodeExporter.ts +319 -32
  216. package/src/Visitors/BlockPatcher.ts +87 -11
  217. package/src/Visitors/DOMMorpher.ts +15 -5
  218. package/src/Visitors/HTMLRenderer.ts +374 -151
  219. package/src/Visitors/MarkdownExporter.ts +98 -41
  220. package/src/Visitors/TiptapExporter.ts +1 -0
  221. package/src/Visuals/index.ts +7 -4
  222. package/src/Visuals/lyne.css +117 -6
  223. package/src/Visuals/osu.css +36 -5
  224. package/src/index.ts +172 -5
  225. package/dist/index.d.mts +0 -4612
  226. package/dist/index.d.ts +0 -4612
  227. package/src/Analysis/Passes/Analysis/__tests__/GradientAnalyzer.test.ts +0 -135
  228. package/src/Analysis/Passes/Analysis/__tests__/MergeableColorAnalyzer.test.ts +0 -84
  229. package/src/Analysis/Passes/Analysis/__tests__/RainbowAnalyzer.test.ts +0 -99
  230. package/src/Analysis/Passes/Analysis/__tests__/WaveAnalyzer.test.ts +0 -119
  231. package/src/Analysis/Passes/Decision/__tests__/DefaultDecision.test.ts +0 -179
  232. package/src/Analysis/__tests__/Integration.test.ts +0 -162
  233. package/src/Analysis/__tests__/Pipeline.test.ts +0 -133
  234. package/src/Diff/__tests__/TreeDiffer.test.ts +0 -65
  235. package/src/Incremental/__tests__/IncrementalParser.test.ts +0 -164
  236. package/src/Syntax/__tests__/GreenNode.test.ts +0 -33
  237. package/src/Syntax/__tests__/RedNode.test.ts +0 -81
  238. package/src/Syntax/__tests__/RedNodeStore.test.ts +0 -104
  239. package/src/Tests/ASTOptimizerIdempotence.test.ts +0 -77
  240. package/src/Tests/BlockPatcher.test.ts +0 -437
  241. package/src/Tests/BlockPatcherWindowed.test.ts +0 -364
  242. package/src/Tests/BoxDrawer.test.ts +0 -217
  243. package/src/Tests/BoxRichTitle.test.ts +0 -105
  244. package/src/Tests/Chars500kBenchmark.test.ts +0 -151
  245. package/src/Tests/Chars500kEdits.test.ts +0 -321
  246. package/src/Tests/CollabPositions.test.ts +0 -146
  247. package/src/Tests/CompilerPathProfiling.test.ts +0 -186
  248. package/src/Tests/DOMMorpher.test.ts +0 -142
  249. package/src/Tests/DomPatchPerf.test.ts +0 -60
  250. package/src/Tests/EffectSegments.snapshot.json +0 -616
  251. package/src/Tests/EffectSegments.test.ts +0 -68
  252. package/src/Tests/FindNodeAtOffset.test.ts +0 -65
  253. package/src/Tests/Fuzzer.test.ts +0 -166
  254. package/src/Tests/GreenNodePool.test.ts +0 -153
  255. package/src/Tests/Lexer.test.ts +0 -238
  256. package/src/Tests/LyneMode.test.ts +0 -291
  257. package/src/Tests/ModelCoherence.test.ts +0 -180
  258. package/src/Tests/Partition.test.ts +0 -238
  259. package/src/Tests/PluginTags.test.ts +0 -150
  260. package/src/Tests/ProblematicSection.test.ts +0 -46
  261. package/src/Tests/ProblematicSectionHTML.test.ts +0 -58
  262. package/src/Tests/RedReuse.test.ts +0 -134
  263. package/src/Tests/ReproDelete20k.test.ts +0 -62
  264. package/src/Tests/SemanticValidators.test.ts +0 -136
  265. package/src/Tests/StableNodeIds.test.ts +0 -210
  266. package/src/Tests/StudioColorBloat.test.ts +0 -25
  267. package/src/Tests/StudioDebugText.test.ts +0 -27
  268. package/src/Tests/StudioTrailingChar.test.ts +0 -25
  269. package/src/Tests/StudioValidText.test.ts +0 -25
  270. package/src/Tests/UrlImgBug.test.ts +0 -23
  271. package/src/Tests/VisualBuilderFidelity.test.ts +0 -105
  272. package/src/Tests/referenceDocument.ts +0 -119
  273. package/src/Utils/dom-to-svg.test.ts +0 -86
@@ -0,0 +1,92 @@
1
+ /**
2
+ * DocumentEngine — BBCodeDocumentModel
3
+ *
4
+ * A DocumentModel subclass that uses the DocumentEngine's built-in
5
+ * BBCode Lexer + Parser to produce GreenNode/RedNode trees.
6
+ *
7
+ * This COMPLETELY replaces the old BBCode parser (MiliastryNovaFeatures/BBCode/Parser).
8
+ * The old parser is DEPRECATED.
9
+ *
10
+ * Architecture:
11
+ * BBCode text
12
+ * ↓ BBCodeLexer.scanBBCode()
13
+ * BBCodeToken[]
14
+ * ↓ Parser.parseTokensToGreen()
15
+ * GreenNode
16
+ * ↓ BBCodeToGreenNode.greenToRedNode()
17
+ * RedNode
18
+ * ↓ HTMLRenderer.render()
19
+ * HTML preview
20
+ *
21
+ * Usage:
22
+ * const model = new BBCodeDocumentModel({ source: '[b]Hello[/b]' })
23
+ * const html = new HTMLRenderer().render(model.redRoot!)
24
+ */
25
+ import { DocumentModel, type DocumentModelOptions } from '../Model/DocumentModel';
26
+ import type { ReparseParseOptions } from '../Incremental/IncrementalParser';
27
+ import { type InterningMode } from '../Syntax/GreenNodePool';
28
+ import { GreenNode } from '../Syntax/GreenNode';
29
+ import { RedNode } from '../Syntax/RedNode';
30
+ import { type BBCodeDialect } from './BBCodeToGreenNode';
31
+ import { HTMLRenderer } from '../Visitors/HTMLRenderer';
32
+ export interface BBCodeDocumentModelOptions extends DocumentModelOptions {
33
+ /** Source BBCode text to parse */
34
+ source?: string;
35
+ /** Language identifier (default: 'bbcode') */
36
+ language?: string;
37
+ /** Enforce strict tag nesting (disables osu! auto-close legacy behavior) */
38
+ strictMode?: boolean;
39
+ /** BBCode dialect to parse against ('osu' | 'miliastry' | 'lyne'). Default: 'miliastry'. */
40
+ dialect?: BBCodeDialect;
41
+ /** Alias for dialect ('osu' | 'miliastry' | 'lyne') */
42
+ mode?: BBCodeDialect;
43
+ /**
44
+ * Deduplicate structurally identical green nodes across the document.
45
+ *
46
+ * Off by default. It is correct now — see the header of `GreenNodePool.ts`
47
+ * for why it was not — but it is a memory/latency trade, and this engine's
48
+ * declared budget is latency: on the 19.6 KB reference document `'leaves'`
49
+ * costs 16% more parse time to save 42% of the green tree's memory. Turn it
50
+ * on for workloads that hold many documents at once; leave it off to type
51
+ * into one.
52
+ */
53
+ interning?: InterningMode;
54
+ }
55
+ export declare class BBCodeDocumentModel extends DocumentModel {
56
+ private _strictMode;
57
+ private _dialect;
58
+ /** Per-document interner, or null when interning is off. */
59
+ private _interner;
60
+ /** Memoized parser `extraTags`, rebuilt only when the registry changes. */
61
+ private _extraTags;
62
+ private _extraTagsVersion;
63
+ constructor(options?: BBCodeDocumentModelOptions);
64
+ get dialect(): BBCodeDialect;
65
+ get root(): RedNode | null;
66
+ toHTML(renderer?: HTMLRenderer): string;
67
+ /**
68
+ * Parse BBCode text directly to a GreenNode tree using the
69
+ * DocumentEngine's built-in BBCode Lexer + Parser.
70
+ * No dependency on the deprecated old parser.
71
+ */
72
+ protected parseToGreen(source: string, options?: ReparseParseOptions): GreenNode;
73
+ /**
74
+ * Build a RedNode from a GreenNode, extracting metadata
75
+ * from BBCode attributes in the process.
76
+ */
77
+ protected buildRedFromGreen(green: GreenNode): RedNode;
78
+ /**
79
+ * Reuse-aware red build for the incremental path: adopts old red subtrees
80
+ * wherever the splice shared their green by reference. See the contract on
81
+ * `greenToRedNodeReusing` — the old tree is consumed.
82
+ */
83
+ protected buildRedFromGreenReusing(green: GreenNode, oldRed: RedNode, stats?: {
84
+ adopted: number;
85
+ }): RedNode;
86
+ /**
87
+ * Serialize the red tree back to BBCode, so `transact`/`undo`/`redo` can
88
+ * rebuild from text. Target 'miliastry' keeps native tags (gradient, grow,
89
+ * …) as-is instead of expanding them, which is what round-tripping needs.
90
+ */
91
+ protected exportSource(root: RedNode): string;
92
+ }
@@ -0,0 +1,111 @@
1
+ /**
2
+ * DocumentEngine — BBCodeToGreenNode
3
+ *
4
+ * Bridge between the existing BBCode Parser (BBBlock[]) and the
5
+ * DocumentEngine's GreenNode/RedNode syntax tree.
6
+ *
7
+ * This is how we integrate the mature, battle-tested BBCode parser
8
+ * with the new Language Platform architecture.
9
+ *
10
+ * The flow:
11
+ * BBCode text
12
+ * → parseBBCode() [existing] → BBBlock[]
13
+ * → convertToGreenNode() [this] → GreenNode
14
+ * → buildRedNode() [this] → RedNode
15
+ * → DocumentModel
16
+ */
17
+ import { GreenNode } from '../Syntax/GreenNode';
18
+ import { RedNode } from '../Syntax/RedNode';
19
+ import { RedNodeStore } from '../Syntax/RedNodeStore';
20
+ import type { NodeKind } from '../Types/core';
21
+ export type BBCodeDialect = 'osu' | 'miliastry' | 'lyne';
22
+ export declare const BBCODE_TAG_NAMES: readonly string[];
23
+ export declare function getBBCodeTagNames(dialect?: BBCodeDialect): readonly string[];
24
+ export declare function tagToNodeKind(tag: string | null, dialect?: BBCodeDialect): NodeKind;
25
+ export declare function nodeKindToTag(kind: NodeKind): string | null;
26
+ export declare function isBlockKind(kind: NodeKind): boolean;
27
+ export interface BBBlock {
28
+ id: string;
29
+ tag: string | null;
30
+ attrs: string;
31
+ content: string;
32
+ rawStart: number;
33
+ rawEnd: number;
34
+ children: BBBlock[];
35
+ attrChildren?: BBBlock[];
36
+ html?: string;
37
+ }
38
+ /**
39
+ * Convert a single BBBlock to a GreenNode.
40
+ * Recursively converts children.
41
+ */
42
+ export declare function bbBlockToGreenNode(block: BBBlock): GreenNode;
43
+ /**
44
+ * Convert an array of BBBlock[] (the root of the existing parser's output)
45
+ * to a GreenNode tree.
46
+ *
47
+ * Note: This function is kept for backward compatibility with the old parser.
48
+ * The new DocumentEngine parser (Parser.ts + BBCodeLexer) produces GreenNode
49
+ * directly and does NOT go through BBBlock[].
50
+ */
51
+ export declare function bbBlocksToGreenTree(blocks: BBBlock[], source: string): GreenNode;
52
+ export declare function extractGreenNodeMetadata(green: GreenNode): Record<string, unknown>;
53
+ /**
54
+ * Build a RedNode tree from a GreenNode.
55
+ * Similar to TreeBuilder.buildRed but uses actual kind from the green node
56
+ * and extracts BBCode metadata from attributes.
57
+ *
58
+ * When a RedNodeStore is provided, instance RedNodes are created with
59
+ * correct parent references copied from the canonical's metadata.
60
+ * The canonicalId (from green._hash) enables:
61
+ * - React.memo in BBCodeCanvas by canonicalId
62
+ * - HTMLRenderer cache by canonicalId
63
+ * - Diff optimization (same canonicalId = unchanged subtree)
64
+ * - Future PositionRef-based sharing
65
+ */
66
+ export declare function greenToRedNode(green: GreenNode, parent?: RedNode | null, store?: RedNodeStore, start?: number): RedNode;
67
+ /**
68
+ * Build the red tree for `green`, adopting subtrees of the PREVIOUS red tree
69
+ * wherever the new green shares a green node by reference with the old one.
70
+ *
71
+ * The incremental splice (`spliceGreen`) rebuilds only the spine of ancestors
72
+ * around an edit; every untouched sibling keeps its exact green object. Yet
73
+ * `greenToRedNode` reconstructed all ~1700 red nodes on every keystroke —
74
+ * measured as the single largest phase of a keystroke (0.30 of 0.94 ms).
75
+ * Reference equality of greens is proof the subtree did not change, so its old
76
+ * red subtree — ids, metadata, diagnostics and all — can be adopted wholesale.
77
+ * Adoption is one `parent` reassignment (done by `initChildren`) plus, only
78
+ * when the subtree moved, a `setStart` walk that adds a delta to two ints per
79
+ * node. Both are far cheaper than re-extracting metadata and reallocating.
80
+ *
81
+ * ⚠ Contract: the OLD red tree is consumed. Adopted subtrees are reparented
82
+ * into the new tree, so the previous `redRoot` must not be used again after
83
+ * this returns. Nothing in the engine or the app reads a superseded red tree
84
+ * (verified), and `DocumentModelOptions.reuseRed` is the kill-switch if a
85
+ * future consumer ever needs the old tree to stay intact.
86
+ *
87
+ * The child walk mirrors `NodeMatcher` Phase 0 / `preserveNodeIds`: trim the
88
+ * common prefix and suffix by green reference, descend into the changed window
89
+ * only when it is the single-child shape a keystroke produces, and build the
90
+ * rest fresh. Positional lockstep also makes double-adoption impossible: each
91
+ * old red child is adopted at most once, even when interning makes distinct
92
+ * positions share one green object.
93
+ */
94
+ export declare function greenToRedNodeReusing(green: GreenNode, oldRed: RedNode, start?: number, stats?: {
95
+ adopted: number;
96
+ }): RedNode;
97
+ /**
98
+ * A `RedNodeStore` wired with BBCode metadata semantics.
99
+ *
100
+ * `RedNodeStore` used to carry its own verbatim copy of
101
+ * `extractGreenNodeMetadata` — its comment even said *"Mirrors
102
+ * extractGreenNodeMetadata"* — which meant two sources of truth for the
103
+ * attrs→metadata mapping, and they had already drifted apart. The store now
104
+ * takes the extractor as a dependency; this is the BBCode wiring.
105
+ */
106
+ export declare function createBBCodeRedNodeStore(): RedNodeStore;
107
+ /**
108
+ * Convert a BBBlock array directly to a RedNode root.
109
+ * This is the main entry point for the bridge.
110
+ */
111
+ export declare function bbBlocksToRedTree(blocks: BBBlock[], source: string): RedNode;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * DocumentEngine — BBCode Parser
3
+ *
4
+ * Builds a GreenNode (immutable syntax tree) from BBCode tokens.
5
+ *
6
+ * This is the core parsing logic that replaces the old BBCode parser.
7
+ * Unlike the old parser, this produces GreenNode directly — no BBBlock[]
8
+ * intermediate step. The flow is:
9
+ *
10
+ * BBCode text
11
+ * ↓ scanBBCode() [BBCodeLexer]
12
+ * BBCodeToken[]
13
+ * ↓ parseTokensToGreen() [this]
14
+ * GreenNode
15
+ * ↓ greenToRedNode()
16
+ * RedNode
17
+ *
18
+ * Key differences from the old parser:
19
+ * - Newlines are explicit tokens (not mixed into text) → precise empty_line detection
20
+ * - All syntactically valid tags are parsed (not just BLOCK_TAGS)
21
+ * - Produces GreenNode directly (no BBBlock[] intermediate)
22
+ * - No newline stripping between block-level tags
23
+ * - Consecutive newlines (2+) = empty_line node (paragraph break)
24
+ * - Single newlines between inline content = ignored (CSS handles spacing)
25
+ */
26
+ import { GreenNode } from '../Syntax/GreenNode';
27
+ import type { NodeKind } from '../Types/core';
28
+ import { GreenNodePool } from '../Syntax/GreenNodePool';
29
+ import { type BBCodeDialect } from './BBCodeToGreenNode';
30
+ import type { BBCodeToken } from '../Lexer/BBCodeLexer';
31
+ /**
32
+ * Parse BBCode tokens into a GreenNode tree.
33
+ *
34
+ * @param tokens Flat array of tokens from scanBBCode()
35
+ * @param source Original source text (used for fallback error text)
36
+ * @returns A GreenNode tree with 'document' as root
37
+ */
38
+ export interface ParseOptions {
39
+ strictMode?: boolean;
40
+ /** BBCode dialect to parse against ('osu' | 'miliastry' | 'lyne'). Default: 'miliastry'. */
41
+ dialect?: BBCodeDialect;
42
+ /** Optional interner for structural sharing. If provided, identical subtrees
43
+ * share the same GreenNode reference in memory. */
44
+ interner?: GreenNodePool;
45
+ /**
46
+ * Group top-level inline nodes into `paragraph` nodes. Default `true`.
47
+ *
48
+ * Paragraph grouping happens at the ROOT ONLY — inside `[centre]` or `[box]`
49
+ * the children stay flat. So when the incremental parser re-parses the inner
50
+ * span of such a container in isolation, that span's content is not root
51
+ * content and must not be grouped, or the re-parsed subtree would gain
52
+ * paragraphs the full parse never produces.
53
+ */
54
+ normalizeParagraphs?: boolean;
55
+ /**
56
+ * Plugin-registered tags: tag name → the kind their nodes get.
57
+ *
58
+ * The built-in table deliberately turns unknown tags into literal text
59
+ * (`[Gateron]` in prose must stay visible), which also meant a plugin's tag
60
+ * could render and export but never PARSE. This is the missing link: a tag
61
+ * present here parses as a normal paired container. `BBCodeDocumentModel`
62
+ * fills it from the `TagRegistry`'s non-builtin entries; everything not
63
+ * registered still falls to literal text exactly as before.
64
+ */
65
+ extraTags?: ReadonlyMap<string, NodeKind>;
66
+ }
67
+ export declare function parseTokensToGreen(tokens: BBCodeToken[], source: string, options?: ParseOptions): GreenNode;
68
+ /**
69
+ * Full parse: BBCode text → GreenNode.
70
+ *
71
+ * Convenience function that combines the lexer and parser.
72
+ * BBCodeDocumentModel internally uses scanBBCode() + parseTokensToGreen() directly.
73
+ *
74
+ * Usage:
75
+ * import { parseBBCode } from '../BBCode/Parser'
76
+ * const tree = parseBBCode('[b]Hello[/b]')
77
+ */
78
+ export declare function parseBBCode(source: string, options?: ParseOptions): GreenNode;
@@ -0,0 +1,4 @@
1
+ export { BBCodeDocumentModel } from './BBCodeDocumentModel';
2
+ export { parseBBCode, parseTokensToGreen } from './Parser';
3
+ export { bbBlocksToGreenTree, greenToRedNode, bbBlocksToRedTree, bbBlockToGreenNode, tagToNodeKind, nodeKindToTag, isBlockKind, } from './BBCodeToGreenNode';
4
+ export type { BBBlock } from './BBCodeToGreenNode';
@@ -0,0 +1,55 @@
1
+ /**
2
+ * DocumentEngine — Position transforms
3
+ *
4
+ * Where does a position end up after a text edit?
5
+ *
6
+ * This is the primitive collaboration stands on: keeping carets, selections
7
+ * and remote cursors pointing at the same *content* while the text shifts
8
+ * under them — whether the edit came from the local user, a remote peer, or
9
+ * a programmatic `transact`. See `QuasarCollab.MD` for the architecture; the
10
+ * short version is that Quasar syncs TEXT, so mapping positions through
11
+ * `TextChange`s is all the transform machinery the engine needs. This module
12
+ * transforms positions, not changes-against-changes: convergence of
13
+ * concurrent edits is the CRDT's job, not ours.
14
+ */
15
+ import type { TextChange } from '../Incremental/ChangeTracker';
16
+ /**
17
+ * Which side a position sticks to when an edit happens exactly at it.
18
+ *
19
+ * A caret usually wants `'right'`: text inserted at the caret by someone else
20
+ * should push it forward (you keep typing after their insertion). The start
21
+ * of a persistent highlight usually wants `'left'`: text inserted exactly at
22
+ * its start belongs before the highlight, not inside it.
23
+ */
24
+ export type TransformBias = 'left' | 'right';
25
+ /**
26
+ * Map `offset` through one change or an ordered sequence of changes.
27
+ *
28
+ * Rules, in order:
29
+ * - strictly before the edit → unchanged;
30
+ * - strictly after the replaced span → shifted by the length delta;
31
+ * - inside the replaced span → collapsed to the edit's boundary (`'left'` →
32
+ * where the replacement starts, `'right'` → where it ends). A position
33
+ * inside deleted text has no content to point at anymore; the boundary is
34
+ * the only honest answer;
35
+ * - exactly at a pure insertion point → `bias` decides which side of the
36
+ * inserted text it lands on.
37
+ */
38
+ export declare function transformOffset(offset: number, changes: TextChange | readonly TextChange[], bias?: TransformBias): number;
39
+ /**
40
+ * Map a `{start, end}` range through one change or a sequence.
41
+ *
42
+ * The start sticks RIGHT and the end sticks LEFT, which is what preserves the
43
+ * selected content: text inserted exactly at a boundary lands OUTSIDE the
44
+ * range, so the range keeps covering exactly the characters it covered — it
45
+ * neither absorbs a neighbour's insertion nor leaks its own content. The
46
+ * result is clamped so it can never come out inverted; a range entirely
47
+ * inside deleted text collapses to a point at the edit boundary.
48
+ */
49
+ export declare function transformRange(range: {
50
+ start: number;
51
+ end: number;
52
+ }, changes: TextChange | readonly TextChange[]): {
53
+ start: number;
54
+ end: number;
55
+ };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * DocumentEngine — Command
3
+ *
4
+ * Commands are high-level user actions that MAY produce
5
+ * a Transaction (or multiple) to modify the document.
6
+ *
7
+ * Commands are stateless — they receive context and produce operations.
8
+ * This makes them testable, undoable, and safe for AI use.
9
+ *
10
+ * Inspired by ProseMirror's Commands and VSCode's Command system.
11
+ */
12
+ import { DocumentModel } from '../Model/DocumentModel';
13
+ import type { Operation } from '../Types/operations';
14
+ import type { RedNode } from '../Syntax/RedNode';
15
+ export interface CommandContext {
16
+ model: DocumentModel;
17
+ root: RedNode;
18
+ selection?: {
19
+ nodeId: string;
20
+ start: number;
21
+ end: number;
22
+ };
23
+ }
24
+ export type CommandResult = {
25
+ success: boolean;
26
+ operations?: Operation[];
27
+ message?: string;
28
+ };
29
+ export interface Command {
30
+ readonly id: string;
31
+ readonly label: string;
32
+ readonly description?: string;
33
+ readonly shortcut?: string;
34
+ execute(ctx: CommandContext): CommandResult;
35
+ canExecute?(ctx: CommandContext): boolean;
36
+ }
37
+ export declare function canExecute(command: Command, ctx: CommandContext): boolean;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * DocumentEngine — CommandRegistry
3
+ *
4
+ * Central registry for all document commands.
5
+ * Commands can be added by plugins.
6
+ *
7
+ * Enables:
8
+ * - Keyboard shortcut binding
9
+ * - Toolbar integration
10
+ * - AI command execution
11
+ * - Menu integration
12
+ */
13
+ import type { Command, CommandContext, CommandResult } from './Command';
14
+ export declare class CommandRegistry {
15
+ private commands;
16
+ /**
17
+ * Register a command.
18
+ */
19
+ register(command: Command): void;
20
+ /**
21
+ * Unregister a command.
22
+ */
23
+ unregister(id: string): void;
24
+ /**
25
+ * Get a command by ID.
26
+ */
27
+ get(id: string): Command | undefined;
28
+ /**
29
+ * Check if a command is registered.
30
+ */
31
+ has(id: string): boolean;
32
+ /**
33
+ * Execute a command by ID.
34
+ */
35
+ execute(id: string, ctx: CommandContext): CommandResult;
36
+ /**
37
+ * Get all registered commands.
38
+ */
39
+ getAll(): Command[];
40
+ /**
41
+ * Get commands by a filter function.
42
+ */
43
+ filter(predicate: (cmd: Command) => boolean): Command[];
44
+ /**
45
+ * Get the count of registered commands.
46
+ */
47
+ get size(): number;
48
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * DocumentEngine — DeleteNode Command
3
+ *
4
+ * Deletes a node from the document tree.
5
+ */
6
+ import type { Command } from './Command';
7
+ export declare const DeleteNode: Command;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * DocumentEngine — InsertText Command
3
+ *
4
+ * Inserts text at the current cursor position.
5
+ * Creates or reuses a text node.
6
+ */
7
+ import type { Command } from './Command';
8
+ export declare const InsertText: Command;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * DocumentEngine — SplitNode & MergeNodes Commands
3
+ *
4
+ * Split a node at a position, or merge two adjacent nodes.
5
+ * Essential for block editing and backspace handling.
6
+ */
7
+ import type { Command } from './Command';
8
+ export declare const SplitNode: Command;
9
+ export declare const MergeNode: Command;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * DocumentEngine — WrapInTag Command
3
+ *
4
+ * Wraps the current selection in a BBCode tag.
5
+ * E.g. selected text → [b]selected text[/b]
6
+ */
7
+ import type { Command } from './Command';
8
+ export declare const WrapInTag: Command;
@@ -0,0 +1,6 @@
1
+ export { CommandRegistry } from './CommandRegistry';
2
+ export type { Command, CommandContext, CommandResult } from './Command';
3
+ export { InsertText } from './InsertText';
4
+ export { DeleteNode } from './DeleteNode';
5
+ export { WrapInTag } from './WrapInTag';
6
+ export { SplitNode, MergeNode } from './SplitMerge';
@@ -0,0 +1,52 @@
1
+ /**
2
+ * DocumentEngine — TreeDiffer
3
+ *
4
+ * Computes structural differences between two Red Trees.
5
+ * Produces a list of DiffOperations that can be used for:
6
+ * - Updating the UI with minimal DOM changes
7
+ * - Syncing with collaboration servers
8
+ * - Animation interpolation
9
+ * - Undo/redo granularity
10
+ *
11
+ * Inspired by React's reconciliation and ProseMirror's diff.
12
+ */
13
+ import { RedNode } from '../Syntax/RedNode';
14
+ export type DiffKind = 'insert' | 'delete' | 'update' | 'move' | 'preserve';
15
+ export interface DiffOperation {
16
+ kind: DiffKind;
17
+ node: RedNode;
18
+ oldNode?: RedNode;
19
+ /** Index in parent */
20
+ oldIndex?: number;
21
+ newIndex?: number;
22
+ /** Parent node ID */
23
+ parentId?: string;
24
+ }
25
+ export interface DiffResult {
26
+ operations: DiffOperation[];
27
+ /** Count by kind */
28
+ stats: {
29
+ inserts: number;
30
+ deletes: number;
31
+ updates: number;
32
+ moves: number;
33
+ preserves: number;
34
+ };
35
+ /** Time taken in ms */
36
+ duration: number;
37
+ }
38
+ export declare class TreeDiffer {
39
+ /**
40
+ * Compute the diff between two Red Trees.
41
+ */
42
+ diff(oldRoot: RedNode, newRoot: RedNode): DiffResult;
43
+ private diffChildren;
44
+ /**
45
+ * Check if a node's content has changed.
46
+ */
47
+ private nodeContentChanged;
48
+ /**
49
+ * Deep equality check for content equivalence when pairing unmatched nodes.
50
+ */
51
+ private nodesAreEquivalent;
52
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export { TreeDiffer } from './TreeDiffer';
2
+ export type { DiffOperation, DiffKind, DiffResult } from './TreeDiffer';