@macroforge/svelte-preprocessor 0.1.78 → 0.1.80

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 CHANGED
@@ -1,37 +1,10 @@
1
1
  # @macroforge/svelte-preprocessor
2
2
 
3
- Svelte preprocessor for expanding Macroforge macros in component script blocks
4
-
5
3
  [![npm version](https://badge.fury.io/js/%40macroforge%2Fsvelte-preprocessor.svg)](https://www.npmjs.com/package/@macroforge/svelte-preprocessor)
6
4
 
7
5
  ## Overview
8
6
 
9
- @macroforge/svelte-preprocessor
10
-
11
- Svelte preprocessor for expanding Macroforge macros in component script blocks.
12
-
13
- This module provides integration between Macroforge's macro expansion system and
14
- Svelte's preprocessing pipeline. It intercepts `<script>` blocks in `.svelte`
15
- files, detects `@derive` decorators, and expands them into generated code before
16
- TypeScript compilation occurs.
17
-
18
- ## How It Works
19
-
20
- 1. The preprocessor is registered in `svelte.config.js` as part of the
21
- preprocess array
22
- 2. When Svelte compiles a component, it passes each `<script>` block to this
23
- preprocessor
24
- 3. The preprocessor checks if the script contains `@derive` decorators
25
- 4. If found, it calls the native `macroforge` binding to expand the macros
26
- 5. The expanded code replaces the original script content
27
-
28
- ## Important Notes
29
-
30
- - Must be placed BEFORE other preprocessors (like `vitePreprocess()`) in the
31
- chain
32
- - Uses lazy-loading for native bindings to avoid initialization overhead
33
- - Gracefully degrades if native bindings are unavailable
34
- - Only processes TypeScript blocks by default (configurable via options)
7
+ Svelte preprocessor for expanding Macroforge macros in component script blocks
35
8
 
36
9
  ## Installation
37
10
 
@@ -43,23 +16,17 @@ npm install @macroforge/svelte-preprocessor
43
16
 
44
17
  ### Functions
45
18
 
46
- - **`macroforgePreprocess`** - Whether to preserve `@derive` decorators in the
47
- expanded output.
19
+ - **`macroforgePreprocess`** - Creates a Svelte preprocessor that expands
20
+ Macroforge macros in `<script>` blocks.
48
21
 
49
- ### Types
22
+ ### Interfaces
50
23
 
51
- - **`ExpandResult`** - Whether to preserve `@derive` decorators in the expanded
52
- output.
53
24
  - **`MacroforgePreprocessorOptions`** - Configuration options for the Macroforge
54
25
  Svelte preprocessor.
55
26
 
56
- ## Examples
27
+ ### Constants
57
28
 
58
- ```typescript
59
- macroforgePreprocess();
60
- macroforgePreprocess({ keepDecorators: true });
61
- macroforgePreprocess({ processJavaScript: true });
62
- ```
29
+ - **`default`** - Default export for convenient importing.
63
30
 
64
31
  ## Documentation
65
32
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAgB,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAyIvE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;;;;;;;;;OAaG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,6BAAkC,GAC1C,iBAAiB,CA2JnB;AAED;;;;;;;GAOG;AACH,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAgB,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AA6OvE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;;;;;;;;;OAaG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,6BAAkC,GAC1C,iBAAiB,CAoJnB;AAED;;;;;;;GAOG;AACH,eAAe,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -25,7 +25,95 @@
25
25
  *
26
26
  * @packageDocumentation
27
27
  */
28
- import { hasMacroAnnotations } from "@macroforge/shared";
28
+ // ============================================================================
29
+ // Source Map Generation
30
+ // ============================================================================
31
+ const VLQ_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
32
+ function vlqEncode(value) {
33
+ let vlq = value < 0 ? (-value << 1) | 1 : value << 1;
34
+ let encoded = "";
35
+ do {
36
+ let digit = vlq & 0x1f;
37
+ vlq >>>= 5;
38
+ if (vlq > 0)
39
+ digit |= 0x20;
40
+ encoded += VLQ_CHARS[digit];
41
+ } while (vlq > 0);
42
+ return encoded;
43
+ }
44
+ /** Build line offsets table: lineOffsets[i] = byte offset of the start of line i */
45
+ function buildLineOffsets(text) {
46
+ const offsets = [0];
47
+ for (let i = 0; i < text.length; i++) {
48
+ if (text[i] === "\n")
49
+ offsets.push(i + 1);
50
+ }
51
+ return offsets;
52
+ }
53
+ /** Convert byte offset to { line, column } (0-based) */
54
+ function offsetToLineCol(offset, lineOffsets) {
55
+ let lo = 0, hi = lineOffsets.length - 1;
56
+ while (lo < hi) {
57
+ const mid = (lo + hi + 1) >> 1;
58
+ if (lineOffsets[mid] <= offset)
59
+ lo = mid;
60
+ else
61
+ hi = mid - 1;
62
+ }
63
+ return { line: lo, column: offset - lineOffsets[lo] };
64
+ }
65
+ /**
66
+ * Build a v3 source map from macroforge's segment-based mapping.
67
+ * Each segment maps a byte range in the expanded code to a byte range in the original.
68
+ */
69
+ function buildSourceMap(original, expanded, mapping, filename) {
70
+ const origOffsets = buildLineOffsets(original);
71
+ const expOffsets = buildLineOffsets(expanded);
72
+ // Group segments by expanded line
73
+ const lineSegments = new Map();
74
+ for (const seg of mapping.segments) {
75
+ const exp = offsetToLineCol(seg.expandedStart, expOffsets);
76
+ const orig = offsetToLineCol(seg.originalStart, origOffsets);
77
+ if (!lineSegments.has(exp.line))
78
+ lineSegments.set(exp.line, []);
79
+ lineSegments.get(exp.line).push({
80
+ expCol: exp.column,
81
+ origLine: orig.line,
82
+ origCol: orig.column,
83
+ });
84
+ }
85
+ // Encode VLQ mappings
86
+ const totalLines = expOffsets.length;
87
+ const mappingsArr = [];
88
+ let prevOrigLine = 0, prevOrigCol = 0;
89
+ for (let line = 0; line < totalLines; line++) {
90
+ const segs = lineSegments.get(line);
91
+ if (!segs || segs.length === 0) {
92
+ mappingsArr.push("");
93
+ continue;
94
+ }
95
+ segs.sort((a, b) => a.expCol - b.expCol);
96
+ const parts = [];
97
+ let lineExpCol = 0;
98
+ for (const seg of segs) {
99
+ parts.push(vlqEncode(seg.expCol - lineExpCol) +
100
+ vlqEncode(0) + // source index (always 0)
101
+ vlqEncode(seg.origLine - prevOrigLine) +
102
+ vlqEncode(seg.origCol - prevOrigCol));
103
+ lineExpCol = seg.expCol;
104
+ prevOrigLine = seg.origLine;
105
+ prevOrigCol = seg.origCol;
106
+ }
107
+ mappingsArr.push(parts.join(","));
108
+ }
109
+ return {
110
+ version: 3,
111
+ sources: [filename],
112
+ sourcesContent: [original],
113
+ names: [],
114
+ mappings: mappingsArr.join(";"),
115
+ };
116
+ }
29
117
  /**
30
118
  * Cached reference to the native `expandSync` function from the macroforge package.
31
119
  *
@@ -182,14 +270,7 @@ export function macroforgePreprocess(options = {}) {
182
270
  /*
183
271
  * STEP 2: Quick Scan Optimization
184
272
  *
185
- * Before loading native bindings, do a cheap string check for "@derive".
186
- * Most components won't have macros, so this saves the cost of loading
187
- * and calling the native expansion engine in the common case.
188
- */
189
- if (!hasMacroAnnotations(content)) {
190
- return;
191
- }
192
- /*
273
+ /*
193
274
  * STEP 3: Load Native Bindings
194
275
  *
195
276
  * The expansion engine is a native module (Rust compiled to Node addon).
@@ -238,11 +319,12 @@ export function macroforgePreprocess(options = {}) {
238
319
  * - map: Source map for debugging (optional, not yet implemented)
239
320
  */
240
321
  if (result.code && result.code !== content) {
241
- return {
242
- code: result.code,
243
- // TODO: Add source map support when expandSync provides mappings
244
- // map: result.source_mapping
245
- };
322
+ const mapping = result
323
+ .sourceMapping;
324
+ const map = mapping?.segments?.length && filename
325
+ ? buildSourceMap(content, result.code, mapping, filename)
326
+ : undefined;
327
+ return { code: result.code, map };
246
328
  }
247
329
  }
248
330
  catch (error) {
package/package.json CHANGED
@@ -1,13 +1,19 @@
1
1
  {
2
2
  "dependencies": {
3
- "@macroforge/shared": "^0.1.78",
4
- "macroforge": "^0.1.78"
3
+ "@macroforge/shared": "file:../shared",
4
+ "macroforge": "file:../../crates/macroforge_ts"
5
5
  },
6
6
  "description": "Svelte preprocessor for expanding Macroforge macros in component script blocks",
7
7
  "devDependencies": {
8
8
  "svelte": "^5.43.8",
9
9
  "typescript": "^5.9.3"
10
10
  },
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
11
17
  "files": [
12
18
  "dist"
13
19
  ],
@@ -28,7 +34,7 @@
28
34
  "repository": {
29
35
  "directory": "packages/svelte-preprocessor",
30
36
  "type": "git",
31
- "url": "git+https://github.com/macroforge-ts/svelte-preprocessor.git"
37
+ "url": "git+https://github.com/macroforge-ts/macroforge-ts.git"
32
38
  },
33
39
  "scripts": {
34
40
  "build": "deno install --node-modules-dir --quiet && deno run -A npm:typescript@5/tsc -p tsconfig.json",
@@ -38,5 +44,5 @@
38
44
  },
39
45
  "type": "module",
40
46
  "types": "dist/index.d.ts",
41
- "version": "0.1.78"
47
+ "version": "0.1.80"
42
48
  }