astro-xmdx 0.0.2
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/index.ts +8 -0
- package/package.json +80 -0
- package/src/constants.ts +52 -0
- package/src/index.ts +150 -0
- package/src/pipeline/index.ts +38 -0
- package/src/pipeline/orchestrator.test.ts +324 -0
- package/src/pipeline/orchestrator.ts +121 -0
- package/src/pipeline/pipe.test.ts +251 -0
- package/src/pipeline/pipe.ts +70 -0
- package/src/pipeline/types.ts +59 -0
- package/src/plugins.test.ts +274 -0
- package/src/presets/index.ts +225 -0
- package/src/transforms/blocks-to-jsx.test.ts +590 -0
- package/src/transforms/blocks-to-jsx.ts +617 -0
- package/src/transforms/expressive-code.test.ts +274 -0
- package/src/transforms/expressive-code.ts +147 -0
- package/src/transforms/index.test.ts +143 -0
- package/src/transforms/index.ts +100 -0
- package/src/transforms/inject-components.test.ts +406 -0
- package/src/transforms/inject-components.ts +184 -0
- package/src/transforms/shiki.test.ts +289 -0
- package/src/transforms/shiki.ts +312 -0
- package/src/types.ts +92 -0
- package/src/utils/config.test.ts +252 -0
- package/src/utils/config.ts +146 -0
- package/src/utils/frontmatter.ts +33 -0
- package/src/utils/imports.test.ts +518 -0
- package/src/utils/imports.ts +201 -0
- package/src/utils/mdx-detection.test.ts +41 -0
- package/src/utils/mdx-detection.ts +209 -0
- package/src/utils/paths.test.ts +206 -0
- package/src/utils/paths.ts +92 -0
- package/src/utils/validation.test.ts +60 -0
- package/src/utils/validation.ts +15 -0
- package/src/vite-plugin/binding-loader.ts +81 -0
- package/src/vite-plugin/directive-rewriter.test.ts +331 -0
- package/src/vite-plugin/directive-rewriter.ts +272 -0
- package/src/vite-plugin/esbuild-pool.ts +173 -0
- package/src/vite-plugin/index.ts +37 -0
- package/src/vite-plugin/jsx-module.ts +106 -0
- package/src/vite-plugin/mdx-wrapper.ts +328 -0
- package/src/vite-plugin/normalize-config.test.ts +78 -0
- package/src/vite-plugin/normalize-config.ts +29 -0
- package/src/vite-plugin/shiki-highlighter.ts +46 -0
- package/src/vite-plugin/shiki-manager.test.ts +175 -0
- package/src/vite-plugin/shiki-manager.ts +53 -0
- package/src/vite-plugin/types.ts +189 -0
- package/src/vite-plugin.ts +1342 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages Shiki highlighter lifecycle as a lazy singleton.
|
|
3
|
+
* @module vite-plugin/shiki-manager
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { createShikiHighlighter } from './shiki-highlighter.js';
|
|
7
|
+
import type { ShikiHighlighter } from '../transforms/shiki.js';
|
|
8
|
+
|
|
9
|
+
export class ShikiManager {
|
|
10
|
+
private instance: Promise<ShikiHighlighter> | undefined;
|
|
11
|
+
private enabled: boolean;
|
|
12
|
+
|
|
13
|
+
constructor(enabled: boolean) {
|
|
14
|
+
this.enabled = enabled;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Returns the Shiki highlighter promise, initializing on first call.
|
|
19
|
+
* Returns null if Shiki is disabled or code has no `<pre>` tags.
|
|
20
|
+
*/
|
|
21
|
+
async getFor(code: string): Promise<ShikiHighlighter | null> {
|
|
22
|
+
if (!this.enabled || !ShikiManager.hasCodeBlocks(code)) return null;
|
|
23
|
+
if (!this.instance) {
|
|
24
|
+
this.instance = createShikiHighlighter();
|
|
25
|
+
}
|
|
26
|
+
return this.instance.catch(() => null);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Eagerly initializes the highlighter (e.g. in buildStart).
|
|
31
|
+
* Returns the resolved highlighter or null.
|
|
32
|
+
*/
|
|
33
|
+
async init(): Promise<ShikiHighlighter | null> {
|
|
34
|
+
if (!this.enabled) return null;
|
|
35
|
+
if (!this.instance) {
|
|
36
|
+
this.instance = createShikiHighlighter();
|
|
37
|
+
}
|
|
38
|
+
return this.instance.catch(() => null);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns the already-resolved highlighter for code with pre tags,
|
|
43
|
+
* using a pre-resolved instance to avoid extra awaits in hot paths.
|
|
44
|
+
*/
|
|
45
|
+
forCode(code: string, resolved: ShikiHighlighter | null): ShikiHighlighter | null {
|
|
46
|
+
if (!this.enabled || !resolved || !ShikiManager.hasCodeBlocks(code)) return null;
|
|
47
|
+
return resolved;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static hasCodeBlocks(code: string): boolean {
|
|
51
|
+
return /<pre[\s>]/.test(code);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for the Xmdx Vite plugin
|
|
3
|
+
* @module vite-plugin/types
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { DefaultTreeAdapterMap } from 'parse5';
|
|
7
|
+
import type { ComponentLibrary } from 'xmdx/registry';
|
|
8
|
+
import type { XmdxPlugin, MdxImportHandlingOptions } from '../types.js';
|
|
9
|
+
|
|
10
|
+
// Parse5 DOM types
|
|
11
|
+
export type DocumentFragment = DefaultTreeAdapterMap['documentFragment'];
|
|
12
|
+
export type Node = DefaultTreeAdapterMap['node'];
|
|
13
|
+
export type Element = DefaultTreeAdapterMap['element'];
|
|
14
|
+
export type TextNode = DefaultTreeAdapterMap['textNode'];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Native NAPI binding interface for Xmdx compiler.
|
|
18
|
+
*/
|
|
19
|
+
export interface XmdxBinding {
|
|
20
|
+
createCompiler?: (config: Record<string, unknown>) => XmdxCompiler;
|
|
21
|
+
XmdxCompiler?: new (config: Record<string, unknown>) => XmdxCompiler;
|
|
22
|
+
compileBatch: (
|
|
23
|
+
inputs: Array<{ id: string; source: string; filepath?: string }>,
|
|
24
|
+
options: { continueOnError: boolean; config: Record<string, unknown> }
|
|
25
|
+
) => BatchCompileResult;
|
|
26
|
+
compileBatchToModule: (
|
|
27
|
+
inputs: Array<{ id: string; source: string; filepath?: string }>,
|
|
28
|
+
options: { continueOnError: boolean; config: Record<string, unknown> }
|
|
29
|
+
) => ModuleBatchCompileResult;
|
|
30
|
+
compileMdxBatch: (
|
|
31
|
+
inputs: Array<{ id: string; source: string; filepath?: string }>,
|
|
32
|
+
options: { continueOnError: boolean; config: Record<string, unknown> }
|
|
33
|
+
) => MdxBatchCompileResult;
|
|
34
|
+
parseBlocks: (
|
|
35
|
+
source: string,
|
|
36
|
+
options: { enable_directives: boolean }
|
|
37
|
+
) => ParseBlocksResult;
|
|
38
|
+
parseFrontmatter: (source: string) => { frontmatter: Record<string, unknown> };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Compiler instance for single-file compilation.
|
|
43
|
+
*/
|
|
44
|
+
export interface XmdxCompiler {
|
|
45
|
+
compile: (
|
|
46
|
+
source: string,
|
|
47
|
+
filename: string,
|
|
48
|
+
options: { file?: string; url?: string }
|
|
49
|
+
) => CompileResult;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Result from single-file compilation.
|
|
54
|
+
*/
|
|
55
|
+
export interface CompileResult {
|
|
56
|
+
code: string;
|
|
57
|
+
map?: unknown;
|
|
58
|
+
frontmatter_json?: string;
|
|
59
|
+
headings?: Array<{ depth: number; slug: string; text: string }>;
|
|
60
|
+
imports?: Array<{ path: string }>;
|
|
61
|
+
diagnostics?: {
|
|
62
|
+
warnings?: Array<{ line: number; message: string }>;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Export specification from Rust compiler.
|
|
68
|
+
*/
|
|
69
|
+
export interface ExportSpec {
|
|
70
|
+
source: string;
|
|
71
|
+
isDefault: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Result from batch compilation.
|
|
76
|
+
*/
|
|
77
|
+
export interface BatchCompileResult {
|
|
78
|
+
results: Array<{
|
|
79
|
+
id: string;
|
|
80
|
+
result?: {
|
|
81
|
+
html: string;
|
|
82
|
+
frontmatterJson?: string;
|
|
83
|
+
headings?: Array<{ depth: number; slug: string; text: string }>;
|
|
84
|
+
hoistedImports?: Array<{ source: string; kind: string }>;
|
|
85
|
+
hoistedExports?: ExportSpec[];
|
|
86
|
+
hasUserDefaultExport?: boolean;
|
|
87
|
+
};
|
|
88
|
+
}>;
|
|
89
|
+
stats: {
|
|
90
|
+
succeeded: number;
|
|
91
|
+
total: number;
|
|
92
|
+
processingTimeMs: number;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Result from batch compilation to complete Astro modules.
|
|
98
|
+
* Unlike BatchCompileResult which returns IR, this returns complete module code.
|
|
99
|
+
*/
|
|
100
|
+
export interface ModuleBatchCompileResult {
|
|
101
|
+
results: Array<{
|
|
102
|
+
id: string;
|
|
103
|
+
result?: {
|
|
104
|
+
/** Complete Astro module code ready for esbuild */
|
|
105
|
+
code: string;
|
|
106
|
+
/** Source map (if available) */
|
|
107
|
+
map?: unknown;
|
|
108
|
+
/** Frontmatter as JSON string */
|
|
109
|
+
frontmatterJson: string;
|
|
110
|
+
/** Extracted headings */
|
|
111
|
+
headings: Array<{ depth: number; slug: string; text: string }>;
|
|
112
|
+
/** Imported modules */
|
|
113
|
+
imports: Array<{ path: string; kind: string }>;
|
|
114
|
+
/** Parse diagnostics */
|
|
115
|
+
diagnostics?: {
|
|
116
|
+
warnings?: Array<{ line: number; message: string }>;
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
error?: string;
|
|
120
|
+
}>;
|
|
121
|
+
stats: {
|
|
122
|
+
succeeded: number;
|
|
123
|
+
total: number;
|
|
124
|
+
failed: number;
|
|
125
|
+
processingTimeMs: number;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Result from MDX batch compilation using mdxjs-rs.
|
|
131
|
+
*/
|
|
132
|
+
export interface MdxBatchCompileResult {
|
|
133
|
+
results: Array<{
|
|
134
|
+
id: string;
|
|
135
|
+
result?: {
|
|
136
|
+
/** Compiled JavaScript code (full module with MDXContent) */
|
|
137
|
+
code: string;
|
|
138
|
+
/** Frontmatter as JSON string */
|
|
139
|
+
frontmatterJson: string;
|
|
140
|
+
/** Extracted headings */
|
|
141
|
+
headings: Array<{ depth: number; slug: string; text: string }>;
|
|
142
|
+
};
|
|
143
|
+
error?: string;
|
|
144
|
+
}>;
|
|
145
|
+
stats: {
|
|
146
|
+
succeeded: number;
|
|
147
|
+
total: number;
|
|
148
|
+
failed: number;
|
|
149
|
+
processingTimeMs: number;
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Result from parsing blocks.
|
|
155
|
+
*/
|
|
156
|
+
/** A render block from the Rust compiler. */
|
|
157
|
+
export interface RenderBlockData {
|
|
158
|
+
type: 'html' | 'component' | 'code';
|
|
159
|
+
content?: string;
|
|
160
|
+
name?: string;
|
|
161
|
+
props?: Record<string, unknown>;
|
|
162
|
+
slotChildren?: RenderBlockData[];
|
|
163
|
+
code?: string;
|
|
164
|
+
lang?: string;
|
|
165
|
+
meta?: string;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface ParseBlocksResult {
|
|
169
|
+
blocks: RenderBlockData[];
|
|
170
|
+
headings: Array<{ depth: number; slug: string; text: string }>;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Plugin options for the Xmdx Vite plugin.
|
|
175
|
+
*/
|
|
176
|
+
export interface XmdxPluginOptions {
|
|
177
|
+
include?: (id: string) => boolean;
|
|
178
|
+
libraries?: ComponentLibrary[];
|
|
179
|
+
starlightComponents?: boolean | { enabled?: boolean; components?: string[]; module?: string };
|
|
180
|
+
expressiveCode?: boolean | { enabled?: boolean; component?: string; module?: string };
|
|
181
|
+
compiler?: {
|
|
182
|
+
jsx?: {
|
|
183
|
+
code_sample_components?: string[];
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
plugins?: XmdxPlugin[];
|
|
187
|
+
binding?: XmdxBinding;
|
|
188
|
+
mdx?: MdxImportHandlingOptions;
|
|
189
|
+
}
|