@markuplint/ml-ast 5.0.0-rc.2 → 5.0.0-rc.5

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.
@@ -1,214 +0,0 @@
1
- # Maintenance Guide
2
-
3
- Practical operations and maintenance guide for `@markuplint/ml-ast`.
4
-
5
- ## Commands
6
-
7
- | Command | Description |
8
- | --------------------------------------------- | ---------------------------- |
9
- | `yarn build --scope @markuplint/ml-ast` | Compile TypeScript to `lib/` |
10
- | `yarn workspace @markuplint/ml-ast run dev` | Watch mode compilation |
11
- | `yarn workspace @markuplint/ml-ast run clean` | Clean compiled output |
12
-
13
- ## Testing
14
-
15
- This package has **no test files**. It is a pure type-definition package, so correctness is verified by the TypeScript compiler during build. Integration testing is performed by downstream packages that consume these types.
16
-
17
- To verify type correctness:
18
-
19
- ```bash
20
- yarn build --scope @markuplint/ml-ast
21
- ```
22
-
23
- ## Common Recipes
24
-
25
- ### 1. Adding a New Node Type
26
-
27
- To add a new AST node type (e.g., a hypothetical `MLASTDirective`):
28
-
29
- 1. **Add the type value to `MLASTNodeType`** in `src/types.ts`:
30
-
31
- ```typescript
32
- export type MLASTNodeType =
33
- | 'doctype'
34
- | 'starttag'
35
- // ... existing values
36
- | 'directive'; // Add here
37
- ```
38
-
39
- 2. **Define the interface** extending `MLASTAbstractNode`:
40
-
41
- ```typescript
42
- export interface MLASTDirective extends MLASTAbstractNode {
43
- readonly type: 'directive';
44
- readonly depth: number;
45
- // Add type-specific fields
46
- }
47
- ```
48
-
49
- 3. **Add to relevant union types**:
50
- - `MLASTNode` -- Always add to this union
51
- - `MLASTChildNode` -- If it can be a child of elements
52
- - `MLASTNodeTreeItem` -- If it can appear at the top level of `nodeList`
53
- - `MLASTParentNode` -- If it can contain child nodes
54
-
55
- 4. **Update `ml-core`'s `createNode()`** in `packages/@markuplint/ml-core/src/ml-dom/helper/create-node.ts`:
56
- - Add a `case` for the new type value in the `switch` statement
57
- - Create or reuse an appropriate DOM node class
58
-
59
- 5. **Update parsers** that should produce this node type
60
-
61
- 6. **Build and verify**:
62
- ```bash
63
- yarn build --scope @markuplint/ml-ast
64
- yarn build --scope @markuplint/ml-core
65
- ```
66
-
67
- ### 2. Adding a Field to an Existing Node Type
68
-
69
- To add a new field to an existing node interface:
70
-
71
- 1. **Add the field** to the interface in `src/types.ts`:
72
-
73
- ```typescript
74
- export interface MLASTElement extends MLASTAbstractNode {
75
- // ... existing fields
76
- readonly newField: string; // Required field
77
- readonly optionalField?: boolean; // Optional field (prefer for backward compat)
78
- }
79
- ```
80
-
81
- 2. **Prefer optional fields** (`?`) for backward compatibility -- existing parsers will not break if the field is missing.
82
-
83
- 3. **Update parsers** that should populate the new field.
84
-
85
- 4. **Update `ml-core`** if the field affects DOM node creation or behavior.
86
-
87
- 5. **Build the full chain**:
88
- ```bash
89
- yarn build --scope @markuplint/ml-ast
90
- yarn build --scope @markuplint/ml-core
91
- ```
92
-
93
- ### 3. Adding a New Attribute Variant
94
-
95
- To add a new attribute type alongside `MLASTHTMLAttr` and `MLASTSpreadAttr`:
96
-
97
- 1. **Add the type value to `MLASTNodeType`** (if not already present)
98
-
99
- 2. **Define the interface** extending `MLASTToken`:
100
-
101
- ```typescript
102
- export interface MLASTNewAttr extends MLASTToken {
103
- readonly type: 'newattr';
104
- readonly nodeName: string;
105
- // Add attribute-specific fields
106
- }
107
- ```
108
-
109
- 3. **Add to `MLASTAttr` union**:
110
-
111
- ```typescript
112
- export type MLASTAttr = MLASTHTMLAttr | MLASTSpreadAttr | MLASTNewAttr;
113
- ```
114
-
115
- 4. **Update downstream consumers** that switch on attribute types
116
-
117
- 5. **Build and verify**
118
-
119
- ### 4. Adding a `PreprocessorSpecificBlockConditionalType` Value
120
-
121
- To add a new conditional type value for preprocessor blocks:
122
-
123
- 1. **Add the value** to `MLASTPreprocessorSpecificBlockConditionalType` in `src/types.ts`:
124
-
125
- ```typescript
126
- export type MLASTPreprocessorSpecificBlockConditionalType =
127
- | 'if'
128
- | 'if:elseif'
129
- // ... existing values
130
- | 'newvalue' // Add here
131
- | null;
132
- ```
133
-
134
- 2. **Update the parser** that produces blocks with this conditional type
135
-
136
- 3. **Update `ml-core`** if the new value requires special handling during DOM creation
137
-
138
- 4. **Build and verify**:
139
- ```bash
140
- yarn build --scope @markuplint/ml-ast
141
- ```
142
-
143
- ### 5. Modifying the `MLParser` Interface
144
-
145
- When changing the parser interface:
146
-
147
- 1. **Make changes** to `MLParser` in `src/types.ts`
148
-
149
- 2. **Consider backward compatibility**:
150
- - Adding optional fields is safe
151
- - Adding required fields or changing signatures is a breaking change
152
-
153
- 3. **Update all parser implementations**:
154
- - `@markuplint/html-parser`
155
- - `@markuplint/jsx-parser`
156
- - `@markuplint/vue-parser`
157
- - `@markuplint/svelte-parser`
158
- - `@markuplint/astro-parser`
159
- - `@markuplint/pug-parser`
160
- - `@markuplint/parser-utils`
161
-
162
- 4. **Build all affected packages**:
163
- ```bash
164
- yarn build
165
- ```
166
-
167
- ## Downstream Impact Checklist
168
-
169
- When modifying types in this package, verify that these downstream packages still build and pass tests:
170
-
171
- - [ ] `@markuplint/html-parser` -- HTML parser
172
- - [ ] `@markuplint/parser-utils` -- Parser utility functions
173
- - [ ] `@markuplint/jsx-parser` -- JSX parser
174
- - [ ] `@markuplint/astro-parser` -- Astro parser
175
- - [ ] `@markuplint/vue-parser` -- Vue SFC parser
176
- - [ ] `@markuplint/svelte-parser` -- Svelte parser
177
- - [ ] `@markuplint/pug-parser` -- Pug parser
178
- - [ ] `@markuplint/ml-core` -- Core DOM mapping (most critical)
179
- - [ ] `@markuplint/ml-config` -- Configuration types
180
- - [ ] `@markuplint/ml-spec` -- Specification types
181
- - [ ] `@markuplint/file-resolver` -- File resolution
182
-
183
- The most critical downstream package is `@markuplint/ml-core`, which contains `createNode()` -- the function that maps AST nodes to DOM nodes via a `switch` statement on `node.type`.
184
-
185
- ## Troubleshooting
186
-
187
- ### Build Errors After Type Changes
188
-
189
- **Symptom:** Downstream packages fail to build after modifying types.
190
-
191
- **Diagnosis:**
192
-
193
- 1. Build this package first: `yarn build --scope @markuplint/ml-ast`
194
- 2. Build `ml-core` next: `yarn build --scope @markuplint/ml-core`
195
- 3. Check for `switch` exhaustiveness errors -- TypeScript will report if a `switch` on `node.type` is missing a case for a new type value
196
- 4. Check for union type mismatches -- adding a type to a union may cause existing narrowing code to need updates
197
-
198
- ### Missing Case in ml-core's `createNode()`
199
-
200
- **Symptom:** `TypeError: Invalid AST node types "newtype"` at runtime.
201
-
202
- **Cause:** A new node type was added to `MLASTNodeType` and the relevant union types, but `ml-core`'s `createNode()` switch statement was not updated.
203
-
204
- **Fix:** Add a `case` for the new type in `packages/@markuplint/ml-core/src/ml-dom/helper/create-node.ts`.
205
-
206
- ### Parser Not Producing Expected Nodes
207
-
208
- **Symptom:** A parser does not produce nodes with newly added fields or types.
209
-
210
- **Diagnosis:**
211
-
212
- 1. Check that the parser implementation has been updated to populate new fields
213
- 2. For optional fields, verify that the field is not silently `undefined`
214
- 3. Build both the parser and this package to ensure type alignment