satteri 0.8.1 → 0.9.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 (60) hide show
  1. package/README.md +35 -0
  2. package/dist/byte-writer.d.ts +31 -0
  3. package/dist/byte-writer.js +106 -0
  4. package/dist/child-stub.d.ts +17 -0
  5. package/dist/child-stub.js +57 -0
  6. package/dist/command-buffer.d.ts +23 -26
  7. package/dist/command-buffer.js +64 -132
  8. package/dist/compile.d.ts +5 -1
  9. package/dist/compile.js +40 -26
  10. package/dist/directive-types.d.ts +4 -2
  11. package/dist/generated/arena-layout.d.ts +37 -0
  12. package/dist/generated/arena-layout.js +41 -0
  13. package/dist/generated/wire-constants.d.ts +51 -0
  14. package/dist/generated/wire-constants.js +63 -0
  15. package/dist/handles.d.ts +21 -0
  16. package/dist/handles.js +1 -0
  17. package/dist/hast/child-stub.d.ts +18 -0
  18. package/dist/hast/child-stub.js +43 -0
  19. package/dist/hast/element-props.d.ts +2 -0
  20. package/dist/hast/element-props.js +23 -0
  21. package/dist/hast/generated/node-types.d.ts +14 -0
  22. package/dist/hast/generated/node-types.js +64 -0
  23. package/dist/hast/hast-materializer.d.ts +2 -1
  24. package/dist/hast/hast-materializer.js +9 -45
  25. package/dist/hast/hast-reader.d.ts +18 -23
  26. package/dist/hast/hast-reader.js +48 -115
  27. package/dist/hast/hast-visitor.d.ts +35 -13
  28. package/dist/hast/hast-visitor.js +395 -302
  29. package/dist/index.d.ts +10 -4
  30. package/dist/index.js +23 -1
  31. package/dist/lazy-child-resolver.d.ts +36 -0
  32. package/dist/lazy-child-resolver.js +95 -0
  33. package/dist/lazy-props.d.ts +1 -1
  34. package/dist/mdast/child-stub.d.ts +18 -0
  35. package/dist/mdast/child-stub.js +46 -0
  36. package/dist/mdast/column-align.d.ts +1 -0
  37. package/dist/mdast/column-align.js +6 -0
  38. package/dist/mdast/generated/layout.d.ts +19 -0
  39. package/dist/mdast/generated/layout.js +272 -0
  40. package/dist/mdast/generated/node-types.d.ts +58 -0
  41. package/dist/mdast/generated/node-types.js +266 -0
  42. package/dist/mdast/mdast-materializer.d.ts +3 -2
  43. package/dist/mdast/mdast-materializer.js +9 -93
  44. package/dist/mdast/mdast-reader.d.ts +4 -120
  45. package/dist/mdast/mdast-reader.js +45 -272
  46. package/dist/mdast/mdast-visitor.d.ts +52 -14
  47. package/dist/mdast/mdast-visitor.js +348 -427
  48. package/dist/mdx-attr.d.ts +2 -0
  49. package/dist/mdx-attr.js +20 -0
  50. package/dist/op-stream.d.ts +38 -0
  51. package/dist/op-stream.js +125 -0
  52. package/dist/phantom.d.ts +2 -0
  53. package/dist/phantom.js +13 -0
  54. package/dist/types.d.ts +34 -4
  55. package/dist/visitor-shared.d.ts +28 -0
  56. package/dist/visitor-shared.js +52 -0
  57. package/dist/wire-read.d.ts +27 -0
  58. package/dist/wire-read.js +59 -0
  59. package/index.js +52 -52
  60. package/package.json +6 -6
@@ -1,94 +1,9 @@
1
- // Node type discriminant values (must match NodeType enum in node.rs)
2
- export const NodeType = Object.freeze({
3
- Root: 0,
4
- Paragraph: 1,
5
- Heading: 2,
6
- ThematicBreak: 3,
7
- Blockquote: 4,
8
- List: 5,
9
- ListItem: 6,
10
- Html: 7,
11
- Code: 8,
12
- Definition: 9,
13
- Text: 10,
14
- Emphasis: 11,
15
- Strong: 12,
16
- InlineCode: 13,
17
- Break: 14,
18
- Link: 15,
19
- Image: 16,
20
- LinkReference: 17,
21
- ImageReference: 18,
22
- FootnoteDefinition: 19,
23
- FootnoteReference: 20,
24
- Table: 21,
25
- TableRow: 22,
26
- TableCell: 23,
27
- Delete: 24,
28
- Yaml: 25,
29
- Toml: 26,
30
- Math: 27,
31
- InlineMath: 28,
32
- // Directives
33
- ContainerDirective: 30,
34
- LeafDirective: 31,
35
- TextDirective: 32,
36
- // MDX
37
- MdxJsxFlowElement: 100,
38
- MdxJsxTextElement: 101,
39
- MdxFlowExpression: 102,
40
- MdxTextExpression: 103,
41
- MdxjsEsm: 104,
42
- });
43
- // Reverse map: number → string name
44
- export const NodeTypeName = Object.fromEntries(Object.entries(NodeType).map(([k, v]) => [v, k]));
45
- // MdastNode field offsets within NODE_STRUCT_SIZE bytes.
46
- // Must match MdastNode #[repr(C)] layout in node.rs:
47
- // id: u32 @ 0
48
- // node_type: u8 @ 4
49
- // _pad: [u8; 3] @ 5
50
- // parent: u32 @ 8
51
- // start_offset: u32 @ 12
52
- // end_offset: u32 @ 16
53
- // start_line: u32 @ 20
54
- // start_column: u32 @ 24
55
- // end_line: u32 @ 28
56
- // end_column: u32 @ 32
57
- // children_start: u32 @ 36
58
- // children_count: u32 @ 40
59
- // data_offset: u32 @ 44
60
- // data_len: u32 @ 48
61
- // Total: 52 bytes
62
- const FIELD = {
63
- id: 0,
64
- node_type: 4, // u8
65
- parent: 8,
66
- start_offset: 12,
67
- end_offset: 16,
68
- start_line: 20,
69
- start_column: 24,
70
- end_line: 28,
71
- end_column: 32,
72
- children_start: 36,
73
- children_count: 40,
74
- data_offset: 44,
75
- data_len: 48,
76
- };
77
- // BufferHeader field offsets (all u32, little-endian):
78
- // magic: [u8; 4] @ 0
79
- // kind: u32 @ 4 (1 = mdast, 2 = hast)
80
- // node_struct_size: u32 @ 8
81
- // node_count: u32 @ 12
82
- // nodes_offset: u32 @ 16
83
- // children_count: u32 @ 20
84
- // children_offset: u32 @ 24
85
- // type_data_len: u32 @ 28
86
- // type_data_offset: u32 @ 32
87
- // source_len: u32 @ 36
88
- // source_offset: u32 @ 40
89
- // Total: 44 bytes
90
- const MAGIC = 0x5241444d; // "MDAR" bytes [0x4d,0x44,0x41,0x52] read as little-endian u32
91
- const KIND_MDAST = 1;
1
+ import { restorePhantomSpaces } from "../phantom.js";
2
+ import { readPosition } from "../wire-read.js";
3
+ import { decodeColumnAlign } from "./column-align.js";
4
+ import { NodeTypeName } from "./generated/node-types.js";
5
+ import { ARENA_MAGIC, KIND_MDAST, FIELD, HEADER } from "../generated/arena-layout.js";
6
+ export { NodeType, NodeTypeName } from "./generated/node-types.js";
92
7
  export class MdastReader {
93
8
  #view;
94
9
  #header;
@@ -106,27 +21,27 @@ export class MdastReader {
106
21
  }
107
22
  #readHeader() {
108
23
  const v = this.#view;
109
- const magic = v.getUint32(0, true);
110
- if (magic !== MAGIC) {
111
- throw new Error(`Invalid buffer: bad magic 0x${magic.toString(16)}, expected 0x${MAGIC.toString(16)}`);
24
+ const magic = v.getUint32(HEADER.magic, true);
25
+ if (magic !== ARENA_MAGIC) {
26
+ throw new Error(`Invalid buffer: bad magic 0x${magic.toString(16)}, expected 0x${ARENA_MAGIC.toString(16)}`);
112
27
  }
113
- const kind = v.getUint32(4, true);
28
+ const kind = v.getUint32(HEADER.kind, true);
114
29
  if (kind !== KIND_MDAST) {
115
30
  throw new Error(`MdastReader was handed a buffer of kind ${kind} (expected ${KIND_MDAST}). ` +
116
31
  `MDAST and HAST node types overlap; reading the wrong kind decodes garbage.`);
117
32
  }
118
33
  return {
119
- nodeStructSize: v.getUint32(8, true),
120
- nodeCount: v.getUint32(12, true),
121
- nodesOffset: v.getUint32(16, true),
122
- childrenCount: v.getUint32(20, true),
123
- childrenOffset: v.getUint32(24, true),
124
- typeDataLen: v.getUint32(28, true),
125
- typeDataOffset: v.getUint32(32, true),
126
- sourceLen: v.getUint32(36, true),
127
- sourceOffset: v.getUint32(40, true),
128
- nodeDataCount: v.getUint32(44, true),
129
- nodeDataOffset: v.getUint32(48, true),
34
+ nodeStructSize: v.getUint32(HEADER.node_struct_size, true),
35
+ nodeCount: v.getUint32(HEADER.node_count, true),
36
+ nodesOffset: v.getUint32(HEADER.nodes_offset, true),
37
+ childrenCount: v.getUint32(HEADER.children_count, true),
38
+ childrenOffset: v.getUint32(HEADER.children_offset, true),
39
+ typeDataLen: v.getUint32(HEADER.type_data_len, true),
40
+ typeDataOffset: v.getUint32(HEADER.type_data_offset, true),
41
+ sourceLen: v.getUint32(HEADER.source_len, true),
42
+ sourceOffset: v.getUint32(HEADER.source_offset, true),
43
+ nodeDataCount: v.getUint32(HEADER.node_data_count, true),
44
+ nodeDataOffset: v.getUint32(HEADER.node_data_offset, true),
130
45
  };
131
46
  }
132
47
  #nodeDataTable = null;
@@ -181,25 +96,7 @@ export class MdastReader {
181
96
  const base = nodesOffset + nodeId * nodeStructSize;
182
97
  const v = this.#view;
183
98
  const type = v.getUint8(base + FIELD.node_type);
184
- const startLine = v.getUint32(base + FIELD.start_line, true);
185
- const startOffset = v.getUint32(base + FIELD.start_offset, true);
186
- // Sentinel: nodes with both line=0 and offset=0 are synthesized
187
- // without source position (e.g. GFM autolink-literal nodes that
188
- // remark-gfm produces via mdast-util-find-and-replace).
189
- const position = startLine === 0 && startOffset === 0
190
- ? undefined
191
- : {
192
- start: {
193
- offset: startOffset,
194
- line: startLine,
195
- column: v.getUint32(base + FIELD.start_column, true),
196
- },
197
- end: {
198
- offset: v.getUint32(base + FIELD.end_offset, true),
199
- line: v.getUint32(base + FIELD.end_line, true),
200
- column: v.getUint32(base + FIELD.end_column, true),
201
- },
202
- };
99
+ const position = readPosition(v, base + FIELD.start_offset);
203
100
  return {
204
101
  id: v.getUint32(base + FIELD.id, true),
205
102
  type,
@@ -217,15 +114,22 @@ export class MdastReader {
217
114
  const { nodesOffset, nodeStructSize } = this.#header;
218
115
  return this.#view.getUint8(nodesOffset + nodeId * nodeStructSize + FIELD.node_type);
219
116
  }
117
+ /** Fast path: read only the parent id for a node (0xffffffff at the root). */
118
+ getParentId(nodeId) {
119
+ const { nodesOffset, nodeStructSize } = this.#header;
120
+ return this.#view.getUint32(nodesOffset + nodeId * nodeStructSize + FIELD.parent, true);
121
+ }
220
122
  getChildIds(nodeId) {
221
- const node = this.getNode(nodeId);
222
- if (node.childrenCount === 0)
123
+ const { nodesOffset, nodeStructSize, childrenOffset } = this.#header;
124
+ const base = nodesOffset + nodeId * nodeStructSize;
125
+ const v = this.#view;
126
+ const childrenStart = v.getUint32(base + FIELD.children_start, true);
127
+ const childrenCount = v.getUint32(base + FIELD.children_count, true);
128
+ if (childrenCount === 0)
223
129
  return [];
224
- const { childrenOffset } = this.#header;
225
130
  const ids = [];
226
- for (let i = 0; i < node.childrenCount; i++) {
227
- const off = childrenOffset + (node.childrenStart + i) * 4;
228
- ids.push(this.#view.getUint32(off, true));
131
+ for (let i = 0; i < childrenCount; i++) {
132
+ ids.push(v.getUint32(childrenOffset + (childrenStart + i) * 4, true));
229
133
  }
230
134
  return ids;
231
135
  }
@@ -243,11 +147,13 @@ export class MdastReader {
243
147
  }
244
148
  }
245
149
  getTypeData(nodeId) {
246
- const node = this.getNode(nodeId);
247
- if (node.dataLen === 0)
150
+ const base = this.#header.nodesOffset + nodeId * this.#header.nodeStructSize;
151
+ const v = this.#view;
152
+ const dataOffset = v.getUint32(base + FIELD.data_offset, true);
153
+ const dataLen = v.getUint32(base + FIELD.data_len, true);
154
+ if (dataLen === 0)
248
155
  return new Uint8Array(0);
249
- const { typeDataOffset } = this.#header;
250
- return new Uint8Array(this.#view.buffer, this.#view.byteOffset + typeDataOffset + node.dataOffset, node.dataLen);
156
+ return new Uint8Array(v.buffer, v.byteOffset + this.#header.typeDataOffset + dataOffset, dataLen);
251
157
  }
252
158
  /** Read a StringRef (offset: u32 LE, len: u32 LE) from type data. */
253
159
  readStringRef(typeData, byteOffset = 0) {
@@ -257,12 +163,8 @@ export class MdastReader {
257
163
  len: view.getUint32(4, true),
258
164
  };
259
165
  }
260
- /** HeadingData: depth u8 @ 0. */
261
- getHeadingDepth(nodeId) {
262
- return this.getTypeData(nodeId)[0];
263
- }
264
166
  /**
265
- * StringRef value. Valid for Text, InlineCode, Html, Yaml, Toml, InlineMath nodes.
167
+ * StringRef value. Valid for Text, InlineCode, Html, Yaml, Toml nodes.
266
168
  * These store a single StringRef as their type data.
267
169
  */
268
170
  getTextValue(nodeId) {
@@ -270,79 +172,6 @@ export class MdastReader {
270
172
  const ref = this.readStringRef(data);
271
173
  return this.getString(ref.offset, ref.len);
272
174
  }
273
- /**
274
- * LinkData: url(0..8), title(8..16).
275
- * Valid for Link nodes.
276
- */
277
- getLinkData(nodeId) {
278
- const data = this.getTypeData(nodeId);
279
- const urlRef = this.readStringRef(data, 0);
280
- const titleRef = this.readStringRef(data, 8);
281
- return {
282
- url: this.getString(urlRef.offset, urlRef.len),
283
- title: titleRef.len > 0 ? this.getString(titleRef.offset, titleRef.len) : null,
284
- };
285
- }
286
- /**
287
- * ImageData: url(0..8), alt(8..16), title(16..24).
288
- * Valid for Image nodes.
289
- */
290
- getImageData(nodeId) {
291
- const data = this.getTypeData(nodeId);
292
- const urlRef = this.readStringRef(data, 0);
293
- const altRef = this.readStringRef(data, 8);
294
- const titleRef = this.readStringRef(data, 16);
295
- return {
296
- url: this.getString(urlRef.offset, urlRef.len),
297
- alt: this.getString(altRef.offset, altRef.len),
298
- title: titleRef.len > 0 ? this.getString(titleRef.offset, titleRef.len) : null,
299
- };
300
- }
301
- /**
302
- * CodeData #[repr(C)]: lang(0..8), meta(8..16), value(16..24), fence_char(24), _pad(25..28).
303
- * Valid for Code nodes.
304
- */
305
- getCodeData(nodeId) {
306
- const data = this.getTypeData(nodeId);
307
- const langRef = this.readStringRef(data, 0);
308
- const metaRef = this.readStringRef(data, 8);
309
- const valueRef = this.readStringRef(data, 16);
310
- return {
311
- lang: langRef.len > 0 ? this.getString(langRef.offset, langRef.len) : null,
312
- meta: metaRef.len > 0 ? this.getString(metaRef.offset, metaRef.len) : null,
313
- value: this.getString(valueRef.offset, valueRef.len),
314
- };
315
- }
316
- /**
317
- * MathData #[repr(C)]: meta(0..8), value(8..16).
318
- * Valid for Math nodes.
319
- */
320
- getMathData(nodeId) {
321
- const data = this.getTypeData(nodeId);
322
- const metaRef = this.readStringRef(data, 0);
323
- const valueRef = this.readStringRef(data, 8);
324
- return {
325
- meta: metaRef.len > 0 ? this.getString(metaRef.offset, metaRef.len) : null,
326
- value: this.getString(valueRef.offset, valueRef.len),
327
- };
328
- }
329
- /**
330
- * DefinitionData #[repr(C)]: url(0..8), title(8..16), identifier(16..24), label(24..32).
331
- * Valid for Definition nodes.
332
- */
333
- getDefinitionData(nodeId) {
334
- const data = this.getTypeData(nodeId);
335
- const urlRef = this.readStringRef(data, 0);
336
- const titleRef = this.readStringRef(data, 8);
337
- const identifierRef = this.readStringRef(data, 16);
338
- const labelRef = this.readStringRef(data, 24);
339
- return {
340
- url: this.getString(urlRef.offset, urlRef.len),
341
- title: titleRef.len > 0 ? this.getString(titleRef.offset, titleRef.len) : null,
342
- identifier: this.getString(identifierRef.offset, identifierRef.len),
343
- label: this.getString(labelRef.offset, labelRef.len),
344
- };
345
- }
346
175
  /**
347
176
  * ListData #[repr(C)]: start(0..4), ordered(4), spread(5), _pad(6..8).
348
177
  * Valid for List nodes.
@@ -368,52 +197,6 @@ export class MdastReader {
368
197
  spread: data[1] !== 0,
369
198
  };
370
199
  }
371
- /**
372
- * ReferenceData #[repr(C)]: identifier(0..8), label(8..16), reference_kind(16), _pad(17..20).
373
- * referenceKind: 0=shortcut, 1=collapsed, 2=full.
374
- * Valid for LinkReference, ImageReference, FootnoteReference nodes.
375
- */
376
- getReferenceData(nodeId) {
377
- const data = this.getTypeData(nodeId);
378
- const identifierRef = this.readStringRef(data, 0);
379
- const labelRef = this.readStringRef(data, 8);
380
- const kindByte = data[16];
381
- const referenceTypes = ["shortcut", "collapsed", "full"];
382
- return {
383
- identifier: this.getString(identifierRef.offset, identifierRef.len),
384
- label: this.getString(labelRef.offset, labelRef.len),
385
- referenceType: referenceTypes[kindByte] ?? "shortcut",
386
- };
387
- }
388
- /**
389
- * ImageReference layout: 20-byte ReferenceData header + 8-byte alt StringRef.
390
- * Parser-emitted image references carry alt inline; plugin-created ones
391
- * may lack this suffix, in which case `alt` is empty.
392
- */
393
- getImageReferenceData(nodeId) {
394
- const base = this.getReferenceData(nodeId);
395
- const data = this.getTypeData(nodeId);
396
- if (data.length >= 28) {
397
- const altRef = this.readStringRef(data, 20);
398
- return {
399
- ...base,
400
- alt: this.getString(altRef.offset, altRef.len),
401
- };
402
- }
403
- return { ...base, alt: "" };
404
- }
405
- /**
406
- * FootnoteDefinitionData #[repr(C)]: identifier(0..8), label(8..16).
407
- */
408
- getFootnoteDefinitionData(nodeId) {
409
- const data = this.getTypeData(nodeId);
410
- const identifierRef = this.readStringRef(data, 0);
411
- const labelRef = this.readStringRef(data, 8);
412
- return {
413
- identifier: this.getString(identifierRef.offset, identifierRef.len),
414
- label: this.getString(labelRef.offset, labelRef.len),
415
- };
416
- }
417
200
  /**
418
201
  * TableData #[repr(C)]: align_count(0..4), then align_count bytes.
419
202
  * Alignment bytes: 0=none, 1=left, 2=right, 3=center.
@@ -424,10 +207,9 @@ export class MdastReader {
424
207
  return [];
425
208
  const view = new DataView(data.buffer, data.byteOffset);
426
209
  const count = view.getUint32(0, true);
427
- const alignNames = [null, "left", "right", "center"];
428
210
  const result = [];
429
211
  for (let i = 0; i < count; i++) {
430
- result.push(alignNames[data[4 + i]] ?? null);
212
+ result.push(decodeColumnAlign(data[4 + i]));
431
213
  }
432
214
  return result;
433
215
  }
@@ -485,14 +267,14 @@ export class MdastReader {
485
267
  name: this.getString(attrNameRef.offset, attrNameRef.len),
486
268
  value: {
487
269
  type: "mdxJsxAttributeValueExpression",
488
- value: this.getString(attrValueRef.offset, attrValueRef.len).replaceAll("", " "),
270
+ value: restorePhantomSpaces(this.getString(attrValueRef.offset, attrValueRef.len)),
489
271
  },
490
272
  });
491
273
  break;
492
274
  case 3: // Spread
493
275
  attributes.push({
494
276
  type: "mdxJsxExpressionAttribute",
495
- value: this.getString(attrValueRef.offset, attrValueRef.len).replaceAll("", " "),
277
+ value: restorePhantomSpaces(this.getString(attrValueRef.offset, attrValueRef.len)),
496
278
  });
497
279
  break;
498
280
  }
@@ -525,15 +307,6 @@ export class MdastReader {
525
307
  }
526
308
  return { name, attributes };
527
309
  }
528
- /**
529
- * ExpressionData #[repr(C)]: value StringRef (0..8).
530
- * Valid for MdxFlowExpression, MdxTextExpression, MdxjsEsm.
531
- */
532
- getExpressionValue(nodeId) {
533
- const data = this.getTypeData(nodeId);
534
- const valueRef = this.readStringRef(data, 0);
535
- return this.getString(valueRef.offset, valueRef.len).replaceAll("", " ");
536
- }
537
310
  /**
538
311
  * Walk the tree depth-first. Return false from visitor to skip children.
539
312
  */
@@ -1,10 +1,21 @@
1
+ import { MdastReader } from "./mdast-reader.js";
1
2
  import { CommandBuffer } from "../command-buffer.js";
2
- import type { MdastNode, Toml, MathNode, InlineMath } from "../types.js";
3
- import type { Blockquote, Break, Code, Definition, Delete, Emphasis, FootnoteDefinition, FootnoteReference, Heading, Html, Image, ImageReference, InlineCode, Link, LinkReference, List, ListItem, Paragraph, Strong, Table, TableRow, TableCell, Text, ThematicBreak, Yaml } from "mdast";
3
+ import type { MdastNode, Toml, MathNode, InlineMath, Superscript, Subscript, Data } from "../types.js";
4
+ import { LazyChildResolver } from "../lazy-child-resolver.js";
5
+ import type { MdastHandle } from "../handles.js";
6
+ import type { Blockquote, Break, Code, Definition, Delete, Emphasis, FootnoteDefinition, FootnoteReference, Heading, Html, Image, ImageReference, InlineCode, Link, LinkReference, List, ListItem, Paragraph, Strong, Table, TableRow, TableCell, Text, ThematicBreak, Yaml, Parents as MdastParents, Root as MdastRoot } from "mdast";
4
7
  import type { MdxJsxFlowElement, MdxJsxTextElement } from "../mdx-types.js";
5
8
  import type { MdxFlowExpression, MdxTextExpression } from "../mdx-types.js";
6
9
  import type { MdxjsEsm } from "../mdx-types.js";
7
10
  import type { ContainerDirective, LeafDirective, TextDirective } from "../directive-types.js";
11
+ /** New content for a structural mutation: a declarative node, or a raw markdown
12
+ * / HTML escape hatch. Declarative nodes compile to the op-stream; a type the
13
+ * op-stream can't encode is a hard error. */
14
+ export type MdastContent = MdastNode | {
15
+ raw: string;
16
+ } | {
17
+ rawHtml: string;
18
+ };
8
19
  export interface MdastDiagnostic {
9
20
  message: string;
10
21
  nodeId?: number | undefined;
@@ -19,29 +30,56 @@ export declare class MdastVisitorContext {
19
30
  * decoded filesystem path.
20
31
  */
21
32
  readonly fileURL: URL | undefined;
22
- constructor(handle: MdastHandle, getSource: () => string, fileURL: URL | undefined);
33
+ /**
34
+ * Document-level data bag, shared across every plugin in the compile and
35
+ * across the mdast→hast phase boundary. Mutate keys directly
36
+ * (`ctx.data.foo = x`); the bag itself isn't reassignable. Values are kept
37
+ * on the JS side, so any value is allowed, including functions and class
38
+ * instances. Returned to the caller as `result.data`.
39
+ */
40
+ readonly data: Data;
41
+ constructor(handle: MdastHandle, getSource: () => string, fileURL: URL | undefined, resolver: LazyChildResolver<MdastReader, MdastNode>, data: Data);
23
42
  get source(): string;
24
43
  removeNode(node: Readonly<MdastNode>): void;
25
- insertBefore(node: Readonly<MdastNode>, newNode: MdastNode | MdastNode[]): void;
26
- insertAfter(node: Readonly<MdastNode>, newNode: MdastNode | MdastNode[]): void;
44
+ insertBefore(node: Readonly<MdastNode>, newNode: MdastContent | MdastContent[]): void;
45
+ insertAfter(node: Readonly<MdastNode>, newNode: MdastContent | MdastContent[]): void;
27
46
  /**
28
47
  * Wrap `node` in `parentNode`, making it `parentNode`'s first child. Any
29
48
  * children `parentNode` declares are kept after it.
30
49
  */
31
- wrapNode(node: Readonly<MdastNode>, parentNode: MdastNode): void;
32
- prependChild(node: Readonly<MdastNode>, childNode: MdastNode | MdastNode[]): void;
33
- appendChild(node: Readonly<MdastNode>, childNode: MdastNode | MdastNode[]): void;
50
+ wrapNode(node: Readonly<MdastNode>, parentNode: MdastContent): void;
51
+ prependChild(node: Readonly<MdastNode>, childNode: MdastContent | MdastContent[]): void;
52
+ appendChild(node: Readonly<MdastNode>, childNode: MdastContent | MdastContent[]): void;
34
53
  /** Insert one node or an array at `index`; clamps (`0` or less prepends, past the end appends). */
35
- insertChildAt(node: Readonly<MdastNode>, index: number, childNode: MdastNode | MdastNode[]): void;
54
+ insertChildAt(node: Readonly<MdastNode>, index: number, childNode: MdastContent | MdastContent[]): void;
36
55
  /** Remove the `index`-th child of `node`; a no-op when there is no such child. */
37
56
  removeChildAt(node: Readonly<MdastNode>, index: number): void;
38
- replaceNode(node: Readonly<MdastNode>, newNode: MdastNode): void;
57
+ replaceNode(node: Readonly<MdastNode>, newNode: MdastContent): void;
39
58
  setProperty<N extends MdastNode, K extends keyof N & string>(node: Readonly<N>, key: K, value: N[K]): void;
59
+ /** `children` is structural and every parent accepts it, so the key also
60
+ * works on node-type unions (e.g. a node returned by `parent()`). */
61
+ setProperty(node: Readonly<MdastNode>, key: "children", value: readonly MdastNode[]): void;
62
+ /** `data` is an open per-node bag serialized to JSON on the wire, so it
63
+ * accepts any record (hName/hProperties/custom fields), not just the node's
64
+ * declared `data` shape. `null` clears it. */
65
+ setProperty(node: Readonly<MdastNode>, key: "data", value: Record<string, unknown> | null): void;
40
66
  /** Collect the concatenated text of all descendant text nodes (like mdast-util-to-string). */
41
67
  textContent(node: Readonly<MdastNode>, options?: {
42
68
  includeImageAlt?: boolean;
43
69
  includeHtml?: boolean;
44
70
  }): string;
71
+ /**
72
+ * The parent of a node, or `undefined` at the root. Within a pass the same
73
+ * parent is always the same object, so visitors on sibling nodes can dedupe
74
+ * by identity.
75
+ */
76
+ parent<N extends Exclude<MdastNode, MdastRoot>>(node: Readonly<N>): Readonly<MdastParents>;
77
+ parent(node: Readonly<MdastNode>): Readonly<MdastParents> | undefined;
78
+ /**
79
+ * Index of `node` within its parent's children, or `undefined` at the root.
80
+ * Use this rather than `parent.children.indexOf(node)`, which won't find it.
81
+ */
82
+ indexOf(node: Readonly<MdastNode>): number | undefined;
45
83
  report({ message, node, severity, }: {
46
84
  message: string;
47
85
  node?: Readonly<MdastNode>;
@@ -89,6 +127,8 @@ export interface MdastPluginInstance {
89
127
  containerDirective?: MdastVisitorFn<ContainerDirective>;
90
128
  leafDirective?: MdastVisitorFn<LeafDirective>;
91
129
  textDirective?: MdastVisitorFn<TextDirective>;
130
+ superscript?: MdastVisitorFn<Superscript>;
131
+ subscript?: MdastVisitorFn<Subscript>;
92
132
  mdxJsxFlowElement?: MdastVisitorFn<MdxJsxFlowElement>;
93
133
  mdxJsxTextElement?: MdastVisitorFn<MdxJsxTextElement>;
94
134
  mdxFlowExpression?: MdastVisitorFn<MdxFlowExpression>;
@@ -101,12 +141,11 @@ interface MdastVisitResult {
101
141
  diagnostics: MdastDiagnostic[];
102
142
  hasMutations: boolean;
103
143
  }
104
- export type MdastHandle = any;
144
+ export type { MdastHandle };
105
145
  interface MdastSubscription {
106
146
  nodeType: number;
107
147
  visitFn: (node: MdastNode, context: MdastVisitorContext) => unknown;
108
148
  }
109
- /** Resolve subscriptions from a plugin instance. */
110
149
  export declare function resolveMdastSubscriptions(plugin: MdastPluginInstance): MdastSubscription[];
111
150
  /**
112
151
  * Walk an MDAST handle in Rust, dispatch matched nodes to JS visitor functions,
@@ -115,5 +154,4 @@ export declare function resolveMdastSubscriptions(plugin: MdastPluginInstance):
115
154
  * Returns MdastVisitResult synchronously if all visitors are sync,
116
155
  * or Promise<MdastVisitResult> if any visitor is async.
117
156
  */
118
- export declare function visitMdastHandle(handle: MdastHandle, plugin: MdastPluginInstance, subs: MdastSubscription[], source: string | (() => string), fileURL: URL | undefined): MdastVisitResult | Promise<MdastVisitResult>;
119
- export {};
157
+ export declare function visitMdastHandle(handle: MdastHandle, plugin: MdastPluginInstance, subs: MdastSubscription[], source: string | (() => string), fileURL: URL | undefined, data?: Data): MdastVisitResult | Promise<MdastVisitResult>;