tkeron 4.0.0-beta.8 → 4.0.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 (81) hide show
  1. package/{readme.md → README.md} +36 -4
  2. package/bun.lock +23 -21
  3. package/changelog.md +292 -8
  4. package/docs/best-practices.md +127 -101
  5. package/docs/cli-reference.md +58 -38
  6. package/docs/components-html.md +30 -24
  7. package/docs/components-typescript.md +110 -79
  8. package/docs/getting-started.md +24 -18
  9. package/docs/mcp-server.md +19 -36
  10. package/docs/overview.md +16 -10
  11. package/docs/pre-rendering.md +163 -157
  12. package/docs/testing.md +331 -0
  13. package/examples/basic_build/src/index.ts +5 -5
  14. package/examples/with_assets/src/index.ts +5 -5
  15. package/examples/with_com_html_priority/src/admin/admin-panel.com.html +1 -1
  16. package/examples/with_com_html_priority/src/admin/dashboard.html +16 -16
  17. package/examples/with_com_html_priority/src/admin/nested-stat.com.html +1 -1
  18. package/examples/with_com_html_priority/src/admin/site-header.com.html +1 -1
  19. package/examples/with_com_html_priority/src/blog/comment-item.com.html +1 -1
  20. package/examples/with_com_html_priority/src/blog/comment-section.com.html +1 -1
  21. package/examples/with_com_html_priority/src/blog/post.html +22 -19
  22. package/examples/with_com_html_priority/src/index.html +15 -15
  23. package/examples/with_com_html_priority/src/info-box.com.html +1 -1
  24. package/examples/with_com_html_priority/src/site-header.com.html +1 -1
  25. package/examples/with_com_mixed_priority/src/dashboard/main.html +17 -17
  26. package/examples/with_com_mixed_priority/src/dashboard/stats-widget.com.ts +1 -1
  27. package/examples/with_com_mixed_priority/src/footer-info.com.html +3 -1
  28. package/examples/with_com_mixed_priority/src/index.html +16 -16
  29. package/examples/with_com_mixed_priority/src/page-header.com.html +8 -1
  30. package/examples/with_com_mixed_priority/src/settings/config.html +16 -16
  31. package/examples/with_com_mixed_priority/src/settings/priority-test.com.html +3 -1
  32. package/examples/with_com_mixed_priority/src/users/profiles/activity-feed.com.ts +7 -3
  33. package/examples/with_com_mixed_priority/src/users/profiles/page-header.com.html +8 -1
  34. package/examples/with_com_mixed_priority/src/users/profiles/profile-actions.com.html +45 -4
  35. package/examples/with_com_mixed_priority/src/users/profiles/user-profile.com.ts +1 -1
  36. package/examples/with_com_mixed_priority/src/users/profiles/view.html +17 -17
  37. package/examples/with_com_ts/src/index.html +15 -11
  38. package/examples/with_com_ts_priority/src/analytics/chart-widget.com.ts +7 -5
  39. package/examples/with_com_ts_priority/src/analytics/report.html +16 -16
  40. package/examples/with_com_ts_priority/src/analytics/user-stats.com.ts +1 -1
  41. package/examples/with_com_ts_priority/src/data-table.com.ts +7 -4
  42. package/examples/with_com_ts_priority/src/index.html +15 -15
  43. package/examples/with_com_ts_priority/src/sales/regional/data-table.com.ts +8 -5
  44. package/examples/with_com_ts_priority/src/sales/regional/overview.html +16 -16
  45. package/examples/with_com_ts_priority/src/sales/regional/sales-summary.com.ts +7 -4
  46. package/examples/with_com_ts_priority/src/user-stats.com.ts +1 -1
  47. package/examples/with_component_iteration/src/card-list.com.ts +40 -12
  48. package/examples/with_component_iteration/src/engagement-meter.com.ts +11 -6
  49. package/examples/with_component_iteration/src/index.html +108 -51
  50. package/examples/with_component_iteration/src/index.ts +1 -1
  51. package/examples/with_component_iteration/src/note-box.com.html +12 -2
  52. package/examples/with_component_iteration/src/status-badge.com.ts +14 -7
  53. package/examples/with_component_iteration/src/user-card.com.ts +10 -9
  54. package/examples/with_pre/src/contact.pre.ts +3 -3
  55. package/examples/with_pre/src/index.ts +5 -5
  56. package/examples/with_pre/src/section/index.pre.ts +2 -4
  57. package/index.ts +31 -40
  58. package/mcp-server.ts +168 -445
  59. package/package.json +19 -8
  60. package/src/banner.ts +5 -4
  61. package/src/build.ts +29 -29
  62. package/src/buildDir.ts +36 -18
  63. package/src/buildEntrypoints.ts +17 -6
  64. package/src/buildWrapper.ts +21 -0
  65. package/src/cleanupOrphanedTempDirs.ts +31 -0
  66. package/src/createTestLogger.ts +24 -0
  67. package/src/develop.ts +47 -46
  68. package/src/getBuildResult.ts +146 -0
  69. package/src/index.ts +7 -0
  70. package/src/init.ts +39 -42
  71. package/src/initWrapper.ts +39 -26
  72. package/src/logger.ts +4 -11
  73. package/src/loggerObj.ts +13 -0
  74. package/src/processCom.ts +137 -110
  75. package/src/processComTs.ts +174 -153
  76. package/src/processPre.ts +24 -27
  77. package/src/promptUser.ts +15 -0
  78. package/src/setupSigintHandler.ts +6 -0
  79. package/src/silentLogger.ts +8 -0
  80. package/tests/test-helpers.ts +30 -0
  81. package/funciones.md +0 -63
@@ -0,0 +1,331 @@
1
+ # Testing Tkeron Projects
2
+
3
+ ## Overview
4
+
5
+ Tkeron provides a `getBuildResult()` function that lets you test your built projects programmatically. This is useful for verifying that your components, pre-rendering scripts, and build output work correctly.
6
+
7
+ **Important:** These tests validate YOUR project's build output — not tkeron internals. You're testing that your HTML, components, and scripts produce the expected result after the build.
8
+
9
+ ## Setup
10
+
11
+ Install tkeron as a dependency in your project:
12
+
13
+ ```bash
14
+ bun add -d tkeron
15
+ ```
16
+
17
+ ## API
18
+
19
+ ```typescript
20
+ import { getBuildResult, type BuildResult } from "tkeron";
21
+
22
+ const result: BuildResult = await getBuildResult("./websrc");
23
+ ```
24
+
25
+ ### BuildResult
26
+
27
+ `getBuildResult()` returns a `Record<string, FileInfo>` indexed by relative path:
28
+
29
+ ```typescript
30
+ type BuildResult = Record<string, FileInfo>;
31
+
32
+ interface FileInfo {
33
+ fileName: string; // "index.html"
34
+ filePath: string; // "styles" or "" for root files
35
+ path: string; // "styles/main.css" (the key)
36
+ type: string; // MIME type: "text/html", "text/css", etc.
37
+ size: number; // size in bytes
38
+ fileHash: string; // SHA-256 hash
39
+ getContentAsString?: () => string; // text files only
40
+ dom?: Document; // HTML files only - parsed DOM
41
+ }
42
+ ```
43
+
44
+ - `dom` is only present on `.html` files. It provides full DOM API: `querySelector()`, `getElementById()`, `querySelectorAll()`, etc.
45
+ - `getContentAsString()` is only present on text files (html, css, js, json, txt, svg, xml, ts, mjs, cjs, md, map).
46
+ - Binary files (images, fonts) only have metadata — no `dom` or `getContentAsString`.
47
+
48
+ ## Test Structure
49
+
50
+ ### Single Build with beforeAll
51
+
52
+ **Always** build once and share the result across tests. This is:
53
+
54
+ - Concurrent-safe (`bun test --concurrent`)
55
+ - Efficient (1 build instead of N builds)
56
+ - Reliable (no race conditions)
57
+
58
+ ```typescript
59
+ import { describe, it, expect, beforeAll } from "bun:test";
60
+ import { getBuildResult, type BuildResult } from "tkeron";
61
+ import { join } from "path";
62
+
63
+ describe("my project", () => {
64
+ const sourcePath = join(import.meta.dir, "src");
65
+ let result: BuildResult;
66
+
67
+ beforeAll(async () => {
68
+ result = await getBuildResult(sourcePath);
69
+ });
70
+
71
+ it("should generate index.html", () => {
72
+ expect(result?.["index.html"]).toBeDefined();
73
+ });
74
+ });
75
+ ```
76
+
77
+ **Never** call `getBuildResult()` inside each `it()` — this causes race conditions in concurrent mode.
78
+
79
+ ## Testing Patterns
80
+
81
+ ### 1. Verify File Existence
82
+
83
+ Check that expected output files exist:
84
+
85
+ ```typescript
86
+ it("should generate expected files", () => {
87
+ expect(result?.["index.html"]).toBeDefined();
88
+ expect(result?.["index.js"]).toBeDefined();
89
+ expect(result?.["styles/main.css"]).toBeDefined();
90
+ });
91
+ ```
92
+
93
+ ### 2. Verify Element Existence (Always Check First)
94
+
95
+ **Rule:** Always verify an element exists BEFORE checking its properties.
96
+
97
+ ```typescript
98
+ // ✅ CORRECT: check existence first, then properties
99
+ it("should have login button", () => {
100
+ const dom = result?.["index.html"]?.dom;
101
+
102
+ const button = dom?.querySelector("#login-button");
103
+ expect(button).toBeDefined();
104
+ expect(button!.textContent).toBe("Log In");
105
+ });
106
+
107
+ // ❌ WRONG: accessing properties without checking existence
108
+ it("should have login button", () => {
109
+ const dom = result?.["index.html"]?.dom;
110
+ expect(dom!.querySelector("#login-button")!.textContent).toBe("Log In");
111
+ });
112
+ ```
113
+
114
+ ### 3. Verify Bounded Content
115
+
116
+ Test specific, short, predictable values — not full output strings.
117
+
118
+ ```typescript
119
+ // ✅ GOOD: specific, bounded values
120
+ it("should have correct title", () => {
121
+ const dom = result?.["index.html"]?.dom;
122
+
123
+ const title = dom?.querySelector("title");
124
+ expect(title).toBeDefined();
125
+ expect(title!.textContent).toBe("My App");
126
+ });
127
+
128
+ // ✅ GOOD: keyword presence in compiled JS
129
+ it("should contain event handling logic", () => {
130
+ const js = result?.["index.js"]?.getContentAsString!();
131
+ expect(js).toContain("addEventListener");
132
+ });
133
+
134
+ // ❌ BAD: comparing full minified JS output (fragile, breaks on any optimization change)
135
+ it("should match exact JS", () => {
136
+ const js = result?.["index.js"]?.getContentAsString!();
137
+ expect(js).toBe('var t=0,e=document.querySelector("button")...');
138
+ });
139
+
140
+ // ❌ BAD: comparing full HTML output
141
+ it("should match exact HTML", () => {
142
+ const html = result?.["index.html"]?.getContentAsString!();
143
+ expect(html).toBe("<!doctype html><html>...");
144
+ });
145
+ ```
146
+
147
+ **Why bounded:** Build output changes with optimizations, minification, and bundling. Test the **meaning**, not the **exact format**.
148
+
149
+ ### 4. Verify DOM Elements (Specific Queries)
150
+
151
+ Test specific elements that matter to your project:
152
+
153
+ ```typescript
154
+ it("should have navigation with correct links", () => {
155
+ const dom = result?.["index.html"]?.dom;
156
+
157
+ const homeLink = dom?.querySelector('nav a[href="/"]');
158
+ expect(homeLink).toBeDefined();
159
+ expect(homeLink!.textContent).toBe("Home");
160
+
161
+ const aboutLink = dom?.querySelector('nav a[href="/about"]');
162
+ expect(aboutLink).toBeDefined();
163
+ });
164
+
165
+ it("should have user profile section", () => {
166
+ const dom = result?.["index.html"]?.dom;
167
+
168
+ const profile = dom?.querySelector("#user-profile");
169
+ expect(profile).toBeDefined();
170
+
171
+ const avatar = profile?.querySelector("img.avatar");
172
+ expect(avatar).toBeDefined();
173
+ expect(avatar!.getAttribute("alt")).toBe("User avatar");
174
+ });
175
+ ```
176
+
177
+ ### 5. Verify Tkeron Transformations
178
+
179
+ Test that tkeron's build features work correctly in your project:
180
+
181
+ **Script injection (TypeScript → JavaScript):**
182
+
183
+ ```typescript
184
+ it("should have compiled script in head", () => {
185
+ const dom = result?.["index.html"]?.dom;
186
+
187
+ const script = dom?.querySelector('script[type="module"]');
188
+ expect(script).toBeDefined();
189
+ expect(script!.getAttribute("src")).toBe("./index.js");
190
+ expect(script!.parentElement!.tagName).toBe("HEAD");
191
+ });
192
+ ```
193
+
194
+ **Component substitution (.com.html):**
195
+
196
+ ```typescript
197
+ it("should have processed nav component", () => {
198
+ const dom = result?.["index.html"]?.dom;
199
+
200
+ // The <nav-menu> tag should be replaced by its .com.html content
201
+ const nav = dom?.querySelector("nav");
202
+ expect(nav).toBeDefined();
203
+
204
+ const links = dom?.querySelectorAll("nav a");
205
+ expect(links).toBeDefined();
206
+ expect(links!.length).toBeGreaterThan(0);
207
+ });
208
+ ```
209
+
210
+ **TypeScript component (.com.ts):**
211
+
212
+ ```typescript
213
+ it("should have dynamically generated list", () => {
214
+ const dom = result?.["index.html"]?.dom;
215
+
216
+ const list = dom?.querySelector("#item-list");
217
+ expect(list).toBeDefined();
218
+
219
+ const items = list?.querySelectorAll("li");
220
+ expect(items).toBeDefined();
221
+ expect(items!.length).toBe(5);
222
+ });
223
+ ```
224
+
225
+ **Pre-rendering (.pre.ts):**
226
+
227
+ ```typescript
228
+ it("should have pre-rendered content", () => {
229
+ const dom = result?.["index.html"]?.dom;
230
+
231
+ const generated = dom?.querySelector("#generated-content");
232
+ expect(generated).toBeDefined();
233
+ expect(generated!.textContent).not.toBe("");
234
+ });
235
+ ```
236
+
237
+ ### 6. Verify File Metadata
238
+
239
+ ```typescript
240
+ it("should have correct metadata", () => {
241
+ expect(result?.["index.html"]?.type).toBe("text/html");
242
+ expect(result?.["index.html"]?.size).toBeGreaterThan(0);
243
+ expect(result?.["index.html"]?.fileHash).toBeDefined();
244
+ });
245
+
246
+ it("should not have DOM on non-HTML files", () => {
247
+ expect(result?.["index.js"]?.dom).toBeUndefined();
248
+ });
249
+
250
+ it("should have correct path info for nested files", () => {
251
+ expect(result?.["pages/about.html"]?.fileName).toBe("about.html");
252
+ expect(result?.["pages/about.html"]?.filePath).toBe("pages");
253
+ });
254
+ ```
255
+
256
+ ## Complete Example
257
+
258
+ Here's a complete test file for a tkeron project with components:
259
+
260
+ ```typescript
261
+ import { describe, it, expect, beforeAll } from "bun:test";
262
+ import { getBuildResult, type BuildResult } from "tkeron";
263
+ import { join } from "path";
264
+
265
+ describe("my-website build", () => {
266
+ const sourcePath = join(import.meta.dir, "websrc");
267
+ let result: BuildResult;
268
+
269
+ beforeAll(async () => {
270
+ result = await getBuildResult(sourcePath);
271
+ });
272
+
273
+ it("should generate expected files", () => {
274
+ expect(result?.["index.html"]).toBeDefined();
275
+ expect(result?.["index.js"]).toBeDefined();
276
+ expect(result?.["about.html"]).toBeDefined();
277
+ });
278
+
279
+ it("should have page title", () => {
280
+ const dom = result?.["index.html"]?.dom;
281
+
282
+ const title = dom?.querySelector("title");
283
+ expect(title).toBeDefined();
284
+ expect(title!.textContent).toBe("My Website");
285
+ });
286
+
287
+ it("should have navigation from component", () => {
288
+ const dom = result?.["index.html"]?.dom;
289
+
290
+ const nav = dom?.querySelector("nav");
291
+ expect(nav).toBeDefined();
292
+
293
+ const homeLink = dom?.querySelector('nav a[href="/"]');
294
+ expect(homeLink).toBeDefined();
295
+ expect(homeLink!.textContent).toBe("Home");
296
+ });
297
+
298
+ it("should have footer from component", () => {
299
+ const dom = result?.["index.html"]?.dom;
300
+
301
+ const footer = dom?.querySelector("footer");
302
+ expect(footer).toBeDefined();
303
+ });
304
+
305
+ it("should have compiled JavaScript", () => {
306
+ const js = result?.["index.js"]?.getContentAsString!();
307
+
308
+ expect(js).toBeDefined();
309
+ expect(js!.length).toBeGreaterThan(0);
310
+ });
311
+
312
+ it("should have script injected in head", () => {
313
+ const dom = result?.["index.html"]?.dom;
314
+
315
+ const script = dom?.querySelector('head script[type="module"]');
316
+ expect(script).toBeDefined();
317
+ expect(script!.getAttribute("src")).toBe("./index.js");
318
+ });
319
+ });
320
+ ```
321
+
322
+ ## Rules Summary
323
+
324
+ 1. **Build once** with `beforeAll()` — never inside individual tests
325
+ 2. **Check existence first** — always `expect(element).toBeDefined()` before accessing properties
326
+ 3. **Use optional chaining** (`?.`) for safe property access on result entries
327
+ 4. **Test bounded content** — specific values, keywords, attributes; not full output strings
328
+ 5. **Test specific elements** — query for elements that matter to your project
329
+ 6. **Verify transformations** — components processed, scripts injected, pre-rendering applied
330
+ 7. **Don't test the parser** — you're testing your project, not tkeron internals
331
+ 8. **Concurrent-safe** — tests must work with `bun test --concurrent`
@@ -1,10 +1,10 @@
1
1
  // Simple click counter
2
2
  let clickCount = 0;
3
3
 
4
- const button = document.querySelector('button') as HTMLButtonElement;
5
- const heading = document.querySelector('h1') as HTMLHeadingElement;
4
+ const button = document.querySelector("button") as HTMLButtonElement;
5
+ const heading = document.querySelector("h1") as HTMLHeadingElement;
6
6
 
7
- button.addEventListener('click', () => {
8
- clickCount++;
9
- heading.textContent = `Clicks: ${clickCount}`;
7
+ button.addEventListener("click", () => {
8
+ clickCount++;
9
+ heading.textContent = `Clicks: ${clickCount}`;
10
10
  });
@@ -1,10 +1,10 @@
1
1
  // Simple click counter
2
2
  let clickCount = 0;
3
3
 
4
- const button = document.querySelector('button') as HTMLButtonElement;
5
- const heading = document.querySelector('h1') as HTMLHeadingElement;
4
+ const button = document.querySelector("button") as HTMLButtonElement;
5
+ const heading = document.querySelector("h1") as HTMLHeadingElement;
6
6
 
7
- button.addEventListener('click', () => {
8
- clickCount++;
9
- heading.textContent = `Clicks: ${clickCount}`;
7
+ button.addEventListener("click", () => {
8
+ clickCount++;
9
+ heading.textContent = `Clicks: ${clickCount}`;
10
10
  });
@@ -1,4 +1,4 @@
1
- <div style="border: 3px solid #e74c3c; padding: 1rem; margin: 1rem 0;">
1
+ <div style="border: 3px solid #e74c3c; padding: 1rem; margin: 1rem 0">
2
2
  <h4>Admin Panel</h4>
3
3
  <p>This component only exists in admin directory</p>
4
4
  <nested-stat></nested-stat>
@@ -1,18 +1,18 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Admin Dashboard</title>
7
- </head>
8
- <body>
9
- <h1>Admin Dashboard</h1>
10
-
11
- <section>
12
- <h2>Local Components Override Root</h2>
13
- <site-header></site-header>
14
- <info-box></info-box>
15
- <admin-panel></admin-panel>
16
- </section>
17
- </body>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Admin Dashboard</title>
7
+ </head>
8
+ <body>
9
+ <h1>Admin Dashboard</h1>
10
+
11
+ <section>
12
+ <h2>Local Components Override Root</h2>
13
+ <site-header></site-header>
14
+ <info-box></info-box>
15
+ <admin-panel></admin-panel>
16
+ </section>
17
+ </body>
18
18
  </html>
@@ -1,4 +1,4 @@
1
- <div style="background: #f39c12; padding: 0.5rem; margin-top: 0.5rem;">
1
+ <div style="background: #f39c12; padding: 0.5rem; margin-top: 0.5rem">
2
2
  <strong>Nested Stat Component</strong>
3
3
  <p>Total Users: 1,234 | Active: 567</p>
4
4
  </div>
@@ -1,4 +1,4 @@
1
- <header style="background: #e74c3c; color: white; padding: 1rem;">
1
+ <header style="background: #e74c3c; color: white; padding: 1rem">
2
2
  <h3>🔐 Admin Header (Local Override)</h3>
3
3
  <p>This header is from the admin directory - overrides root!</p>
4
4
  </header>
@@ -1,3 +1,3 @@
1
- <div style="background: #ecf0f1; padding: 0.5rem; margin: 0.5rem 0;">
1
+ <div style="background: #ecf0f1; padding: 0.5rem; margin: 0.5rem 0">
2
2
  <strong>User123:</strong> Great article!
3
3
  </div>
@@ -1,4 +1,4 @@
1
- <div style="border: 2px solid #27ae60; padding: 1rem; margin: 1rem 0;">
1
+ <div style="border: 2px solid #27ae60; padding: 1rem; margin: 1rem 0">
2
2
  <h4>Comments</h4>
3
3
  <p>This component is specific to the blog directory</p>
4
4
  <comment-item></comment-item>
@@ -1,21 +1,24 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Blog Post</title>
7
- </head>
8
- <body>
9
- <h1>Blog Post</h1>
10
-
11
- <site-header></site-header>
12
-
13
- <article>
14
- <h2>Using Root Components</h2>
15
- <info-box></info-box>
16
- <p>This page uses components from the root directory since there are no local overrides.</p>
17
-
18
- <comment-section></comment-section>
19
- </article>
20
- </body>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Blog Post</title>
7
+ </head>
8
+ <body>
9
+ <h1>Blog Post</h1>
10
+
11
+ <site-header></site-header>
12
+
13
+ <article>
14
+ <h2>Using Root Components</h2>
15
+ <info-box></info-box>
16
+ <p>
17
+ This page uses components from the root directory since there are no
18
+ local overrides.
19
+ </p>
20
+
21
+ <comment-section></comment-section>
22
+ </article>
23
+ </body>
21
24
  </html>
@@ -1,17 +1,17 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Component Priority - HTML Components</title>
7
- </head>
8
- <body>
9
- <h1>HTML Component Priority Demo</h1>
10
-
11
- <section>
12
- <h2>Root Level Components</h2>
13
- <site-header></site-header>
14
- <info-box></info-box>
15
- </section>
16
- </body>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Component Priority - HTML Components</title>
7
+ </head>
8
+ <body>
9
+ <h1>HTML Component Priority Demo</h1>
10
+
11
+ <section>
12
+ <h2>Root Level Components</h2>
13
+ <site-header></site-header>
14
+ <info-box></info-box>
15
+ </section>
16
+ </body>
17
17
  </html>
@@ -1,4 +1,4 @@
1
- <div style="border: 2px solid #4a90e2; padding: 1rem; margin: 1rem 0;">
1
+ <div style="border: 2px solid #4a90e2; padding: 1rem; margin: 1rem 0">
2
2
  <strong>Root Info Box</strong>
3
3
  <p>This is the default info box from root</p>
4
4
  </div>
@@ -1,4 +1,4 @@
1
- <header style="background: #4a90e2; color: white; padding: 1rem;">
1
+ <header style="background: #4a90e2; color: white; padding: 1rem">
2
2
  <h3>Root Header Component</h3>
3
3
  <p>This header is from the root directory</p>
4
4
  </header>
@@ -1,19 +1,19 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Dashboard - Mixed Priority</title>
7
- </head>
8
- <body>
9
- <h1>Dashboard with Mixed Priorities</h1>
10
-
11
- <section>
12
- <h2>Local Overrides and .com.ts Priority</h2>
13
- <page-header></page-header>
14
- <feature-card title="Dashboard Feature"></feature-card>
15
- <stats-widget></stats-widget>
16
- <footer-info></footer-info>
17
- </section>
18
- </body>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Dashboard - Mixed Priority</title>
7
+ </head>
8
+ <body>
9
+ <h1>Dashboard with Mixed Priorities</h1>
10
+
11
+ <section>
12
+ <h2>Local Overrides and .com.ts Priority</h2>
13
+ <page-header></page-header>
14
+ <feature-card title="Dashboard Feature"></feature-card>
15
+ <stats-widget></stats-widget>
16
+ <footer-info></footer-info>
17
+ </section>
18
+ </body>
19
19
  </html>
@@ -1,7 +1,7 @@
1
1
  const stats = {
2
2
  users: 1523,
3
3
  revenue: 45230,
4
- growth: 23.5
4
+ growth: 23.5,
5
5
  };
6
6
 
7
7
  com.innerHTML = `
@@ -1,3 +1,5 @@
1
- <footer style="background: #34495e; color: white; padding: 1rem; text-align: center;">
1
+ <footer
2
+ style="background: #34495e; color: white; padding: 1rem; text-align: center"
3
+ >
2
4
  <p>© 2025 - Root Footer (HTML Component)</p>
3
5
  </footer>
@@ -1,18 +1,18 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Mixed Component Priority Demo</title>
7
- </head>
8
- <body>
9
- <h1>Mixed Component Priority (.com.html + .com.ts)</h1>
10
-
11
- <section>
12
- <h2>Root Level - Both Component Types</h2>
13
- <page-header></page-header>
14
- <feature-card title="Feature 1"></feature-card>
15
- <footer-info></footer-info>
16
- </section>
17
- </body>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Mixed Component Priority Demo</title>
7
+ </head>
8
+ <body>
9
+ <h1>Mixed Component Priority (.com.html + .com.ts)</h1>
10
+
11
+ <section>
12
+ <h2>Root Level - Both Component Types</h2>
13
+ <page-header></page-header>
14
+ <feature-card title="Feature 1"></feature-card>
15
+ <footer-info></footer-info>
16
+ </section>
17
+ </body>
18
18
  </html>
@@ -1,4 +1,11 @@
1
- <header style="background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); color: white; padding: 2rem; text-align: center;">
1
+ <header
2
+ style="
3
+ background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
4
+ color: white;
5
+ padding: 2rem;
6
+ text-align: center;
7
+ "
8
+ >
2
9
  <h2>Root Header (HTML Component)</h2>
3
10
  <p>This is a static HTML component from root</p>
4
11
  </header>
@@ -1,18 +1,18 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Settings - Priority Showcase</title>
7
- </head>
8
- <body>
9
- <h1>Settings Page</h1>
10
-
11
- <section>
12
- <h2>Both .com.ts and .com.html in Same Directory</h2>
13
- <priority-test></priority-test>
14
- <feature-card title="Settings Feature"></feature-card>
15
- <footer-info></footer-info>
16
- </section>
17
- </body>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Settings - Priority Showcase</title>
7
+ </head>
8
+ <body>
9
+ <h1>Settings Page</h1>
10
+
11
+ <section>
12
+ <h2>Both .com.ts and .com.html in Same Directory</h2>
13
+ <priority-test></priority-test>
14
+ <feature-card title="Settings Feature"></feature-card>
15
+ <footer-info></footer-info>
16
+ </section>
17
+ </body>
18
18
  </html>