tkeron 4.5.0 → 5.0.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 +2 -2
- package/changelog.md +53 -0
- package/docs/best-practices.md +3 -6
- package/docs/cli-reference.md +41 -51
- package/docs/common-issues.md +20 -13
- package/docs/components-html.md +10 -8
- package/docs/components-markdown.md +5 -5
- package/docs/components-typescript.md +1 -1
- package/docs/getting-started.md +17 -23
- package/docs/overview.md +5 -3
- package/docs/pre-rendering.md +7 -4
- package/examples/init_sample/tkeron.d.ts +1 -13
- package/index.ts +0 -4
- package/package.json +2 -2
- package/src/buildWrapper.ts +1 -3
- package/src/ensureTsconfig.ts +68 -0
- package/src/init.ts +30 -33
- package/src/processComTs.ts +6 -2
- package/src/processPre.ts +3 -1
- package/tkeron.d.ts +1 -13
package/README.md
CHANGED
|
@@ -82,8 +82,8 @@ document.getElementById("quote").textContent = data.content;
|
|
|
82
82
|
|
|
83
83
|
```bash
|
|
84
84
|
tk init <name> # Initialize new project
|
|
85
|
-
tk build
|
|
86
|
-
tk dev [
|
|
85
|
+
tk build # Build project (websrc → web)
|
|
86
|
+
tk dev [port] [host] # Dev server with hot reload (default: localhost:3000)
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
**Aliases:** `tk i`, `tk b`, `tk d`
|
package/changelog.md
CHANGED
|
@@ -1,3 +1,56 @@
|
|
|
1
|
+
# v5.0.1
|
|
2
|
+
|
|
3
|
+
## Documentation fixes and dependency updates
|
|
4
|
+
|
|
5
|
+
- Fix: `tk build` and `tk dev` CLI signatures corrected in README (removed wrong `[src] [out]` args, aligned with v5.0 breaking change)
|
|
6
|
+
- Fix: Component resolution docs updated to reflect actual glob search behavior (not limited to root `websrc/`)
|
|
7
|
+
- Fix: Build process docs updated to include `.com.md` processing step and iterative loop (up to 10 iterations)
|
|
8
|
+
- Fix: `tsconfig.json` example corrected to match real config (`lib: ["ESNext", "DOM"]`, removed `types: ["bun-types"]`)
|
|
9
|
+
- Fix: TypeScript compilation docs clarified — Bun transpiler does NOT type-check, only transpiles
|
|
10
|
+
- Fix: Broken link `tkeron.dev/docs` → `tkeron.com`
|
|
11
|
+
- Fix: `components-html.md` quick start used `<button>` (reserved HTML tag, no hyphen) — replaced with `<my-button>`
|
|
12
|
+
- Fix: `best-practices.md` Summary had orphaned/corrupted code fragment — removed
|
|
13
|
+
- Fix: Added `.com.md` to all feature lists, tables, and build process diagrams across all docs
|
|
14
|
+
- Fix: `package.json` description updated to reflect actual purpose
|
|
15
|
+
- Deps: `bun update --latest` — updated all dependencies
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# v5.0.0
|
|
20
|
+
|
|
21
|
+
## Breaking: sourceDir and targetDir removed as CLI arguments
|
|
22
|
+
|
|
23
|
+
- `tk build` and `tk dev` no longer accept positional directory arguments
|
|
24
|
+
- Fixed convention: source in `websrc/`, output in `web/`
|
|
25
|
+
- To migrate: rename your source directory to `websrc/` (`mv your-dir websrc`)
|
|
26
|
+
- Output is always `web/` (sibling of `websrc/`) — no longer configurable via CLI
|
|
27
|
+
- `port` and `host` remain as positional arguments for `tk dev`
|
|
28
|
+
|
|
29
|
+
## Fix: pre-rendering module resolution in projects without node_modules
|
|
30
|
+
|
|
31
|
+
- `processPre.ts` now injects the absolute resolved path of `@tkeron/html-parser` instead of the bare specifier
|
|
32
|
+
- Fixes failure when the user's project lives inside a workspace root with a `node_modules/` that doesn't include `@tkeron` dependencies
|
|
33
|
+
|
|
34
|
+
### Migration
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Before (v4.x)
|
|
38
|
+
tk build src dist
|
|
39
|
+
tk dev src dist 8080
|
|
40
|
+
|
|
41
|
+
# After (v5.0)
|
|
42
|
+
tk build
|
|
43
|
+
tk dev 8080
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### What changed
|
|
47
|
+
|
|
48
|
+
- `buildWrapper` no longer forwards `sourceDir`/`targetDir` to `build()`
|
|
49
|
+
- CLI positioned arguments for directories removed from `build` and `develop` commands
|
|
50
|
+
- Documentation updated (cli-reference, getting-started)
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
1
54
|
# v4.5.0
|
|
2
55
|
|
|
3
56
|
## tsconfig.json Generation on Init
|
package/docs/best-practices.md
CHANGED
|
@@ -231,23 +231,20 @@ document.getElementById("stars").textContent = data.public_repos;
|
|
|
231
231
|
|
|
232
232
|
- HTML components: static markup
|
|
233
233
|
- TypeScript components: dynamic generation
|
|
234
|
+
- Markdown components: content in Markdown
|
|
234
235
|
- Pre-rendering: DOM manipulation at build time
|
|
235
236
|
- Browser code: regular TypeScript/JavaScript
|
|
236
237
|
- No bundling of npm packages
|
|
237
238
|
- No type checking (use `tsc --noEmit`)
|
|
238
239
|
- Powered by Bun
|
|
239
|
-
document.querySelectorAll('.my-button').forEach(btn => {
|
|
240
|
-
btn.addEventListener('click', handleClick);
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
240
|
|
|
244
|
-
|
|
241
|
+
---
|
|
245
242
|
|
|
246
243
|
```typescript
|
|
247
244
|
// ❌ Don't try to maintain state
|
|
248
245
|
let count = 0; // This is meaningless
|
|
249
246
|
com.innerHTML = `<button>Count: ${count}</button>`;
|
|
250
|
-
|
|
247
|
+
```
|
|
251
248
|
|
|
252
249
|
**Solution:** Use client-side JavaScript for stateful UI.
|
|
253
250
|
|
package/docs/cli-reference.md
CHANGED
|
@@ -52,30 +52,22 @@ Build your project by processing source files into static output.
|
|
|
52
52
|
**Usage:**
|
|
53
53
|
|
|
54
54
|
```bash
|
|
55
|
-
tk build
|
|
55
|
+
tk build
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
**
|
|
58
|
+
**Convention:**
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
| `sourceDir` | string | `websrc` | Source directory containing your project files |
|
|
63
|
-
| `targetDir` | string | `web` | Output directory for built files |
|
|
60
|
+
- Source directory: `websrc/` (relative to current directory)
|
|
61
|
+
- Output directory: `web/` (sibling of `websrc/`)
|
|
64
62
|
|
|
65
63
|
**Examples:**
|
|
66
64
|
|
|
67
65
|
```bash
|
|
68
|
-
# Build
|
|
66
|
+
# Build the project
|
|
69
67
|
tk build
|
|
70
68
|
|
|
71
|
-
#
|
|
72
|
-
tk
|
|
73
|
-
|
|
74
|
-
# Build to custom output directory
|
|
75
|
-
tk build websrc dist
|
|
76
|
-
|
|
77
|
-
# Build with both custom
|
|
78
|
-
tk build source output
|
|
69
|
+
# Using alias
|
|
70
|
+
tk b
|
|
79
71
|
```
|
|
80
72
|
|
|
81
73
|
**Build Process:**
|
|
@@ -83,16 +75,20 @@ tk build source output
|
|
|
83
75
|
1. Creates temporary directory as sibling to source
|
|
84
76
|
2. Copies source to temp directory
|
|
85
77
|
3. Runs `.pre.ts` files (pre-rendering)
|
|
86
|
-
4.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
78
|
+
4. Iterative component processing (up to 10 iterations):
|
|
79
|
+
- Processes `.com.ts` components (TypeScript components)
|
|
80
|
+
- Processes `.com.html` components (HTML components)
|
|
81
|
+
- Processes `.com.md` components (Markdown components)
|
|
82
|
+
- Repeats until no changes are detected
|
|
83
|
+
5. Compiles TypeScript to JavaScript
|
|
84
|
+
6. Copies result to target directory
|
|
85
|
+
7. Cleans up temporary directory
|
|
91
86
|
|
|
92
87
|
**Files Excluded from Output:**
|
|
93
88
|
|
|
94
89
|
- `*.com.html` - HTML components (inlined)
|
|
95
90
|
- `*.com.ts` - TypeScript components (inlined)
|
|
91
|
+
- `*.com.md` - Markdown components (inlined)
|
|
96
92
|
- `*.pre.ts` - Pre-rendering scripts (executed)
|
|
97
93
|
|
|
98
94
|
**Exit Codes:**
|
|
@@ -120,17 +116,20 @@ Start a development server with hot reload.
|
|
|
120
116
|
**Usage:**
|
|
121
117
|
|
|
122
118
|
```bash
|
|
123
|
-
tk develop [
|
|
119
|
+
tk develop [port] [host]
|
|
124
120
|
```
|
|
125
121
|
|
|
126
122
|
**Arguments:**
|
|
127
123
|
|
|
128
|
-
| Argument
|
|
129
|
-
|
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
|
|
133
|
-
|
|
124
|
+
| Argument | Type | Default | Description |
|
|
125
|
+
| -------- | ------ | ----------- | --------------------------- |
|
|
126
|
+
| `port` | number | `3000` | Port for development server |
|
|
127
|
+
| `host` | string | `localhost` | Host to bind server to |
|
|
128
|
+
|
|
129
|
+
**Convention:**
|
|
130
|
+
|
|
131
|
+
- Source directory: `websrc/` (relative to current directory)
|
|
132
|
+
- Output directory: `web/` (sibling of `websrc/`)
|
|
134
133
|
|
|
135
134
|
**Examples:**
|
|
136
135
|
|
|
@@ -138,17 +137,14 @@ tk develop [sourceDir] [outputDir] [port] [host]
|
|
|
138
137
|
# Start with defaults
|
|
139
138
|
tk dev
|
|
140
139
|
|
|
141
|
-
# Custom source and output
|
|
142
|
-
tk dev src dist
|
|
143
|
-
|
|
144
140
|
# Custom port
|
|
145
|
-
tk dev
|
|
141
|
+
tk dev 8080
|
|
146
142
|
|
|
147
143
|
# Bind to all interfaces
|
|
148
|
-
tk dev
|
|
144
|
+
tk dev 3000 0.0.0.0
|
|
149
145
|
|
|
150
146
|
# Complete custom configuration
|
|
151
|
-
tk develop
|
|
147
|
+
tk develop 8080 0.0.0.0
|
|
152
148
|
```
|
|
153
149
|
|
|
154
150
|
**What It Does:**
|
|
@@ -317,7 +313,7 @@ tk init . --force
|
|
|
317
313
|
cd my-website
|
|
318
314
|
|
|
319
315
|
# Start development server
|
|
320
|
-
tk dev
|
|
316
|
+
tk dev
|
|
321
317
|
|
|
322
318
|
# Open http://localhost:3000
|
|
323
319
|
```
|
|
@@ -356,7 +352,7 @@ Quick reference for command shortcuts:
|
|
|
356
352
|
```bash
|
|
357
353
|
tk b # Same as: tk build
|
|
358
354
|
tk d # Same as: tk develop
|
|
359
|
-
tk dev
|
|
355
|
+
tk dev 8080 # Same as: tk develop 8080
|
|
360
356
|
tk i my-site # Same as: tk init my-site
|
|
361
357
|
```
|
|
362
358
|
|
|
@@ -430,22 +426,19 @@ Tkeron uses **convention over configuration**. There are no configuration files.
|
|
|
430
426
|
|
|
431
427
|
**Project Structure Convention:**
|
|
432
428
|
|
|
433
|
-
- Source directory: `websrc/` (
|
|
434
|
-
- Output directory: `web/` (
|
|
429
|
+
- Source directory: `websrc/` (fixed)
|
|
430
|
+
- Output directory: `web/` (fixed)
|
|
435
431
|
- Component files: `*.com.html` and `*.com.ts`
|
|
436
432
|
- Pre-render files: `*.pre.ts`
|
|
437
433
|
- Type definitions: `tkeron.d.ts`
|
|
438
434
|
|
|
439
435
|
**Customization:**
|
|
440
436
|
|
|
441
|
-
|
|
437
|
+
Server configuration is done via command-line arguments:
|
|
442
438
|
|
|
443
439
|
```bash
|
|
444
|
-
# Custom directories
|
|
445
|
-
tk build src dist
|
|
446
|
-
|
|
447
440
|
# Custom server config
|
|
448
|
-
tk dev
|
|
441
|
+
tk dev 8080 0.0.0.0
|
|
449
442
|
```
|
|
450
443
|
|
|
451
444
|
---
|
|
@@ -459,8 +452,8 @@ Tkeron doesn't require a `tsconfig.json`, but you can add one for editor support
|
|
|
459
452
|
"compilerOptions": {
|
|
460
453
|
"target": "ESNext",
|
|
461
454
|
"module": "ESNext",
|
|
455
|
+
"lib": ["ESNext", "DOM"],
|
|
462
456
|
"moduleResolution": "bundler",
|
|
463
|
-
"types": ["bun-types"],
|
|
464
457
|
"strict": true,
|
|
465
458
|
"skipLibCheck": true
|
|
466
459
|
},
|
|
@@ -580,7 +573,7 @@ Error: Port 3000 is already in use
|
|
|
580
573
|
|
|
581
574
|
```bash
|
|
582
575
|
# Use different port
|
|
583
|
-
tk dev
|
|
576
|
+
tk dev 3001
|
|
584
577
|
```
|
|
585
578
|
|
|
586
579
|
### Source Directory Not Found
|
|
@@ -597,8 +590,8 @@ tk dev websrc web 3001
|
|
|
597
590
|
# Create directory
|
|
598
591
|
mkdir websrc
|
|
599
592
|
|
|
600
|
-
# Or
|
|
601
|
-
tk
|
|
593
|
+
# Or initialize a new project
|
|
594
|
+
tk init .
|
|
602
595
|
```
|
|
603
596
|
|
|
604
597
|
### Permission Denied
|
|
@@ -646,7 +639,7 @@ tk
|
|
|
646
639
|
This document! Also available at:
|
|
647
640
|
|
|
648
641
|
- [GitHub Repository](https://github.com/tkeron/tkeron)
|
|
649
|
-
- [Documentation Site](https://tkeron.
|
|
642
|
+
- [Documentation Site](https://tkeron.com)
|
|
650
643
|
|
|
651
644
|
### Report Issues
|
|
652
645
|
|
|
@@ -668,11 +661,8 @@ tk dev
|
|
|
668
661
|
# Build for production
|
|
669
662
|
NODE_ENV=production tk build
|
|
670
663
|
|
|
671
|
-
# Build to custom directory
|
|
672
|
-
tk build websrc dist
|
|
673
|
-
|
|
674
664
|
# Development on port 8080
|
|
675
|
-
tk dev
|
|
665
|
+
tk dev 8080
|
|
676
666
|
|
|
677
667
|
# Initialize in current directory
|
|
678
668
|
tk init .
|
package/docs/common-issues.md
CHANGED
|
@@ -125,9 +125,9 @@ blog-post.com.ts → <blog-post>
|
|
|
125
125
|
|
|
126
126
|
## TypeScript Compilation
|
|
127
127
|
|
|
128
|
-
### Issue: TypeScript Errors
|
|
128
|
+
### Issue: TypeScript Errors in Source
|
|
129
129
|
|
|
130
|
-
**Problem:**
|
|
130
|
+
**Problem:** TypeScript code has type errors
|
|
131
131
|
|
|
132
132
|
```typescript
|
|
133
133
|
// ❌ WRONG
|
|
@@ -135,18 +135,24 @@ const user = { name: "Alice" };
|
|
|
135
135
|
user.age = 30; // Error: Property 'age' does not exist
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
-
**Why this
|
|
138
|
+
**Why this matters:**
|
|
139
139
|
|
|
140
|
-
- Tkeron uses Bun's TypeScript transpiler
|
|
141
|
-
- Type errors
|
|
142
|
-
-
|
|
140
|
+
- Tkeron uses Bun's TypeScript transpiler, which **does NOT type-check** — it only transpiles
|
|
141
|
+
- Type errors won't prevent the build from running
|
|
142
|
+
- However, type errors may indicate real bugs in your code
|
|
143
|
+
- Missing types for global variables can confuse your IDE
|
|
143
144
|
|
|
144
145
|
**Solution:**
|
|
145
146
|
|
|
147
|
+
- Run `tsc --noEmit` separately to catch type errors before building
|
|
146
148
|
- Use `tkeron.d.ts` for global type declarations
|
|
147
|
-
- Fix type errors before building
|
|
148
149
|
- Use `any` strategically if types are complex
|
|
149
150
|
|
|
151
|
+
```bash
|
|
152
|
+
# Check types, then build
|
|
153
|
+
tsc --noEmit && tk build
|
|
154
|
+
```
|
|
155
|
+
|
|
150
156
|
```typescript
|
|
151
157
|
// ✅ CORRECT
|
|
152
158
|
const user: { name: string; age?: number } = { name: "Alice" };
|
|
@@ -166,16 +172,17 @@ user.age = 30; // OK
|
|
|
166
172
|
|
|
167
173
|
**Why this happens:**
|
|
168
174
|
|
|
169
|
-
- Tkeron searches in 2
|
|
175
|
+
- Tkeron searches in 2 ways:
|
|
170
176
|
1. Same directory as HTML file
|
|
171
|
-
2.
|
|
172
|
-
-
|
|
177
|
+
2. Glob search across the entire source tree
|
|
178
|
+
- If no match is found in either, the element remains unchanged
|
|
173
179
|
|
|
174
180
|
**Solution:**
|
|
175
|
-
|
|
181
|
+
Place the component file anywhere in the source tree — Tkeron will find it via glob search. For clarity, common locations:
|
|
176
182
|
|
|
177
|
-
- In `blog/user-card.com.html` (next to `post.html`)
|
|
178
|
-
-
|
|
183
|
+
- In `blog/user-card.com.html` (next to `post.html` — higher priority)
|
|
184
|
+
- In `websrc/user-card.com.html` (root)
|
|
185
|
+
- In `websrc/components/user-card.com.html` (organized in a subfolder)
|
|
179
186
|
|
|
180
187
|
## Build Performance
|
|
181
188
|
|
package/docs/components-html.md
CHANGED
|
@@ -7,7 +7,7 @@ HTML components (`.com.html` files) are the simplest way to create reusable piec
|
|
|
7
7
|
Create a file named with `.com.html` extension:
|
|
8
8
|
|
|
9
9
|
```html
|
|
10
|
-
<!-- button.com.html -->
|
|
10
|
+
<!-- my-button.com.html -->
|
|
11
11
|
<button class="btn">Click me</button>
|
|
12
12
|
```
|
|
13
13
|
|
|
@@ -15,7 +15,7 @@ Use it with a matching custom element:
|
|
|
15
15
|
|
|
16
16
|
```html
|
|
17
17
|
<!-- index.html -->
|
|
18
|
-
<button></button>
|
|
18
|
+
<my-button></my-button>
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Build, and the custom element is replaced with the component's content.
|
|
@@ -36,7 +36,7 @@ Component filenames must:
|
|
|
36
36
|
| -------------------- | -------------- | ------------------------- |
|
|
37
37
|
| `user-card.com.html` | `<user-card>` | ✅ Yes |
|
|
38
38
|
| `nav-menu.com.html` | `<nav-menu>` | ✅ Yes |
|
|
39
|
-
| `
|
|
39
|
+
| `card.com.html` | `<card>` | ❌ No (no hyphen) |
|
|
40
40
|
| `UserCard.com.html` | `<user-card>` | ✅ Yes (case-insensitive) |
|
|
41
41
|
|
|
42
42
|
### 2. Component Resolution
|
|
@@ -44,23 +44,25 @@ Component filenames must:
|
|
|
44
44
|
Tkeron looks for components in this order:
|
|
45
45
|
|
|
46
46
|
1. **Same directory** as the file using it
|
|
47
|
-
2. **
|
|
47
|
+
2. **Any directory** in the source tree (via glob search)
|
|
48
48
|
|
|
49
49
|
**Example structure:**
|
|
50
50
|
|
|
51
51
|
```
|
|
52
52
|
websrc/
|
|
53
53
|
├── index.html
|
|
54
|
-
├── header.com.html
|
|
54
|
+
├── site-header.com.html # Available to all files
|
|
55
|
+
├── components/
|
|
56
|
+
│ └── blog-comment.com.html # Also available to all files
|
|
55
57
|
├── blog/
|
|
56
58
|
│ ├── post.html
|
|
57
|
-
│ └── comment.com.html
|
|
59
|
+
│ └── blog-comment.com.html # Takes priority for blog/post.html
|
|
58
60
|
```
|
|
59
61
|
|
|
60
62
|
In `blog/post.html`:
|
|
61
63
|
|
|
62
|
-
- `<comment>` → Finds `blog/comment.com.html` first
|
|
63
|
-
- `<header>` →
|
|
64
|
+
- `<blog-comment>` → Finds `blog/blog-comment.com.html` first (same directory)
|
|
65
|
+
- `<site-header>` → Found via glob search in the source tree
|
|
64
66
|
|
|
65
67
|
### 3. Build Process
|
|
66
68
|
|
|
@@ -50,23 +50,23 @@ Component filenames must:
|
|
|
50
50
|
Tkeron looks for components in this order:
|
|
51
51
|
|
|
52
52
|
1. **Same directory** as the file using it
|
|
53
|
-
2. **
|
|
53
|
+
2. **Any directory** in the source tree (via glob search)
|
|
54
54
|
|
|
55
55
|
**Example structure:**
|
|
56
56
|
|
|
57
57
|
```
|
|
58
58
|
websrc/
|
|
59
59
|
├── index.html
|
|
60
|
-
├── site-intro.com.md
|
|
60
|
+
├── site-intro.com.md # Available to all files
|
|
61
61
|
├── blog/
|
|
62
62
|
│ ├── post.html
|
|
63
|
-
│ └── post-footer.com.md
|
|
63
|
+
│ └── post-footer.com.md # Takes priority for blog/post.html
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
In `blog/post.html`:
|
|
67
67
|
|
|
68
|
-
- `<post-footer>` → Finds `blog/post-footer.com.md` first
|
|
69
|
-
- `<site-intro>` →
|
|
68
|
+
- `<post-footer>` → Finds `blog/post-footer.com.md` first (same directory)
|
|
69
|
+
- `<site-intro>` → Found via glob search in the source tree
|
|
70
70
|
|
|
71
71
|
### 3. Component Priority
|
|
72
72
|
|
|
@@ -84,7 +84,7 @@ Custom elements in HTML must contain at least one hyphen to distinguish them fro
|
|
|
84
84
|
Same as HTML components:
|
|
85
85
|
|
|
86
86
|
1. **Same directory** as the file using it
|
|
87
|
-
2. **
|
|
87
|
+
2. **Any directory** in the source tree (via glob search)
|
|
88
88
|
|
|
89
89
|
### IDE Support & IntelliSense
|
|
90
90
|
|
package/docs/getting-started.md
CHANGED
|
@@ -65,22 +65,20 @@ tk init my-website --force
|
|
|
65
65
|
Build your project to compile it into static files:
|
|
66
66
|
|
|
67
67
|
```bash
|
|
68
|
-
tk build
|
|
68
|
+
tk build
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
**
|
|
71
|
+
**Convention:**
|
|
72
72
|
|
|
73
|
-
-
|
|
74
|
-
-
|
|
73
|
+
- Source: `websrc/` (relative to current directory)
|
|
74
|
+
- Output: `web/` (sibling of `websrc/`)
|
|
75
75
|
|
|
76
|
-
**
|
|
76
|
+
**Using alias:**
|
|
77
77
|
|
|
78
78
|
```bash
|
|
79
|
-
tk
|
|
79
|
+
tk b
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
This uses the defaults: `websrc` → `web`
|
|
83
|
-
|
|
84
82
|
**Output structure:**
|
|
85
83
|
|
|
86
84
|
```
|
|
@@ -90,7 +88,7 @@ web/
|
|
|
90
88
|
└── ... # Other processed files
|
|
91
89
|
```
|
|
92
90
|
|
|
93
|
-
Notice that `.com.html`, `.com.ts`, and `.pre.ts` files are **not** copied to output - they're processed and inlined.
|
|
91
|
+
Notice that `.com.html`, `.com.ts`, `.com.md`, and `.pre.ts` files are **not** copied to output - they're processed and inlined.
|
|
94
92
|
|
|
95
93
|
## Start Development Server
|
|
96
94
|
|
|
@@ -110,20 +108,18 @@ This will:
|
|
|
110
108
|
**Custom configuration:**
|
|
111
109
|
|
|
112
110
|
```bash
|
|
113
|
-
tk dev
|
|
111
|
+
tk dev 8080 0.0.0.0
|
|
114
112
|
```
|
|
115
113
|
|
|
116
114
|
**Parameters:**
|
|
117
115
|
|
|
118
|
-
- Source directory (default: `websrc`)
|
|
119
|
-
- Output directory (default: `web`)
|
|
120
116
|
- Port (default: `3000`)
|
|
121
117
|
- Host (default: `localhost`)
|
|
122
118
|
|
|
123
119
|
**Example with custom port:**
|
|
124
120
|
|
|
125
121
|
```bash
|
|
126
|
-
tk dev
|
|
122
|
+
tk dev 8080
|
|
127
123
|
```
|
|
128
124
|
|
|
129
125
|
Visit `http://localhost:8080` in your browser.
|
|
@@ -202,6 +198,7 @@ Open `web/index.html` in your browser. You'll see the greeting component inlined
|
|
|
202
198
|
| `.ts` / `.js` | Scripts for pages | ✅ Yes (compiled) |
|
|
203
199
|
| `.com.html` | HTML components | ❌ No (inlined) |
|
|
204
200
|
| `.com.ts` | TypeScript components | ❌ No (inlined) |
|
|
201
|
+
| `.com.md` | Markdown components | ❌ No (inlined) |
|
|
205
202
|
| `.pre.ts` | Pre-rendering scripts | ❌ No (executed) |
|
|
206
203
|
| `.css` | Stylesheets | ✅ Yes |
|
|
207
204
|
| Images, fonts, etc. | Static assets | ✅ Yes |
|
|
@@ -212,17 +209,14 @@ Open `web/index.html` in your browser. You'll see the greeting component inlined
|
|
|
212
209
|
# Show help
|
|
213
210
|
tk
|
|
214
211
|
|
|
215
|
-
# Build
|
|
212
|
+
# Build the project
|
|
216
213
|
tk build
|
|
217
214
|
|
|
218
|
-
# Build with custom directories
|
|
219
|
-
tk build src dist
|
|
220
|
-
|
|
221
215
|
# Start dev server
|
|
222
216
|
tk dev
|
|
223
217
|
|
|
224
218
|
# Start dev server on port 8080
|
|
225
|
-
tk dev
|
|
219
|
+
tk dev 8080
|
|
226
220
|
|
|
227
221
|
# Initialize new project
|
|
228
222
|
tk init my-project
|
|
@@ -248,14 +242,14 @@ Now that you have a basic understanding:
|
|
|
248
242
|
|
|
249
243
|
### "Source directory does not exist"
|
|
250
244
|
|
|
251
|
-
Make sure you're running commands from the right directory:
|
|
245
|
+
Make sure you're running commands from the right directory and that `websrc/` exists:
|
|
252
246
|
|
|
253
247
|
```bash
|
|
254
248
|
# Check if websrc exists
|
|
255
249
|
ls websrc
|
|
256
250
|
|
|
257
|
-
# Or
|
|
258
|
-
tk
|
|
251
|
+
# Or run tk init to create a new project
|
|
252
|
+
tk init .
|
|
259
253
|
```
|
|
260
254
|
|
|
261
255
|
### "Command not found: tk"
|
|
@@ -271,11 +265,11 @@ bun install -g tkeron
|
|
|
271
265
|
Use a different port:
|
|
272
266
|
|
|
273
267
|
```bash
|
|
274
|
-
tk dev
|
|
268
|
+
tk dev 3001
|
|
275
269
|
```
|
|
276
270
|
|
|
277
271
|
### Components not working
|
|
278
272
|
|
|
279
273
|
- Component names **must** contain a hyphen: `user-card`, not `usercard`
|
|
280
274
|
- File must be named exactly: `user-card.com.html`
|
|
281
|
-
- Component files
|
|
275
|
+
- Component files can be anywhere in the source tree — Tkeron searches the same directory first, then the entire source via glob
|
package/docs/overview.md
CHANGED
|
@@ -11,6 +11,7 @@ Powered by [Bun](https://bun.sh).
|
|
|
11
11
|
- Compiles TypeScript to JavaScript
|
|
12
12
|
- Inlines HTML components (`.com.html`)
|
|
13
13
|
- Executes TypeScript components (`.com.ts`) at build time
|
|
14
|
+
- Renders Markdown components (`.com.md`) at build time
|
|
14
15
|
- Runs pre-rendering scripts (`.pre.ts`)
|
|
15
16
|
- Copies assets
|
|
16
17
|
- Dev server with hot reload
|
|
@@ -107,11 +108,12 @@ websrc/ Build Steps web/
|
|
|
107
108
|
├── index.html → 1. .pre.ts → ├── index.html
|
|
108
109
|
├── index.ts 2. .com.ts ├── index.js
|
|
109
110
|
├── index.pre.ts 3. .com.html
|
|
110
|
-
├── nav.com.html 4.
|
|
111
|
-
|
|
111
|
+
├── nav.com.html 4. .com.md
|
|
112
|
+
├── card.com.ts 5. TypeScript
|
|
113
|
+
└── info.com.md 6. Assets
|
|
112
114
|
```
|
|
113
115
|
|
|
114
|
-
Component files (`.com.html`, `.com.ts`, `.pre.ts`) are not copied to output.
|
|
116
|
+
Component files (`.com.html`, `.com.ts`, `.com.md`, `.pre.ts`) are not copied to output.
|
|
115
117
|
|
|
116
118
|
---
|
|
117
119
|
|
package/docs/pre-rendering.md
CHANGED
|
@@ -71,10 +71,13 @@ This is the parsed DOM from the corresponding `.html` file.
|
|
|
71
71
|
|
|
72
72
|
```
|
|
73
73
|
1. Run .pre.ts files → Modify HTML documents
|
|
74
|
-
2.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
2. Iterative component processing (up to 10 iterations):
|
|
75
|
+
a. Process .com.ts → Replace TypeScript components
|
|
76
|
+
b. Process .com.html → Replace HTML components
|
|
77
|
+
c. Process .com.md → Replace Markdown components
|
|
78
|
+
d. Repeat until no changes
|
|
79
|
+
3. Compile .ts to .js → TypeScript compilation
|
|
80
|
+
4. Copy to output → Final build
|
|
78
81
|
```
|
|
79
82
|
|
|
80
83
|
Pre-rendering happens **first**, so you can inject components dynamically.
|
|
@@ -1,13 +1 @@
|
|
|
1
|
-
|
|
2
|
-
declare module "*.pre.ts" {
|
|
3
|
-
global {
|
|
4
|
-
const document: Document;
|
|
5
|
-
}
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
// Augment global scope for .com.ts files
|
|
9
|
-
declare module "*.com.ts" {
|
|
10
|
-
global {
|
|
11
|
-
const com: HTMLElement;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
1
|
+
declare const com: HTMLElement;
|
package/index.ts
CHANGED
|
@@ -15,8 +15,6 @@ getCommands("tkeron", packageJson.version)
|
|
|
15
15
|
.addCommand("build")
|
|
16
16
|
.addAlias("b")
|
|
17
17
|
.addDescription("Build the project")
|
|
18
|
-
.addPositionedArgument("sourceDir")
|
|
19
|
-
.addPositionedArgument("targetDir")
|
|
20
18
|
.setCallback(buildWrapper)
|
|
21
19
|
|
|
22
20
|
.commands()
|
|
@@ -25,8 +23,6 @@ getCommands("tkeron", packageJson.version)
|
|
|
25
23
|
.addAlias("dev")
|
|
26
24
|
.addAlias("d")
|
|
27
25
|
.addDescription("Start development server")
|
|
28
|
-
.addPositionedArgument("sourceDir")
|
|
29
|
-
.addPositionedArgument("targetDir")
|
|
30
26
|
.addPositionedArgument("port")
|
|
31
27
|
.addPositionedArgument("host")
|
|
32
28
|
.setCallback(develop)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tkeron",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "CLI tool for
|
|
3
|
+
"version": "5.0.1",
|
|
4
|
+
"description": "CLI build tool for vanilla web development with TypeScript.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
7
7
|
"exports": {
|
package/src/buildWrapper.ts
CHANGED
|
@@ -3,8 +3,6 @@ import type { Logger } from "@tkeron/tools";
|
|
|
3
3
|
import { logger as defaultLogger } from "@tkeron/tools";
|
|
4
4
|
|
|
5
5
|
export interface BuildWrapperOptions {
|
|
6
|
-
sourceDir?: string;
|
|
7
|
-
targetDir?: string;
|
|
8
6
|
logger?: Logger;
|
|
9
7
|
[key: string]: any;
|
|
10
8
|
}
|
|
@@ -13,7 +11,7 @@ export const buildWrapper = async (options: BuildWrapperOptions) => {
|
|
|
13
11
|
const log = options?.logger || defaultLogger;
|
|
14
12
|
|
|
15
13
|
try {
|
|
16
|
-
await build({
|
|
14
|
+
await build({ logger: log });
|
|
17
15
|
} catch (error: any) {
|
|
18
16
|
log.error(`\n❌ Build failed: ${error.message}\n`);
|
|
19
17
|
process.exit(1);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
|
|
4
|
+
const REQUIRED_INCLUDES = ["websrc/**/*", "tkeron.d.ts"];
|
|
5
|
+
|
|
6
|
+
const DEFAULT_COMPILER_OPTIONS = {
|
|
7
|
+
target: "ESNext",
|
|
8
|
+
module: "ESNext",
|
|
9
|
+
lib: ["ESNext", "DOM"],
|
|
10
|
+
moduleResolution: "bundler",
|
|
11
|
+
strict: true,
|
|
12
|
+
skipLibCheck: true,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const createFreshTsconfig = () => ({
|
|
16
|
+
compilerOptions: { ...DEFAULT_COMPILER_OPTIONS },
|
|
17
|
+
include: [...REQUIRED_INCLUDES],
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const mergeIncludes = (existing: string[]): string[] => {
|
|
21
|
+
const merged = [...existing];
|
|
22
|
+
for (const entry of REQUIRED_INCLUDES) {
|
|
23
|
+
if (!merged.includes(entry)) {
|
|
24
|
+
merged.push(entry);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return merged;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const ensureTsconfig = (
|
|
31
|
+
targetPath: string,
|
|
32
|
+
previousTsconfig?: Record<string, unknown>,
|
|
33
|
+
) => {
|
|
34
|
+
const tsconfigPath = join(targetPath, "tsconfig.json");
|
|
35
|
+
|
|
36
|
+
if (previousTsconfig) {
|
|
37
|
+
const existingIncludes = Array.isArray(previousTsconfig.include)
|
|
38
|
+
? (previousTsconfig.include as string[])
|
|
39
|
+
: [];
|
|
40
|
+
const merged = {
|
|
41
|
+
...previousTsconfig,
|
|
42
|
+
include: mergeIncludes(existingIncludes),
|
|
43
|
+
};
|
|
44
|
+
writeFileSync(tsconfigPath, JSON.stringify(merged, null, 2));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (existsSync(tsconfigPath)) {
|
|
49
|
+
try {
|
|
50
|
+
const content = readFileSync(tsconfigPath, "utf-8");
|
|
51
|
+
const parsed = JSON.parse(content);
|
|
52
|
+
const existingIncludes = Array.isArray(parsed.include)
|
|
53
|
+
? (parsed.include as string[])
|
|
54
|
+
: [];
|
|
55
|
+
const merged = { ...parsed, include: mergeIncludes(existingIncludes) };
|
|
56
|
+
writeFileSync(tsconfigPath, JSON.stringify(merged, null, 2));
|
|
57
|
+
return;
|
|
58
|
+
} catch {
|
|
59
|
+
writeFileSync(
|
|
60
|
+
tsconfigPath,
|
|
61
|
+
JSON.stringify(createFreshTsconfig(), null, 2),
|
|
62
|
+
);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
writeFileSync(tsconfigPath, JSON.stringify(createFreshTsconfig(), null, 2));
|
|
68
|
+
};
|
package/src/init.ts
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
mkdirSync,
|
|
5
5
|
copyFileSync,
|
|
6
6
|
readFileSync,
|
|
7
|
-
writeFileSync,
|
|
8
7
|
readdirSync,
|
|
9
8
|
rmSync,
|
|
10
9
|
} from "fs";
|
|
@@ -12,6 +11,7 @@ import { join, resolve, basename } from "path";
|
|
|
12
11
|
import type { Logger } from "@tkeron/tools";
|
|
13
12
|
import { silentLogger } from "@tkeron/tools";
|
|
14
13
|
import { promptUser } from "./promptUser";
|
|
14
|
+
import { ensureTsconfig } from "./ensureTsconfig";
|
|
15
15
|
|
|
16
16
|
export interface InitOptions {
|
|
17
17
|
projectName: string;
|
|
@@ -30,6 +30,8 @@ export const init = async (options: InitOptions) => {
|
|
|
30
30
|
const targetPath = resolve(process.cwd(), projectName);
|
|
31
31
|
const isCurrentDir = projectName === "." || targetPath === process.cwd();
|
|
32
32
|
|
|
33
|
+
let skipWebsrc = false;
|
|
34
|
+
|
|
33
35
|
if (existsSync(targetPath)) {
|
|
34
36
|
if (!isCurrentDir) {
|
|
35
37
|
if (!force) {
|
|
@@ -57,18 +59,22 @@ export const init = async (options: InitOptions) => {
|
|
|
57
59
|
"\nDo you want to overwrite them? (y/N): ",
|
|
58
60
|
);
|
|
59
61
|
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
if (shouldContinue) {
|
|
63
|
+
existingTkeronFiles.forEach((file) => {
|
|
64
|
+
const filePath = join(targetPath, file);
|
|
65
|
+
rmSync(filePath, { recursive: true, force: true });
|
|
66
|
+
});
|
|
67
|
+
log.log("✓ Cleaned existing tkeron files");
|
|
68
|
+
} else {
|
|
69
|
+
skipWebsrc = existingTkeronFiles.includes("websrc");
|
|
63
70
|
}
|
|
71
|
+
} else {
|
|
72
|
+
existingTkeronFiles.forEach((file) => {
|
|
73
|
+
const filePath = join(targetPath, file);
|
|
74
|
+
rmSync(filePath, { recursive: true, force: true });
|
|
75
|
+
});
|
|
76
|
+
log.log("✓ Cleaned existing tkeron files");
|
|
64
77
|
}
|
|
65
|
-
|
|
66
|
-
existingTkeronFiles.forEach((file) => {
|
|
67
|
-
const filePath = join(targetPath, file);
|
|
68
|
-
rmSync(filePath, { recursive: true, force: true });
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
log.log("✓ Cleaned existing tkeron files");
|
|
72
78
|
}
|
|
73
79
|
}
|
|
74
80
|
}
|
|
@@ -91,36 +97,27 @@ export const init = async (options: InitOptions) => {
|
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
const tsconfigPath = join(targetPath, "tsconfig.json");
|
|
94
|
-
let
|
|
95
|
-
if (
|
|
100
|
+
let previousTsconfig: Record<string, unknown> | undefined;
|
|
101
|
+
if (existsSync(tsconfigPath)) {
|
|
96
102
|
try {
|
|
97
|
-
|
|
103
|
+
previousTsconfig = JSON.parse(readFileSync(tsconfigPath, "utf-8"));
|
|
98
104
|
} catch {
|
|
99
|
-
|
|
105
|
+
previousTsconfig = undefined;
|
|
100
106
|
}
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
mkdirSync(targetPath, { recursive: true });
|
|
104
|
-
|
|
110
|
+
const websrcInTemplate = join(templatePath, "websrc");
|
|
111
|
+
cpSync(templatePath, targetPath, {
|
|
112
|
+
recursive: true,
|
|
113
|
+
filter: skipWebsrc
|
|
114
|
+
? (src: string) =>
|
|
115
|
+
src !== websrcInTemplate && !src.startsWith(websrcInTemplate + "/")
|
|
116
|
+
: undefined,
|
|
117
|
+
});
|
|
105
118
|
copyFileSync(tkeronDtsPath, join(targetPath, "tkeron.d.ts"));
|
|
106
119
|
|
|
107
|
-
|
|
108
|
-
const templateTsconfig = JSON.parse(readFileSync(tsconfigPath, "utf-8"));
|
|
109
|
-
const requiredIncludes: string[] = Array.isArray(templateTsconfig.include)
|
|
110
|
-
? (templateTsconfig.include as string[])
|
|
111
|
-
: [];
|
|
112
|
-
const existingIncludes: string[] = Array.isArray(existingTsconfig.include)
|
|
113
|
-
? (existingTsconfig.include as string[])
|
|
114
|
-
: [];
|
|
115
|
-
const mergedIncludes = [...existingIncludes];
|
|
116
|
-
for (const entry of requiredIncludes) {
|
|
117
|
-
if (!mergedIncludes.includes(entry)) {
|
|
118
|
-
mergedIncludes.push(entry);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
const merged = { ...existingTsconfig, include: mergedIncludes };
|
|
122
|
-
writeFileSync(tsconfigPath, JSON.stringify(merged, null, 2));
|
|
123
|
-
}
|
|
120
|
+
ensureTsconfig(targetPath, previousTsconfig);
|
|
124
121
|
|
|
125
122
|
const projectDisplayName = isCurrentDir ? basename(targetPath) : projectName;
|
|
126
123
|
log.log(`✓ Created project "${projectDisplayName}"`);
|
package/src/processComTs.ts
CHANGED
|
@@ -137,7 +137,9 @@ const processComponentsTs = async (
|
|
|
137
137
|
|
|
138
138
|
const elementHTML = (child as any).outerHTML;
|
|
139
139
|
|
|
140
|
-
log.info(
|
|
140
|
+
log.info(
|
|
141
|
+
`Processing component <${tagName}> from ${componentPath.replace(rootDir, ".")}`,
|
|
142
|
+
);
|
|
141
143
|
|
|
142
144
|
const tempDoc = parseHTML(
|
|
143
145
|
"<html><body>" + elementHTML + "</body></html>",
|
|
@@ -199,7 +201,9 @@ ${codeWithoutImports}
|
|
|
199
201
|
await executeComponent(com);
|
|
200
202
|
}
|
|
201
203
|
} catch (execError: any) {
|
|
202
|
-
log.error(
|
|
204
|
+
log.error(
|
|
205
|
+
`\n❌ Error executing component <${tagName}>: ${componentPath.replace(rootDir, ".")}`,
|
|
206
|
+
);
|
|
203
207
|
log.error(` ${execError.message}`);
|
|
204
208
|
throw execError;
|
|
205
209
|
}
|
package/src/processPre.ts
CHANGED
|
@@ -7,6 +7,8 @@ const packageJsonPath = join(import.meta.dir, "..", "package.json");
|
|
|
7
7
|
const packageJson = await Bun.file(packageJsonPath).json();
|
|
8
8
|
const TKERON_VERSION = packageJson.version;
|
|
9
9
|
|
|
10
|
+
const HTML_PARSER_PATH = import.meta.resolve("@tkeron/html-parser");
|
|
11
|
+
|
|
10
12
|
const DEFAULT_HTML = `<!DOCTYPE html>
|
|
11
13
|
<html lang="en">
|
|
12
14
|
<head>
|
|
@@ -48,7 +50,7 @@ export const processPre = async (
|
|
|
48
50
|
: DEFAULT_HTML;
|
|
49
51
|
|
|
50
52
|
const modifiedCode = `
|
|
51
|
-
import { parseHTML } from
|
|
53
|
+
import { parseHTML } from ${JSON.stringify(HTML_PARSER_PATH)};
|
|
52
54
|
|
|
53
55
|
const htmlPath = ${JSON.stringify(htmlFile)};
|
|
54
56
|
const htmlContent = ${JSON.stringify(htmlContent)};
|
package/tkeron.d.ts
CHANGED
|
@@ -1,13 +1 @@
|
|
|
1
|
-
|
|
2
|
-
declare module "*.pre.ts" {
|
|
3
|
-
global {
|
|
4
|
-
const document: Document;
|
|
5
|
-
}
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
// Augment global scope for .com.ts files
|
|
9
|
-
declare module "*.com.ts" {
|
|
10
|
-
global {
|
|
11
|
-
const com: HTMLElement;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
1
|
+
declare const com: HTMLElement;
|