thoth-markup-lang 10.5.0 → 12.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 (4) hide show
  1. package/README.md +223 -23
  2. package/engine.php +287 -31
  3. package/package.json +20 -4
  4. package/thoth.js +367 -115
package/thoth.js CHANGED
@@ -1,20 +1,39 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * THOTH Engine v10.5.0 - The Sovereign Architect (Intelligence Suite)
5
- * Lead Developer: Engineer Abdelfatah Abdelhamed
4
+ * THOTH Engine v12.0.0 - The Sovereign Cloud (Intelligence Suite)
5
+ * Lead Developer & Architect: Engineer Abdelfatah Abdelhamed 🇪🇬
6
6
  * ------------------------------------------------------------------
7
- * الميزات المدمجة:
7
+ * الميزات المدمجة (النسخة النهائية):
8
8
  * 1. Strict Identification: إلزامية وجود TYPE THOTH في السطر الأول.
9
9
  * 2. Middleware Support: نظام Auth Guard المتقدم لتصفية العناصر.
10
10
  * 3. Dynamic Meta Engine: توليد وسوم الميتا تلقائياً من سياق البيانات.
11
11
  * 4. Dev Server & Live Reload: خادم محلي لمراقبة التغييرات لحظياً.
12
12
  * 5. Recursive Data Engine: نظام الـ Loops والـ JSON والـ Variables.
13
+ * 6. Python-Style Traceback: متتبع أخطاء ذكي ودقيق جداً.
14
+ * 7. Ultra-Fast Parser: تسريع خوارزميات الـ Indentation.
15
+ * 8. Sovereign Components: القدرة على تعريف وإعادة استخدام المكونات.
16
+ * 9. State Management: حقن متغيرات الحالة لإنشاء واجهات تفاعلية.
17
+ * 10. Layout Engine: نظام شبكات مدمج (Row / Column) بخواص Flexbox.
18
+ * 11. Smart Routing: نظام تنقل داخلي مدمج لبناء تطبيقات SPA.
19
+ * 12. API Fetch Engine [NEW]: محرك لاتزامني (Async) لجلب بيانات الـ APIs.
13
20
  */
14
21
 
15
22
  const fs = require('fs');
16
23
  const path = require('path');
17
24
  const http = require('http');
25
+ const https = require('https');
26
+
27
+ // --- كلاس تتبع الأخطاء الذكي (Python-Style Error Traceback) ---
28
+ class ThothSyntaxError extends Error {
29
+ constructor(message, lineNum, lineContent, filePath) {
30
+ super(message);
31
+ this.name = 'ThothSyntaxError';
32
+ this.lineNum = lineNum;
33
+ this.lineContent = lineContent;
34
+ this.filePath = filePath;
35
+ }
36
+ }
18
37
 
19
38
  // --- القاموس المعماري الشامل ---
20
39
  const TAG_MAP = {
@@ -23,17 +42,17 @@ const TAG_MAP = {
23
42
  'Header': 'header', 'Footer': 'footer', 'Article': 'article', 'Aside': 'aside',
24
43
  'Link': 'a', 'Image': 'img', 'Button': 'button', 'List': 'ul', 'Item': 'li',
25
44
  'Input': 'input', 'Form': 'form', 'Label': 'label', 'Break': 'br', 'Line': 'hr',
26
- 'Main': 'main', 'Layout': 'section'
45
+ 'Main': 'main', 'Layout': 'section',
46
+ 'Row': 'div', 'Column': 'div'
27
47
  };
28
48
 
29
49
  const VOID_ELEMENTS = ['img', 'br', 'hr', 'input', 'meta', 'link'];
30
50
 
31
- // --- سياق التشغيل السيادي ---
32
- let dataContext = {};
33
- let config = {
51
+ // --- سياق التشغيل السيادي العام ---
52
+ let globalConfig = {
34
53
  devMode: process.argv.includes('--dev') || process.argv.includes('serve'),
35
54
  port: 3000,
36
- currentUserRole: 'admin', // القيمة الافتراضية لمحاكاة الميدلوير
55
+ currentUserRole: 'admin',
37
56
  strictMode: true
38
57
  };
39
58
 
@@ -46,118 +65,243 @@ if (!command || (!target && command !== 'serve')) {
46
65
  process.exit(1);
47
66
  }
48
67
 
49
- /**
50
- * عرض إرشادات الاستخدام التقنية
51
- */
52
68
  function displayUsage() {
53
69
  const yellow = '\x1b[33m';
70
+ const cyan = '\x1b[36m';
54
71
  const reset = '\x1b[0m';
55
72
  console.log(yellow + '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━' + reset);
56
- console.log('\x1b[1m\x1b[32m THOTH INTELLIGENCE SUITE v10.5.0 \x1b[0m');
57
- console.log(yellow + ' Lead Architect: Abdelfatah Abdelhamed' + reset);
73
+ console.log('\x1b[1m\x1b[32m THOTH INTELLIGENCE SUITE v12.0.0 (The Sovereign Cloud) \x1b[0m');
74
+ console.log(cyan + ' Lead Architect: Engineer Abdelfatah Abdelhamed' + reset);
58
75
  console.log(yellow + '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━' + reset);
59
76
  console.log(' Usage:');
60
77
  console.log(' thoth build [file].thoth (Production Compilation)');
61
- console.log(' thoth serve [file].thoth (Live Dev Server + Reload)');
78
+ console.log(' thoth serve [file].thoth (Live SPA Server + Traceback)');
62
79
  }
63
80
 
64
- /**
65
- * معالجة البيانات الديناميكية @{{key}} و @Variable
66
- */
81
+ // --- محرك الاتصال الخارجي السيادي (متوافق مع كل نسخ Node) ---
82
+ function fetchJSON(url) {
83
+ return new Promise((resolve, reject) => {
84
+ const client = url.startsWith('https') ? https : http;
85
+ client.get(url, { headers: { 'User-Agent': 'THOTH-Sovereign-Engine/12.0' } }, (res) => {
86
+ let data = '';
87
+ res.on('data', chunk => data += chunk);
88
+ res.on('end', () => {
89
+ if (res.statusCode >= 200 && res.statusCode < 300) {
90
+ try { resolve(JSON.parse(data)); }
91
+ catch (e) { reject(new Error('Invalid JSON response format.')); }
92
+ } else {
93
+ reject(new Error(`HTTP Error: ${res.statusCode}`));
94
+ }
95
+ });
96
+ }).on('error', reject);
97
+ });
98
+ }
99
+
100
+ const DATA_REGEX = /@\{\{([^}]+)\}\}/g;
67
101
  function resolveData(text, context, variables = {}) {
68
- // 1. استبدال المتغيرات @Var
69
102
  let resolved = text;
70
103
  for (const [key, val] of Object.entries(variables)) {
71
104
  resolved = resolved.replace(new RegExp(key, 'g'), val);
72
105
  }
73
- // 2. استبدال بيانات JSON @{{key}}
74
- return resolved.replace(/@\{\{([^}]+)\}\}/g, (match, key) => {
106
+ return resolved.replace(DATA_REGEX, (match, key) => {
75
107
  const val = context[key.trim()];
76
108
  return val !== undefined ? val : match;
77
109
  });
78
110
  }
79
111
 
112
+ function injectStateText(text, stateVars) {
113
+ let processedText = text;
114
+ for (const [key, val] of Object.entries(stateVars)) {
115
+ const token = `@{{${key}}}`;
116
+ if (processedText.includes(token)) {
117
+ processedText = processedText.replace(new RegExp(token, 'g'), `<span data-thoth-state="${key}">${val}</span>`);
118
+ }
119
+ }
120
+ return processedText;
121
+ }
122
+
123
+ function injectStateBindings(attrs) {
124
+ const match = attrs.match(/action="([^"]+)"/);
125
+ if (match) {
126
+ const actionStr = match[1];
127
+ const jsAction = `thothState.dispatch('${actionStr}')`;
128
+ return attrs.replace(/action="[^"]+"/, `onclick="${jsAction}"`);
129
+ }
130
+ return attrs;
131
+ }
132
+
80
133
  /**
81
- * محرك التجميع المعماري
134
+ * المحرك الأساسي (تحول إلى Async/Await لدعم السحابة السيادية)
82
135
  */
83
- function compileThoth(inputPath, isDev = false) {
84
- if (!fs.existsSync(inputPath)) throw new Error(`Source Integrity Error: "${inputPath}" not found.`);
85
-
86
- const source = fs.readFileSync(inputPath, 'utf8');
87
- const lines = source.split(/\r?\n/);
136
+ async function compileThothEngine(sourceContent, inputPath, isDev = false, isSubCall = false, inheritedContext = {}, inheritedComponents = {}, requestedRoute = '/') {
137
+ const lines = sourceContent.split(/\r?\n/);
88
138
 
89
- // --- التحقق من شرط السيادة الأول ---
90
139
  if (lines[0].trim() !== "TYPE THOTH") {
91
- throw new Error("Architectural Identity Error: File must start with 'TYPE THOTH' to ensure sovereignty.");
140
+ throw new ThothSyntaxError("Architectural Identity Error: Missing 'TYPE THOTH' protocol.", 1, lines[0], inputPath);
92
141
  }
93
142
 
94
143
  let htmlContent = "";
95
144
  let stack = [];
96
- let variables = {};
145
+
146
+ let dataContext = { ...inheritedContext.dataContext };
147
+ let variables = { ...inheritedContext.variables };
148
+ let stateVars = { ...inheritedContext.stateVars };
149
+ let componentsContext = { ...inheritedComponents };
150
+
97
151
  let rawScope = { active: false, type: '', indent: 0 };
98
152
  let skipIndent = -1;
99
153
  let repeatScope = { active: false, key: '', indent: 0, buffer: [] };
154
+
155
+ let componentScope = { active: false, name: '', indent: 0, buffer: [] };
100
156
 
101
- for (let i = 1; i < lines.length; i++) { // نبدأ من 1 لتجاوز سطر النوع
157
+ for (let i = 1; i < lines.length; i++) {
158
+ const lineNum = i + 1;
102
159
  let line = lines[i];
103
- const trimmed = line.trim();
104
- const indent = line.search(/\S/);
105
-
160
+
161
+ const trimmed = line.trimStart();
106
162
  if (!trimmed || trimmed.startsWith('#')) continue;
163
+ const indent = line.length - trimmed.length;
164
+ const fullyTrimmed = trimmed.trimEnd();
107
165
 
108
- // --- 1. Middleware / Auth Guard ---
109
166
  if (skipIndent !== -1) {
110
167
  if (indent > skipIndent) continue;
111
168
  else skipIndent = -1;
112
169
  }
113
170
 
114
- const authMatch = trimmed.match(/Auth="([^"]+)"/);
171
+ // --- 1. التنقل الذكي (Smart Routing) ---
172
+ if (fullyTrimmed.startsWith('Route "')) {
173
+ const match = fullyTrimmed.match(/Route "([^"]+)"/);
174
+ const routePath = match ? match[1] : '';
175
+ if (routePath !== requestedRoute) {
176
+ skipIndent = indent;
177
+ }
178
+ continue;
179
+ }
180
+
181
+ // --- 2. Middleware / Auth Guard ---
182
+ const authMatch = fullyTrimmed.match(/Auth="([^"]+)"/);
115
183
  if (authMatch) {
116
- if (authMatch[1] !== config.currentUserRole && authMatch[1] !== 'guest') {
184
+ if (authMatch[1] !== globalConfig.currentUserRole && authMatch[1] !== 'guest') {
117
185
  skipIndent = indent;
118
186
  continue;
119
187
  }
120
188
  }
121
189
 
122
- // --- 2. Repeat Logic (Recursive) ---
190
+ // --- 3. Sovereign Components (Define) ---
191
+ if (componentScope.active) {
192
+ if (indent > componentScope.indent) {
193
+ componentScope.buffer.push(line);
194
+ continue;
195
+ } else {
196
+ componentsContext[componentScope.name] = [...componentScope.buffer];
197
+ componentScope.active = false;
198
+ componentScope.buffer = [];
199
+ }
200
+ }
201
+
202
+ if (fullyTrimmed.startsWith('Define ')) {
203
+ const colonIdx = fullyTrimmed.indexOf(':');
204
+ if (colonIdx === -1) throw new ThothSyntaxError("ComponentError: Missing ':' in Define statement.", lineNum, line, inputPath);
205
+ const compName = fullyTrimmed.substring(7, colonIdx).trim();
206
+ componentScope.name = compName;
207
+ componentScope.active = true;
208
+ componentScope.indent = indent;
209
+ continue;
210
+ }
211
+
212
+ // --- 4. State Management ---
213
+ if (fullyTrimmed.startsWith('State ')) {
214
+ const colonIdx = fullyTrimmed.indexOf(':');
215
+ if (colonIdx !== -1) {
216
+ const stateKey = fullyTrimmed.substring(6, colonIdx).trim();
217
+ const stateVal = fullyTrimmed.substring(colonIdx + 1).trim();
218
+ stateVars[stateKey] = stateVal;
219
+ variables[`@{{${stateKey}}}`] = stateVal;
220
+ } else {
221
+ throw new ThothSyntaxError(`StateError: Invalid State syntax. Expected 'State name: value'.`, lineNum, line, inputPath);
222
+ }
223
+ continue;
224
+ }
225
+
226
+ // --- 5. API Fetch Engine [NEW] ---
227
+ if (fullyTrimmed.startsWith('API ')) {
228
+ const match = fullyTrimmed.match(/API\s+([a-zA-Z0-9_]+)="([^"]+)"/);
229
+ if (match) {
230
+ const apiKey = match[1];
231
+ const apiUrl = match[2];
232
+ try {
233
+ dataContext[apiKey] = await fetchJSON(apiUrl);
234
+ } catch (err) {
235
+ throw new ThothSyntaxError(`APIError: Failed to fetch external data from '${apiUrl}'. ${err.message}`, lineNum, line, inputPath);
236
+ }
237
+ } else {
238
+ throw new ThothSyntaxError("APIError: Invalid API syntax. Expected 'API name=\"URL\"'.", lineNum, line, inputPath);
239
+ }
240
+ continue;
241
+ }
242
+
243
+ // --- 6. Repeat Logic (Recursive & Async) ---
123
244
  if (repeatScope.active) {
124
245
  if (indent > repeatScope.indent) {
125
246
  repeatScope.buffer.push(line);
126
247
  continue;
127
248
  } else {
128
249
  const list = dataContext[repeatScope.key] || [];
129
- list.forEach(item => {
130
- htmlContent += processBuffer(repeatScope.buffer, item, variables);
131
- });
250
+ if(!Array.isArray(list)) {
251
+ throw new ThothSyntaxError(`DataMappingError: '${repeatScope.key}' is not a valid Array in Context.`, lineNum, line, inputPath);
252
+ }
253
+ for (const item of list) {
254
+ const mergedContext = { dataContext: { ...dataContext, ...item }, variables, stateVars };
255
+ htmlContent += await processBuffer(repeatScope.buffer, mergedContext, componentsContext, inputPath, lineNum, requestedRoute);
256
+ }
132
257
  repeatScope.active = false;
133
258
  repeatScope.buffer = [];
134
259
  }
135
260
  }
136
261
 
137
- if (trimmed.startsWith('Repeat Over="')) {
138
- repeatScope.key = trimmed.match(/Over="([^"]+)"/)[1];
262
+ if (fullyTrimmed.startsWith('Repeat Over="')) {
263
+ const match = fullyTrimmed.match(/Over="([^"]+)"/);
264
+ if (!match) throw new ThothSyntaxError("LoopError: Invalid Repeat syntax.", lineNum, line, inputPath);
265
+ repeatScope.key = match[1];
139
266
  repeatScope.active = true;
140
267
  repeatScope.indent = indent;
141
268
  continue;
142
269
  }
143
270
 
144
- // --- 3. Data Ingestion & Variables ---
145
- if (trimmed.startsWith('DataSource:')) {
146
- const dPath = path.resolve(path.dirname(inputPath), trimmed.split(':')[1].trim());
147
- if (fs.existsSync(dPath)) dataContext = JSON.parse(fs.readFileSync(dPath, 'utf8'));
271
+ // --- 7. DataSource & Variables ---
272
+ if (fullyTrimmed.startsWith('DataSource:')) {
273
+ const jsonFileName = fullyTrimmed.split(':')[1].trim();
274
+ const dPath = path.resolve(path.dirname(inputPath), jsonFileName);
275
+ if (!fs.existsSync(dPath)) throw new ThothSyntaxError(`MissingDataError: DataSource '${jsonFileName}' not found.`, lineNum, line, inputPath);
276
+ try {
277
+ const parsedData = JSON.parse(fs.readFileSync(dPath, 'utf8'));
278
+ dataContext = { ...dataContext, ...parsedData };
279
+ } catch(e) {
280
+ throw new ThothSyntaxError(`JSONParseError: Invalid JSON format in '${jsonFileName}'.`, lineNum, line, inputPath);
281
+ }
148
282
  continue;
149
283
  }
150
284
 
151
- if (trimmed.startsWith('Var ')) {
152
- const vParts = trimmed.substring(4).split(':');
285
+ if (fullyTrimmed.startsWith('Var ')) {
286
+ const vParts = fullyTrimmed.substring(4).split(':');
153
287
  if (vParts.length === 2) variables['@' + vParts[0].trim()] = vParts[1].trim();
288
+ else throw new ThothSyntaxError(`VariableError: Invalid Var syntax.`, lineNum, line, inputPath);
289
+ continue;
290
+ }
291
+
292
+ if (fullyTrimmed.startsWith('Import:')) {
293
+ const importFile = fullyTrimmed.substring(7).trim();
294
+ const importPath = path.resolve(path.dirname(inputPath), importFile);
295
+ if (!fs.existsSync(importPath)) throw new ThothSyntaxError(`ImportError: Module '${importFile}' not found.`, lineNum, line, inputPath);
296
+ const importContent = fs.readFileSync(importPath, 'utf8');
297
+ const subCall = await compileThothEngine(importContent, importPath, false, true, { dataContext, variables, stateVars }, componentsContext, requestedRoute);
298
+ htmlContent += subCall.html;
154
299
  continue;
155
300
  }
156
301
 
157
302
  line = resolveData(line, dataContext, variables);
158
303
  const processedTrimmed = line.trim();
159
304
 
160
- // --- 4. Raw Code Injection (CSS/JS) ---
161
305
  if (rawScope.active) {
162
306
  if (indent <= rawScope.indent && processedTrimmed !== "") {
163
307
  rawScope.active = false;
@@ -168,7 +312,6 @@ function compileThoth(inputPath, isDev = false) {
168
312
  }
169
313
  }
170
314
 
171
- // --- خوارزمية تحليل الفصل الذكي ---
172
315
  let colonIdx = -1;
173
316
  let inQuotes = false;
174
317
  for (let j = 0; j < processedTrimmed.length; j++) {
@@ -181,7 +324,7 @@ function compileThoth(inputPath, isDev = false) {
181
324
 
182
325
  const firstSpace = instr.indexOf(' ');
183
326
  const tagName = firstSpace !== -1 ? instr.substring(0, firstSpace) : instr;
184
- const attrs = firstSpace !== -1 ? instr.substring(firstSpace).trim() : "";
327
+ let attrs = firstSpace !== -1 ? instr.substring(firstSpace).trim() : "";
185
328
 
186
329
  if (tagName === "StyleSheet" || tagName === "Scripting") {
187
330
  rawScope.active = true;
@@ -191,74 +334,134 @@ function compileThoth(inputPath, isDev = false) {
191
334
  continue;
192
335
  }
193
336
 
194
- // إدارة المكدس (Stack Indentation)
337
+ // --- 8. Component Instantiation ---
338
+ if (componentsContext[tagName]) {
339
+ let props = {};
340
+ const propMatches = attrs.matchAll(/([a-zA-Z0-9_]+)="([^"]+)"/g);
341
+ for (const match of propMatches) { props[`@${match[1]}`] = match[2]; }
342
+
343
+ let compSource = "TYPE THOTH\n";
344
+ componentsContext[tagName].forEach(l => { compSource += ' '.repeat(indent) + l + '\n'; });
345
+
346
+ const subMergedVars = { ...variables, ...props };
347
+ const subRes = await compileThothEngine(compSource, inputPath, false, true, { dataContext, variables: subMergedVars, stateVars }, componentsContext, requestedRoute);
348
+ htmlContent += subRes.html;
349
+ continue;
350
+ }
351
+
195
352
  while (stack.length > 0 && stack[stack.length - 1].indent >= indent) {
196
353
  htmlContent += `</${stack.pop().name}>\n`;
197
354
  }
198
355
 
199
356
  const tag = TAG_MAP[tagName] || tagName.toLowerCase();
200
- const cleanAttrs = attrs.replace(/Auth="[^"]+"/, '').trim();
357
+
358
+ // --- 9. Layout Engine (Row & Column) ---
359
+ let injectedStyle = "";
360
+ if (tagName === 'Row') {
361
+ injectedStyle = "display:flex; flex-wrap:wrap;";
362
+ const gapMatch = attrs.match(/gap="([^"]+)"/);
363
+ if (gapMatch) injectedStyle += ` gap:${gapMatch[1]};`;
364
+ const alignMatch = attrs.match(/align="([^"]+)"/);
365
+ if (alignMatch) injectedStyle += ` align-items:${alignMatch[1]};`;
366
+ attrs = attrs.replace(/(gap|align)="[^"]+"/g, '');
367
+ } else if (tagName === 'Column') {
368
+ injectedStyle = "display:flex; flex-direction:column;";
369
+ const widthMatch = attrs.match(/width="([^"]+)"/);
370
+ if (widthMatch) injectedStyle += ` flex:0 0 ${widthMatch[1]}; max-width:${widthMatch[1]};`;
371
+ else injectedStyle += " flex:1;";
372
+ attrs = attrs.replace(/width="[^"]+"/g, '');
373
+ }
374
+
375
+ let cleanAttrs = attrs.replace(/Auth="[^"]+"/, '').trim();
376
+ cleanAttrs = injectStateBindings(cleanAttrs);
377
+
378
+ if (injectedStyle !== "") {
379
+ if (cleanAttrs.includes('style="')) cleanAttrs = cleanAttrs.replace(/style="([^"]*)"/, `style="$1 ${injectedStyle.trim()}"`);
380
+ else cleanAttrs += ` style="${injectedStyle.trim()}"`;
381
+ }
382
+
201
383
  const open = `<${tag}${cleanAttrs ? ' ' + cleanAttrs : ''}>`;
202
384
 
203
385
  if (VOID_ELEMENTS.includes(tag)) {
204
- htmlContent += open + '\n';
386
+ htmlContent += ' '.repeat(indent) + open + '\n';
205
387
  } else if (val) {
206
- htmlContent += `${open}${val}</${tag}>\n`;
388
+ const finalVal = injectStateText(val, stateVars);
389
+ htmlContent += ' '.repeat(indent) + `${open}${finalVal}</${tag}>\n`;
207
390
  } else {
208
- htmlContent += open + '\n';
391
+ htmlContent += ' '.repeat(indent) + open + '\n';
209
392
  stack.push({ name: tag, indent: indent });
210
393
  }
211
394
  }
212
395
 
213
- // إغلاق أي تكرار متبقي
396
+ if (componentScope.active) componentsContext[componentScope.name] = [...componentScope.buffer];
214
397
  if (repeatScope.active) {
215
398
  const list = dataContext[repeatScope.key] || [];
216
- list.forEach(item => { htmlContent += processBuffer(repeatScope.buffer, item, variables); });
399
+ for (const item of list) {
400
+ const mergedContext = { dataContext: { ...dataContext, ...item }, variables, stateVars };
401
+ htmlContent += await processBuffer(repeatScope.buffer, mergedContext, componentsContext, inputPath, lines.length, requestedRoute);
402
+ }
217
403
  }
218
404
 
219
405
  while (stack.length > 0) htmlContent += `</${stack.pop().name}>\n`;
220
406
 
221
- return generateBoilerplate(htmlContent, isDev);
407
+ if (isSubCall) return { html: htmlContent, dataContext, stateVars };
408
+ return generateBoilerplate(htmlContent, dataContext, stateVars, isDev);
409
+ }
410
+
411
+ /**
412
+ * دالة التغليف العامة
413
+ */
414
+ async function compileThoth(inputPath, isDev = false, requestedRoute = '/') {
415
+ if (!fs.existsSync(inputPath)) throw new ThothSyntaxError(`Source Integrity Error: File not found.`, 0, "", inputPath);
416
+ const source = fs.readFileSync(inputPath, 'utf8');
417
+ const result = await compileThothEngine(source, inputPath, isDev, false, {}, {}, requestedRoute);
418
+ return result.html;
222
419
  }
223
420
 
224
421
  /**
225
422
  * معالجة الـ Buffer داخل الـ Loop
226
423
  */
227
- function processBuffer(buffer, item, variables) {
228
- let res = "";
229
- let bStack = [];
230
- buffer.forEach(l => {
231
- const ind = l.search(/\S/);
232
- let pLine = resolveData(l, item, variables);
233
- const t = pLine.trim();
234
- let cIdx = t.indexOf(':');
235
- let cmdStr = cIdx !== -1 ? t.substring(0, cIdx).trim() : t;
236
- let valStr = cIdx !== -1 ? t.substring(cIdx + 1).trim() : "";
237
-
238
- const space = cmdStr.indexOf(' ');
239
- const tag = TAG_MAP[cmdStr.substring(0, space === -1 ? cmdStr.length : space)] || cmdStr.toLowerCase();
240
-
241
- while (bStack.length > 0 && bStack[bStack.length - 1].indent >= ind) res += `</${bStack.pop().name}>\n`;
242
-
243
- const op = `<${tag}${space !== -1 ? ' ' + cmdStr.substring(space).trim() : ''}>`;
244
- if (VOID_ELEMENTS.includes(tag)) res += op + '\n';
245
- else if (valStr) res += `${op}${valStr}</${tag}>\n`;
246
- else { res += op + '\n'; bStack.push({ name: tag, indent: ind }); }
247
- });
248
- while (bStack.length > 0) res += `</${bStack.pop().name}>\n`;
249
- return res;
424
+ async function processBuffer(buffer, scopeContext, componentsContext, filePath, baseLineNum, requestedRoute) {
425
+ let tempSource = "TYPE THOTH\n";
426
+ buffer.forEach(l => tempSource += l + "\n");
427
+ const res = await compileThothEngine(tempSource, filePath, false, true, scopeContext, componentsContext, requestedRoute);
428
+ return res.html;
250
429
  }
251
430
 
252
431
  /**
253
- * توليد هيكل HTML5 المعياري مع الـ Meta Tags
432
+ * توليد هيكل HTML5 المعياري
254
433
  */
255
- function generateBoilerplate(content, isDev) {
434
+ function generateBoilerplate(content, dataContext, stateVars, isDev) {
256
435
  const title = dataContext.site_title || "THOTH Sovereign Architecture";
257
436
  const desc = dataContext.site_desc || "Engineered by Abdelfatah Abdelhamed";
437
+ const stateJson = JSON.stringify(stateVars);
258
438
 
439
+ const stateEngineScript = `
440
+ <script>
441
+ const thothState = {
442
+ data: ${stateJson},
443
+ dispatch: function(actionStr) {
444
+ if(actionStr.startsWith('set:')) {
445
+ let logic = actionStr.replace('set:', '').split('=');
446
+ let key = logic[0]; let expr = logic[1];
447
+ if(expr.includes('+1')) this.data[key] = parseInt(this.data[key]) + 1;
448
+ else if(expr.includes('-1')) this.data[key] = parseInt(this.data[key]) - 1;
449
+ else this.data[key] = expr;
450
+ this.render();
451
+ }
452
+ },
453
+ render: function() {
454
+ document.querySelectorAll('[data-thoth-state]').forEach(el => {
455
+ let key = el.getAttribute('data-thoth-state');
456
+ if(this.data[key] !== undefined) el.innerText = this.data[key];
457
+ });
458
+ }
459
+ };
460
+ </script>`;
461
+
259
462
  const liveReload = isDev ? `
260
463
  <script>
261
- console.log('%c THOTH DEV MODE: ACTIVE ', 'background:#D4AF37;color:#000;font-weight:bold;');
464
+ console.log('%c THOTH CLOUD DEV MODE: ACTIVE ', 'background:#06b6d4;color:#000;font-weight:bold;');
262
465
  let lastMod = null;
263
466
  setInterval(async () => {
264
467
  try {
@@ -270,58 +473,107 @@ function generateBoilerplate(content, isDev) {
270
473
  }, 1500);
271
474
  </script>` : "";
272
475
 
273
- return `<!DOCTYPE html>
476
+ return { html: `<!DOCTYPE html>
274
477
  <html lang="ar" dir="rtl">
275
478
  <head>
276
479
  <meta charset="UTF-8">
277
480
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
278
481
  <meta name="description" content="${desc}">
279
- <meta name="generator" content="THOTH Sovereign Engine v10.5.0">
280
- <meta name="author" content="Abdelfatah Abdelhamed">
482
+ <meta name="generator" content="THOTH Sovereign Engine v12.0.0">
483
+ <meta name="author" content="Engineer Abdelfatah Abdelhamed">
281
484
  <title>${title}</title>
282
485
  </head>
283
- <body style="margin:0; background:#050505; color:#fff;">
486
+ <body style="margin:0; background:#020617; color:#f8fafc; font-family:sans-serif;">
284
487
  ${content}
488
+ ${stateEngineScript}
285
489
  ${liveReload}
286
490
  </body>
287
- </html>`;
491
+ </html>`};
492
+ }
493
+
494
+ function getBrowserTracebackHTML(e) {
495
+ if (e.name === 'ThothSyntaxError') {
496
+ const escapedContent = e.lineContent.replace(/</g, '&lt;').replace(/>/g, '&gt;');
497
+ return `
498
+ <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>THOTH Engine Error</title></head>
499
+ <body style="margin:0; background:#020617; font-family:'Fira Code', monospace; display:flex; align-items:center; justify-content:center; height:100vh;">
500
+ <div style="background:#0f172a; border:1px solid #ef4444; width:90%; max-width:800px; padding:30px; border-radius:12px; box-shadow:0 0 30px rgba(239, 68, 68, 0.2); color:#e2e8f0;">
501
+ <div style="border-bottom: 1px solid #334155; padding-bottom:15px; margin-bottom:20px;">
502
+ <h2 style="color:#ef4444; margin:0; font-size:1.5rem;">⚠️ THOTH Traceback (most recent call last):</h2>
503
+ </div>
504
+ <div style="padding: 10px 0;">
505
+ <p style="margin:0 0 10px 0; color:#94a3b8;">File <span style="color:#06b6d4;">"${e.filePath}"</span>, line <span style="color:#f59e0b; font-weight:bold;">${e.lineNum}</span>, in &lt;module&gt;</p>
506
+ <div style="background:#000; padding:15px; border-radius:8px; border-left:4px solid #ef4444; overflow-x:auto;">
507
+ <div style="color:#f87171;">${e.lineNum} | <span style="color:#e2e8f0;">${escapedContent}</span></div>
508
+ <div style="color:#ef4444; margin-top:5px;">&nbsp;&nbsp;&nbsp;&nbsp;^</div>
509
+ </div>
510
+ <p style="margin:20px 0 0 0; color:#ef4444; font-weight:bold; font-size:1.1rem;">${e.message}</p>
511
+ </div>
512
+ <div style="border-top: 1px solid #334155; padding-top:15px; margin-top:20px; text-align:right;">
513
+ <button onclick="location.reload()" style="background:#ef4444; color:#fff; padding:8px 24px; border:none; border-radius:6px; cursor:pointer; font-weight:bold; font-family:inherit;">RESTART ENGINE</button>
514
+ </div>
515
+ </div>
516
+ </body></html>`;
517
+ }
518
+ return `<body style="background:#000;color:#ff5555;padding:50px;font-family:monospace">
519
+ <h2 style="border-bottom:2px solid #ff5555;padding-bottom:10px">SOVEREIGN RUNTIME ERROR</h2>
520
+ <p style="font-size:18px">${e.message}</p>
521
+ <button onclick="location.reload()" style="background:#ff5555;color:#fff;border:none;padding:10px 20px;cursor:pointer">RETRY</button>
522
+ </body>`;
523
+ }
524
+
525
+ function printTerminalError(e) {
526
+ if (e.name === 'ThothSyntaxError') {
527
+ console.error('\x1b[31m%s\x1b[0m', `\n⚠️ THOTH Traceback:`);
528
+ console.error('\x1b[90m%s\x1b[0m', ` File "${e.filePath}", line ${e.lineNum}, in <module>`);
529
+ console.error(` ${e.lineContent}`);
530
+ console.error('\x1b[31m%s\x1b[0m', ` ^`);
531
+ console.error('\x1b[1m\x1b[31m%s\x1b[0m', `${e.message}\n`);
532
+ } else {
533
+ console.error(`\x1b[31m [ERROR] ${e.message}\x1b[0m`);
534
+ }
288
535
  }
289
536
 
290
537
  // --- طبقة التنفيذ ---
291
538
  if (command === 'serve') {
292
- const server = http.createServer((req, res) => {
539
+ const server = http.createServer(async (req, res) => {
540
+ if (req.url === '/favicon.ico') { res.writeHead(204); return res.end(); }
541
+
293
542
  try {
294
- const html = compileThoth(target, true);
295
- res.writeHead(200, {
296
- 'Content-Type': 'text/html',
297
- 'Cache-Control': 'no-cache',
298
- 'ETag': Date.now().toString()
299
- });
543
+ const parsedUrl = new URL(req.url, `http://localhost:${globalConfig.port}`);
544
+ const requestedRoute = parsedUrl.pathname;
545
+
546
+ // استخدام await عشان المحرك يقدر يجلب بيانات الـ API
547
+ const html = await compileThoth(target, true, requestedRoute);
548
+
549
+ res.writeHead(200, { 'Content-Type': 'text/html', 'Cache-Control': 'no-cache', 'ETag': Date.now().toString() });
300
550
  res.end(html);
301
551
  } catch (e) {
552
+ printTerminalError(e);
302
553
  res.writeHead(500, { 'Content-Type': 'text/html' });
303
- res.end(`<body style="background:#000;color:#ff5555;padding:50px;font-family:monospace">
304
- <h2 style="border-bottom:2px solid #ff5555;padding-bottom:10px">SOVEREIGN COMPILATION ERROR</h2>
305
- <p style="font-size:18px">${e.message}</p>
306
- <button onclick="location.reload()" style="background:#ff5555;color:#fff;border:none;padding:10px 20px;cursor:pointer">RETRY</button>
307
- </body>`);
554
+ res.end(getBrowserTracebackHTML(e));
308
555
  }
309
556
  });
310
557
 
311
- server.listen(config.port, () => {
312
- console.log('\x1b[32m%s\x1b[0m', `──────────────────────────────────────────`);
313
- console.log(` ✔ SERVER ACTIVE: http://localhost:${config.port}`);
558
+ server.listen(globalConfig.port, () => {
559
+ console.log('\x1b[36m%s\x1b[0m', `──────────────────────────────────────────`);
560
+ console.log(` ✔ SERVER ACTIVE: http://localhost:${globalConfig.port}`);
314
561
  console.log(` ✔ ARCHITECTURE: ${target}`);
315
- console.log(` ✔ MODE: Intelligence Suite v10.5.0`);
316
- console.log('\x1b[32m%s\x1b[0m', `──────────────────────────────────────────`);
562
+ console.log(` ✔ MODE: The Sovereign Cloud v12.0.0`);
563
+ console.log('\x1b[36m%s\x1b[0m', `──────────────────────────────────────────`);
317
564
  });
565
+ } else if (command === 'build') {
566
+ // التنفيذ غير المتزامن للبناء
567
+ (async () => {
568
+ try {
569
+ const out = await compileThoth(target, false);
570
+ fs.writeFileSync(target.replace('.thoth', '.html'), out);
571
+ console.log(`\x1b[32m [SUCCESS] Architecture materialized: ${target.replace('.thoth', '.html')}\x1b[0m`);
572
+ } catch (e) {
573
+ printTerminalError(e);
574
+ process.exit(1);
575
+ }
576
+ })();
318
577
  } else {
319
- try {
320
- const out = compileThoth(target, false);
321
- fs.writeFileSync(target.replace('.thoth', '.html'), out);
322
- console.log(`\x1b[32m [SUCCESS] Architecture materialized: ${target.replace('.thoth', '.html')}\x1b[0m`);
323
- } catch (e) {
324
- console.error(`\x1b[31m [ERROR] ${e.message}\x1b[0m`);
325
- process.exit(1);
326
- }
578
+ displayUsage();
327
579
  }