@azerothjs/compiler 0.3.0-alpha.2 → 0.4.0-beta.1

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/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # @azerothjs/compiler
2
+
3
+ ## Overview
4
+
5
+ The `.azeroth` single-file-component compiler. A `.azeroth` file is a JavaScript
6
+ or TypeScript module written with AzerothJS markup, a JSX-style syntax. The
7
+ compiler locates the markup regions inside otherwise ordinary code and rewrites
8
+ them into `h()` hyperscript calls with fine-grained reactive bindings, leaving
9
+ the rest of the module byte-for-byte. For example:
10
+
11
+ ```
12
+ <h1>Count: {count()}</h1>
13
+ ```
14
+
15
+ compiles to:
16
+
17
+ ```js
18
+ h('h1', {}, 'Count: ', () => (count()))
19
+ ```
20
+
21
+ It has no runtime dependencies and is used both as a build-time tool (the Vite
22
+ plugin) and as the shared language core that the editor tooling reuses.
23
+
24
+ ## Architecture
25
+
26
+ The compiler does not have a type system, symbol table, or semantic analyzer. It
27
+ treats a `.azeroth` file as code with embedded markup and only transforms the
28
+ markup, which is why the rest of the module passes through unchanged. The
29
+ pipeline, in the order it runs:
30
+
31
+ 1. Scanner: finds markup regions inside arbitrary JavaScript, correctly skipping
32
+ strings, template literals, comments, and regular expressions, and detecting
33
+ whether a `<` begins markup or is a comparison or generic.
34
+ 2. Parser: turns a markup region into an AST (`parseMarkup`).
35
+ 3. Codegen: turns the AST into `h()` and component-call source, adding the
36
+ reactive wrapping (`() => (...)`) around dynamic expressions.
37
+ 4. Compile: orchestrates scan, parse, codegen, and splice back into the module,
38
+ producing the output plus a source map.
39
+
40
+ The scanner and parser are exported because the editor tooling
41
+ (`@azerothjs/language-service`) reuses them as its single source of truth for
42
+ markup behavior, rather than re-implementing a second parser that could drift.
43
+
44
+ ## Components
45
+
46
+ | File | Role |
47
+ | --- | --- |
48
+ | `scanner.ts` | Markup-region detection and the low-level skip helpers. |
49
+ | `parser.ts` | `parseMarkup` and `CompileError`. |
50
+ | `codegen.ts` | `generate`, `walkComponentTags`, the `ExpressionCompiler` hook. |
51
+ | `compile.ts` | `compile`: the end-to-end entry point and `CompileResult`. |
52
+ | `sourcemap.ts` | Source-map construction (VLQ encoding, mappings). |
53
+ | `vite.ts` | `azeroth`: the Vite plugin and its options. |
54
+ | `types.ts` | The markup AST node types and `Span`. |
55
+
56
+ ### Public API
57
+
58
+ - `compile(source, filename?)` returns the compiled module and its source map.
59
+ - `parseMarkup(source, start)` parses one markup region to an AST node.
60
+ - `generate(node, compileExpression)` emits source for a markup AST node.
61
+ - `walkComponentTags(...)` visits component tags in a region.
62
+ - The scanner helpers (`findMarkupStart`, `skipString`, `skipTemplate`,
63
+ `skipBalanced`, `skipRegex`, `isIdentStart`, `isIdentPart`, `isWhitespace`,
64
+ and the comment skippers) are exported for tooling that needs the same
65
+ scanning behavior.
66
+ - `azeroth(options?)` is the Vite plugin.
67
+
68
+ ## Building
69
+
70
+ ```sh
71
+ npm run build -w @azerothjs/compiler
72
+ ```
73
+
74
+ Several other packages (the language service and server, and anything importing
75
+ the AST or scanner) depend on the compiler being built first; the repository root
76
+ `npm run build` builds in dependency order.
77
+
78
+ ## Testing
79
+
80
+ ```sh
81
+ npx vitest run test/compiler
82
+ ```
83
+
84
+ ## Configuration
85
+
86
+ The Vite plugin (`azeroth`) compiles `.azeroth` files as part of a Vite build.
87
+ Add it to a project's `vite.config`:
88
+
89
+ ```ts
90
+ import { azeroth } from '@azerothjs/compiler';
91
+
92
+ export default {
93
+ plugins: [azeroth()]
94
+ };
95
+ ```
96
+
97
+ ## Examples
98
+
99
+ `examples/Showcase.azeroth` is a single comprehensive `.azeroth` file (a function
100
+ component and a class component) used to exercise both the compiler and the
101
+ editor tooling. Compile a string directly:
102
+
103
+ ```ts
104
+ import { compile } from '@azerothjs/compiler';
105
+
106
+ const { code, map } = compile('export default () => <h1>Hi {name()}</h1>;', 'App.azeroth');
107
+ ```
108
+
109
+ ## Contributing
110
+
111
+ The scanner is the trickiest part: it must distinguish markup from comparison and
112
+ generic syntax and skip every JavaScript token kind, because a mistake there
113
+ mis-compiles otherwise valid code. Keep its behavior covered by tests under
114
+ `test/compiler`, and remember that the language service depends on the exported
115
+ scanner and parser behaving exactly as the compiler uses them.
@@ -0,0 +1,45 @@
1
+ import type { MarkupElement, MarkupFragment } from './types.ts';
2
+ /**
3
+ * Recompiles arbitrary JS that may contain nested markup.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * // The identity compiler leaves plain expressions untouched.
8
+ * const identity: ExpressionCompiler = (code) => code;
9
+ * identity('count()'); // 'count()'
10
+ * ```
11
+ */
12
+ export type ExpressionCompiler = (code: string) => string;
13
+ /**
14
+ * Generates code for a markup element or fragment.
15
+ *
16
+ * @param node - The element/fragment AST node
17
+ * @param compileExpression - Recompiles nested-markup-bearing JS
18
+ *
19
+ * @returns A source string: `h(...)`, `Component({...})`, or for a fragment,
20
+ * an array `[...]`.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * const id = (code: string) => code;
25
+ * const { node } = parseMarkup('<h1>Hi</h1>', 0);
26
+ * generate(node, id); // "h('h1', { }, 'Hi')"
27
+ * ```
28
+ */
29
+ export declare function generate(node: MarkupElement | MarkupFragment, compileExpression: ExpressionCompiler): string;
30
+ /**
31
+ * Visits the markup element tree (not expression holes) and calls `visit`
32
+ * with the tag of every component (capitalised/dotted) element. Used by
33
+ * compile() to auto-import the built-in components a file references. Holes
34
+ * are handled by the caller's recursion.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * const { node } = parseMarkup('<Show><p>hi</p></Show>', 0);
39
+ * const tags: string[] = [];
40
+ * walkComponentTags(node, (tag) => tags.push(tag));
41
+ * tags; // ['Show'] (the lowercase <p> host element is skipped)
42
+ * ```
43
+ */
44
+ export declare function walkComponentTags(node: MarkupElement | MarkupFragment, visit: (tag: string) => void): void;
45
+ //# sourceMappingURL=codegen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACR,aAAa,EACb,cAAc,EAGjB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;AA2P1D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,GAAG,MAAM,CAoB5G;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,cAAc,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAa1G"}
@@ -0,0 +1,279 @@
1
+ // Turns a markup AST node into an h() (or component-call) source string. The
2
+ // reactivity rule for how each expression is emitted:
3
+ //
4
+ // - Event handlers (on*): passed through verbatim.
5
+ // - Function / bare-identifier expressions: passed through verbatim - they
6
+ // are already a getter, handler, or component reference.
7
+ // - Any other dynamic expression: wrapped as `() => (expr)` so h() treats it
8
+ // as reactive.
9
+ // - Static "string" attributes: kept as string literals.
10
+ //
11
+ // Expression holes can contain nested markup; we recompile their source via
12
+ // the `compileExpression` callback the caller passes in (which loops back to
13
+ // compile.ts), so `{cond && <p/>}` works.
14
+ /**
15
+ * True when `code` is an arrow/function literal - pass it through unwrapped.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * isFunctionLiteral('(item) => item.name'); // true
20
+ * isFunctionLiteral('count() + 1'); // false
21
+ * ```
22
+ */
23
+ function isFunctionLiteral(code) {
24
+ const t = code.trim();
25
+ if (/^async\s+function\b/.test(t) || /^function\b/.test(t)) {
26
+ return true;
27
+ }
28
+ // Arrow: `x => ...`, `(...) => ...`, `async x => ...`, `async (...) => ...`.
29
+ return /^(async\s+)?(\([^]*?\)|[A-Za-z_$][\w$]*)\s*=>/.test(t);
30
+ }
31
+ /**
32
+ * True when `code` is a single bare identifier or dotted path (e.g. `draft`, `props.x`).
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * isBareReference('props.value'); // true
37
+ * isBareReference('a + b'); // false
38
+ * ```
39
+ */
40
+ function isBareReference(code) {
41
+ return /^[A-Za-z_$][\w$]*(\s*\.\s*[A-Za-z_$][\w$]*)*$/.test(code.trim());
42
+ }
43
+ /**
44
+ * True when `code` is an array or object literal (`[...]` / `{...}`).
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * isCollectionLiteral('[resource]'); // true
49
+ * isCollectionLiteral('count()'); // false
50
+ * ```
51
+ */
52
+ function isCollectionLiteral(code) {
53
+ const t = code.trim();
54
+ return t.startsWith('[') || t.startsWith('{');
55
+ }
56
+ /**
57
+ * Decides how a dynamic `{expr}` is emitted. Passed through verbatim when it's
58
+ * already the right shape for the runtime:
59
+ * - an event handler,
60
+ * - a function literal (handler / render fn / key fn),
61
+ * - a bare reference (a signal getter, a component, props.x),
62
+ * - an array/object literal (e.g. `on={[res]}`, a props bag).
63
+ * Everything else is a computed value, wrapped in a getter so h() (and
64
+ * reactive props like `when`/`each`) stay fine-grained.
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * wrapDynamic('a + b', false); // '() => (a + b)' (computed -> wrapped)
69
+ * wrapDynamic('count', false); // 'count' (bare reference -> verbatim)
70
+ * wrapDynamic('save()', true); // 'save()' (event handler -> verbatim)
71
+ * ```
72
+ */
73
+ function wrapDynamic(code, isEventHandler) {
74
+ const compiled = code.trim();
75
+ if (isEventHandler ||
76
+ isFunctionLiteral(compiled) ||
77
+ isBareReference(compiled) ||
78
+ isCollectionLiteral(compiled)) {
79
+ return compiled;
80
+ }
81
+ return `() => (${compiled})`;
82
+ }
83
+ /**
84
+ * Quotes an object key when it isn't a valid bare identifier.
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * objectKey('class'); // 'class' (bare identifier, unquoted)
89
+ * objectKey('data-id'); // "'data-id'" (hyphen -> quoted)
90
+ * ```
91
+ */
92
+ function objectKey(name) {
93
+ return /^[A-Za-z_$][\w$]*$/.test(name) ? name : `'${name}'`;
94
+ }
95
+ /**
96
+ * True for an `on*` event attribute name (`on` + uppercase letter).
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * isEventName('onClick'); // true
101
+ * isEventName('online'); // false (third char is lowercase)
102
+ * ```
103
+ */
104
+ function isEventName(name) {
105
+ return name.length > 2 && name.startsWith('on') && name[2] === name[2].toUpperCase();
106
+ }
107
+ /**
108
+ * Escapes a literal string for emission inside single quotes.
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * quoteString('a\'b'); // "'a\\'b'" (the inner quote is escaped)
113
+ * ```
114
+ */
115
+ function quoteString(value) {
116
+ return `'${value.replace(/\\/g, '\\\\').replace(/'/g, '\\\'').replace(/\n/g, '\\n')}'`;
117
+ }
118
+ /**
119
+ * Emits one attribute as a `key: value` entry (or a spread).
120
+ *
121
+ * @example
122
+ * ```ts
123
+ * const id = (code: string) => code;
124
+ * generateAttribute(
125
+ * { kind: 'attribute', name: 'id', value: { kind: 'static', value: 'app' }, spread: false },
126
+ * id
127
+ * );
128
+ * // "id: 'app'"
129
+ * ```
130
+ */
131
+ function generateAttribute(attr, compileExpression) {
132
+ if (attr.spread) {
133
+ return `...${compileExpression(attr.value.code)}`;
134
+ }
135
+ const name = attr.name;
136
+ const key = objectKey(name);
137
+ if (attr.value.kind === 'none') {
138
+ return `${key}: true`;
139
+ }
140
+ if (attr.value.kind === 'static') {
141
+ return `${key}: ${quoteString(attr.value.value)}`;
142
+ }
143
+ // Expression value.
144
+ const compiled = compileExpression(attr.value.code);
145
+ return `${key}: ${wrapDynamic(compiled, isEventName(name))}`;
146
+ }
147
+ /**
148
+ * Builds the props object literal for an element/component.
149
+ *
150
+ * @example
151
+ * ```ts
152
+ * const id = (code: string) => code;
153
+ * generateProps(
154
+ * [{ kind: 'attribute', name: 'id', value: { kind: 'static', value: 'app' }, spread: false }],
155
+ * id
156
+ * );
157
+ * // "{ id: 'app' }"
158
+ * ```
159
+ */
160
+ function generateProps(attrs, compileExpression, extra) {
161
+ const parts = attrs.map(a => generateAttribute(a, compileExpression));
162
+ if (extra) {
163
+ parts.push(extra);
164
+ }
165
+ return `{ ${parts.join(', ')} }`;
166
+ }
167
+ /**
168
+ * Emits a single child as an argument to h() / an array element.
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * const id = (code: string) => code;
173
+ * generateChild({ kind: 'text', value: 'Hi', start: 0, end: 2 }, id); // "'Hi'"
174
+ * generateChild({ kind: 'expression', code: 'a + b', start: 0, end: 5 }, id); // '() => (a + b)'
175
+ * ```
176
+ */
177
+ function generateChild(child, compileExpression) {
178
+ if (child.kind === 'text') {
179
+ return quoteString(child.value);
180
+ }
181
+ if (child.kind === 'expression') {
182
+ const compiled = compileExpression(child.code);
183
+ return wrapDynamic(compiled, false);
184
+ }
185
+ return generate(child, compileExpression);
186
+ }
187
+ /**
188
+ * Generates the `children` entry for a component from its markup children. A
189
+ * lone function-hole child becomes the function itself (e.g.
190
+ * `<For>{(item) => ...}</For>`); anything else becomes a thunk returning the
191
+ * child (or an array of children).
192
+ *
193
+ * @example
194
+ * ```ts
195
+ * const id = (code: string) => code;
196
+ * // A lone function hole becomes the render function itself.
197
+ * generateComponentChildren([{ kind: 'expression', code: '(x) => x', start: 0, end: 8 }], id);
198
+ * // 'children: (x) => x'
199
+ * // Plain text becomes a thunk.
200
+ * generateComponentChildren([{ kind: 'text', value: 'Hi', start: 0, end: 2 }], id);
201
+ * // "children: () => 'Hi'"
202
+ * ```
203
+ */
204
+ function generateComponentChildren(children, compileExpression) {
205
+ if (children.length === 0) {
206
+ return null;
207
+ }
208
+ if (children.length === 1) {
209
+ const only = children[0];
210
+ if (only.kind === 'expression') {
211
+ const compiled = compileExpression(only.code).trim();
212
+ // A function child IS the render function (For/Match/etc.).
213
+ if (isFunctionLiteral(compiled)) {
214
+ return `children: ${compiled}`;
215
+ }
216
+ return `children: () => (${compiled})`;
217
+ }
218
+ return `children: () => ${generateChild(only, compileExpression)}`;
219
+ }
220
+ const items = children.map(c => generateChild(c, compileExpression));
221
+ return `children: () => [${items.join(', ')}]`;
222
+ }
223
+ /**
224
+ * Generates code for a markup element or fragment.
225
+ *
226
+ * @param node - The element/fragment AST node
227
+ * @param compileExpression - Recompiles nested-markup-bearing JS
228
+ *
229
+ * @returns A source string: `h(...)`, `Component({...})`, or for a fragment,
230
+ * an array `[...]`.
231
+ *
232
+ * @example
233
+ * ```ts
234
+ * const id = (code: string) => code;
235
+ * const { node } = parseMarkup('<h1>Hi</h1>', 0);
236
+ * generate(node, id); // "h('h1', { }, 'Hi')"
237
+ * ```
238
+ */
239
+ export function generate(node, compileExpression) {
240
+ if (node.kind === 'fragment') {
241
+ const items = node.children.map(c => generateChild(c, compileExpression));
242
+ return `[${items.join(', ')}]`;
243
+ }
244
+ if (node.isComponent) {
245
+ const childrenEntry = generateComponentChildren(node.children, compileExpression);
246
+ const props = generateProps(node.attributes, compileExpression, childrenEntry ?? undefined);
247
+ return `${node.tag}(${props})`;
248
+ }
249
+ // Host element -> h('tag', props, ...children).
250
+ const props = generateProps(node.attributes, compileExpression);
251
+ const children = node.children.map(c => generateChild(c, compileExpression));
252
+ const args = [`'${node.tag}'`, props, ...children];
253
+ return `h(${args.join(', ')})`;
254
+ }
255
+ /**
256
+ * Visits the markup element tree (not expression holes) and calls `visit`
257
+ * with the tag of every component (capitalised/dotted) element. Used by
258
+ * compile() to auto-import the built-in components a file references. Holes
259
+ * are handled by the caller's recursion.
260
+ *
261
+ * @example
262
+ * ```ts
263
+ * const { node } = parseMarkup('<Show><p>hi</p></Show>', 0);
264
+ * const tags: string[] = [];
265
+ * walkComponentTags(node, (tag) => tags.push(tag));
266
+ * tags; // ['Show'] (the lowercase <p> host element is skipped)
267
+ * ```
268
+ */
269
+ export function walkComponentTags(node, visit) {
270
+ if (node.kind === 'element' && node.isComponent) {
271
+ visit(node.tag);
272
+ }
273
+ for (const child of node.children) {
274
+ if (child.kind === 'element' || child.kind === 'fragment') {
275
+ walkComponentTags(child, visit);
276
+ }
277
+ }
278
+ }
279
+ //# sourceMappingURL=codegen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen.js","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { type SourceMapV3 } from './sourcemap.ts';
2
+ /** Result of compiling a `.azeroth` source string. */
3
+ export interface CompileResult {
4
+ /** The compiled JS/TS source. */
5
+ code: string;
6
+ /** Source map (original `.azeroth` -> compiled), or `null` when the file
7
+ * contained no markup (output is identical to input). */
8
+ map: SourceMapV3 | null;
9
+ }
10
+ /**
11
+ * Compiles a `.azeroth` source string: markup -> h() calls, with the `h`
12
+ * import auto-injected when needed.
13
+ *
14
+ * @param source - The `.azeroth` module source
15
+ *
16
+ * @returns The compiled JS/TS and its source map
17
+ *
18
+ * Without compile: author UI as nested h() calls by hand, wrapping every
19
+ * dynamic hole in a getter yourself:
20
+ *
21
+ * import { h } from '@azerothjs/core';
22
+ * export default () =>
23
+ * h('h1', { }, 'Hello ', () => (name())); // hand-write h() + getters, easy to get wrong
24
+ *
25
+ * With compile: write the markup in a `.azeroth` file and compile() emits the
26
+ * equivalent h() calls (and the `h` import) for you:
27
+ *
28
+ * const { code } = compile('export default () => <h1>Hello {name()}</h1>;');
29
+ * // code -> import { h } from '@azerothjs/core'; ... h('h1', { }, 'Hello ', () => (name()))
30
+ * // write JSX-like markup; the getters and the import are generated
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * const { code } = compile(`
35
+ * export default function Hi() {
36
+ * return <h1>Hello {name()}</h1>;
37
+ * }
38
+ * `);
39
+ * // code becomes:
40
+ * // import { h } from '@azerothjs/core';
41
+ * // export default function Hi() {
42
+ * // return h('h1', { }, 'Hello ', () => (name()));
43
+ * // }
44
+ * ```
45
+ */
46
+ export declare function compile(source: string, filename?: string): CompileResult;
47
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../src/compile.ts"],"names":[],"mappings":"AAiBA,OAAO,EAIH,KAAK,WAAW,EAEnB,MAAM,gBAAgB,CAAC;AAexB,sDAAsD;AACtD,MAAM,WAAW,aAAa;IAE1B,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IAEb;8DAC0D;IAC1D,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;CAC3B;AA8BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAmB,GAAG,aAAa,CAmFlF"}