@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.
- package/dist/Visuals/lyne.css +117 -6
- package/dist/Visuals/osu.css +36 -5
- package/dist/index.js +9664 -3282
- package/dist/index.mjs +9535 -3283
- package/dist/types/Analysis/Contracts/AnalysisReport.d.ts +22 -0
- package/dist/types/Analysis/Contracts/Contribution.d.ts +68 -0
- package/dist/types/Analysis/Contracts/Pass.d.ts +59 -0
- package/dist/types/Analysis/Contracts/PipelineContext.d.ts +34 -0
- package/dist/types/Analysis/Passes/Analysis/ColorUsageAnalyzer.d.ts +56 -0
- package/dist/types/Analysis/Passes/Analysis/GradientAnalyzer.d.ts +111 -0
- package/dist/types/Analysis/Passes/Analysis/MergeableColorAnalyzer.d.ts +26 -0
- package/dist/types/Analysis/Passes/Analysis/RainbowAnalyzer.d.ts +47 -0
- package/dist/types/Analysis/Passes/Analysis/SymbolAnalyzer.d.ts +89 -0
- package/dist/types/Analysis/Passes/Analysis/WaveAnalyzer.d.ts +44 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/GradientAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/MergeableColorAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/RainbowAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/WaveAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Decision/DefaultDecision.d.ts +30 -0
- package/dist/types/Analysis/Passes/Decision/PaletteRemapDecision.d.ts +169 -0
- package/dist/types/Analysis/Passes/Decision/__tests__/DefaultDecision.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Transform/CollapseGradientTransform.d.ts +37 -0
- package/dist/types/Analysis/Passes/Transform/MergeColorsTransform.d.ts +28 -0
- package/dist/types/Analysis/Passes/Transform/RainbowCollapseTransform.d.ts +19 -0
- package/dist/types/Analysis/Passes/Transform/WaveCollapseTransform.d.ts +20 -0
- package/dist/types/Analysis/Passes/Utility/CharacterCountAnalyzer.d.ts +19 -0
- package/dist/types/Analysis/Pipeline/Pipeline.d.ts +69 -0
- package/dist/types/Analysis/Pipeline/PipelineBuilder.d.ts +31 -0
- package/dist/types/Analysis/Pipeline/PipelineStage.d.ts +17 -0
- package/dist/types/Analysis/Utils/color-utils.d.ts +60 -0
- package/dist/types/Analysis/__tests__/Integration.test.d.ts +8 -0
- package/dist/types/Analysis/__tests__/PaletteRemap.test.d.ts +14 -0
- package/dist/types/Analysis/__tests__/Pipeline.test.d.ts +10 -0
- package/dist/types/Analysis/__tests__/RoundTrip.test.d.ts +30 -0
- package/dist/types/Analysis/__tests__/SymbolAnalyzer.test.d.ts +11 -0
- package/dist/types/Analysis/index.d.ts +40 -0
- package/dist/types/BBCode/BBCodeDocumentModel.d.ts +92 -0
- package/dist/types/BBCode/BBCodeToGreenNode.d.ts +111 -0
- package/dist/types/BBCode/Parser.d.ts +78 -0
- package/dist/types/BBCode/index.d.ts +4 -0
- package/dist/types/Collab/positions.d.ts +55 -0
- package/dist/types/Commands/Command.d.ts +37 -0
- package/dist/types/Commands/CommandRegistry.d.ts +48 -0
- package/dist/types/Commands/DeleteNode.d.ts +7 -0
- package/dist/types/Commands/InsertText.d.ts +8 -0
- package/dist/types/Commands/SplitMerge.d.ts +9 -0
- package/dist/types/Commands/WrapInTag.d.ts +8 -0
- package/dist/types/Commands/index.d.ts +6 -0
- package/dist/types/Diff/TreeDiffer.d.ts +52 -0
- package/dist/types/Diff/__tests__/TreeDiffer.test.d.ts +1 -0
- package/dist/types/Diff/index.d.ts +2 -0
- package/dist/types/Edits/EditPlan.d.ts +144 -0
- package/dist/types/Edits/Optimizer.d.ts +78 -0
- package/dist/types/Edits/Rules/Rule.d.ts +91 -0
- package/dist/types/Edits/Rules/dropEmptyTags.d.ts +40 -0
- package/dist/types/Edits/Rules/dropRedundantNesting.d.ts +59 -0
- package/dist/types/Edits/Rules/index.d.ts +9 -0
- package/dist/types/Edits/Rules/mergeAdjacent.d.ts +93 -0
- package/dist/types/Edits/Rules/reorderWrappers.d.ts +42 -0
- package/dist/types/Edits/Rules/shortenHex.d.ts +30 -0
- package/dist/types/Edits/Rules/tagValue.d.ts +56 -0
- package/dist/types/Edits/Rules/unwrapInvisibleColor.d.ts +47 -0
- package/dist/types/Edits/applyEdits.d.ts +36 -0
- package/dist/types/Edits/index.d.ts +6 -0
- package/dist/types/Events/EventBus.d.ts +103 -0
- package/dist/types/Events/index.d.ts +2 -0
- package/dist/types/Formatter/Formatter.d.ts +32 -0
- package/dist/types/Formatter/index.d.ts +2 -0
- package/dist/types/HTML/HTMLDocumentModel.d.ts +13 -0
- package/dist/types/HTML/HTMLToGreenNode.d.ts +4 -0
- package/dist/types/Incremental/BracketIndex.d.ts +101 -0
- package/dist/types/Incremental/ChangeTracker.d.ts +69 -0
- package/dist/types/Incremental/IncrementalParser.d.ts +246 -0
- package/dist/types/Incremental/__tests__/BracketIndex.test.d.ts +1 -0
- package/dist/types/Incremental/__tests__/IncrementalParser.test.d.ts +1 -0
- package/dist/types/Incremental/index.d.ts +4 -0
- package/dist/types/Lexer/BBCodeLexer.d.ts +74 -0
- package/dist/types/Lexer/Lexer.d.ts +54 -0
- package/dist/types/Lexer/index.d.ts +4 -0
- package/dist/types/Linter/Linter.d.ts +58 -0
- package/dist/types/Linter/index.d.ts +2 -0
- package/dist/types/Markdown/MarkdownAST.d.ts +122 -0
- package/dist/types/Markdown/MarkdownDocumentModel.d.ts +15 -0
- package/dist/types/Markdown/MarkdownLexer.d.ts +155 -0
- package/dist/types/Markdown/MarkdownParser.d.ts +42 -0
- package/dist/types/Markdown/MarkdownToGreenNode.d.ts +6 -0
- package/dist/types/MilHibri/MilHibriDocumentModel.d.ts +21 -0
- package/dist/types/Model/DocumentModel.d.ts +318 -0
- package/dist/types/Model/NodeFactory.d.ts +29 -0
- package/dist/types/Model/TagRegistry.d.ts +165 -0
- package/dist/types/Model/index.d.ts +5 -0
- package/dist/types/Plugins/PluginAPI.d.ts +44 -0
- package/dist/types/Plugins/PluginRegistry.d.ts +81 -0
- package/dist/types/Plugins/index.d.ts +3 -0
- package/dist/types/Queries/QueryEngine.d.ts +32 -0
- package/dist/types/Queries/index.d.ts +1 -0
- package/dist/types/Reconciler/SurgicalReconciler.d.ts +23 -0
- package/dist/types/RenderPipeline/RenderPipeline.d.ts +46 -0
- package/dist/types/RenderPipeline/RenderTree.d.ts +55 -0
- package/dist/types/RenderPipeline/index.d.ts +4 -0
- package/dist/types/Repair/NestingRepair.d.ts +48 -0
- package/dist/types/Repair/index.d.ts +1 -0
- package/dist/types/Semantic/SemanticAnalyzer.d.ts +321 -0
- package/dist/types/Semantic/index.d.ts +2 -0
- package/dist/types/Symbols/SymbolTable.d.ts +47 -0
- package/dist/types/Symbols/index.d.ts +1 -0
- package/dist/types/Syntax/GreenNode.d.ts +154 -0
- package/dist/types/Syntax/GreenNodePool.d.ts +134 -0
- package/dist/types/Syntax/NodeMatcher.d.ts +75 -0
- package/dist/types/Syntax/RedNode.d.ts +280 -0
- package/dist/types/Syntax/RedNodeStore.d.ts +116 -0
- package/dist/types/Syntax/TreeBuilder.d.ts +54 -0
- package/dist/types/Syntax/__tests__/GreenNode.test.d.ts +1 -0
- package/dist/types/Syntax/__tests__/RedNode.test.d.ts +1 -0
- package/dist/types/Syntax/__tests__/RedNodeStore.test.d.ts +1 -0
- package/dist/types/Syntax/greenEdit.d.ts +64 -0
- package/dist/types/Syntax/hash.d.ts +17 -0
- package/dist/types/Syntax/index.d.ts +8 -0
- package/dist/types/Syntax/nodeAttr.d.ts +63 -0
- package/dist/types/Syntax/partition.d.ts +67 -0
- package/dist/types/Syntax/preserveNodeIds.d.ts +47 -0
- package/dist/types/Tokens/TokenResolver.d.ts +25 -0
- package/dist/types/Tokens/index.d.ts +1 -0
- package/dist/types/Transactions/Transaction.d.ts +36 -0
- package/dist/types/Transactions/UndoManager.d.ts +63 -0
- package/dist/types/Transactions/index.d.ts +3 -0
- package/dist/types/Transformers/ASTOptimizer.d.ts +34 -0
- package/dist/types/Transformers/GradientTransformer.d.ts +18 -0
- package/dist/types/Transformers/GrowTransformer.d.ts +16 -0
- package/dist/types/Transformers/RainbowTransformer.d.ts +17 -0
- package/dist/types/Transformers/SineWaveTransformer.d.ts +17 -0
- package/dist/types/Transformers/Transformer.d.ts +17 -0
- package/dist/types/Types/core.d.ts +104 -0
- package/dist/types/Types/diagnostics.d.ts +85 -0
- package/dist/types/Types/index.d.ts +11 -0
- package/dist/types/Types/operations.d.ts +109 -0
- package/dist/types/Types/queries.d.ts +67 -0
- package/dist/types/Types/symbols.d.ts +42 -0
- package/dist/types/Types/tokens.d.ts +75 -0
- package/dist/types/Utils/BBCodeGenerator.d.ts +21 -0
- package/dist/types/Utils/ColorMath.d.ts +92 -0
- package/dist/types/Utils/EffectMath.d.ts +643 -0
- package/dist/types/Utils/TagVocabulary.d.ts +104 -0
- package/dist/types/Utils/TagVocabulary.test.d.ts +1 -0
- package/dist/types/Utils/color.d.ts +29 -0
- package/dist/types/Utils/dom-to-svg.d.ts +28 -0
- package/dist/types/Utils/dom-to-svg.test.d.ts +1 -0
- package/dist/types/Utils/treeTransformers.d.ts +160 -0
- package/dist/types/Visitors/BBBlocksExporter.d.ts +27 -0
- package/dist/types/Visitors/BBCodeExporter.d.ts +90 -0
- package/dist/types/Visitors/BlockPatcher.d.ts +91 -0
- package/dist/types/Visitors/DOMMorpher.d.ts +13 -0
- package/dist/types/Visitors/HTMLRenderer.d.ts +380 -0
- package/dist/types/Visitors/JSONExporter.d.ts +42 -0
- package/dist/types/Visitors/MarkdownExporter.d.ts +28 -0
- package/dist/types/Visitors/SVGRenderer.d.ts +16 -0
- package/dist/types/Visitors/TiptapExporter.d.ts +40 -0
- package/dist/types/Visitors/Visitor.d.ts +35 -0
- package/dist/types/Visitors/index.d.ts +9 -0
- package/dist/types/Visuals/BoxDrawer.d.ts +49 -0
- package/dist/types/Visuals/index.d.ts +38 -0
- package/dist/types/index.d.ts +154 -0
- package/package.json +14 -10
- package/src/Analysis/Passes/Analysis/ColorUsageAnalyzer.ts +103 -0
- package/src/Analysis/Passes/Analysis/GradientAnalyzer.ts +294 -20
- package/src/Analysis/Passes/Analysis/SymbolAnalyzer.ts +257 -0
- package/src/Analysis/Passes/Decision/PaletteRemapDecision.ts +425 -0
- package/src/Analysis/Pipeline/Pipeline.ts +15 -2
- package/src/Analysis/index.ts +8 -2
- package/src/BBCode/BBCodeDocumentModel.ts +3 -0
- package/src/BBCode/BBCodeToGreenNode.ts +18 -12
- package/src/BBCode/Parser.ts +38 -1
- package/src/Edits/EditPlan.ts +290 -0
- package/src/Edits/Optimizer.ts +185 -0
- package/src/Edits/Rules/Rule.ts +145 -0
- package/src/Edits/Rules/dropEmptyTags.ts +110 -0
- package/src/Edits/Rules/dropRedundantNesting.ts +120 -0
- package/src/Edits/Rules/index.ts +28 -0
- package/src/Edits/Rules/mergeAdjacent.ts +224 -0
- package/src/Edits/Rules/reorderWrappers.ts +154 -0
- package/src/Edits/Rules/shortenHex.ts +79 -0
- package/src/Edits/Rules/tagValue.ts +105 -0
- package/src/Edits/Rules/unwrapInvisibleColor.ts +93 -0
- package/src/Edits/applyEdits.ts +54 -0
- package/src/Edits/index.ts +22 -0
- package/src/Events/EventBus.ts +18 -0
- package/src/HTML/HTMLToGreenNode.ts +185 -37
- package/src/Incremental/BracketIndex.ts +249 -0
- package/src/Incremental/IncrementalParser.ts +464 -41
- package/src/Lexer/BBCodeLexer.ts +25 -3
- package/src/Lexer/index.ts +1 -1
- package/src/Markdown/MarkdownAST.ts +65 -2
- package/src/Markdown/MarkdownLexer.ts +69 -14
- package/src/Markdown/MarkdownParser.ts +749 -62
- package/src/Markdown/MarkdownToGreenNode.ts +148 -27
- package/src/MilHibri/MilHibriDocumentModel.ts +56 -0
- package/src/Model/DocumentModel.ts +138 -5
- package/src/Model/TagRegistry.ts +129 -134
- package/src/Reconciler/SurgicalReconciler.ts +460 -0
- package/src/Repair/NestingRepair.ts +116 -0
- package/src/Repair/index.ts +1 -0
- package/src/Semantic/SemanticAnalyzer.ts +1802 -65
- package/src/Syntax/GreenNodePool.ts +12 -12
- package/src/Syntax/RedNode.ts +17 -3
- package/src/Syntax/RedNodeStore.ts +9 -1
- package/src/Syntax/nodeAttr.ts +172 -0
- package/src/Tokens/TokenResolver.ts +55 -0
- package/src/Tokens/index.ts +1 -0
- package/src/Types/core.ts +15 -0
- package/src/Utils/ColorMath.ts +276 -55
- package/src/Utils/EffectMath.ts +2462 -0
- package/src/Utils/TagVocabulary.ts +141 -0
- package/src/Utils/dom-to-svg.ts +28 -12
- package/src/Visitors/BBBlocksExporter.ts +15 -1
- package/src/Visitors/BBCodeExporter.ts +319 -32
- package/src/Visitors/BlockPatcher.ts +87 -11
- package/src/Visitors/DOMMorpher.ts +15 -5
- package/src/Visitors/HTMLRenderer.ts +374 -151
- package/src/Visitors/MarkdownExporter.ts +98 -41
- package/src/Visitors/TiptapExporter.ts +1 -0
- package/src/Visuals/index.ts +7 -4
- package/src/Visuals/lyne.css +117 -6
- package/src/Visuals/osu.css +36 -5
- package/src/index.ts +172 -5
- package/dist/index.d.mts +0 -4612
- package/dist/index.d.ts +0 -4612
- package/src/Analysis/Passes/Analysis/__tests__/GradientAnalyzer.test.ts +0 -135
- package/src/Analysis/Passes/Analysis/__tests__/MergeableColorAnalyzer.test.ts +0 -84
- package/src/Analysis/Passes/Analysis/__tests__/RainbowAnalyzer.test.ts +0 -99
- package/src/Analysis/Passes/Analysis/__tests__/WaveAnalyzer.test.ts +0 -119
- package/src/Analysis/Passes/Decision/__tests__/DefaultDecision.test.ts +0 -179
- package/src/Analysis/__tests__/Integration.test.ts +0 -162
- package/src/Analysis/__tests__/Pipeline.test.ts +0 -133
- package/src/Diff/__tests__/TreeDiffer.test.ts +0 -65
- package/src/Incremental/__tests__/IncrementalParser.test.ts +0 -164
- package/src/Syntax/__tests__/GreenNode.test.ts +0 -33
- package/src/Syntax/__tests__/RedNode.test.ts +0 -81
- package/src/Syntax/__tests__/RedNodeStore.test.ts +0 -104
- package/src/Tests/ASTOptimizerIdempotence.test.ts +0 -77
- package/src/Tests/BlockPatcher.test.ts +0 -437
- package/src/Tests/BlockPatcherWindowed.test.ts +0 -364
- package/src/Tests/BoxDrawer.test.ts +0 -217
- package/src/Tests/BoxRichTitle.test.ts +0 -105
- package/src/Tests/Chars500kBenchmark.test.ts +0 -151
- package/src/Tests/Chars500kEdits.test.ts +0 -321
- package/src/Tests/CollabPositions.test.ts +0 -146
- package/src/Tests/CompilerPathProfiling.test.ts +0 -186
- package/src/Tests/DOMMorpher.test.ts +0 -142
- package/src/Tests/DomPatchPerf.test.ts +0 -60
- package/src/Tests/EffectSegments.snapshot.json +0 -616
- package/src/Tests/EffectSegments.test.ts +0 -68
- package/src/Tests/FindNodeAtOffset.test.ts +0 -65
- package/src/Tests/Fuzzer.test.ts +0 -166
- package/src/Tests/GreenNodePool.test.ts +0 -153
- package/src/Tests/Lexer.test.ts +0 -238
- package/src/Tests/LyneMode.test.ts +0 -291
- package/src/Tests/ModelCoherence.test.ts +0 -180
- package/src/Tests/Partition.test.ts +0 -238
- package/src/Tests/PluginTags.test.ts +0 -150
- package/src/Tests/ProblematicSection.test.ts +0 -46
- package/src/Tests/ProblematicSectionHTML.test.ts +0 -58
- package/src/Tests/RedReuse.test.ts +0 -134
- package/src/Tests/ReproDelete20k.test.ts +0 -62
- package/src/Tests/SemanticValidators.test.ts +0 -136
- package/src/Tests/StableNodeIds.test.ts +0 -210
- package/src/Tests/StudioColorBloat.test.ts +0 -25
- package/src/Tests/StudioDebugText.test.ts +0 -27
- package/src/Tests/StudioTrailingChar.test.ts +0 -25
- package/src/Tests/StudioValidText.test.ts +0 -25
- package/src/Tests/UrlImgBug.test.ts +0 -23
- package/src/Tests/VisualBuilderFidelity.test.ts +0 -105
- package/src/Tests/referenceDocument.ts +0 -119
- package/src/Utils/dom-to-svg.test.ts +0 -86
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — DocumentModel
|
|
3
|
+
*
|
|
4
|
+
* THE CORE of the Language Platform.
|
|
5
|
+
*
|
|
6
|
+
* The DocumentModel is the single source of truth for the document.
|
|
7
|
+
* BBCode is just ONE representation of this model.
|
|
8
|
+
* The model is language-agnostic and format-agnostic.
|
|
9
|
+
*
|
|
10
|
+
* Responsibilities:
|
|
11
|
+
* - Hold the current Red Tree
|
|
12
|
+
* - Manage incremental parsing
|
|
13
|
+
* - Coordinate transactions (undo/redo)
|
|
14
|
+
* - Emit change events
|
|
15
|
+
* - Provide query/find capabilities
|
|
16
|
+
* - Manage diagnostics
|
|
17
|
+
*
|
|
18
|
+
* Inspired by ProseMirror's EditorState and Roslyn's Document.
|
|
19
|
+
*/
|
|
20
|
+
import { RedNode } from '../Syntax/RedNode';
|
|
21
|
+
import { GreenNode } from '../Syntax/GreenNode';
|
|
22
|
+
import { NodeMatcher } from '../Syntax/NodeMatcher';
|
|
23
|
+
import { IncrementalParser, type ReparseParseOptions, type FallbackReason, type SourceSpan } from '../Incremental/IncrementalParser';
|
|
24
|
+
import { ChangeTracker } from '../Incremental/ChangeTracker';
|
|
25
|
+
import type { TextChange, TextChangeRange } from '../Incremental/ChangeTracker';
|
|
26
|
+
import { SemanticAnalyzer } from '../Semantic/SemanticAnalyzer';
|
|
27
|
+
import type { AnalyzeResult, Validator } from '../Semantic/SemanticAnalyzer';
|
|
28
|
+
import type { Operation } from '../Types/operations';
|
|
29
|
+
import { UndoManager } from '../Transactions/UndoManager';
|
|
30
|
+
import { TreeBuilder } from '../Syntax/TreeBuilder';
|
|
31
|
+
import { QueryEngine } from '../Queries/QueryEngine';
|
|
32
|
+
import type { Query, QueryResult } from '../Types/queries';
|
|
33
|
+
import type { DocumentNode, NodeId } from '../Types/core';
|
|
34
|
+
import type { DiagnosticCollection } from '../Types/diagnostics';
|
|
35
|
+
import { DocumentEventBus } from '../Events/EventBus';
|
|
36
|
+
import { NodeFactory } from './NodeFactory';
|
|
37
|
+
import { TagRegistry } from './TagRegistry';
|
|
38
|
+
export interface DocumentModelOptions {
|
|
39
|
+
/** Initial source text */
|
|
40
|
+
source?: string;
|
|
41
|
+
/** Language identifier */
|
|
42
|
+
language?: string;
|
|
43
|
+
/** Maximum undo stack size */
|
|
44
|
+
maxUndo?: number;
|
|
45
|
+
/** Whether to auto-analyze on change */
|
|
46
|
+
autoAnalyze?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Attempt incremental reparse on `applyChange`. Default `true`.
|
|
49
|
+
*
|
|
50
|
+
* Setting this to `false` makes every change a full rebuild. The result is
|
|
51
|
+
* identical either way — that is the incremental parser's contract, checked
|
|
52
|
+
* differentially over 22.100 edits — so this is a performance switch and a
|
|
53
|
+
* debugging aid, not a correctness one.
|
|
54
|
+
*/
|
|
55
|
+
incremental?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Reuse red subtrees across incremental reparses. Default `true`.
|
|
58
|
+
*
|
|
59
|
+
* When the splice shares a green subtree by reference, the old red subtree
|
|
60
|
+
* is adopted into the new tree instead of being rebuilt — building red was
|
|
61
|
+
* the largest phase of a keystroke. The trade is a contract: the previous
|
|
62
|
+
* `redRoot` is consumed by the adoption and must not be walked afterwards.
|
|
63
|
+
* No engine or app code does; this switch exists for any future consumer
|
|
64
|
+
* that needs the superseded tree to stay intact.
|
|
65
|
+
*/
|
|
66
|
+
reuseRed?: boolean;
|
|
67
|
+
}
|
|
68
|
+
export declare class DocumentModel {
|
|
69
|
+
private _source;
|
|
70
|
+
private _language;
|
|
71
|
+
private _redRoot;
|
|
72
|
+
private _greenRoot;
|
|
73
|
+
private _version;
|
|
74
|
+
readonly tagRegistry: TagRegistry;
|
|
75
|
+
readonly nodeFactory: NodeFactory;
|
|
76
|
+
readonly treeBuilder: TreeBuilder;
|
|
77
|
+
readonly nodeMatcher: NodeMatcher;
|
|
78
|
+
readonly semanticAnalyzer: SemanticAnalyzer;
|
|
79
|
+
readonly incrementalParser: IncrementalParser;
|
|
80
|
+
readonly changeTracker: ChangeTracker;
|
|
81
|
+
readonly undoManager: UndoManager;
|
|
82
|
+
readonly queryEngine: QueryEngine;
|
|
83
|
+
readonly events: DocumentEventBus;
|
|
84
|
+
private _diagnostics;
|
|
85
|
+
private _lastAnalyzeResult;
|
|
86
|
+
/**
|
|
87
|
+
* Source range of the last applied edit — see {@link TextChangeRange}.
|
|
88
|
+
* `null` after a full rebuild, which is not an edit.
|
|
89
|
+
*/
|
|
90
|
+
private _lastChangeRange;
|
|
91
|
+
private _options;
|
|
92
|
+
private _analyzeTimeout;
|
|
93
|
+
/** The debounced post-edit work, kept so `ensureAnalyzed` can run it early. */
|
|
94
|
+
private _pendingAnalyze;
|
|
95
|
+
/** Last reparse timings breakdown (exposed for debugging) */
|
|
96
|
+
lastReparsePath: string;
|
|
97
|
+
/** Why the last reparse fell back to a full rebuild, if it did. */
|
|
98
|
+
lastReparseFallbackReason: FallbackReason | null;
|
|
99
|
+
lastReparseTimings: {
|
|
100
|
+
findAffected: number;
|
|
101
|
+
safeBoundary: number;
|
|
102
|
+
parse: number;
|
|
103
|
+
buildRed: number;
|
|
104
|
+
mutate: number;
|
|
105
|
+
other: number;
|
|
106
|
+
} | null;
|
|
107
|
+
/**
|
|
108
|
+
* The span of the current source the last reparse actually re-parsed, in
|
|
109
|
+
* CURRENT coordinates — `null` after a full rebuild, where the answer is
|
|
110
|
+
* "all of it". See {@link ReparseResult.window}.
|
|
111
|
+
*/
|
|
112
|
+
lastReparseWindow: SourceSpan | null;
|
|
113
|
+
/**
|
|
114
|
+
* The union of every reparse window since the last analysis, in CURRENT
|
|
115
|
+
* coordinates — `null` when nothing is pending. A bounding span rather than
|
|
116
|
+
* a list: over-covering only means re-validating a few more nodes, and the
|
|
117
|
+
* arithmetic to keep several spans current across later edits costs more
|
|
118
|
+
* than the nodes do.
|
|
119
|
+
*/
|
|
120
|
+
private _analysisWindow;
|
|
121
|
+
/** Set by anything a window pass cannot be built on: a rebuild, a reparse that fell back. */
|
|
122
|
+
private _analysisWindowBroken;
|
|
123
|
+
constructor(options?: DocumentModelOptions);
|
|
124
|
+
get source(): string;
|
|
125
|
+
get language(): string;
|
|
126
|
+
get version(): number;
|
|
127
|
+
get redRoot(): RedNode | null;
|
|
128
|
+
get greenRoot(): GreenNode | null;
|
|
129
|
+
get diagnostics(): DiagnosticCollection | null;
|
|
130
|
+
/**
|
|
131
|
+
* What the last analysis cost and how it was obtained — its `scope` says
|
|
132
|
+
* whether it walked the document or only the edit's window, and `window`
|
|
133
|
+
* carries that span when it did. The diagnostics themselves are on
|
|
134
|
+
* {@link diagnostics}, and are the whole document's on either route.
|
|
135
|
+
*/
|
|
136
|
+
get lastAnalyze(): AnalyzeResult | null;
|
|
137
|
+
/**
|
|
138
|
+
* The source range of the last applied edit, in new-source coordinates.
|
|
139
|
+
*
|
|
140
|
+
* `null` after a `rebuild` (there is no incremental edit to point at). The
|
|
141
|
+
* BlockPatcher reads this to reconcile only the blocks around the edit
|
|
142
|
+
* instead of walking the whole document. The same range is also attached to
|
|
143
|
+
* the current `redRoot` (`__changeRange`), so a consumer that only holds the
|
|
144
|
+
* AST — like the live preview — can find it without plumbing the model.
|
|
145
|
+
*/
|
|
146
|
+
get lastChangeRange(): TextChangeRange | null;
|
|
147
|
+
/**
|
|
148
|
+
* Full rebuild from source text.
|
|
149
|
+
* Used for initial load or when incremental parsing isn't possible.
|
|
150
|
+
*/
|
|
151
|
+
rebuild(source: string): void;
|
|
152
|
+
/**
|
|
153
|
+
* Install `nodeMatch` on an event as an accessor, so the match is only
|
|
154
|
+
* computed if a subscriber actually reads it.
|
|
155
|
+
*
|
|
156
|
+
* Matching two 1736-node trees costs ~3.5 ms and allocates a result entry per
|
|
157
|
+
* node plus five Maps/Sets — and it ran on *every* keystroke to populate a
|
|
158
|
+
* field that no subscriber in this codebase reads. The capability is real
|
|
159
|
+
* (preserving selection and scroll across re-parses is what it is for), so it
|
|
160
|
+
* stays available; it just stops running speculatively.
|
|
161
|
+
*
|
|
162
|
+
* Callers still write `event.nodeMatch` and see a `NodeMatch | null`. Note the
|
|
163
|
+
* closure keeps `oldRoot` alive for as long as the event object is retained.
|
|
164
|
+
*/
|
|
165
|
+
private defineLazyNodeMatch;
|
|
166
|
+
/**
|
|
167
|
+
* Attach the last change range to a root node.
|
|
168
|
+
*
|
|
169
|
+
* The range travels with the AST so the preview can read it from the root it
|
|
170
|
+
* is about to patch — no prop drilling through workspace → window → preview.
|
|
171
|
+
* `__changeRange` is deliberately not part of RedNode's API; it is a runtime
|
|
172
|
+
* marker owned by the model (the BlockPatcher reads it with a cast).
|
|
173
|
+
*/
|
|
174
|
+
private _attachChangeRange;
|
|
175
|
+
/**
|
|
176
|
+
* Apply one exact source change — THE edit path, and the one an editor
|
|
177
|
+
* should use.
|
|
178
|
+
*
|
|
179
|
+
* An editor already knows what the user did: Monaco's
|
|
180
|
+
* `onDidChangeModelContent` hands over `rangeOffset`, `rangeLength` and
|
|
181
|
+
* `text`, which is exactly a {@link TextChange}. Handing that over instead
|
|
182
|
+
* of the new document text skips the only part of the pipeline that is
|
|
183
|
+
* unavoidably proportional to the whole document — the prefix/suffix diff
|
|
184
|
+
* in {@link applyTextUpdate} — and the difference is not marginal. Typing
|
|
185
|
+
* 120 characters into the middle of the 500 KB fixture, per keystroke:
|
|
186
|
+
*
|
|
187
|
+
* applyTextUpdate p50 7.35 ms p95 28.79 ms
|
|
188
|
+
* applyChange p50 1.85 ms p95 8.18 ms
|
|
189
|
+
*
|
|
190
|
+
* Everything downstream is already windowed, so what is left after the diff
|
|
191
|
+
* goes is work proportional to the edit.
|
|
192
|
+
*
|
|
193
|
+
* `origin` tags where the change came from — `'local'` (default) for the
|
|
194
|
+
* user's own editing, anything else for programmatic or synced sources
|
|
195
|
+
* (`'remote'`, `'sync'`, a peer id…). It travels on the emitted events, so
|
|
196
|
+
* a collaboration layer can tell its own echo apart from user edits — the
|
|
197
|
+
* classic infinite-loop bug when wiring a CRDT. See `QuasarCollab.MD`.
|
|
198
|
+
*/
|
|
199
|
+
applyChange(change: TextChange, origin?: string): void;
|
|
200
|
+
/**
|
|
201
|
+
* Flush the debounced post-edit analysis, so `diagnostics` describes the
|
|
202
|
+
* *current* tree.
|
|
203
|
+
*
|
|
204
|
+
* `applyChange` defers analysis by a few milliseconds to keep the keystroke
|
|
205
|
+
* path lean. A caller that reads `diagnostics` synchronously right after an
|
|
206
|
+
* edit would otherwise be looking at the previous document's errors — which
|
|
207
|
+
* is exactly what the editor's error panel did.
|
|
208
|
+
*/
|
|
209
|
+
ensureAnalyzed(): void;
|
|
210
|
+
/**
|
|
211
|
+
* Recover the edit from the new document text, then apply it.
|
|
212
|
+
*
|
|
213
|
+
* The FALLBACK, for a caller that only has the text: a textarea's `value`,
|
|
214
|
+
* a CRDT that hands over a materialised document, a paste normaliser. It is
|
|
215
|
+
* a shared-prefix/shared-suffix diff, so it costs one pass over the
|
|
216
|
+
* unchanged part of the document before any of the incremental machinery
|
|
217
|
+
* gets to run — which is precisely the term {@link applyChange} does not
|
|
218
|
+
* pay. Anything that knows the edit should say so and use that instead.
|
|
219
|
+
*/
|
|
220
|
+
applyTextUpdate(newSource: string, origin?: string): void;
|
|
221
|
+
/**
|
|
222
|
+
* Execute operations within a transaction (undoable).
|
|
223
|
+
*
|
|
224
|
+
* Coherence contract: after a `transact` the model's `source`, green tree
|
|
225
|
+
* and red tree all describe the same document. The transaction mutates the
|
|
226
|
+
* red tree, the result is serialized back to text via `exportSource`, and
|
|
227
|
+
* the model rebuilds from that text — parse stays the single source of
|
|
228
|
+
* truth, exactly as in `applyChange`. (The previous implementation swapped
|
|
229
|
+
* `_redRoot` and left `_source`/`_greenRoot` describing the old document,
|
|
230
|
+
* so the next text edit diffed against a source the tree no longer matched.)
|
|
231
|
+
*
|
|
232
|
+
* Returns `true` if the document changed.
|
|
233
|
+
*/
|
|
234
|
+
transact(operations: Operation[], label?: string): boolean;
|
|
235
|
+
/**
|
|
236
|
+
* Undo the last transaction.
|
|
237
|
+
*
|
|
238
|
+
* Undo/redo replay *source snapshots*, not stored tree mutations: a rebuild
|
|
239
|
+
* replaces every node id, so a retained `Transaction` could never be
|
|
240
|
+
* re-applied against the current tree — and its `invert()` was only defined
|
|
241
|
+
* for one of the six operation kinds anyway. Text is always replayable.
|
|
242
|
+
*/
|
|
243
|
+
undo(): boolean;
|
|
244
|
+
/**
|
|
245
|
+
* Redo the last undone transaction. See `undo` for why this replays text.
|
|
246
|
+
*/
|
|
247
|
+
redo(): boolean;
|
|
248
|
+
/**
|
|
249
|
+
* Run semantic analysis on the current tree.
|
|
250
|
+
*
|
|
251
|
+
* Incremental when it can be: if every edit since the last analysis was an
|
|
252
|
+
* incremental reparse that adopted subtrees, only the nodes inside those
|
|
253
|
+
* reparse windows — plus the ones whose document-wide facts the edits moved
|
|
254
|
+
* — are re-validated, and every other node keeps the verdict it already
|
|
255
|
+
* had. The DIAGNOSTICS ARE THE SAME EITHER WAY; the difference is how long
|
|
256
|
+
* it took to arrive at them, and {@link AnalyzeResult.scope} says which
|
|
257
|
+
* route was taken. The differential in `Chars500kAnalysis.test.ts` compares
|
|
258
|
+
* the two, edit by edit, on the real fixture.
|
|
259
|
+
*
|
|
260
|
+
* Falls back to the full pass whenever the window pass declines — no
|
|
261
|
+
* previous pass to build on, the validator set or the token source changed
|
|
262
|
+
* under it, or a validator whose verdicts are not a function of one node
|
|
263
|
+
* (see `Validator.scope`).
|
|
264
|
+
*/
|
|
265
|
+
analyze(): AnalyzeResult;
|
|
266
|
+
/**
|
|
267
|
+
* Find a node by its ID.
|
|
268
|
+
*/
|
|
269
|
+
findNode(id: NodeId): RedNode | null;
|
|
270
|
+
/**
|
|
271
|
+
* Query the document tree.
|
|
272
|
+
*/
|
|
273
|
+
query(q: Query): QueryResult;
|
|
274
|
+
/**
|
|
275
|
+
* Register a semantic validator.
|
|
276
|
+
*/
|
|
277
|
+
registerValidator(validator: Validator): void;
|
|
278
|
+
/**
|
|
279
|
+
* Get the current document as a DocumentNode tree.
|
|
280
|
+
*/
|
|
281
|
+
toDocumentNode(): DocumentNode | null;
|
|
282
|
+
/**
|
|
283
|
+
* Get the current source text.
|
|
284
|
+
*/
|
|
285
|
+
toString(): string;
|
|
286
|
+
/**
|
|
287
|
+
* Parse source text to a GreenNode tree.
|
|
288
|
+
* Override this for language-specific parsing.
|
|
289
|
+
*
|
|
290
|
+
* `options.normalizeParagraphs === false` means the text is the inner span
|
|
291
|
+
* of a container rather than a whole document, and root-level grouping must
|
|
292
|
+
* be skipped. Languages without such grouping can ignore it.
|
|
293
|
+
*/
|
|
294
|
+
protected parseToGreen(source: string, options?: ReparseParseOptions): GreenNode;
|
|
295
|
+
/**
|
|
296
|
+
* Build a RedNode tree from a GreenNode.
|
|
297
|
+
*/
|
|
298
|
+
protected buildRedFromGreen(green: GreenNode): RedNode;
|
|
299
|
+
/**
|
|
300
|
+
* Build a red tree for `green`, reusing subtrees of `oldRed` where the green
|
|
301
|
+
* is shared by reference. The base model has no reuse-aware builder, so it
|
|
302
|
+
* falls back to a full build; language models override this
|
|
303
|
+
* (BBCodeDocumentModel uses `greenToRedNodeReusing`).
|
|
304
|
+
*/
|
|
305
|
+
protected buildRedFromGreenReusing(green: GreenNode, oldRed: RedNode, stats?: {
|
|
306
|
+
adopted: number;
|
|
307
|
+
}): RedNode;
|
|
308
|
+
/**
|
|
309
|
+
* Serialize a red tree back to source text. `transact`/`undo`/`redo` rebuild
|
|
310
|
+
* from this text to keep source, green and red coherent.
|
|
311
|
+
*
|
|
312
|
+
* The base model has no syntax to serialize to, so this throws; language
|
|
313
|
+
* models override it (BBCodeDocumentModel uses the BBCodeExporter).
|
|
314
|
+
* Failing loudly here beats the alternative: silently desynchronizing the
|
|
315
|
+
* model's three representations.
|
|
316
|
+
*/
|
|
317
|
+
protected exportSource(root: RedNode): string;
|
|
318
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — NodeFactory
|
|
3
|
+
*
|
|
4
|
+
* Creates DocumentNode instances, RedNode instances, and GreenNode
|
|
5
|
+
* instances from tag definitions. Centralizes node creation so
|
|
6
|
+
* plugins can provide custom node factories.
|
|
7
|
+
*/
|
|
8
|
+
import { RedNode } from '../Syntax/RedNode';
|
|
9
|
+
import { TagRegistry } from './TagRegistry';
|
|
10
|
+
export declare class NodeFactory {
|
|
11
|
+
private registry;
|
|
12
|
+
constructor(registry: TagRegistry);
|
|
13
|
+
/**
|
|
14
|
+
* Create a RedNode from a tag definition.
|
|
15
|
+
*/
|
|
16
|
+
createFromTag(tagName: string, attrs?: string, start?: number, end?: number, children?: RedNode[]): RedNode;
|
|
17
|
+
/**
|
|
18
|
+
* Create a text RedNode.
|
|
19
|
+
*/
|
|
20
|
+
createText(text: string, start?: number, end?: number): RedNode;
|
|
21
|
+
/**
|
|
22
|
+
* Create a self-closing tag RedNode (like [*], [img]src[/img]).
|
|
23
|
+
*/
|
|
24
|
+
createSelfClosing(tagName: string, attrs?: string, start?: number, end?: number): RedNode;
|
|
25
|
+
/**
|
|
26
|
+
* Create a document root RedNode.
|
|
27
|
+
*/
|
|
28
|
+
createDocument(children?: RedNode[]): RedNode;
|
|
29
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — TagRegistry
|
|
3
|
+
*
|
|
4
|
+
* The central registry for all known tags/node kinds.
|
|
5
|
+
* This is the plugin extension point for adding new BBCode tags,
|
|
6
|
+
* custom node types, or even entire new languages.
|
|
7
|
+
*
|
|
8
|
+
* Each tag definition includes:
|
|
9
|
+
* - Parser handler (how to parse this tag from tokens)
|
|
10
|
+
* - Renderer (how to render this tag to HTML, Markdown, etc.)
|
|
11
|
+
* - Validator (semantic validation rules)
|
|
12
|
+
* - Toolbar definition (for the visual editor)
|
|
13
|
+
* - Property editor (for the properties panel)
|
|
14
|
+
*
|
|
15
|
+
* Inspired by VSCode's contribution points.
|
|
16
|
+
*/
|
|
17
|
+
import type { NodeKind, NodeAttributes } from '../Types/core';
|
|
18
|
+
import type { RedNode } from '../Syntax/RedNode';
|
|
19
|
+
import type { RenderNode } from '../RenderPipeline/RenderTree';
|
|
20
|
+
import type { Validator } from '../Semantic/SemanticAnalyzer';
|
|
21
|
+
export interface TagHandlerContext {
|
|
22
|
+
node: RedNode;
|
|
23
|
+
source: string;
|
|
24
|
+
visitChildren: (node: RedNode) => string;
|
|
25
|
+
renderChild: (node: RedNode) => RenderNode;
|
|
26
|
+
}
|
|
27
|
+
export interface TagDefinition {
|
|
28
|
+
/** The tag name (e.g. 'color', 'b', 'img') */
|
|
29
|
+
name: string;
|
|
30
|
+
/** Semantic kind */
|
|
31
|
+
kind: NodeKind;
|
|
32
|
+
/** Human-readable label */
|
|
33
|
+
label: string;
|
|
34
|
+
/** Category for grouping in UI */
|
|
35
|
+
category?: 'formatting' | 'layout' | 'media' | 'special' | 'text';
|
|
36
|
+
/** Icon name for UI */
|
|
37
|
+
icon?: string;
|
|
38
|
+
/** Whether this tag is inline (span) or block (div) */
|
|
39
|
+
isInline: boolean;
|
|
40
|
+
/** Whether this tag is self-closing */
|
|
41
|
+
isSelfClosing: boolean;
|
|
42
|
+
/** Whether this tag can contain children */
|
|
43
|
+
canHaveChildren: boolean;
|
|
44
|
+
/** Whether this tag is deprecated */
|
|
45
|
+
isDeprecated?: boolean;
|
|
46
|
+
/** Replacement tag name if deprecated */
|
|
47
|
+
deprecatedReplacement?: string;
|
|
48
|
+
/** Convert a RedNode back to BBCode text */
|
|
49
|
+
toBBCode?: (ctx: TagHandlerContext) => string;
|
|
50
|
+
/** Convert a RedNode to a RenderNode for the render pipeline */
|
|
51
|
+
toRenderNode?: (ctx: TagHandlerContext) => RenderNode;
|
|
52
|
+
/** Convert a RedNode to HTML string (legacy) */
|
|
53
|
+
toHTML?: (ctx: TagHandlerContext) => string;
|
|
54
|
+
/** Default attributes for new instances */
|
|
55
|
+
defaultAttributes?: () => NodeAttributes;
|
|
56
|
+
/** Additional validator for this specific tag */
|
|
57
|
+
validator?: Validator;
|
|
58
|
+
/** Toolbar button definition */
|
|
59
|
+
toolbar?: {
|
|
60
|
+
group: string;
|
|
61
|
+
label: string;
|
|
62
|
+
icon?: string;
|
|
63
|
+
shortcut?: string;
|
|
64
|
+
};
|
|
65
|
+
/** Properties panel definition */
|
|
66
|
+
properties?: PropertyDefinition[];
|
|
67
|
+
}
|
|
68
|
+
export interface PropertyDefinition {
|
|
69
|
+
name: string;
|
|
70
|
+
label: string;
|
|
71
|
+
type: 'text' | 'color' | 'number' | 'select' | 'boolean' | 'slider';
|
|
72
|
+
defaultValue?: string | number | boolean;
|
|
73
|
+
options?: {
|
|
74
|
+
label: string;
|
|
75
|
+
value: string;
|
|
76
|
+
}[];
|
|
77
|
+
min?: number;
|
|
78
|
+
max?: number;
|
|
79
|
+
step?: number;
|
|
80
|
+
placeholder?: string;
|
|
81
|
+
description?: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Recursively extract plain text from a RedNode tree.
|
|
85
|
+
*
|
|
86
|
+
* A line break is a childless `spacing` leaf with no text of its own, so
|
|
87
|
+
* it has to be spelled out here or an effect spanning two lines is handed
|
|
88
|
+
* one line and exports without its break — silent data loss, and the
|
|
89
|
+
* reason every two-dimensional axis (`line`, `column`, `radial`) measured
|
|
90
|
+
* a block one line tall.
|
|
91
|
+
*/
|
|
92
|
+
export declare function extractTextContent(node: RedNode): string;
|
|
93
|
+
export type TagHandler = {
|
|
94
|
+
[K in keyof TagDefinition]: TagDefinition[K];
|
|
95
|
+
};
|
|
96
|
+
export declare class TagRegistry {
|
|
97
|
+
private tags;
|
|
98
|
+
private kinds;
|
|
99
|
+
/** Names registered by the constructor — the language's own tags. */
|
|
100
|
+
private builtins;
|
|
101
|
+
/**
|
|
102
|
+
* Whether `tags`/`kinds` are still the process-wide builtin maps. While
|
|
103
|
+
* they are, this registry must not write to them.
|
|
104
|
+
*/
|
|
105
|
+
private shared;
|
|
106
|
+
/**
|
|
107
|
+
* Bumped on every register/unregister, so consumers that derive something
|
|
108
|
+
* from the registry (the parser's `extraTags` map) can memoize against it
|
|
109
|
+
* instead of rebuilding per parse.
|
|
110
|
+
*/
|
|
111
|
+
version: number;
|
|
112
|
+
constructor();
|
|
113
|
+
/** Take a private copy of the builtin maps before the first write. */
|
|
114
|
+
private own;
|
|
115
|
+
/**
|
|
116
|
+
* Register a tag definition.
|
|
117
|
+
*/
|
|
118
|
+
register(tag: TagDefinition): void;
|
|
119
|
+
/**
|
|
120
|
+
* Unregister a tag definition.
|
|
121
|
+
*/
|
|
122
|
+
unregister(name: string): void;
|
|
123
|
+
/**
|
|
124
|
+
* Whether `name` is one of the language's own tags, as opposed to a
|
|
125
|
+
* plugin registration. The distinction matters: plugin tags must reach the
|
|
126
|
+
* parser (via `ParseOptions.extraTags`) and serialize with their own name,
|
|
127
|
+
* while builtins already have both behaviors hardcoded — routing them
|
|
128
|
+
* through the plugin path would change engine semantics.
|
|
129
|
+
*/
|
|
130
|
+
isBuiltin(name: string): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* tag name → kind for every non-builtin registration: the parser's
|
|
133
|
+
* `extraTags`. Returns `null` when there are none, so the common case
|
|
134
|
+
* costs one size comparison and no allocation.
|
|
135
|
+
*/
|
|
136
|
+
customTags(): Map<string, NodeKind> | null;
|
|
137
|
+
/**
|
|
138
|
+
* Get a tag definition by name.
|
|
139
|
+
*/
|
|
140
|
+
get(name: string): TagDefinition | undefined;
|
|
141
|
+
/**
|
|
142
|
+
* Get a tag definition by semantic kind.
|
|
143
|
+
*/
|
|
144
|
+
getByKind(kind: NodeKind): TagDefinition | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* Check if a tag is registered.
|
|
147
|
+
*/
|
|
148
|
+
has(name: string): boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Get all registered tags.
|
|
151
|
+
*/
|
|
152
|
+
getAll(): TagDefinition[];
|
|
153
|
+
/**
|
|
154
|
+
* Get tags by category.
|
|
155
|
+
*/
|
|
156
|
+
getByCategory(category: string): TagDefinition[];
|
|
157
|
+
/**
|
|
158
|
+
* Get tags by whether they are inline.
|
|
159
|
+
*/
|
|
160
|
+
getInline(): TagDefinition[];
|
|
161
|
+
/**
|
|
162
|
+
* Get block-level tags.
|
|
163
|
+
*/
|
|
164
|
+
getBlock(): TagDefinition[];
|
|
165
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { DocumentModel } from './DocumentModel';
|
|
2
|
+
export type { DocumentModelOptions } from './DocumentModel';
|
|
3
|
+
export { TagRegistry } from './TagRegistry';
|
|
4
|
+
export type { TagDefinition, TagHandler, PropertyDefinition, TagHandlerContext } from './TagRegistry';
|
|
5
|
+
export { NodeFactory } from './NodeFactory';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — PluginAPI
|
|
3
|
+
*
|
|
4
|
+
* The public API exposed to plugins.
|
|
5
|
+
* Plugin authors use this to register tags, commands, validators, etc.
|
|
6
|
+
*
|
|
7
|
+
* Inspired by VSCode's `vscode` module.
|
|
8
|
+
*/
|
|
9
|
+
import { DocumentModel } from '../Model/DocumentModel';
|
|
10
|
+
import { TagRegistry } from '../Model/TagRegistry';
|
|
11
|
+
import { CommandRegistry } from '../Commands';
|
|
12
|
+
import { SemanticAnalyzer } from '../Semantic/SemanticAnalyzer';
|
|
13
|
+
import { Linter } from '../Linter/Linter';
|
|
14
|
+
import { RenderPipeline } from '../RenderPipeline/RenderPipeline';
|
|
15
|
+
import { PluginRegistry, type PluginManifest, type PluginContribution } from './PluginRegistry';
|
|
16
|
+
export declare class PluginAPI {
|
|
17
|
+
readonly model: DocumentModel;
|
|
18
|
+
readonly tags: TagRegistry;
|
|
19
|
+
readonly commands: CommandRegistry;
|
|
20
|
+
readonly semantic: SemanticAnalyzer;
|
|
21
|
+
readonly linter: Linter;
|
|
22
|
+
readonly renderer: RenderPipeline;
|
|
23
|
+
readonly plugins: PluginRegistry;
|
|
24
|
+
constructor(model: DocumentModel);
|
|
25
|
+
/**
|
|
26
|
+
* Register a plugin with all its contributions.
|
|
27
|
+
*
|
|
28
|
+
* Example:
|
|
29
|
+
* ```ts
|
|
30
|
+
* api.registerPlugin({
|
|
31
|
+
* name: 'my-plugin',
|
|
32
|
+
* version: '1.0.0'
|
|
33
|
+
* }, {
|
|
34
|
+
* tags: [{ name: 'blur', kind: 'custom', ... }],
|
|
35
|
+
* commands: [{ id: 'my-command', ... }]
|
|
36
|
+
* })
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
registerPlugin(manifest: PluginManifest, contributions: PluginContribution): void;
|
|
40
|
+
/**
|
|
41
|
+
* Unregister a plugin and remove its contributions.
|
|
42
|
+
*/
|
|
43
|
+
unregisterPlugin(name: string): void;
|
|
44
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — PluginRegistry
|
|
3
|
+
*
|
|
4
|
+
* Manages the lifecycle of plugins/extensions.
|
|
5
|
+
* Each plugin registers contributions (tags, commands, validators, etc.)
|
|
6
|
+
* and can be loaded/unloaded at runtime.
|
|
7
|
+
*
|
|
8
|
+
* Inspired by VSCode's extension system.
|
|
9
|
+
*/
|
|
10
|
+
import type { TagDefinition } from '../Model/TagRegistry';
|
|
11
|
+
import type { Command } from '../Commands/Command';
|
|
12
|
+
import type { Validator } from '../Semantic/SemanticAnalyzer';
|
|
13
|
+
import type { LintRule } from '../Linter/Linter';
|
|
14
|
+
import type { RenderHook } from '../RenderPipeline/RenderPipeline';
|
|
15
|
+
export interface PluginManifest {
|
|
16
|
+
name: string;
|
|
17
|
+
version: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
author?: string;
|
|
20
|
+
/** Dependencies on other plugins */
|
|
21
|
+
dependencies?: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface PluginContribution {
|
|
24
|
+
/** Tags to register */
|
|
25
|
+
tags?: TagDefinition[];
|
|
26
|
+
/** Commands to register */
|
|
27
|
+
commands?: Command[];
|
|
28
|
+
/** Semantic validators */
|
|
29
|
+
validators?: Validator[];
|
|
30
|
+
/** Lint rules */
|
|
31
|
+
lintRules?: LintRule[];
|
|
32
|
+
/** Render hooks */
|
|
33
|
+
renderHooks?: RenderHook[];
|
|
34
|
+
/** CSS to inject */
|
|
35
|
+
styles?: string[];
|
|
36
|
+
/** Initialization function */
|
|
37
|
+
activate?: () => void | Promise<void>;
|
|
38
|
+
/** Cleanup function */
|
|
39
|
+
deactivate?: () => void;
|
|
40
|
+
}
|
|
41
|
+
export interface Plugin {
|
|
42
|
+
manifest: PluginManifest;
|
|
43
|
+
contributions: PluginContribution;
|
|
44
|
+
/** Whether the plugin is currently active */
|
|
45
|
+
active: boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare class PluginRegistry {
|
|
48
|
+
private plugins;
|
|
49
|
+
/**
|
|
50
|
+
* Register a plugin.
|
|
51
|
+
*/
|
|
52
|
+
register(manifest: PluginManifest, contributions: PluginContribution): Plugin;
|
|
53
|
+
/**
|
|
54
|
+
* Unregister and deactivate a plugin.
|
|
55
|
+
*/
|
|
56
|
+
unregister(name: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Get a plugin by name.
|
|
59
|
+
*/
|
|
60
|
+
get(name: string): Plugin | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Get all registered plugins.
|
|
63
|
+
*/
|
|
64
|
+
getAll(): Plugin[];
|
|
65
|
+
/**
|
|
66
|
+
* Activate a plugin (calls activate function).
|
|
67
|
+
*/
|
|
68
|
+
activate(plugin: Plugin): void;
|
|
69
|
+
/**
|
|
70
|
+
* Deactivate a plugin (calls deactivate function).
|
|
71
|
+
*/
|
|
72
|
+
deactivate(plugin: Plugin): void;
|
|
73
|
+
/**
|
|
74
|
+
* Activate all registered plugins.
|
|
75
|
+
*/
|
|
76
|
+
activateAll(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Deactivate all plugins.
|
|
79
|
+
*/
|
|
80
|
+
deactivateAll(): void;
|
|
81
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — QueryEngine
|
|
3
|
+
*
|
|
4
|
+
* CSS-inspired query engine for the document tree.
|
|
5
|
+
* Enables queries like:
|
|
6
|
+
* query('paragraph > bold')
|
|
7
|
+
* query('quote text')
|
|
8
|
+
* query('[color]')
|
|
9
|
+
* query('list > *')
|
|
10
|
+
*
|
|
11
|
+
* Useful for:
|
|
12
|
+
* - Finding nodes by structure
|
|
13
|
+
* - AI context gathering
|
|
14
|
+
* - Plugin discovery
|
|
15
|
+
* - Lint rule targeting
|
|
16
|
+
*/
|
|
17
|
+
import { RedNode } from '../Syntax/RedNode';
|
|
18
|
+
import type { Query, QueryResult } from '../Types/queries';
|
|
19
|
+
export declare class QueryEngine {
|
|
20
|
+
/**
|
|
21
|
+
* Execute a query against a RedNode tree.
|
|
22
|
+
*/
|
|
23
|
+
execute(query: Query, root: RedNode): QueryResult;
|
|
24
|
+
/**
|
|
25
|
+
* Filter candidates by applying a query step's selectors.
|
|
26
|
+
*/
|
|
27
|
+
private matchStep;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a single node matches a single selector.
|
|
30
|
+
*/
|
|
31
|
+
private matchesSelector;
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { QueryEngine } from './QueryEngine';
|