@webmate-studio/builder 0.2.75 → 0.2.77

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/build-service.js CHANGED
@@ -168,6 +168,20 @@ async function buildComponent(payload) {
168
168
  console.log(`[Build Service] Wrote ${assets.length} asset(s)`);
169
169
  }
170
170
 
171
+ // Detect which islands are actually used in component.html (top-level islands)
172
+ // These become Custom Elements, others are just utilities/sub-components
173
+ const usedIslands = new Set();
174
+ if (html) {
175
+ // Find all custom elements in HTML (e.g. <MenuMobile />, <SearchModal />)
176
+ // Match: <ComponentName or <ComponentName> or <ComponentName/>
177
+ const componentTagRegex = /<([A-Z][a-zA-Z0-9]*)\s*\/?>/g;
178
+ let match;
179
+ while ((match = componentTagRegex.exec(html)) !== null) {
180
+ const componentName = match[1]; // e.g. "MenuMobile"
181
+ usedIslands.add(componentName);
182
+ }
183
+ }
184
+
171
185
  // Build islands
172
186
  const bundledIslands = [];
173
187
  if (islands && islands.length > 0) {
@@ -189,12 +203,29 @@ async function buildComponent(payload) {
189
203
  await writeFile(inputPath, content);
190
204
  }
191
205
 
192
- // SECOND: Bundle each island
206
+ // SECOND: Bundle only top-level islands (those used in component.html)
207
+ // Others are utilities/sub-components that get bundled via imports
193
208
  for (const island of islands) {
209
+ // Extract component name from filename (e.g. "MenuMobile.svelte" → "MenuMobile")
210
+ const componentName = island.file.replace(/\.(jsx?|tsx?|svelte|vue)$/, '');
211
+ const isTopLevel = usedIslands.has(componentName);
212
+
213
+ // Skip non-component files (e.g. .js utilities that aren't top-level islands)
214
+ if (!island.file.match(/\.(jsx?|tsx?|svelte|vue)$/)) {
215
+ console.log(`[Build Service] Skipping ${island.file} (utility file, not an island)`);
216
+ continue;
217
+ }
218
+
219
+ // Only bundle top-level islands (those referenced in HTML)
220
+ if (!isTopLevel) {
221
+ console.log(`[Build Service] Skipping ${island.file} (sub-component, will be bundled via import)`);
222
+ continue;
223
+ }
224
+
194
225
  const inputPath = join(islandsDir, island.file);
195
226
  const outputPath = join(islandsDir, island.file.replace(/\.(jsx?|tsx?|svelte|vue)$/, '.js'));
196
227
 
197
- console.log(`[Build Service] Bundling ${island.file}...`);
228
+ console.log(`[Build Service] Bundling ${island.file} (top-level island)...`);
198
229
 
199
230
  // Bundle with esbuild (pass tmpDir for node_modules resolution)
200
231
  const result = await bundleIsland(inputPath, outputPath, {
@@ -222,6 +253,10 @@ async function buildComponent(payload) {
222
253
 
223
254
  console.log(`[Build Service] ✓ ${island.file} → ${outputFilename} (${(result.size / 1024).toFixed(2)}kb)`);
224
255
  }
256
+
257
+ if (usedIslands.size > 0) {
258
+ console.log(`[Build Service] Detected ${usedIslands.size} top-level island(s): ${Array.from(usedIslands).join(', ')}`);
259
+ }
225
260
  }
226
261
 
227
262
  // Transform HTML: Convert <IslandName /> to <island-name> Custom Elements
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webmate-studio/builder",
3
- "version": "0.2.75",
3
+ "version": "0.2.77",
4
4
  "type": "module",
5
5
  "description": "Webmate Studio Component Builder",
6
6
  "keywords": [
@@ -32,53 +32,92 @@ function generateSemanticColorUtilities(tokens) {
32
32
  'infoDark': 'info-dark',
33
33
  'infoLight': 'info-light',
34
34
 
35
- // Base semantic colors
36
- 'bgBase': 'default',
37
- 'bgElevated': 'elevated',
38
- 'bgLifted': 'lifted',
39
- 'textBase': 'default',
40
- 'textSubtle': 'subtle',
41
- 'textMuted': 'muted',
42
- 'borderBase': 'default',
43
- 'borderSubtle': 'subtle',
44
- 'borderMuted': 'muted',
35
+ // Base semantic colors (use prefixed names to avoid conflicts)
36
+ 'bgBase': 'bg-default',
37
+ 'bgElevated': 'bg-elevated',
38
+ 'bgLifted': 'bg-lifted',
39
+ 'textBase': 'text-default',
40
+ 'textSubtle': 'text-subtle',
41
+ 'textMuted': 'text-muted',
42
+ 'borderBase': 'border-default',
43
+ 'borderSubtle': 'border-subtle',
44
+ 'borderMuted': 'border-muted',
45
45
 
46
46
  // Accent colors
47
- 'bgAccentBase': 'accent-default',
48
- 'bgAccentElevated': 'accent-elevated',
49
- 'bgAccentLifted': 'accent-lifted',
50
- 'textAccentBase': 'accent-default',
51
- 'textAccentSubtle': 'accent-subtle',
52
- 'textAccentMuted': 'accent-muted',
53
- 'borderAccentBase': 'accent-default',
54
- 'borderAccentSubtle': 'accent-subtle',
55
- 'borderAccentMuted': 'accent-muted'
47
+ 'bgAccentBase': 'bg-accent-default',
48
+ 'bgAccentElevated': 'bg-accent-elevated',
49
+ 'bgAccentLifted': 'bg-accent-lifted',
50
+ 'textAccentBase': 'text-accent-default',
51
+ 'textAccentSubtle': 'text-accent-subtle',
52
+ 'textAccentMuted': 'text-accent-muted',
53
+ 'borderAccentBase': 'border-accent-default',
54
+ 'borderAccentSubtle': 'border-accent-subtle',
55
+ 'borderAccentMuted': 'border-accent-muted'
56
56
  };
57
57
 
58
- // Collect unique base names (deduplicate)
59
- const processedNames = new Set();
58
+ // Collect unique class names (deduplicate)
59
+ const processedClasses = new Set();
60
60
 
61
- for (const [tokenKey, baseName] of Object.entries(colorMap)) {
61
+ for (const [tokenKey, className] of Object.entries(colorMap)) {
62
62
  if (!tokens.colors[tokenKey]) continue;
63
63
 
64
- // Skip if we already processed this base name
65
- if (processedNames.has(baseName)) continue;
66
- processedNames.add(baseName);
67
-
68
64
  const colorVar = `--color-${tokenKey.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
69
65
 
70
- // Generate all three variants for every color
71
- utilities += `\n.text-${baseName} {`;
72
- utilities += `\n color: var(${colorVar});`;
73
- utilities += `\n}`;
66
+ // Determine which type(s) of utility classes to generate based on className prefix
67
+ // If className already has prefix (bg-, text-, border-), generate only that variant
68
+ // Otherwise generate all three variants
69
+
70
+ if (className.startsWith('bg-')) {
71
+ // Only generate bg-* utility
72
+ if (!processedClasses.has(className)) {
73
+ processedClasses.add(className);
74
+ utilities += `\n.${className} {`;
75
+ utilities += `\n background-color: var(${colorVar});`;
76
+ utilities += `\n}`;
77
+ }
78
+ } else if (className.startsWith('text-')) {
79
+ // Only generate text-* utility
80
+ if (!processedClasses.has(className)) {
81
+ processedClasses.add(className);
82
+ utilities += `\n.${className} {`;
83
+ utilities += `\n color: var(${colorVar});`;
84
+ utilities += `\n}`;
85
+ }
86
+ } else if (className.startsWith('border-')) {
87
+ // Only generate border-* utility
88
+ if (!processedClasses.has(className)) {
89
+ processedClasses.add(className);
90
+ utilities += `\n.${className} {`;
91
+ utilities += `\n border-color: var(${colorVar});`;
92
+ utilities += `\n}`;
93
+ }
94
+ } else {
95
+ // No prefix: generate all three variants (for primary, secondary, etc.)
96
+ const textClass = `text-${className}`;
97
+ const bgClass = `bg-${className}`;
98
+ const borderClass = `border-${className}`;
99
+
100
+ if (!processedClasses.has(textClass)) {
101
+ processedClasses.add(textClass);
102
+ utilities += `\n.${textClass} {`;
103
+ utilities += `\n color: var(${colorVar});`;
104
+ utilities += `\n}`;
105
+ }
74
106
 
75
- utilities += `\n.bg-${baseName} {`;
76
- utilities += `\n background-color: var(${colorVar});`;
77
- utilities += `\n}`;
107
+ if (!processedClasses.has(bgClass)) {
108
+ processedClasses.add(bgClass);
109
+ utilities += `\n.${bgClass} {`;
110
+ utilities += `\n background-color: var(${colorVar});`;
111
+ utilities += `\n}`;
112
+ }
78
113
 
79
- utilities += `\n.border-${baseName} {`;
80
- utilities += `\n border-color: var(${colorVar});`;
81
- utilities += `\n}`;
114
+ if (!processedClasses.has(borderClass)) {
115
+ processedClasses.add(borderClass);
116
+ utilities += `\n.${borderClass} {`;
117
+ utilities += `\n border-color: var(${colorVar});`;
118
+ utilities += `\n}`;
119
+ }
120
+ }
82
121
  }
83
122
 
84
123
  return utilities;