@miliastry/quasar 1.0.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 (172) hide show
  1. package/LICENSE +119 -0
  2. package/README.md +45 -0
  3. package/dist/Visuals/lyne.css +1027 -0
  4. package/dist/Visuals/osu.css +257 -0
  5. package/dist/index.d.mts +4563 -0
  6. package/dist/index.d.ts +4563 -0
  7. package/dist/index.js +11291 -0
  8. package/dist/index.mjs +11197 -0
  9. package/package.json +51 -0
  10. package/src/Analysis/Contracts/AnalysisReport.ts +26 -0
  11. package/src/Analysis/Contracts/Contribution.ts +76 -0
  12. package/src/Analysis/Contracts/Pass.ts +76 -0
  13. package/src/Analysis/Contracts/PipelineContext.ts +48 -0
  14. package/src/Analysis/Passes/Analysis/GradientAnalyzer.ts +292 -0
  15. package/src/Analysis/Passes/Analysis/MergeableColorAnalyzer.ts +112 -0
  16. package/src/Analysis/Passes/Analysis/RainbowAnalyzer.ts +233 -0
  17. package/src/Analysis/Passes/Analysis/WaveAnalyzer.ts +211 -0
  18. package/src/Analysis/Passes/Analysis/__tests__/GradientAnalyzer.test.ts +135 -0
  19. package/src/Analysis/Passes/Analysis/__tests__/MergeableColorAnalyzer.test.ts +84 -0
  20. package/src/Analysis/Passes/Analysis/__tests__/RainbowAnalyzer.test.ts +99 -0
  21. package/src/Analysis/Passes/Analysis/__tests__/WaveAnalyzer.test.ts +119 -0
  22. package/src/Analysis/Passes/Decision/DefaultDecision.ts +139 -0
  23. package/src/Analysis/Passes/Decision/__tests__/DefaultDecision.test.ts +179 -0
  24. package/src/Analysis/Passes/Transform/CollapseGradientTransform.ts +176 -0
  25. package/src/Analysis/Passes/Transform/MergeColorsTransform.ts +126 -0
  26. package/src/Analysis/Passes/Transform/RainbowCollapseTransform.ts +83 -0
  27. package/src/Analysis/Passes/Transform/WaveCollapseTransform.ts +88 -0
  28. package/src/Analysis/Passes/Utility/CharacterCountAnalyzer.ts +45 -0
  29. package/src/Analysis/Pipeline/Pipeline.ts +133 -0
  30. package/src/Analysis/Pipeline/PipelineBuilder.ts +55 -0
  31. package/src/Analysis/Pipeline/PipelineStage.ts +19 -0
  32. package/src/Analysis/Utils/color-utils.ts +132 -0
  33. package/src/Analysis/__tests__/Integration.test.ts +162 -0
  34. package/src/Analysis/__tests__/Pipeline.test.ts +133 -0
  35. package/src/Analysis/index.ts +52 -0
  36. package/src/BBCode/BBCodeDocumentModel.ts +175 -0
  37. package/src/BBCode/BBCodeToGreenNode.ts +755 -0
  38. package/src/BBCode/Parser.ts +384 -0
  39. package/src/BBCode/index.ts +12 -0
  40. package/src/Collab/positions.ts +91 -0
  41. package/src/Commands/Command.ts +44 -0
  42. package/src/Commands/CommandRegistry.ts +78 -0
  43. package/src/Commands/DeleteNode.ts +20 -0
  44. package/src/Commands/InsertText.ts +21 -0
  45. package/src/Commands/SplitMerge.ts +28 -0
  46. package/src/Commands/WrapInTag.ts +21 -0
  47. package/src/Commands/index.ts +6 -0
  48. package/src/Diff/TreeDiffer.ts +264 -0
  49. package/src/Diff/__tests__/TreeDiffer.test.ts +65 -0
  50. package/src/Diff/index.ts +2 -0
  51. package/src/Events/EventBus.ts +160 -0
  52. package/src/Events/index.ts +2 -0
  53. package/src/Formatter/Formatter.ts +54 -0
  54. package/src/Formatter/index.ts +2 -0
  55. package/src/HTML/HTMLDocumentModel.ts +35 -0
  56. package/src/HTML/HTMLToGreenNode.ts +290 -0
  57. package/src/Incremental/ChangeTracker.ts +105 -0
  58. package/src/Incremental/IncrementalParser.ts +591 -0
  59. package/src/Incremental/__tests__/IncrementalParser.test.ts +164 -0
  60. package/src/Incremental/index.ts +4 -0
  61. package/src/Lexer/BBCodeLexer.ts +382 -0
  62. package/src/Lexer/Lexer.ts +181 -0
  63. package/src/Lexer/index.ts +10 -0
  64. package/src/Linter/Linter.ts +193 -0
  65. package/src/Linter/index.ts +2 -0
  66. package/src/Markdown/MarkdownAST.ts +112 -0
  67. package/src/Markdown/MarkdownDocumentModel.ts +55 -0
  68. package/src/Markdown/MarkdownLexer.ts +203 -0
  69. package/src/Markdown/MarkdownParser.ts +455 -0
  70. package/src/Markdown/MarkdownToGreenNode.ts +153 -0
  71. package/src/Model/DocumentModel.ts +694 -0
  72. package/src/Model/NodeFactory.ts +117 -0
  73. package/src/Model/TagRegistry.ts +495 -0
  74. package/src/Model/index.ts +5 -0
  75. package/src/Plugins/PluginAPI.ts +119 -0
  76. package/src/Plugins/PluginRegistry.ts +132 -0
  77. package/src/Plugins/index.ts +3 -0
  78. package/src/Queries/QueryEngine.ts +152 -0
  79. package/src/Queries/index.ts +1 -0
  80. package/src/RenderPipeline/RenderPipeline.ts +125 -0
  81. package/src/RenderPipeline/RenderTree.ts +134 -0
  82. package/src/RenderPipeline/index.ts +4 -0
  83. package/src/Semantic/SemanticAnalyzer.ts +506 -0
  84. package/src/Semantic/index.ts +2 -0
  85. package/src/Symbols/SymbolTable.ts +124 -0
  86. package/src/Symbols/index.ts +1 -0
  87. package/src/Syntax/GreenNode.ts +324 -0
  88. package/src/Syntax/GreenNodePool.ts +269 -0
  89. package/src/Syntax/NodeMatcher.ts +370 -0
  90. package/src/Syntax/RedNode.ts +569 -0
  91. package/src/Syntax/RedNodeStore.ts +184 -0
  92. package/src/Syntax/TreeBuilder.ts +214 -0
  93. package/src/Syntax/__tests__/GreenNode.test.ts +33 -0
  94. package/src/Syntax/__tests__/RedNode.test.ts +81 -0
  95. package/src/Syntax/__tests__/RedNodeStore.test.ts +104 -0
  96. package/src/Syntax/greenEdit.ts +110 -0
  97. package/src/Syntax/hash.ts +30 -0
  98. package/src/Syntax/index.ts +12 -0
  99. package/src/Syntax/partition.ts +161 -0
  100. package/src/Syntax/preserveNodeIds.ts +201 -0
  101. package/src/Tests/ASTOptimizerIdempotence.test.ts +77 -0
  102. package/src/Tests/BlockPatcher.test.ts +437 -0
  103. package/src/Tests/BlockPatcherWindowed.test.ts +364 -0
  104. package/src/Tests/BoxDrawer.test.ts +217 -0
  105. package/src/Tests/BoxRichTitle.test.ts +105 -0
  106. package/src/Tests/Chars500kBenchmark.test.ts +151 -0
  107. package/src/Tests/Chars500kEdits.test.ts +321 -0
  108. package/src/Tests/CollabPositions.test.ts +146 -0
  109. package/src/Tests/CompilerPathProfiling.test.ts +186 -0
  110. package/src/Tests/DOMMorpher.test.ts +142 -0
  111. package/src/Tests/DomPatchPerf.test.ts +60 -0
  112. package/src/Tests/EffectSegments.snapshot.json +616 -0
  113. package/src/Tests/EffectSegments.test.ts +68 -0
  114. package/src/Tests/FindNodeAtOffset.test.ts +65 -0
  115. package/src/Tests/Fuzzer.test.ts +166 -0
  116. package/src/Tests/GreenNodePool.test.ts +153 -0
  117. package/src/Tests/Lexer.test.ts +238 -0
  118. package/src/Tests/LyneMode.test.ts +187 -0
  119. package/src/Tests/ModelCoherence.test.ts +180 -0
  120. package/src/Tests/Partition.test.ts +238 -0
  121. package/src/Tests/PluginTags.test.ts +150 -0
  122. package/src/Tests/ProblematicSection.test.ts +46 -0
  123. package/src/Tests/ProblematicSectionHTML.test.ts +58 -0
  124. package/src/Tests/RedReuse.test.ts +134 -0
  125. package/src/Tests/ReproDelete20k.test.ts +62 -0
  126. package/src/Tests/SemanticValidators.test.ts +136 -0
  127. package/src/Tests/StableNodeIds.test.ts +210 -0
  128. package/src/Tests/StudioColorBloat.test.ts +25 -0
  129. package/src/Tests/StudioDebugText.test.ts +27 -0
  130. package/src/Tests/StudioTrailingChar.test.ts +25 -0
  131. package/src/Tests/StudioValidText.test.ts +25 -0
  132. package/src/Tests/UrlImgBug.test.ts +23 -0
  133. package/src/Tests/VisualBuilderFidelity.test.ts +105 -0
  134. package/src/Tests/referenceDocument.ts +119 -0
  135. package/src/Transactions/Transaction.ts +176 -0
  136. package/src/Transactions/UndoManager.ts +111 -0
  137. package/src/Transactions/index.ts +3 -0
  138. package/src/Transformers/ASTOptimizer.ts +315 -0
  139. package/src/Transformers/GradientTransformer.ts +143 -0
  140. package/src/Transformers/GrowTransformer.ts +115 -0
  141. package/src/Transformers/RainbowTransformer.ts +121 -0
  142. package/src/Transformers/SineWaveTransformer.ts +130 -0
  143. package/src/Transformers/Transformer.ts +22 -0
  144. package/src/Types/core.ts +270 -0
  145. package/src/Types/diagnostics.ts +156 -0
  146. package/src/Types/index.ts +23 -0
  147. package/src/Types/operations.ts +180 -0
  148. package/src/Types/queries.ts +121 -0
  149. package/src/Types/symbols.ts +69 -0
  150. package/src/Types/tokens.ts +186 -0
  151. package/src/Utils/BBCodeGenerator.ts +126 -0
  152. package/src/Utils/ColorMath.ts +276 -0
  153. package/src/Utils/color.ts +112 -0
  154. package/src/Utils/dom-to-svg.test.ts +86 -0
  155. package/src/Utils/dom-to-svg.ts +615 -0
  156. package/src/Utils/treeTransformers.ts +717 -0
  157. package/src/Visitors/BBBlocksExporter.ts +69 -0
  158. package/src/Visitors/BBCodeExporter.ts +318 -0
  159. package/src/Visitors/BlockPatcher.ts +963 -0
  160. package/src/Visitors/DOMMorpher.ts +134 -0
  161. package/src/Visitors/HTMLRenderer.ts +1077 -0
  162. package/src/Visitors/JSONExporter.ts +66 -0
  163. package/src/Visitors/MarkdownExporter.ts +99 -0
  164. package/src/Visitors/SVGRenderer.ts +35 -0
  165. package/src/Visitors/TiptapExporter.ts +145 -0
  166. package/src/Visitors/Visitor.ts +48 -0
  167. package/src/Visitors/index.ts +9 -0
  168. package/src/Visuals/BoxDrawer.ts +175 -0
  169. package/src/Visuals/index.ts +42 -0
  170. package/src/Visuals/lyne.css +1027 -0
  171. package/src/Visuals/osu.css +257 -0
  172. package/src/index.ts +197 -0
@@ -0,0 +1,175 @@
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
+
26
+ import { DocumentModel, type DocumentModelOptions } from '../Model/DocumentModel'
27
+ import type { ReparseParseOptions } from '../Incremental/IncrementalParser'
28
+ import { GreenNodePool, type InterningMode } from '../Syntax/GreenNodePool'
29
+ import { GreenNode, greenLeaf } from '../Syntax/GreenNode'
30
+ import { RedNode } from '../Syntax/RedNode'
31
+ import { greenToRedNode, greenToRedNodeReusing, type BBCodeDialect } from './BBCodeToGreenNode'
32
+ import { parseTokensToGreen } from './Parser'
33
+ import { scanBBCode } from '../Lexer/BBCodeLexer'
34
+ import { BBCodeExporter } from '../Visitors/BBCodeExporter'
35
+ import { HTMLRenderer } from '../Visitors/HTMLRenderer'
36
+
37
+ export interface BBCodeDocumentModelOptions extends DocumentModelOptions {
38
+ /** Source BBCode text to parse */
39
+ source?: string
40
+ /** Language identifier (default: 'bbcode') */
41
+ language?: string
42
+ /** Enforce strict tag nesting (disables osu! auto-close legacy behavior) */
43
+ strictMode?: boolean
44
+ /** BBCode dialect to parse against ('osu' | 'miliastry' | 'lyne'). Default: 'miliastry'. */
45
+ dialect?: BBCodeDialect
46
+ /** Alias for dialect ('osu' | 'miliastry' | 'lyne') */
47
+ mode?: BBCodeDialect
48
+ /**
49
+ * Deduplicate structurally identical green nodes across the document.
50
+ *
51
+ * Off by default. It is correct now — see the header of `GreenNodePool.ts`
52
+ * for why it was not — but it is a memory/latency trade, and this engine's
53
+ * declared budget is latency: on the 19.6 KB reference document `'leaves'`
54
+ * costs 16% more parse time to save 42% of the green tree's memory. Turn it
55
+ * on for workloads that hold many documents at once; leave it off to type
56
+ * into one.
57
+ */
58
+ interning?: InterningMode
59
+ }
60
+
61
+ // ─── BBCodeDocumentModel ────────────────────────────────────
62
+
63
+ export class BBCodeDocumentModel extends DocumentModel {
64
+ private _strictMode: boolean
65
+ private _dialect: BBCodeDialect
66
+ /** Per-document interner, or null when interning is off. */
67
+ private _interner: GreenNodePool | null
68
+ /** Memoized parser `extraTags`, rebuilt only when the registry changes. */
69
+ private _extraTags: ReadonlyMap<string, import('../Types/core').NodeKind> | null = null
70
+ private _extraTagsVersion: number = -1
71
+
72
+ constructor(options: BBCodeDocumentModelOptions = {}) {
73
+ // `source` is deliberately empty here: the base constructor would parse it
74
+ // with `parseToGreen`, which runs before this subclass has set
75
+ // `_strictMode`. The initial parse happens below instead.
76
+ //
77
+ // Everything else must be forwarded. It previously was not, so `autoAnalyze`
78
+ // and `maxUndo` were silently dropped and semantic analysis could not be
79
+ // turned off at all.
80
+ super({
81
+ source: '',
82
+ language: options.language ?? 'bbcode',
83
+ maxUndo: options.maxUndo,
84
+ autoAnalyze: options.autoAnalyze,
85
+ incremental: options.incremental,
86
+ reuseRed: options.reuseRed,
87
+ })
88
+ this._strictMode = options.strictMode ?? false
89
+ this._dialect = options.dialect ?? options.mode ?? 'miliastry'
90
+ this._interner = options.interning ? GreenNodePool.create(options.interning) : null
91
+ if (options.source) {
92
+ this.rebuild(options.source)
93
+ }
94
+ }
95
+
96
+ get dialect(): BBCodeDialect {
97
+ return this._dialect
98
+ }
99
+
100
+ get root(): RedNode | null {
101
+ return this.redRoot
102
+ }
103
+
104
+ toHTML(renderer?: HTMLRenderer): string {
105
+ if (!this.redRoot) return ''
106
+ const r = renderer ?? new HTMLRenderer({ dialect: this._dialect, theme: this._dialect === 'lyne' ? 'lyne' : 'osu' })
107
+ return r.render(this.redRoot)
108
+ }
109
+
110
+ /**
111
+ * Parse BBCode text directly to a GreenNode tree using the
112
+ * DocumentEngine's built-in BBCode Lexer + Parser.
113
+ * No dependency on the deprecated old parser.
114
+ */
115
+ protected parseToGreen(source: string, options?: ReparseParseOptions): GreenNode {
116
+ try {
117
+ // 1. Lex: BBCode text → tokens (with explicit newline tokens)
118
+ const tokens = scanBBCode(source)
119
+
120
+ // Plugin tags reach the parser here. Memoized against the registry's
121
+ // version: with no plugins (the common case) this is one integer
122
+ // compare and `extraTags` stays undefined — the parser's zero-cost path.
123
+ if (this._extraTagsVersion !== this.tagRegistry.version) {
124
+ this._extraTags = this.tagRegistry.customTags()
125
+ this._extraTagsVersion = this.tagRegistry.version
126
+ }
127
+
128
+ // 2. Parse: tokens → GreenNode (with proper empty_line handling)
129
+ const green = parseTokensToGreen(tokens, source, {
130
+ strictMode: this._strictMode,
131
+ dialect: this._dialect,
132
+ normalizeParagraphs: options?.normalizeParagraphs ?? true,
133
+ interner: this._interner ?? undefined,
134
+ extraTags: this._extraTags ?? undefined,
135
+ })
136
+
137
+ return green
138
+ } catch (error) {
139
+ console.warn('[BBCodeDocumentModel] Parse error:', error)
140
+ // Fallback: preserve source as a text node
141
+ return greenLeaf('text', source)
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Build a RedNode from a GreenNode, extracting metadata
147
+ * from BBCode attributes in the process.
148
+ */
149
+ protected buildRedFromGreen(green: GreenNode): RedNode {
150
+ return greenToRedNode(green)
151
+ }
152
+
153
+ /**
154
+ * Reuse-aware red build for the incremental path: adopts old red subtrees
155
+ * wherever the splice shared their green by reference. See the contract on
156
+ * `greenToRedNodeReusing` — the old tree is consumed.
157
+ */
158
+ protected buildRedFromGreenReusing(
159
+ green: GreenNode,
160
+ oldRed: RedNode,
161
+ stats?: { adopted: number },
162
+ ): RedNode {
163
+ return greenToRedNodeReusing(green, oldRed, 0, stats)
164
+ }
165
+
166
+ /**
167
+ * Serialize the red tree back to BBCode, so `transact`/`undo`/`redo` can
168
+ * rebuild from text. Target 'miliastry' keeps native tags (gradient, grow,
169
+ * …) as-is instead of expanding them, which is what round-tripping needs.
170
+ */
171
+ protected exportSource(root: RedNode): string {
172
+ const exportTarget = this._dialect === 'lyne' ? 'lyne' : this._dialect === 'osu' ? 'osu' : 'miliastry'
173
+ return new BBCodeExporter(this.tagRegistry, exportTarget).export(root)
174
+ }
175
+ }