@progalaxyelabs/htms-cli 0.4.1 → 0.5.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.
package/bin/htms.js CHANGED
@@ -23,9 +23,12 @@ program
23
23
  // Compile command
24
24
  program
25
25
  .command('compile')
26
- .description('Compile .htms file to TypeScript')
26
+ .description('Compile .htms file to TypeScript or HTML')
27
27
  .argument('<input>', 'Input .htms file')
28
28
  .option('-o, --output <dir>', 'Output directory', 'dist')
29
+ .option('-f, --format <format>', 'Output format: typescript or html', 'typescript')
30
+ .option('-t, --template <file>', 'HTML template file to inject into (only for html format)')
31
+ .option('-s, --split-templates', 'Split templates into separate files for lazy loading (only for html format)')
29
32
  .option('-w, --watch', 'Watch for changes')
30
33
  .option('-q, --quiet', 'Suppress output')
31
34
  .action(async (input, options) => {
package/dist/router.ts ADDED
@@ -0,0 +1,77 @@
1
+ // Generated by HTMS Compiler
2
+ // Do not edit manually
3
+
4
+ interface RouterConfig {
5
+ mode: 'hash' | 'history';
6
+ routes: Record<string, () => void>;
7
+ notFound: () => void;
8
+ }
9
+
10
+ class Router {
11
+ constructor(config: RouterConfig) {
12
+ const handleRoute = () => {
13
+ const hash = window.location.hash.slice(1) || '/';
14
+ const handler = config.routes[hash];
15
+ if (handler) {
16
+ handler();
17
+ } else {
18
+ config.notFound();
19
+ }
20
+ };
21
+ window.addEventListener('hashchange', handleRoute);
22
+ handleRoute();
23
+ }
24
+ }
25
+
26
+ import { HomePage } from './templates';
27
+
28
+ // Application context
29
+ let context: Record<string, unknown> = {};
30
+ let currentPage: string = '';
31
+ const appContainer = document.getElementById('app');
32
+
33
+ export function getContext(): Record<string, unknown> {
34
+ return context;
35
+ }
36
+
37
+ export function setContext(data: Record<string, unknown>): void {
38
+ context = data;
39
+ }
40
+
41
+ export function rerender(): void {
42
+ if (currentPage && appContainer) {
43
+ const renderer = routes[currentPage];
44
+ if (renderer) {
45
+ appContainer.innerHTML = '';
46
+ appContainer.appendChild(renderer(context));
47
+ }
48
+ }
49
+ }
50
+
51
+ // Route definitions
52
+ const routes: Record<string, (ctx: Record<string, unknown>) => HTMLElement> = {
53
+ '/': HomePage,
54
+ };
55
+
56
+ function renderPage(route: string): void {
57
+ currentPage = route;
58
+ const renderer = routes[route];
59
+ if (renderer && appContainer) {
60
+ appContainer.innerHTML = '';
61
+ appContainer.appendChild(renderer(context));
62
+ } else if (appContainer) {
63
+ const el = document.createElement('h1');
64
+ el.textContent = '404 - Page Not Found';
65
+ appContainer.innerHTML = '';
66
+ appContainer.appendChild(el);
67
+ }
68
+ }
69
+
70
+ // Create router
71
+ export const router = new Router({
72
+ mode: 'hash',
73
+ routes: {
74
+ '/': () => renderPage('/'),
75
+ },
76
+ notFound: () => renderPage('__404__'),
77
+ });
@@ -0,0 +1,69 @@
1
+ // Generated by HTMS Compiler
2
+ // Do not edit manually
3
+
4
+ export type Context = Record<string, unknown>;
5
+
6
+ export function TodoItem(ctx: Context): HTMLElement {
7
+ const el0 = document.createElement('div');
8
+ el0.className = 'todo-item';
9
+ const el1 = document.createElement('input');
10
+ el1.type = 'checkbox';
11
+ el0.appendChild(el1);
12
+ const el2 = document.createElement('span');
13
+ el2.className = 'todo-title';
14
+ const el3 = document.createTextNode('Todo title');
15
+ el2.appendChild(el3);
16
+ el0.appendChild(el2);
17
+ const el4 = document.createElement('span');
18
+ el4.className = 'todo-date';
19
+ const el5 = document.createTextNode('Date');
20
+ el4.appendChild(el5);
21
+ el0.appendChild(el4);
22
+ const el6 = document.createElement('button');
23
+ el6.className = 'delete-btn';
24
+ const el7 = document.createTextNode('×');
25
+ el6.appendChild(el7);
26
+ el0.appendChild(el6);
27
+ return el0;
28
+ }
29
+
30
+ export function EmptyState(ctx: Context): HTMLElement {
31
+ const el0 = document.createElement('p');
32
+ el0.className = 'empty';
33
+ const el1 = document.createTextNode('No todos yet. Add one above!');
34
+ el0.appendChild(el1);
35
+ return el0;
36
+ }
37
+
38
+ export function HomePage(ctx: Context): HTMLElement {
39
+ const el0 = document.createElement('main');
40
+ el0.className = 'container';
41
+ const el1 = document.createElement('h1');
42
+ const el2 = document.createTextNode('My Todos');
43
+ el1.appendChild(el2);
44
+ el0.appendChild(el1);
45
+ const el3 = document.createElement('p');
46
+ el3.className = 'subtitle';
47
+ const el4 = document.createTextNode('Simple todo app with localStorage');
48
+ el3.appendChild(el4);
49
+ el0.appendChild(el3);
50
+ const el5 = document.createElement('div');
51
+ el5.className = 'add-todo';
52
+ const el6 = document.createElement('input');
53
+ el6.type = 'text';
54
+ el6.id = 'todoInput';
55
+ el6.placeholder = 'What needs to be done?';
56
+ el5.appendChild(el6);
57
+ const el7 = document.createElement('button');
58
+ el7.id = 'addBtn';
59
+ const el8 = document.createTextNode('Add Todo');
60
+ el7.appendChild(el8);
61
+ el5.appendChild(el7);
62
+ el0.appendChild(el5);
63
+ const el9 = document.createElement('div');
64
+ el9.id = 'todoList';
65
+ el9.className = 'todo-list';
66
+ el0.appendChild(el9);
67
+ return el0;
68
+ }
69
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progalaxyelabs/htms-cli",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "CLI for HTMS compiler",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,10 +19,10 @@
19
19
  "compiler",
20
20
  "cli"
21
21
  ],
22
- "author": "ProGalaxy Labs",
22
+ "author": "ProGalaxy eLabs <info@progalaxyelabs.com>",
23
23
  "license": "MIT",
24
24
  "dependencies": {
25
- "@progalaxyelabs/htms-compiler": "^0.4.1",
25
+ "@progalaxyelabs/htms-compiler": "^0.5.0",
26
26
  "chokidar": "^3.5.0",
27
27
  "commander": "^11.0.0",
28
28
  "picocolors": "^1.0.0"
package/src/compiler.js CHANGED
@@ -1,4 +1,4 @@
1
- import { compile_wasm, init } from '@progalaxyelabs/htms-compiler';
1
+ import { compile_wasm, compile_with_options_wasm, init } from '@progalaxyelabs/htms-compiler';
2
2
  import { readFile, writeFile, mkdir } from 'fs/promises';
3
3
  import { dirname, join, basename } from 'path';
4
4
  import { printDiagnostics } from './format-errors.js';
@@ -14,7 +14,7 @@ async function ensureWasmInit() {
14
14
  }
15
15
 
16
16
  /**
17
- * Compile HTMS file to TypeScript
17
+ * Compile HTMS file to TypeScript or HTML
18
18
  * @param {string} inputPath - Path to .htms file
19
19
  * @param {string} outputDir - Output directory for generated files
20
20
  * @param {object} options - Compilation options
@@ -26,8 +26,27 @@ export async function compileFile(inputPath, outputDir, options = {}) {
26
26
  // Read source file
27
27
  const source = await readFile(inputPath, 'utf-8');
28
28
 
29
+ // Read template file if provided
30
+ let templateHtml = undefined;
31
+ if (options.template) {
32
+ templateHtml = await readFile(options.template, 'utf-8');
33
+ }
34
+
35
+ // Get source filename for HTML output (e.g., "app.htms" -> "app.html")
36
+ const sourceFilename = basename(inputPath, '.htms') + '.html';
37
+
38
+ // Prepare compile options
39
+ const compileOptions = {
40
+ output_format: options.format || 'typescript',
41
+ generate_router: true,
42
+ generate_events: true,
43
+ template_html: templateHtml,
44
+ source_filename: sourceFilename,
45
+ split_templates: options.splitTemplates || false,
46
+ };
47
+
29
48
  // Compile using WASM
30
- const result = compile_wasm(source);
49
+ const result = compile_with_options_wasm(source, compileOptions);
31
50
 
32
51
  // Print diagnostics
33
52
  if (result.diagnostics && result.diagnostics.length > 0) {
Binary file