@heshammesalam/heshjs 0.0.0-stage → 0.2.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/README.md CHANGED
@@ -1,3 +1,52 @@
1
- # Temporary Holding Version
1
+ # HeshJS
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ An independent JavaScript/TypeScript UI framework created by Hesham. Experimental
4
+ 0.2 release with History API routing and hierarchical MVC modules.
5
+
6
+ Requires Node.js 22.12 or later.
7
+
8
+ ```sh
9
+ npm create @heshammesalam/heshjs@latest my-app
10
+ cd my-app
11
+ npm install
12
+ npm run dev
13
+ ```
14
+
15
+ For TypeScript, use `npm create @heshammesalam/heshjs@latest my-app -- --ts`.
16
+ The starter is a working HMVC SPA with nested modules, Home/About/detail/not-found
17
+ routes and a persistent shell. Each module contains model, controller, View.hesh
18
+ and module registration. See `docs/hmvc.md` for APIs, lifecycle and deployment.
19
+
20
+ ```hesh
21
+ export default view Counter {
22
+ count = 0;
23
+ h1("Count: {count}");
24
+ button("+", { count++; });
25
+ button("-", { count--; });
26
+ }
27
+ ```
28
+
29
+ For an existing Vite app, install `@heshammesalam/heshjs` and add `hesh()` from `@heshammesalam/heshjs/vite`
30
+ to your Vite plugins. Import a default `.hesh` component, then call
31
+ `mount(Component, document.querySelector('#app'))` from `@heshammesalam/heshjs`.
32
+
33
+ ESM entrypoints: `@heshammesalam/heshjs`, `@heshammesalam/heshjs/reactivity`, `@heshammesalam/heshjs/dom`, `@heshammesalam/heshjs/parser`,
34
+ `@heshammesalam/heshjs/compiler`, `@heshammesalam/heshjs/vite`,
35
+ `@heshammesalam/heshjs/router`, `@heshammesalam/heshjs/hmvc`. JavaScript and declarations are included.
36
+ The root entry contains runtime APIs only; compiler/TypeScript code stays out of
37
+ the browser unless explicitly imported. Vite is an optional peer dependency.
38
+
39
+ State is shallow: replace arrays/objects to notify. Component instances own DOM,
40
+ effects and listener cleanup. Async handlers report errors but are not automatically
41
+ canceled on unmount. Hesh edits reload the page. See `docs/grammar.md` for supported
42
+ syntax. Props, conditional rendering, keyed lists, themes, SSR and full
43
+ type checking inside `.hesh` are not yet implemented. TypeScript helpers and
44
+ consumer APIs support strict type checking.
45
+
46
+ Router navigation intercepts eligible same-origin anchors and supports nested
47
+ outlets, :params, query/hash updates, back/forward and not-found handling. Parents
48
+ remain mounted across child navigation. Refreshing a deep link requires the host
49
+ to serve index.html for application paths; the scaffold documents that setup.
50
+
51
+ This package is published without granting an open-source license (`UNLICENSED`).
52
+
@@ -0,0 +1,37 @@
1
+ import { type Module } from '../parser/index.js';
2
+ export interface CompileOptions {
3
+ filename?: string;
4
+ development?: boolean;
5
+ runtime?: string;
6
+ reactivity?: string;
7
+ }
8
+ export interface Binding {
9
+ view: string;
10
+ start: number;
11
+ end: number;
12
+ dependencies: string[];
13
+ kind: string;
14
+ }
15
+ export interface ViewIR {
16
+ name: string;
17
+ exported: boolean;
18
+ default: boolean;
19
+ instructions: string[];
20
+ }
21
+ export interface ModuleIR {
22
+ prelude: string[];
23
+ views: ViewIR[];
24
+ bindings: Binding[];
25
+ }
26
+ export interface Result {
27
+ code: string;
28
+ css: string;
29
+ metadata: Binding[];
30
+ ast: Module;
31
+ ir: ModuleIR;
32
+ }
33
+ export declare function compile(source: string, options?: CompileOptions): Result;
34
+ export declare function createCompiler(): {
35
+ compile(source: string, options?: CompileOptions): Result;
36
+ clear(): void;
37
+ };
@@ -0,0 +1,294 @@
1
+ import ts from 'typescript';
2
+ import { parse, tokenize, HeshError } from '../parser/index.js';
3
+ const printer = ts.createPrinter();
4
+ const f = ts.factory;
5
+ export function compile(source, options = {}) {
6
+ const ast = parse(source, options.filename);
7
+ const metadata = [];
8
+ const fail = (message, offset) => { throw new HeshError(message, source, offset, ast.filename); };
9
+ const names = new Set();
10
+ let defaults = 0;
11
+ const imported = new Set();
12
+ const addImport = (name, offset) => {
13
+ if (name.startsWith('__h'))
14
+ fail('Identifiers beginning __h are reserved', offset);
15
+ if (imported.has(name))
16
+ fail(`Duplicate import binding ${name}`, offset);
17
+ imported.add(name);
18
+ };
19
+ for (const item of ast.imports) {
20
+ const diagnostics = ts.transpileModule(item.source, { fileName: 'imports.js', reportDiagnostics: true, compilerOptions: { allowJs: true, module: ts.ModuleKind.ESNext } }).diagnostics;
21
+ if (diagnostics?.length)
22
+ fail(ts.flattenDiagnosticMessageText(diagnostics[0].messageText, '\n'), item.start);
23
+ const parsed = ts.createSourceFile('imports.js', item.source, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
24
+ const statement = parsed.statements[0];
25
+ if (!statement || !ts.isImportDeclaration(statement))
26
+ fail('Expected ESM import', item.start);
27
+ const clause = statement.importClause;
28
+ if (clause?.name)
29
+ addImport(clause.name.text, item.start);
30
+ const bindings = clause?.namedBindings;
31
+ if (bindings && ts.isNamedImports(bindings))
32
+ bindings.elements.forEach(e => addImport(e.name.text, item.start));
33
+ else if (bindings)
34
+ addImport(bindings.name.text, item.start);
35
+ }
36
+ for (const view of ast.views) {
37
+ if (!/^[A-Z]/.test(view.name))
38
+ fail('View names must begin with an uppercase letter', view.start);
39
+ if (names.has(view.name) || imported.has(view.name))
40
+ fail(`Duplicate component ${view.name}`, view.start);
41
+ names.add(view.name);
42
+ if (view.default && ++defaults > 1)
43
+ fail('Only one default view is allowed', view.start);
44
+ }
45
+ const prelude = [
46
+ `import { signal as __hSignal } from ${JSON.stringify(options.reactivity ?? '@heshammesalam/heshjs/reactivity')};`,
47
+ `import * as __hDOM from ${JSON.stringify(options.runtime ?? '@heshammesalam/heshjs/dom')};`,
48
+ ...ast.imports.map(i => i.source),
49
+ 'const __hUpdate = (s, delta, post) => { const value = s.get(); const old = typeof value === "bigint" ? value : +value; const next = typeof old === "bigint" ? old + BigInt(delta) : old + delta; s.set(next); return post ? old : next; };'
50
+ ];
51
+ const views = [];
52
+ for (const view of ast.views) {
53
+ const output = [];
54
+ const states = new Set(), constants = new Set();
55
+ for (const node of view.body)
56
+ if (node.kind !== 'element') {
57
+ if (states.has(node.name) || constants.has(node.name) || imported.has(node.name) || names.has(node.name))
58
+ fail(`Duplicate binding ${node.name}`, node.start);
59
+ (node.kind === 'state' ? states : constants).add(node.name);
60
+ }
61
+ let serial = 0;
62
+ const available = new Set();
63
+ const transform = (expression, handler = false, async = false) => {
64
+ const declarations = [...states, ...constants].map(name => `${constants.has(name) ? 'const' : 'let'} ${name} = undefined;`).join('\n');
65
+ const prefix = `${ast.imports.map(i => i.source).join('\n')}\n${[...names].map(n => `function ${n}() {}`).join('\n')}\nfunction __hContext() {\n${declarations}\n${async ? 'async ' : ''}function __hExpression(${handler ? 'event' : ''}) {\n${handler ? '' : 'return ('}`;
66
+ const text = prefix + expression.source + (handler ? '' : ');') + '\n}\n}';
67
+ const filename = '/__hesh_expression__.js';
68
+ const settings = { allowJs: true, checkJs: true, target: ts.ScriptTarget.ESNext, module: ts.ModuleKind.ESNext, noEmit: true };
69
+ const host = ts.createCompilerHost(settings);
70
+ const original = host.getSourceFile.bind(host);
71
+ host.getSourceFile = (name, languageVersion, onError, shouldCreate) => name === filename ? ts.createSourceFile(name, text, languageVersion, true, ts.ScriptKind.JS) : original(name, languageVersion, onError, shouldCreate);
72
+ const program = ts.createProgram([filename], settings, host);
73
+ const file = program.getSourceFile(filename);
74
+ const diagnostics = program.getSyntacticDiagnostics(file);
75
+ if (diagnostics.length) {
76
+ const d = diagnostics[0];
77
+ fail(ts.flattenDiagnosticMessageText(d.messageText, '\n'), expression.start + Math.max(0, (d.start ?? prefix.length) - prefix.length));
78
+ }
79
+ const checker = program.getTypeChecker();
80
+ const context = file.statements.find(n => ts.isFunctionDeclaration(n) && n.name?.text === '__hContext');
81
+ const symbols = new Map();
82
+ for (const stmt of context.body.statements)
83
+ if (ts.isVariableStatement(stmt)) {
84
+ const name = stmt.declarationList.declarations[0].name;
85
+ symbols.set(checker.getSymbolAtLocation(name), name.text);
86
+ }
87
+ const fn = context.body.statements.at(-1);
88
+ const dependencies = new Set();
89
+ const stateName = (node) => {
90
+ if (!ts.isIdentifier(node))
91
+ return;
92
+ const symbol = checker.getSymbolAtLocation(node);
93
+ const name = symbol ? symbols.get(symbol) : undefined;
94
+ if (name && !handler && !available.has(name))
95
+ fail(`Binding ${name} is used before initialization`, expression.start);
96
+ return name;
97
+ };
98
+ const read = (name) => f.createCallExpression(f.createPropertyAccessExpression(f.createIdentifier(name), 'get'), undefined, []);
99
+ const write = (name, value) => f.createCallExpression(f.createPropertyAccessExpression(f.createIdentifier(name), 'set'), undefined, [value]);
100
+ const result = ts.transform(fn.body, [context => {
101
+ const visit = node => {
102
+ if (ts.isIdentifier(node) && node.text.startsWith('__h'))
103
+ fail('Identifiers beginning __h are reserved', expression.start + Math.max(0, node.getStart(file) - prefix.length));
104
+ if ((ts.isPrefixUnaryExpression(node) || ts.isPostfixUnaryExpression(node)) && [ts.SyntaxKind.PlusPlusToken, ts.SyntaxKind.MinusMinusToken].includes(node.operator)) {
105
+ const name = stateName(node.operand);
106
+ if (name) {
107
+ dependencies.add(name);
108
+ if (constants.has(name))
109
+ fail(`Cannot assign constant ${name}`, expression.start);
110
+ const delta = node.operator === ts.SyntaxKind.PlusPlusToken ? f.createNumericLiteral(1) : f.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, f.createNumericLiteral(1));
111
+ return f.createCallExpression(f.createIdentifier('__hUpdate'), undefined, [f.createIdentifier(name), delta, node.kind === ts.SyntaxKind.PostfixUnaryExpression ? f.createTrue() : f.createFalse()]);
112
+ }
113
+ }
114
+ if (ts.isBinaryExpression(node) && node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment && node.operatorToken.kind <= ts.SyntaxKind.LastAssignment) {
115
+ if (ts.isArrayLiteralExpression(node.left) || ts.isObjectLiteralExpression(node.left)) {
116
+ const checkTarget = (target) => {
117
+ const name = stateName(target);
118
+ if (name)
119
+ fail('Destructuring assignments to component bindings are not supported', expression.start);
120
+ ts.forEachChild(target, checkTarget);
121
+ };
122
+ checkTarget(node.left);
123
+ }
124
+ const name = stateName(node.left);
125
+ if (name) {
126
+ dependencies.add(name);
127
+ if (constants.has(name))
128
+ fail(`Cannot assign constant ${name}`, expression.start);
129
+ const right = ts.visitNode(node.right, visit);
130
+ if (node.operatorToken.kind === ts.SyntaxKind.EqualsToken)
131
+ return write(name, right);
132
+ const operators = {
133
+ [ts.SyntaxKind.PlusEqualsToken]: ts.SyntaxKind.PlusToken, [ts.SyntaxKind.MinusEqualsToken]: ts.SyntaxKind.MinusToken,
134
+ [ts.SyntaxKind.AsteriskEqualsToken]: ts.SyntaxKind.AsteriskToken, [ts.SyntaxKind.SlashEqualsToken]: ts.SyntaxKind.SlashToken,
135
+ [ts.SyntaxKind.PercentEqualsToken]: ts.SyntaxKind.PercentToken, [ts.SyntaxKind.AsteriskAsteriskEqualsToken]: ts.SyntaxKind.AsteriskAsteriskToken,
136
+ [ts.SyntaxKind.AmpersandEqualsToken]: ts.SyntaxKind.AmpersandToken, [ts.SyntaxKind.BarEqualsToken]: ts.SyntaxKind.BarToken,
137
+ [ts.SyntaxKind.CaretEqualsToken]: ts.SyntaxKind.CaretToken, [ts.SyntaxKind.LessThanLessThanEqualsToken]: ts.SyntaxKind.LessThanLessThanToken,
138
+ [ts.SyntaxKind.GreaterThanGreaterThanEqualsToken]: ts.SyntaxKind.GreaterThanGreaterThanToken, [ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken]: ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken
139
+ };
140
+ const op = operators[node.operatorToken.kind];
141
+ if (!op)
142
+ fail('Logical assignment to state is not supported yet', expression.start);
143
+ return write(name, f.createBinaryExpression(read(name), op, right));
144
+ }
145
+ }
146
+ if (ts.isShorthandPropertyAssignment(node)) {
147
+ const symbol = checker.getShorthandAssignmentValueSymbol(node);
148
+ const name = symbol && symbols.get(symbol);
149
+ if (name && !handler && !available.has(name))
150
+ fail(`Binding ${name} is used before initialization`, expression.start);
151
+ if (name && states.has(name)) {
152
+ dependencies.add(name);
153
+ return f.createPropertyAssignment(node.name.text, read(name));
154
+ }
155
+ }
156
+ if (ts.isIdentifier(node)) {
157
+ const name = stateName(node);
158
+ if (name && !handler && !available.has(name))
159
+ fail(`Binding ${name} is used before initialization`, expression.start);
160
+ if (name && states.has(name)) {
161
+ dependencies.add(name);
162
+ return read(name);
163
+ }
164
+ }
165
+ if ((ts.isForOfStatement(node) || ts.isForInStatement(node)) && stateName(node.initializer))
166
+ fail('Use a local loop variable, then assign state in the loop body', expression.start);
167
+ return ts.visitEachChild(node, visit, context);
168
+ };
169
+ return node => ts.visitNode(node, visit);
170
+ }]);
171
+ // Report unresolved names while leaving module resolution and imported types to Vite/tsc.
172
+ for (const d of program.getSemanticDiagnostics(file))
173
+ if ((d.code < 2000 || [2304, 2552, 2588].includes(d.code)) && (d.start ?? 0) >= prefix.length && (d.start ?? 0) < prefix.length + expression.source.length) {
174
+ fail(ts.flattenDiagnosticMessageText(d.messageText, '\n'), expression.start + d.start - prefix.length);
175
+ }
176
+ const body = result.transformed[0];
177
+ metadata.push({ view: view.name, start: expression.start, end: expression.end, dependencies: [...dependencies].sort(), kind: handler ? 'event' : 'expression' });
178
+ let rendered;
179
+ if (handler)
180
+ rendered = printer.printNode(ts.EmitHint.Unspecified, body, file);
181
+ else
182
+ rendered = printer.printNode(ts.EmitHint.Expression, body.statements[0].expression, file);
183
+ result.dispose();
184
+ return rendered;
185
+ };
186
+ const value = (expr) => {
187
+ if (!expr.source.startsWith('"'))
188
+ return transform(expr);
189
+ const tokens = tokenize(expr.source);
190
+ if (tokens.length !== 1 || tokens[0].kind !== ts.SyntaxKind.StringLiteral)
191
+ return transform(expr);
192
+ const raw = expr.source.slice(1, -1);
193
+ const parts = [];
194
+ let literal = '', i = 0;
195
+ const emit = () => { if (literal) {
196
+ parts.push(JSON.stringify(literal));
197
+ literal = '';
198
+ } };
199
+ while (i < raw.length) {
200
+ if (raw[i] === '\\') {
201
+ const next = raw[++i];
202
+ const escapes = { n: '\n', r: '\r', t: '\t', b: '\b', f: '\f', v: '\v', '0': '\0' };
203
+ if (next === 'u' || next === 'x')
204
+ fail('Use single quotes for Unicode/hex escapes in literal strings', expr.start + i);
205
+ literal += escapes[next ?? ''] ?? next ?? '';
206
+ i++;
207
+ continue;
208
+ }
209
+ if (raw[i] !== '{') {
210
+ literal += raw[i++];
211
+ continue;
212
+ }
213
+ emit();
214
+ const start = ++i;
215
+ const nested = tokenize(raw.slice(start));
216
+ let depth = 1, end = -1;
217
+ for (const token of nested) {
218
+ if (token.text === '{')
219
+ depth++;
220
+ if (token.text === '}' && --depth === 0) {
221
+ end = start + token.start;
222
+ break;
223
+ }
224
+ }
225
+ if (end < 0)
226
+ fail('Unterminated text interpolation', expr.start + start);
227
+ parts.push(`String(${transform({ source: raw.slice(start, end), start: expr.start + 1 + start, end: expr.start + 1 + end })} ?? "")`);
228
+ i = end + 1;
229
+ }
230
+ emit();
231
+ return parts.length ? parts.join(' + ') : '""';
232
+ };
233
+ const emit = (node, parent) => {
234
+ if (/^[A-Z]/.test(node.name)) {
235
+ if (!names.has(node.name) && !imported.has(node.name))
236
+ fail(`Unknown component ${node.name}`, node.start);
237
+ if (node.value || node.handler || node.children.length)
238
+ fail('Component props, event blocks and slots are not supported in Milestone 1', node.start);
239
+ output.push(`__hDOM.component(${parent}, ${node.name});`);
240
+ return;
241
+ }
242
+ const id = `__hNode${serial++}`;
243
+ output.push(`const ${id} = __hDOM.element(${parent}, ${JSON.stringify(node.name)});`);
244
+ if (node.value) {
245
+ if (node.name === 'input') {
246
+ if (!states.has(node.value.source.trim()) || !available.has(node.value.source.trim()))
247
+ fail('input requires an initialized state identifier', node.value.start);
248
+ output.push(`__hDOM.input(${id}, ${node.value.source});`);
249
+ }
250
+ else if (node.name === 'image' || node.name === 'img')
251
+ output.push(`__hDOM.attribute(${id}, "src", () => ${value(node.value)});`);
252
+ else
253
+ output.push(`__hDOM.text(${id}, () => ${value(node.value)});`);
254
+ }
255
+ if (node.handler)
256
+ output.push(`__hDOM.listen(${id}, "click", ${node.async ? 'async ' : ''}(event) => ${transform(node.handler, true, node.async)});`);
257
+ node.children.forEach(child => emit(child, id));
258
+ };
259
+ for (const node of view.body) {
260
+ if (node.kind === 'element')
261
+ emit(node, '__hParent');
262
+ else {
263
+ output.push(`const ${node.name} = ${node.kind === 'state' ? '__hSignal(' : ''}${transform(node.value)}${node.kind === 'state' ? ')' : ''};`);
264
+ available.add(node.name);
265
+ }
266
+ }
267
+ views.push({ name: view.name, exported: view.exported, default: view.default, instructions: output });
268
+ }
269
+ const ir = { prelude, views, bindings: options.development === false ? [] : metadata };
270
+ const output = [...ir.prelude, ...ir.views.flatMap(view => [
271
+ `${view.exported ? 'export ' : ''}${view.default ? 'default ' : ''}function ${view.name}(__hParent) {`,
272
+ ...view.instructions.map(instruction => instruction.split('\n').map(line => ` ${line}`).join('\n')),
273
+ '}'
274
+ ])];
275
+ if (options.development !== false)
276
+ output.push(`export const __hesh = ${JSON.stringify(metadata)};`);
277
+ return { code: output.join('\n'), css: '', metadata: options.development === false ? [] : metadata, ast, ir };
278
+ }
279
+ export function createCompiler() {
280
+ const cache = new Map();
281
+ return {
282
+ compile(source, options = {}) {
283
+ const key = JSON.stringify([source, options]);
284
+ let result = cache.get(key);
285
+ if (!result) {
286
+ result = compile(source, options);
287
+ cache.set(key, result);
288
+ }
289
+ return result;
290
+ },
291
+ clear() { cache.clear(); }
292
+ };
293
+ }
294
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/compiler/index.ts"],"names":[],"mappings":"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","sourcesContent":["import ts from 'typescript';\nimport { parse, tokenize, HeshError, type Expression, type Element, type Module } from '../parser/index.js';\n\nexport interface CompileOptions { filename?: string; development?: boolean; runtime?: string; reactivity?: string }\nexport interface Binding { view: string; start: number; end: number; dependencies: string[]; kind: string }\nexport interface ViewIR { name: string; exported: boolean; default: boolean; instructions: string[] }\nexport interface ModuleIR { prelude: string[]; views: ViewIR[]; bindings: Binding[] }\nexport interface Result { code: string; css: string; metadata: Binding[]; ast: Module; ir: ModuleIR }\nconst printer = ts.createPrinter();\nconst f = ts.factory;\n\nexport function compile(source: string, options: CompileOptions = {}): Result {\n const ast = parse(source, options.filename);\n const metadata: Binding[] = [];\n const fail = (message: string, offset: number): never => { throw new HeshError(message, source, offset, ast.filename); };\n const names = new Set<string>();\n let defaults = 0;\n const imported = new Set<string>();\n const addImport = (name: string, offset: number): void => {\n if (name.startsWith('__h')) fail('Identifiers beginning __h are reserved', offset);\n if (imported.has(name)) fail(`Duplicate import binding ${name}`, offset);\n imported.add(name);\n };\n for (const item of ast.imports) {\n const diagnostics = ts.transpileModule(item.source, { fileName: 'imports.js', reportDiagnostics: true, compilerOptions: { allowJs: true, module: ts.ModuleKind.ESNext } }).diagnostics;\n if (diagnostics?.length) fail(ts.flattenDiagnosticMessageText(diagnostics[0]!.messageText, '\\n'), item.start);\n const parsed = ts.createSourceFile('imports.js', item.source, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);\n const statement = parsed.statements[0];\n if (!statement || !ts.isImportDeclaration(statement)) fail('Expected ESM import', item.start);\n const clause = (statement as ts.ImportDeclaration).importClause;\n if (clause?.name) addImport(clause.name.text, item.start);\n const bindings = clause?.namedBindings;\n if (bindings && ts.isNamedImports(bindings)) bindings.elements.forEach(e => addImport(e.name.text, item.start));\n else if (bindings) addImport(bindings.name.text, item.start);\n }\n for (const view of ast.views) {\n if (!/^[A-Z]/.test(view.name)) fail('View names must begin with an uppercase letter', view.start);\n if (names.has(view.name) || imported.has(view.name)) fail(`Duplicate component ${view.name}`, view.start);\n names.add(view.name);\n if (view.default && ++defaults > 1) fail('Only one default view is allowed', view.start);\n }\n const prelude = [\n `import { signal as __hSignal } from ${JSON.stringify(options.reactivity ?? '@heshammesalam/heshjs/reactivity')};`,\n `import * as __hDOM from ${JSON.stringify(options.runtime ?? '@heshammesalam/heshjs/dom')};`,\n ...ast.imports.map(i => i.source),\n 'const __hUpdate = (s, delta, post) => { const value = s.get(); const old = typeof value === \"bigint\" ? value : +value; const next = typeof old === \"bigint\" ? old + BigInt(delta) : old + delta; s.set(next); return post ? old : next; };'\n ];\n const views: ViewIR[] = [];\n for (const view of ast.views) {\n const output: string[] = [];\n const states = new Set<string>(), constants = new Set<string>();\n for (const node of view.body) if (node.kind !== 'element') {\n if (states.has(node.name) || constants.has(node.name) || imported.has(node.name) || names.has(node.name)) fail(`Duplicate binding ${node.name}`, node.start);\n (node.kind === 'state' ? states : constants).add(node.name);\n }\n let serial = 0;\n const available = new Set<string>();\n const transform = (expression: Expression, handler = false, async = false): string => {\n const declarations = [...states, ...constants].map(name => `${constants.has(name) ? 'const' : 'let'} ${name} = undefined;`).join('\\n');\n const prefix = `${ast.imports.map(i => i.source).join('\\n')}\\n${[...names].map(n => `function ${n}() {}`).join('\\n')}\\nfunction __hContext() {\\n${declarations}\\n${async ? 'async ' : ''}function __hExpression(${handler ? 'event' : ''}) {\\n${handler ? '' : 'return ('}`;\n const text = prefix + expression.source + (handler ? '' : ');') + '\\n}\\n}';\n const filename = '/__hesh_expression__.js';\n const settings: ts.CompilerOptions = { allowJs: true, checkJs: true, target: ts.ScriptTarget.ESNext, module: ts.ModuleKind.ESNext, noEmit: true };\n const host = ts.createCompilerHost(settings);\n const original = host.getSourceFile.bind(host);\n host.getSourceFile = (name, languageVersion, onError, shouldCreate) => name === filename ? ts.createSourceFile(name, text, languageVersion, true, ts.ScriptKind.JS) : original(name, languageVersion, onError, shouldCreate);\n const program = ts.createProgram([filename], settings, host);\n const file = program.getSourceFile(filename)!;\n const diagnostics = program.getSyntacticDiagnostics(file);\n if (diagnostics.length) {\n const d = diagnostics[0]!;\n fail(ts.flattenDiagnosticMessageText(d.messageText, '\\n'), expression.start + Math.max(0, (d.start ?? prefix.length) - prefix.length));\n }\n const checker = program.getTypeChecker();\n const context = file.statements.find(n => ts.isFunctionDeclaration(n) && n.name?.text === '__hContext') as ts.FunctionDeclaration;\n const symbols = new Map<ts.Symbol, string>();\n for (const stmt of context.body!.statements) if (ts.isVariableStatement(stmt)) {\n const name = stmt.declarationList.declarations[0]!.name as ts.Identifier;\n symbols.set(checker.getSymbolAtLocation(name)!, name.text);\n }\n const fn = context.body!.statements.at(-1) as ts.FunctionDeclaration;\n const dependencies = new Set<string>();\n const stateName = (node: ts.Node): string | undefined => {\n if (!ts.isIdentifier(node)) return;\n const symbol = checker.getSymbolAtLocation(node);\n const name = symbol ? symbols.get(symbol) : undefined;\n if (name && !handler && !available.has(name)) fail(`Binding ${name} is used before initialization`, expression.start);\n return name;\n };\n const read = (name: string) => f.createCallExpression(f.createPropertyAccessExpression(f.createIdentifier(name), 'get'), undefined, []);\n const write = (name: string, value: ts.Expression) => f.createCallExpression(f.createPropertyAccessExpression(f.createIdentifier(name), 'set'), undefined, [value]);\n const result = ts.transform(fn.body!, [context => {\n const visit: ts.Visitor = node => {\n if (ts.isIdentifier(node) && node.text.startsWith('__h')) fail('Identifiers beginning __h are reserved', expression.start + Math.max(0, node.getStart(file) - prefix.length));\n if ((ts.isPrefixUnaryExpression(node) || ts.isPostfixUnaryExpression(node)) && [ts.SyntaxKind.PlusPlusToken, ts.SyntaxKind.MinusMinusToken].includes(node.operator)) {\n const name = stateName(node.operand);\n if (name) {\n dependencies.add(name);\n if (constants.has(name)) fail(`Cannot assign constant ${name}`, expression.start);\n const delta = node.operator === ts.SyntaxKind.PlusPlusToken ? f.createNumericLiteral(1) : f.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, f.createNumericLiteral(1));\n return f.createCallExpression(f.createIdentifier('__hUpdate'), undefined, [f.createIdentifier(name), delta, node.kind === ts.SyntaxKind.PostfixUnaryExpression ? f.createTrue() : f.createFalse()]);\n }\n }\n if (ts.isBinaryExpression(node) && node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment && node.operatorToken.kind <= ts.SyntaxKind.LastAssignment) {\n if (ts.isArrayLiteralExpression(node.left) || ts.isObjectLiteralExpression(node.left)) {\n const checkTarget = (target: ts.Node): void => {\n const name = stateName(target);\n if (name) fail('Destructuring assignments to component bindings are not supported', expression.start);\n ts.forEachChild(target, checkTarget);\n };\n checkTarget(node.left);\n }\n const name = stateName(node.left);\n if (name) {\n dependencies.add(name);\n if (constants.has(name)) fail(`Cannot assign constant ${name}`, expression.start);\n const right = ts.visitNode(node.right, visit) as ts.Expression;\n if (node.operatorToken.kind === ts.SyntaxKind.EqualsToken) return write(name, right);\n const operators: Partial<Record<ts.SyntaxKind, ts.BinaryOperator>> = {\n [ts.SyntaxKind.PlusEqualsToken]: ts.SyntaxKind.PlusToken, [ts.SyntaxKind.MinusEqualsToken]: ts.SyntaxKind.MinusToken,\n [ts.SyntaxKind.AsteriskEqualsToken]: ts.SyntaxKind.AsteriskToken, [ts.SyntaxKind.SlashEqualsToken]: ts.SyntaxKind.SlashToken,\n [ts.SyntaxKind.PercentEqualsToken]: ts.SyntaxKind.PercentToken, [ts.SyntaxKind.AsteriskAsteriskEqualsToken]: ts.SyntaxKind.AsteriskAsteriskToken,\n [ts.SyntaxKind.AmpersandEqualsToken]: ts.SyntaxKind.AmpersandToken, [ts.SyntaxKind.BarEqualsToken]: ts.SyntaxKind.BarToken,\n [ts.SyntaxKind.CaretEqualsToken]: ts.SyntaxKind.CaretToken, [ts.SyntaxKind.LessThanLessThanEqualsToken]: ts.SyntaxKind.LessThanLessThanToken,\n [ts.SyntaxKind.GreaterThanGreaterThanEqualsToken]: ts.SyntaxKind.GreaterThanGreaterThanToken, [ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken]: ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken\n };\n const op = operators[node.operatorToken.kind];\n if (!op) fail('Logical assignment to state is not supported yet', expression.start);\n return write(name, f.createBinaryExpression(read(name), op!, right));\n }\n }\n if (ts.isShorthandPropertyAssignment(node)) {\n const symbol = checker.getShorthandAssignmentValueSymbol(node);\n const name = symbol && symbols.get(symbol);\n if (name && !handler && !available.has(name)) fail(`Binding ${name} is used before initialization`, expression.start);\n if (name && states.has(name)) { dependencies.add(name); return f.createPropertyAssignment(node.name.text, read(name)); }\n }\n if (ts.isIdentifier(node)) {\n const name = stateName(node);\n if (name && !handler && !available.has(name)) fail(`Binding ${name} is used before initialization`, expression.start);\n if (name && states.has(name)) { dependencies.add(name); return read(name); }\n }\n if ((ts.isForOfStatement(node) || ts.isForInStatement(node)) && stateName(node.initializer)) fail('Use a local loop variable, then assign state in the loop body', expression.start);\n return ts.visitEachChild(node, visit, context);\n };\n return node => ts.visitNode(node, visit) as ts.Block;\n }]);\n // Report unresolved names while leaving module resolution and imported types to Vite/tsc.\n for (const d of program.getSemanticDiagnostics(file)) if ((d.code < 2000 || [2304, 2552, 2588].includes(d.code)) && (d.start ?? 0) >= prefix.length && (d.start ?? 0) < prefix.length + expression.source.length) {\n fail(ts.flattenDiagnosticMessageText(d.messageText, '\\n'), expression.start + d.start! - prefix.length);\n }\n const body = result.transformed[0] as ts.Block;\n metadata.push({ view: view.name, start: expression.start, end: expression.end, dependencies: [...dependencies].sort(), kind: handler ? 'event' : 'expression' });\n let rendered: string;\n if (handler) rendered = printer.printNode(ts.EmitHint.Unspecified, body, file);\n else rendered = printer.printNode(ts.EmitHint.Expression, (body.statements[0] as ts.ReturnStatement).expression!, file);\n result.dispose();\n return rendered;\n };\n const value = (expr: Expression): string => {\n if (!expr.source.startsWith('\"')) return transform(expr);\n const tokens = tokenize(expr.source);\n if (tokens.length !== 1 || tokens[0]!.kind !== ts.SyntaxKind.StringLiteral) return transform(expr);\n const raw = expr.source.slice(1, -1);\n const parts: string[] = [];\n let literal = '', i = 0;\n const emit = () => { if (literal) { parts.push(JSON.stringify(literal)); literal = ''; } };\n while (i < raw.length) {\n if (raw[i] === '\\\\') {\n const next = raw[++i];\n const escapes: Record<string, string> = { n: '\\n', r: '\\r', t: '\\t', b: '\\b', f: '\\f', v: '\\v', '0': '\\0' };\n if (next === 'u' || next === 'x') fail('Use single quotes for Unicode/hex escapes in literal strings', expr.start + i);\n literal += escapes[next ?? ''] ?? next ?? ''; i++; continue;\n }\n if (raw[i] !== '{') { literal += raw[i++]; continue; }\n emit(); const start = ++i;\n const nested = tokenize(raw.slice(start)); let depth = 1, end = -1;\n for (const token of nested) { if (token.text === '{') depth++; if (token.text === '}' && --depth === 0) { end = start + token.start; break; } }\n if (end < 0) fail('Unterminated text interpolation', expr.start + start);\n parts.push(`String(${transform({ source: raw.slice(start, end), start: expr.start + 1 + start, end: expr.start + 1 + end })} ?? \"\")`);\n i = end + 1;\n }\n emit(); return parts.length ? parts.join(' + ') : '\"\"';\n };\n const emit = (node: Element, parent: string): void => {\n if (/^[A-Z]/.test(node.name)) {\n if (!names.has(node.name) && !imported.has(node.name)) fail(`Unknown component ${node.name}`, node.start);\n if (node.value || node.handler || node.children.length) fail('Component props, event blocks and slots are not supported in Milestone 1', node.start);\n output.push(`__hDOM.component(${parent}, ${node.name});`); return;\n }\n const id = `__hNode${serial++}`;\n output.push(`const ${id} = __hDOM.element(${parent}, ${JSON.stringify(node.name)});`);\n if (node.value) {\n if (node.name === 'input') {\n if (!states.has(node.value.source.trim()) || !available.has(node.value.source.trim())) fail('input requires an initialized state identifier', node.value.start);\n output.push(`__hDOM.input(${id}, ${node.value.source});`);\n } else if (node.name === 'image' || node.name === 'img') output.push(`__hDOM.attribute(${id}, \"src\", () => ${value(node.value)});`);\n else output.push(`__hDOM.text(${id}, () => ${value(node.value)});`);\n }\n if (node.handler) output.push(`__hDOM.listen(${id}, \"click\", ${node.async ? 'async ' : ''}(event) => ${transform(node.handler, true, node.async)});`);\n node.children.forEach(child => emit(child, id));\n };\n for (const node of view.body) {\n if (node.kind === 'element') emit(node, '__hParent');\n else { output.push(`const ${node.name} = ${node.kind === 'state' ? '__hSignal(' : ''}${transform(node.value)}${node.kind === 'state' ? ')' : ''};`); available.add(node.name); }\n }\n views.push({ name: view.name, exported: view.exported, default: view.default, instructions: output });\n }\n const ir: ModuleIR = { prelude, views, bindings: options.development === false ? [] : metadata };\n const output = [...ir.prelude, ...ir.views.flatMap(view => [\n `${view.exported ? 'export ' : ''}${view.default ? 'default ' : ''}function ${view.name}(__hParent) {`,\n ...view.instructions.map(instruction => instruction.split('\\n').map(line => ` ${line}`).join('\\n')),\n '}'\n ])];\n if (options.development !== false) output.push(`export const __hesh = ${JSON.stringify(metadata)};`);\n return { code: output.join('\\n'), css: '', metadata: options.development === false ? [] : metadata, ast, ir };\n}\n\nexport function createCompiler() {\n const cache = new Map<string, Result>();\n return {\n compile(source: string, options: CompileOptions = {}) {\n const key = JSON.stringify([source, options]);\n let result = cache.get(key);\n if (!result) { result = compile(source, options); cache.set(key, result); }\n return result;\n },\n clear() { cache.clear(); }\n };\n}\n\r\n"]}
@@ -0,0 +1,12 @@
1
+ import { type Signal, type Disposer } from '../reactivity/index.js';
2
+ export type Component = (parent: Node) => void;
3
+ export interface MountOptions {
4
+ onError?: (error: unknown) => void;
5
+ }
6
+ export declare function mount(component: Component, parent: Node, options?: MountOptions): Disposer;
7
+ export declare function element(parent: Node, name: string): HTMLElement;
8
+ export declare function text(parent: Node, read: () => unknown): void;
9
+ export declare function attribute(node: HTMLElement, name: string, read: () => unknown): void;
10
+ export declare function listen(node: HTMLElement, name: string, handler: (event: Event) => unknown): void;
11
+ export declare function input(node: HTMLInputElement, state: Signal<unknown>): void;
12
+ export declare function component(parent: Node, view: Component): void;
@@ -0,0 +1,69 @@
1
+ import { effect, onCleanup, scope, batch } from '../reactivity/index.js';
2
+ let errorHandler = error => console.error(error);
3
+ const aliases = { text: 'span', card: 'div', row: 'div', stack: 'div', grid: 'div', image: 'img', link: 'a' };
4
+ export function mount(component, parent, options = {}) {
5
+ const previous = errorHandler;
6
+ errorHandler = options.onError ?? previous;
7
+ try {
8
+ return scope(() => component(parent)).dispose;
9
+ }
10
+ finally {
11
+ errorHandler = previous;
12
+ }
13
+ }
14
+ export function element(parent, name) {
15
+ const node = parent.ownerDocument.createElement(aliases[name] ?? name);
16
+ parent.appendChild(node);
17
+ onCleanup(() => node.remove());
18
+ return node;
19
+ }
20
+ export function text(parent, read) {
21
+ const node = parent.ownerDocument.createTextNode('');
22
+ parent.appendChild(node);
23
+ onCleanup(() => node.remove());
24
+ effect(() => { node.data = String(read() ?? ''); });
25
+ }
26
+ function safeURL(value) {
27
+ // Parse like a browser, including embedded ASCII tabs/newlines.
28
+ const normalized = value.replace(/[\u0000-\u0020]/g, '');
29
+ const scheme = /^([a-z][a-z\d+.-]*):/i.exec(normalized)?.[1]?.toLowerCase();
30
+ if (scheme && !['http', 'https', 'mailto', 'tel'].includes(scheme)) {
31
+ throw new Error(`Unsafe URL scheme: ${scheme}`);
32
+ }
33
+ return value;
34
+ }
35
+ export function attribute(node, name, read) {
36
+ if (/^on/i.test(name) || ['innerhtml', 'outerhtml', 'srcdoc'].includes(name.toLowerCase()))
37
+ throw new Error(`Unsafe attribute: ${name}`);
38
+ effect(() => {
39
+ const value = read();
40
+ if (value == null || value === false)
41
+ node.removeAttribute(name);
42
+ else {
43
+ const rendered = value === true ? '' : String(value);
44
+ node.setAttribute(name, ['href', 'src', 'action', 'formaction', 'poster', 'xlink:href'].includes(name.toLowerCase()) ? safeURL(rendered) : rendered);
45
+ }
46
+ });
47
+ }
48
+ export function listen(node, name, handler) {
49
+ const report = errorHandler;
50
+ const listener = (event) => {
51
+ try {
52
+ Promise.resolve(batch(() => handler(event))).catch(report);
53
+ }
54
+ catch (error) {
55
+ report(error);
56
+ }
57
+ };
58
+ node.addEventListener(name, listener);
59
+ onCleanup(() => node.removeEventListener(name, listener));
60
+ }
61
+ export function input(node, state) {
62
+ effect(() => { const value = String(state.get() ?? ''); if (node.value !== value)
63
+ node.value = value; });
64
+ listen(node, 'input', () => state.set(node.value));
65
+ }
66
+ export function component(parent, view) {
67
+ scope(() => view(parent));
68
+ }
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dom/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { effect, onCleanup, scope, batch, type Signal, type Disposer } from '../reactivity/index.js';\nexport type Component = (parent: Node) => void;\nexport interface MountOptions { onError?: (error: unknown) => void }\nlet errorHandler: (error: unknown) => void = error => console.error(error);\nconst aliases: Record<string, string> = { text: 'span', card: 'div', row: 'div', stack: 'div', grid: 'div', image: 'img', link: 'a' };\n\nexport function mount(component: Component, parent: Node, options: MountOptions = {}): Disposer {\n const previous = errorHandler;\n errorHandler = options.onError ?? previous;\n try { return scope(() => component(parent)).dispose; }\n finally { errorHandler = previous; }\n}\n\nexport function element(parent: Node, name: string): HTMLElement {\n const node = parent.ownerDocument!.createElement(aliases[name] ?? name);\n parent.appendChild(node);\n onCleanup(() => node.remove());\n return node;\n}\n\nexport function text(parent: Node, read: () => unknown): void {\n const node = parent.ownerDocument!.createTextNode('');\n parent.appendChild(node);\n onCleanup(() => node.remove());\n effect(() => { node.data = String(read() ?? ''); });\n}\n\nfunction safeURL(value: string): string {\n // Parse like a browser, including embedded ASCII tabs/newlines.\n const normalized = value.replace(/[\\u0000-\\u0020]/g, '');\n const scheme = /^([a-z][a-z\\d+.-]*):/i.exec(normalized)?.[1]?.toLowerCase();\n if (scheme && !['http', 'https', 'mailto', 'tel'].includes(scheme)) {\n throw new Error(`Unsafe URL scheme: ${scheme}`);\n }\n return value;\n}\n\nexport function attribute(node: HTMLElement, name: string, read: () => unknown): void {\n if (/^on/i.test(name) || ['innerhtml', 'outerhtml', 'srcdoc'].includes(name.toLowerCase())) throw new Error(`Unsafe attribute: ${name}`);\n effect(() => {\n const value = read();\n if (value == null || value === false) node.removeAttribute(name);\n else {\n const rendered = value === true ? '' : String(value);\n node.setAttribute(name, ['href', 'src', 'action', 'formaction', 'poster', 'xlink:href'].includes(name.toLowerCase()) ? safeURL(rendered) : rendered);\n }\n });\n}\n\nexport function listen(node: HTMLElement, name: string, handler: (event: Event) => unknown): void {\n const report = errorHandler;\n const listener = (event: Event) => {\n try { Promise.resolve(batch(() => handler(event))).catch(report); }\n catch (error) { report(error); }\n };\n node.addEventListener(name, listener);\n onCleanup(() => node.removeEventListener(name, listener));\n}\n\nexport function input(node: HTMLInputElement, state: Signal<unknown>): void {\n effect(() => { const value = String(state.get() ?? ''); if (node.value !== value) node.value = value; });\n listen(node, 'input', () => state.set(node.value));\n}\n\nexport function component(parent: Node, view: Component): void {\n scope(() => view(parent));\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export { signal, effect, derived, batch, scope, onCleanup, untrack } from '../reactivity/index.js';
2
+ export type { Signal, Disposer } from '../reactivity/index.js';
3
+ export { mount, element, text, attribute, listen, input, component } from '../dom/index.js';
4
+ export type { Component, MountOptions } from '../dom/index.js';
@@ -0,0 +1,3 @@
1
+ export { signal, effect, derived, batch, scope, onCleanup, untrack } from '../reactivity/index.js';
2
+ export { mount, element, text, attribute, listen, input, component } from '../dom/index.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/heshjs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEnG,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC","sourcesContent":["export { signal, effect, derived, batch, scope, onCleanup, untrack } from '../reactivity/index.js';\nexport type { Signal, Disposer } from '../reactivity/index.js';\nexport { mount, element, text, attribute, listen, input, component } from '../dom/index.js';\nexport type { Component, MountOptions } from '../dom/index.js';\n"]}
@@ -0,0 +1,35 @@
1
+ import { type Component, type MountOptions } from '../dom/index.js';
2
+ import { type Signal, type Disposer } from '../reactivity/index.js';
3
+ export interface RouteLocation {
4
+ readonly url: URL;
5
+ readonly pathname: string;
6
+ readonly params: Readonly<Record<string, string>>;
7
+ readonly query: URLSearchParams;
8
+ readonly hash: string;
9
+ }
10
+ export interface ModuleContext<M = unknown, C = unknown> {
11
+ readonly route: Pick<Signal<RouteLocation>, 'get'>;
12
+ readonly parent?: ModuleContext;
13
+ readonly model: M;
14
+ readonly controller: C;
15
+ }
16
+ export interface ModuleDefinition<M, C> {
17
+ model: (context: Pick<ModuleContext, 'route' | 'parent'>) => M;
18
+ controller: (model: M, context: Pick<ModuleContext, 'route' | 'parent'>) => C;
19
+ view: Component;
20
+ }
21
+ export interface MountedModule {
22
+ readonly context: ModuleContext;
23
+ readonly outlet?: Node;
24
+ readonly dispose: Disposer;
25
+ update(location: RouteLocation): void;
26
+ }
27
+ export interface AppModule {
28
+ attach(parent: Node, location: RouteLocation, parentContext?: ModuleContext, options?: MountOptions): MountedModule;
29
+ }
30
+ export declare function useModule<M = unknown, C = unknown>(): ModuleContext<M, C>;
31
+ export declare function useController<C = unknown>(): C;
32
+ export declare function useModel<M = unknown>(): M;
33
+ /** Child route outlet. Import this component in a .hesh layout and call Outlet(). */
34
+ export declare function Outlet(parent: Node): void;
35
+ export declare function defineModule<M, C>(definition: ModuleDefinition<M, C>): AppModule;