thoth-markup-lang 11.0.0 โ 12.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 +285 -24
- package/engine.php +220 -21
- package/package.json +17 -4
- package/thoth.js +278 -104
package/README.md
CHANGED
|
@@ -1,43 +1,304 @@
|
|
|
1
|
-
# THOTH: The Sovereign Intelligence
|
|
1
|
+
# ๐ THOTH: The Sovereign Web Intelligence Engine
|
|
2
|
+
### v12.0.0 โ Sovereign Cloud โข Async Core โข Reactive Architecture
|
|
2
3
|
|
|
3
4
|
<p align="center">
|
|
4
|
-
<img src="https://img.shields.io/npm/v/thoth-markup-lang?style=for-the-badge&color=06b6d4&logo=npm"
|
|
5
|
-
<img src="https://img.shields.io/badge/
|
|
6
|
-
<img src="https://img.shields.io/badge/
|
|
5
|
+
<img src="https://img.shields.io/npm/v/thoth-markup-lang?style=for-the-badge&color=06b6d4&logo=npm" />
|
|
6
|
+
<img src="https://img.shields.io/badge/Core-Async%20Non--Blocking-0ea5e9?style=for-the-badge" />
|
|
7
|
+
<img src="https://img.shields.io/badge/Architecture-Sovereign-f59e0b?style=for-the-badge" />
|
|
8
|
+
<img src="https://img.shields.io/badge/Rendering-Reactive%20Engine-22c55e?style=for-the-badge" />
|
|
9
|
+
<img src="https://img.shields.io/badge/Built%20In-Egypt%20๐ช๐ฌ-020617?style=for-the-badge" />
|
|
7
10
|
</p>
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
<p align="center">
|
|
13
|
+
<b>Structure is Truth โข Logic is Indentation โข Control is Sovereignty</b>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## ๐ง What is THOTH?
|
|
19
|
+
|
|
20
|
+
**THOTH** is a next-generation **Asynchronous Reactive Web Engine** designed to eliminate the structural and cognitive overhead of modern frontend development.
|
|
21
|
+
|
|
22
|
+
It is not:
|
|
23
|
+
- โ A framework
|
|
24
|
+
- โ A wrapper
|
|
25
|
+
- โ A templating engine
|
|
26
|
+
|
|
27
|
+
It is:
|
|
28
|
+
- โ
A **unified architecture layer**
|
|
29
|
+
- โ
A **runtime + syntax + philosophy**
|
|
30
|
+
- โ
A **replacement for fragmented stacks**
|
|
31
|
+
|
|
32
|
+
> You donโt โbuild UIโ with THOTHโฆ you **define systems**.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## ๐จ The Problem THOTH Solves
|
|
37
|
+
|
|
38
|
+
Modern web stacks suffer from:
|
|
39
|
+
|
|
40
|
+
- Dependency hell (React, Vite, Redux, Axiosโฆ)
|
|
41
|
+
- Boilerplate explosion
|
|
42
|
+
- Context switching (HTML + CSS + JS)
|
|
43
|
+
- Manual state wiring
|
|
44
|
+
- Routing complexity
|
|
45
|
+
- API integration overhead
|
|
46
|
+
|
|
47
|
+
### THOTH Response:
|
|
48
|
+
|
|
49
|
+
โ Zero-bracket syntax
|
|
50
|
+
โ Native state engine
|
|
51
|
+
โ Built-in SPA routing
|
|
52
|
+
โ Direct API binding
|
|
53
|
+
โ No external JS required for core logic
|
|
54
|
+
โ Single unified architecture file
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## ๐๏ธ Sovereign Scaffolding System [REVOLUTION]
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
thoth create my-app
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Instantly Generates:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
/my-app
|
|
68
|
+
โโโ index.thoth
|
|
69
|
+
โโโ /components
|
|
70
|
+
โโโ /data
|
|
71
|
+
โโโ /pages
|
|
72
|
+
โโโ thoth.config.json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Built for:
|
|
76
|
+
- Rapid prototyping
|
|
77
|
+
- Enterprise architecture
|
|
78
|
+
- Scalable systems
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## ๐ Core Engine Capabilities
|
|
83
|
+
|
|
84
|
+
### โ๏ธ Sovereign Cloud Engine (Native API Layer)
|
|
85
|
+
```text
|
|
86
|
+
API users="https://api.example.com/users"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- Async by default
|
|
90
|
+
- Non-blocking rendering
|
|
91
|
+
- Auto binding to UI nodes
|
|
10
92
|
|
|
11
93
|
---
|
|
12
94
|
|
|
13
|
-
|
|
95
|
+
### โก Native Reactive State Engine
|
|
96
|
+
```text
|
|
97
|
+
State energy: 0
|
|
98
|
+
```
|
|
14
99
|
|
|
15
|
-
|
|
100
|
+
- Instant UI updates
|
|
101
|
+
- No virtual DOM diffing
|
|
102
|
+
- No hooks / reducers
|
|
16
103
|
|
|
17
|
-
|
|
18
|
-
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### ๐ Smart SPA Routing Engine
|
|
107
|
+
```text
|
|
108
|
+
Route "/":
|
|
109
|
+
Route "/dashboard":
|
|
110
|
+
Route "/system":
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
- History API handled internally
|
|
114
|
+
- Zero configuration
|
|
115
|
+
- Automatic DOM hydration
|
|
19
116
|
|
|
20
117
|
---
|
|
21
118
|
|
|
22
|
-
|
|
119
|
+
### ๐ Native Layout System (Flex Engine)
|
|
120
|
+
```text
|
|
121
|
+
Row gap="20px" align="center":
|
|
122
|
+
Column width="300px":
|
|
123
|
+
```
|
|
23
124
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
* **๐ Zero-Bracket Architecture:** Eliminates opening/closing DOM tags, reducing syntax noise by up to 70%.
|
|
28
|
-
* **๐ Recursive Data Binding:** Native integration with JSON flat-file databases using `@{{key}}` syntax.
|
|
29
|
-
* **๐ Procedural Middleware (Auth Guard):** Secure structural DOM nodes natively using `Auth="role"` attributes.
|
|
30
|
-
* **๐ Pulse Dev Server & Live Reload:** Integrated HTTP server with automated browser synchronization and state tracking.
|
|
31
|
-
* **๐ Advanced Meta SEO Engine:** Automated generation of HTML5 Meta Tags directly from your JSON data context.
|
|
32
|
-
* **๐ฆ Scoped Components:** Modular file architecture and management through the `Import:` directive.
|
|
33
|
-
* **๐ Hybrid Injection:** Native support for scoped `StyleSheet` (Raw CSS) and `Scripting` (Raw JS) inside the `.thoth` environment.
|
|
125
|
+
- No Tailwind
|
|
126
|
+
- No Bootstrap
|
|
127
|
+
- Pure structural layout logic
|
|
34
128
|
|
|
35
129
|
---
|
|
36
130
|
|
|
37
|
-
|
|
131
|
+
### ๐งฉ Sovereign Component System
|
|
132
|
+
```text
|
|
133
|
+
Define Card:
|
|
134
|
+
Box:
|
|
135
|
+
Text: @{{title}}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
- Reusable
|
|
139
|
+
- Stateless or stateful
|
|
140
|
+
- Fully isolated
|
|
141
|
+
|
|
142
|
+
---
|
|
38
143
|
|
|
39
|
-
###
|
|
40
|
-
|
|
144
|
+
### ๐ Recursive Data Binding Engine
|
|
145
|
+
```text
|
|
146
|
+
Text: @{{username}}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
- JSON / API binding
|
|
150
|
+
- Deep nesting support
|
|
151
|
+
- Zero transformation layer
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### ๐ Structural Security (Auth Guards)
|
|
156
|
+
```text
|
|
157
|
+
Header Auth="admin":
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
- Built-in access control
|
|
161
|
+
- DOM-level protection
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### ๐ Intelligent Traceback System
|
|
166
|
+
```text
|
|
167
|
+
File "app.thoth", line 22
|
|
168
|
+
APIError: Invalid endpoint
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
- Precise debugging
|
|
172
|
+
- Developer-friendly errors
|
|
173
|
+
- Runtime + overlay support
|
|
174
|
+
|
|
175
|
+
---
|
|
41
176
|
|
|
177
|
+
## ๐ Master Example (Full System)
|
|
178
|
+
|
|
179
|
+
```text
|
|
180
|
+
TYPE THOTH
|
|
181
|
+
|
|
182
|
+
# Data & Imports
|
|
183
|
+
DataSource: data/config.json
|
|
184
|
+
Import: components/Navbar.thoth
|
|
185
|
+
|
|
186
|
+
# API Layer
|
|
187
|
+
API users="https://jsonplaceholder.typicode.com/users"
|
|
188
|
+
|
|
189
|
+
# State Layer
|
|
190
|
+
State clicks: 0
|
|
191
|
+
|
|
192
|
+
# Root Architecture
|
|
193
|
+
Container class="app-shell":
|
|
194
|
+
|
|
195
|
+
Navbar title="THOTH Engine"
|
|
196
|
+
|
|
197
|
+
Route "/":
|
|
198
|
+
Column align="center":
|
|
199
|
+
|
|
200
|
+
Title: "Sovereign Cloud Interface"
|
|
201
|
+
|
|
202
|
+
Row gap="20px":
|
|
203
|
+
Repeat Over="users":
|
|
204
|
+
Box class="card":
|
|
205
|
+
Sub: @{{name}}
|
|
206
|
+
Text: @{{email}}
|
|
207
|
+
|
|
208
|
+
Row:
|
|
209
|
+
Text: "Clicks: @{{clicks}}"
|
|
210
|
+
Button action="set:clicks=clicks+1":
|
|
211
|
+
"Inject Signal"
|
|
212
|
+
|
|
213
|
+
Route "/system":
|
|
214
|
+
Column:
|
|
215
|
+
Sub: "Diagnostics"
|
|
216
|
+
Text: "All systems operational."
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## โ๏ธ CLI Commands
|
|
222
|
+
|
|
223
|
+
### Install Engine
|
|
42
224
|
```bash
|
|
43
|
-
npm install -g thoth-markup-lang
|
|
225
|
+
npm install -g thoth-markup-lang
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Run Dev Server
|
|
229
|
+
```bash
|
|
230
|
+
thoth serve index.thoth
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Build Production
|
|
234
|
+
```bash
|
|
235
|
+
thoth build index.thoth
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## ๐งฌ Architecture Keywords (SEO + Indexing)
|
|
241
|
+
|
|
242
|
+
Asynchronous Web Engine
|
|
243
|
+
Reactive UI Engine
|
|
244
|
+
No-JavaScript Framework Alternative
|
|
245
|
+
Zero-Bracket Markup Language
|
|
246
|
+
Indentation-Based Syntax Engine
|
|
247
|
+
SPA Without React
|
|
248
|
+
Native State Management Engine
|
|
249
|
+
API-First Frontend Architecture
|
|
250
|
+
Unified Web Stack
|
|
251
|
+
Declarative Web Systems
|
|
252
|
+
Non-Blocking Rendering Engine
|
|
253
|
+
Component-Based Architecture
|
|
254
|
+
Modern Web Engine 2026
|
|
255
|
+
Frontend Without Frameworks
|
|
256
|
+
Alternative to React / Vue / Angular
|
|
257
|
+
Sovereign Architecture System
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## ๐ฅ Competitive Comparison
|
|
262
|
+
|
|
263
|
+
| Feature | React / Vue | THOTH |
|
|
264
|
+
|--------|------------|-------|
|
|
265
|
+
| Setup Complexity | High | **Minimal** |
|
|
266
|
+
| State Management | External | **Native** |
|
|
267
|
+
| Routing | Library-based | **Built-in** |
|
|
268
|
+
| API Calls | Manual | **Native** |
|
|
269
|
+
| Syntax | JSX / Templates | **Indentation Logic** |
|
|
270
|
+
| Performance | Virtual DOM | **Direct Render Engine** |
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## ๐๏ธ Core Philosophy
|
|
275
|
+
|
|
276
|
+
> โThe web is not brokenโฆ
|
|
277
|
+
> developers just built too many layers on top of it.โ
|
|
278
|
+
|
|
279
|
+
THOTH removes the layers.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## ๐ Vision
|
|
284
|
+
|
|
285
|
+
THOTH aims to:
|
|
286
|
+
|
|
287
|
+
- Replace frontend frameworks
|
|
288
|
+
- Simplify web architecture
|
|
289
|
+
- Reduce dev time by 70%+
|
|
290
|
+
- Enable true system-level thinking
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## ๐ Final Statement
|
|
295
|
+
|
|
296
|
+
> โYou donโt scale codeโฆ
|
|
297
|
+
> you scale architecture.โ
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
<p align="center">
|
|
302
|
+
<b>Architected by Abdelfatah Abdelhamed</b><br>
|
|
303
|
+
<i>Egypt ๐ช๐ฌ โข Sovereign Systems Engineering</i>
|
|
304
|
+
</p>
|
package/engine.php
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
<?php
|
|
2
2
|
/**
|
|
3
|
-
* THOTH Sovereign Runtime Engine
|
|
3
|
+
* THOTH Sovereign Runtime Engine v12.0.0 - The Sovereign Cloud
|
|
4
4
|
* Architect: Engineer Abdelfatah Abdelhamed ๐ช๐ฌ
|
|
5
5
|
* --------------------------------------------------
|
|
6
|
-
* ุงูู
ูุฒุงุช ุงูู
ุฏู
ุฌุฉ (ุงููุณุฎุฉ
|
|
6
|
+
* ุงูู
ูุฒุงุช ุงูู
ุฏู
ุฌุฉ (ุงููุณุฎุฉ ุงูููุงุฆูุฉ):
|
|
7
7
|
* 1. ุงูุชูุซูู ุงูู
ุนู
ุงุฑู: ุฅูุฒุงู
ูุฉ ูุฌูุฏ TYPE THOTH ูู ุงูุณุทุฑ ุงูุฃูู.
|
|
8
8
|
* 2. ูุธุงู
Middleware (Auth Guard): ุงูุชุญูู
ุงููุงู
ู ูู ุตูุงุญูุงุช ุงููุตูู.
|
|
9
9
|
* 3. ูุธุงู
ุงูุจูุงูุงุช ุงูุฏููุงู
ููู: JSON Binding & Recursive Loops.
|
|
10
10
|
* 4. ูุธุงู
Meta SEO ุงูุฐูู: ุชูููุฏ ุนูุงุตุฑ Meta ุจูุงุกู ุนูู ุงูุจูุงูุงุช.
|
|
11
11
|
* 5. Python-Style Traceback: ู
ุชุชุจุน ุฃุฎุทุงุก ุฐูู ูุญุฏุฏ ุงูุณุทุฑ ูููุน ุงูุฎุทุฃ ุจุฏูุฉ.
|
|
12
12
|
* 6. High-Performance Core: ุชุณุฑูุน ุงูุชุญููู ุจุงุณุชุฎุฏุงู
ุฏูุงู PHP ุงูุญุฏูุซุฉ.
|
|
13
|
+
* 7. Sovereign Components: ุงููุฏุฑุฉ ุนูู ุชุนุฑูู ูุฅุนุงุฏุฉ ุงุณุชุฎุฏุงู
ุงูู
ูููุงุช.
|
|
14
|
+
* 8. State Management: ุญูู ู
ุชุบูุฑุงุช ุงูุญุงูุฉ ูุฅูุดุงุก ูุงุฌูุงุช ุชูุงุนููุฉ.
|
|
15
|
+
* 9. Layout Engine: ูุธุงู
ุดุจูุงุช ู
ุฏู
ุฌ (Row / Column) ุจุฎูุงุต Flexbox.
|
|
16
|
+
* 10. Smart Routing: ูุธุงู
ุชููู ุฏุงุฎูู ู
ุฏู
ุฌ ูุจูุงุก ุชุทุจููุงุช SPA.
|
|
17
|
+
* 11. API Fetch Engine [NEW]: ุฌูุจ ุงูุจูุงูุงุช ุงูุฎุงุฑุฌูุฉ ุจุฑู
ุฌูุงู ุจุฏูู ูุชุงุจุฉ JS.
|
|
13
18
|
*/
|
|
14
19
|
|
|
15
20
|
session_start();
|
|
@@ -32,7 +37,8 @@ class ThothEngine {
|
|
|
32
37
|
'Header' => 'header', 'Footer' => 'footer', 'Bold' => 'strong',
|
|
33
38
|
'Link' => 'a', 'Image' => 'img', 'List' => 'ul', 'Item' => 'li',
|
|
34
39
|
'Button' => 'button', 'Input' => 'input', 'Break' => 'br',
|
|
35
|
-
'Line' => 'hr', 'Layout' => 'main'
|
|
40
|
+
'Line' => 'hr', 'Layout' => 'main',
|
|
41
|
+
'Row' => 'div', 'Column' => 'div'
|
|
36
42
|
];
|
|
37
43
|
|
|
38
44
|
private $voidTags = ['img', 'br', 'hr', 'input', 'meta', 'link'];
|
|
@@ -41,6 +47,9 @@ class ThothEngine {
|
|
|
41
47
|
private $devMode = true;
|
|
42
48
|
private $currentLine = 0;
|
|
43
49
|
private $currentFile = "";
|
|
50
|
+
|
|
51
|
+
private $components = [];
|
|
52
|
+
private $stateVars = [];
|
|
44
53
|
|
|
45
54
|
/**
|
|
46
55
|
* ุงูู
ุฏุฎู ุงูุฑุฆูุณู ููู
ุญุฑู
|
|
@@ -60,7 +69,10 @@ class ThothEngine {
|
|
|
60
69
|
if ($firstLine !== "TYPE THOTH") {
|
|
61
70
|
return $this->devErrorOverlay("SyntaxError: Missing Identity Protocol. File must begin with TYPE THOTH.", 1, $lines[0]);
|
|
62
71
|
}
|
|
63
|
-
unset($lines[0]);
|
|
72
|
+
unset($lines[0]);
|
|
73
|
+
|
|
74
|
+
// ุงุณุชุฎุฑุงุฌ ุงูู
ุณุงุฑ ุงูุญุงูู ููุธุงู
ุงูู Routing
|
|
75
|
+
$requestedRoute = isset($_GET['route']) ? '/' . ltrim($_GET['route'], '/') : '/';
|
|
64
76
|
|
|
65
77
|
try {
|
|
66
78
|
$htmlBody = "";
|
|
@@ -73,30 +85,89 @@ class ThothEngine {
|
|
|
73
85
|
$repeatBuffer = [];
|
|
74
86
|
$repeatKey = "";
|
|
75
87
|
$repeatIndent = 0;
|
|
88
|
+
|
|
89
|
+
$isDefiningComponent = false;
|
|
90
|
+
$currentComponentName = "";
|
|
91
|
+
$componentIndent = 0;
|
|
76
92
|
|
|
77
93
|
foreach ($lines as $index => $line) {
|
|
78
94
|
$this->currentLine = $index + 1;
|
|
79
95
|
$trimmed = trim($line);
|
|
80
96
|
|
|
81
|
-
// ุชุณุฑูุน ู
ุนุงูุฌุฉ ุงูุฃุณุทุฑ ุงููุงุฑุบุฉ ูุงูุชุนูููุงุช ุจุงุณุชุฎุฏุงู
str_starts_with
|
|
82
97
|
if ($trimmed === "" || str_starts_with($trimmed, '#')) continue;
|
|
83
98
|
|
|
84
99
|
$indent = strlen($line) - strlen(ltrim($line));
|
|
85
100
|
|
|
86
|
-
//
|
|
101
|
+
// Guard System
|
|
87
102
|
if ($skipUntilIndent !== -1) {
|
|
88
103
|
if ($indent > $skipUntilIndent) continue;
|
|
89
104
|
else $skipUntilIndent = -1;
|
|
90
105
|
}
|
|
91
106
|
|
|
107
|
+
// --- 1. ุงูุชููู ุงูุฐูู (Smart Routing) ---
|
|
108
|
+
if (str_starts_with($trimmed, 'Route "')) {
|
|
109
|
+
preg_match('/Route "([^"]+)"/', $trimmed, $matches);
|
|
110
|
+
$routePath = $matches[1] ?? '';
|
|
111
|
+
if ($routePath !== $requestedRoute) {
|
|
112
|
+
$skipUntilIndent = $indent;
|
|
113
|
+
}
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// --- 2. Middleware ---
|
|
92
118
|
if (preg_match('/Auth="([^"]+)"/', $trimmed, $matches)) {
|
|
93
119
|
if (!$this->checkAuth($matches[1])) {
|
|
94
120
|
$skipUntilIndent = $indent;
|
|
95
121
|
continue;
|
|
96
122
|
}
|
|
97
123
|
}
|
|
124
|
+
|
|
125
|
+
// --- 3. Sovereign Components ---
|
|
126
|
+
if ($isDefiningComponent) {
|
|
127
|
+
if ($indent > $componentIndent) {
|
|
128
|
+
$this->components[$currentComponentName][] = $line;
|
|
129
|
+
continue;
|
|
130
|
+
} else {
|
|
131
|
+
$isDefiningComponent = false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (str_starts_with($trimmed, 'Define ')) {
|
|
136
|
+
$sep = $this->findSeparator($trimmed);
|
|
137
|
+
if($sep === -1) throw new ThothSyntaxError("ComponentError: Missing ':' in Define statement.", $this->currentLine, $line);
|
|
138
|
+
$currentComponentName = trim(substr($trimmed, 7, $sep - 7));
|
|
139
|
+
$this->components[$currentComponentName] = [];
|
|
140
|
+
$componentIndent = $indent;
|
|
141
|
+
$isDefiningComponent = true;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// --- 4. State Management ---
|
|
146
|
+
if (str_starts_with($trimmed, 'State ')) {
|
|
147
|
+
$parts = explode(':', substr($trimmed, 6), 2);
|
|
148
|
+
if (count($parts) === 2) {
|
|
149
|
+
$stateKey = trim($parts[0]);
|
|
150
|
+
$stateVal = trim($parts[1]);
|
|
151
|
+
$this->stateVars[$stateKey] = $stateVal;
|
|
152
|
+
} else {
|
|
153
|
+
throw new ThothSyntaxError("StateError: Invalid State syntax. Expected 'State name: value'.", $this->currentLine, $line);
|
|
154
|
+
}
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// --- 5. API Fetch Engine (ุงูุฑุจุท ุงูุฎุงุฑุฌู ุงูุณูุงุฏู) ---
|
|
159
|
+
if (str_starts_with($trimmed, 'API ')) {
|
|
160
|
+
if (preg_match('/API\s+([a-zA-Z0-9_]+)="([^"]+)"/', $trimmed, $matches)) {
|
|
161
|
+
$apiKey = $matches[1];
|
|
162
|
+
$apiUrl = $matches[2];
|
|
163
|
+
$this->fetchExternalApi($apiKey, $apiUrl, $this->currentLine, $line);
|
|
164
|
+
} else {
|
|
165
|
+
throw new ThothSyntaxError("APIError: Invalid API syntax. Expected 'API name=\"URL\"'.", $this->currentLine, $line);
|
|
166
|
+
}
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
98
169
|
|
|
99
|
-
// Repeat System
|
|
170
|
+
// --- 6. Repeat System ---
|
|
100
171
|
if ($isRepeatMode) {
|
|
101
172
|
if ($indent > $repeatIndent) { $repeatBuffer[] = $line; continue; }
|
|
102
173
|
else { $htmlBody .= $this->processRepeat($repeatKey, $repeatBuffer); $isRepeatMode = false; $repeatBuffer = []; }
|
|
@@ -109,7 +180,7 @@ class ThothEngine {
|
|
|
109
180
|
$repeatIndent = $indent; $isRepeatMode = true; continue;
|
|
110
181
|
}
|
|
111
182
|
|
|
112
|
-
//
|
|
183
|
+
// --- 7. DataSource & Imports ---
|
|
113
184
|
if (str_starts_with($trimmed, 'DataSource:')) { $this->loadData(trim(substr($trimmed, 11))); continue; }
|
|
114
185
|
if (str_starts_with($trimmed, 'Var ')) { $this->parseVariable($trimmed); continue; }
|
|
115
186
|
if (str_starts_with($trimmed, 'Import:')) {
|
|
@@ -121,24 +192,31 @@ class ThothEngine {
|
|
|
121
192
|
$line = $this->resolveDynamicData($line);
|
|
122
193
|
$trimmed = trim($line);
|
|
123
194
|
|
|
124
|
-
// Raw Injection (CSS/JS)
|
|
195
|
+
// --- 8. Raw Injection (CSS/JS) ---
|
|
125
196
|
if ($inRawMode) {
|
|
126
197
|
if ($indent <= $rawIndent && !empty($trimmed)) { $inRawMode = false; $htmlBody .= "</$rawType>\n"; }
|
|
127
198
|
else { $htmlBody .= $line . "\n"; continue; }
|
|
128
199
|
}
|
|
129
200
|
|
|
130
201
|
$sep = $this->findSeparator($trimmed);
|
|
131
|
-
|
|
132
|
-
// ุงูุฐูุงุก ุงูุงุตุทูุงุนู ูุงูุชุดุงู ุงูุฃุฎุทุงุก ุงูู
ุทุจุนูุฉ
|
|
133
|
-
throw new ThothSyntaxError("ParseError: Invalid syntax or missing separator ':'.", $this->currentLine, $line);
|
|
134
|
-
}
|
|
135
|
-
|
|
202
|
+
|
|
136
203
|
$cmdPart = ($sep !== -1) ? trim(substr($trimmed, 0, $sep)) : $trimmed;
|
|
137
204
|
$val = ($sep !== -1) ? trim(substr($trimmed, $sep + 1)) : "";
|
|
138
205
|
|
|
139
206
|
$spacePos = strpos($cmdPart, ' ');
|
|
140
207
|
$cmd = ($spacePos !== false) ? substr($cmdPart, 0, $spacePos) : $cmdPart;
|
|
141
208
|
$attrs = ($spacePos !== false) ? trim(substr($cmdPart, $spacePos)) : "";
|
|
209
|
+
|
|
210
|
+
// Component Instantiation
|
|
211
|
+
if (isset($this->components[$cmd])) {
|
|
212
|
+
$componentHtml = $this->processComponent($cmd, $attrs, $indent);
|
|
213
|
+
$htmlBody .= $componentHtml;
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if($sep === -1 && !empty($trimmed) && !isset($this->tagMap[explode(' ', $trimmed)[0]]) && !in_array(strtolower(explode(' ', $trimmed)[0]), $this->voidTags) && $cmd !== "StyleSheet" && $cmd !== "Scripting"){
|
|
218
|
+
throw new ThothSyntaxError("ParseError: Invalid syntax or missing separator ':'. Unrecognized command or component '$cmd'.", $this->currentLine, $line);
|
|
219
|
+
}
|
|
142
220
|
|
|
143
221
|
if ($cmd === "StyleSheet" || $cmd === "Scripting") {
|
|
144
222
|
$inRawMode = true; $rawType = ($cmd === "StyleSheet") ? "style" : "script";
|
|
@@ -152,12 +230,38 @@ class ThothEngine {
|
|
|
152
230
|
}
|
|
153
231
|
|
|
154
232
|
$tag = isset($this->tagMap[$cmd]) ? $this->tagMap[$cmd] : strtolower($cmd);
|
|
233
|
+
|
|
234
|
+
// --- 9. Layout Engine ---
|
|
235
|
+
$injectedStyle = "";
|
|
236
|
+
if ($cmd === 'Row') {
|
|
237
|
+
$injectedStyle = "display:flex; flex-wrap:wrap;";
|
|
238
|
+
if (preg_match('/gap="([^"]+)"/', $attrs, $m)) $injectedStyle .= " gap:{$m[1]};";
|
|
239
|
+
if (preg_match('/align="([^"]+)"/', $attrs, $m)) $injectedStyle .= " align-items:{$m[1]};";
|
|
240
|
+
$attrs = preg_replace('/(gap|align)="[^"]+"/', '', $attrs);
|
|
241
|
+
} elseif ($cmd === 'Column') {
|
|
242
|
+
$injectedStyle = "display:flex; flex-direction:column;";
|
|
243
|
+
if (preg_match('/width="([^"]+)"/', $attrs, $m)) $injectedStyle .= " flex:0 0 {$m[1]}; max-width:{$m[1]};";
|
|
244
|
+
else $injectedStyle .= " flex:1;";
|
|
245
|
+
$attrs = preg_replace('/width="[^"]+"/', '', $attrs);
|
|
246
|
+
}
|
|
247
|
+
|
|
155
248
|
$cleanAttrs = preg_replace('/Auth="[^"]+"/', '', $attrs);
|
|
156
|
-
$
|
|
249
|
+
$cleanAttrs = $this->injectStateBindings($tag, $cleanAttrs);
|
|
250
|
+
|
|
251
|
+
if (!empty($injectedStyle)) {
|
|
252
|
+
if (strpos($cleanAttrs, 'style="') !== false) {
|
|
253
|
+
$cleanAttrs = preg_replace('/style="([^"]*)"/', 'style="$1 ' . $injectedStyle . '"', $cleanAttrs);
|
|
254
|
+
} else {
|
|
255
|
+
$cleanAttrs .= ' style="' . trim($injectedStyle) . '"';
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
$openingTag = "<$tag" . ($cleanAttrs ? " " . trim($cleanAttrs) : "") . ">";
|
|
157
260
|
|
|
158
261
|
if (in_array($tag, $this->voidTags)) {
|
|
159
262
|
$htmlBody .= str_repeat(" ", $indent) . $openingTag . "\n";
|
|
160
263
|
} elseif ($val !== "") {
|
|
264
|
+
$val = $this->injectStateText($val);
|
|
161
265
|
$htmlBody .= str_repeat(" ", $indent) . $openingTag . $val . "</$tag>\n";
|
|
162
266
|
} else {
|
|
163
267
|
$htmlBody .= str_repeat(" ", $indent) . $openingTag . "\n";
|
|
@@ -182,6 +286,31 @@ class ThothEngine {
|
|
|
182
286
|
return (isset($_SESSION['user_role']) && $_SESSION['user_role'] === $role);
|
|
183
287
|
}
|
|
184
288
|
|
|
289
|
+
/**
|
|
290
|
+
* ุฏุงูุฉ ุฌูุจ ุงูุจูุงูุงุช ู
ู ุงูู APIs ุงูุฎุงุฑุฌูุฉ
|
|
291
|
+
*/
|
|
292
|
+
private function fetchExternalApi($key, $url, $lineNum, $lineContent) {
|
|
293
|
+
$options = [
|
|
294
|
+
'http' => [
|
|
295
|
+
'method' => 'GET',
|
|
296
|
+
'header' => "User-Agent: THOTH-Sovereign-Engine/12.0\r\n"
|
|
297
|
+
]
|
|
298
|
+
];
|
|
299
|
+
$context = stream_context_create($options);
|
|
300
|
+
$response = @file_get_contents($url, false, $context);
|
|
301
|
+
|
|
302
|
+
if ($response === false) {
|
|
303
|
+
throw new ThothSyntaxError("APIError: Failed to fetch external data from '$url'.", $lineNum, $lineContent);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
$data = json_decode($response, true);
|
|
307
|
+
if ($data === null) {
|
|
308
|
+
throw new ThothSyntaxError("APIParseError: Received invalid JSON response from '$url'.", $lineNum, $lineContent);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
$this->dataContext[$key] = $data;
|
|
312
|
+
}
|
|
313
|
+
|
|
185
314
|
private function processRepeat($key, $linesBuffer) {
|
|
186
315
|
$dataArray = $this->dataContext[$key] ?? [];
|
|
187
316
|
$output = "";
|
|
@@ -193,6 +322,54 @@ class ThothEngine {
|
|
|
193
322
|
}
|
|
194
323
|
return $output;
|
|
195
324
|
}
|
|
325
|
+
|
|
326
|
+
private function processComponent($componentName, $attrsStr, $baseIndent) {
|
|
327
|
+
$buffer = $this->components[$componentName];
|
|
328
|
+
$output = "";
|
|
329
|
+
preg_match_all('/([a-zA-Z0-9_]+)="([^"]+)"/', $attrsStr, $matches);
|
|
330
|
+
$props = [];
|
|
331
|
+
if(!empty($matches[1])) {
|
|
332
|
+
foreach($matches[1] as $idx => $propName) {
|
|
333
|
+
$props['@'.$propName] = $matches[2][$idx];
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
$subEngine = new ThothEngine();
|
|
338
|
+
$subEngine->dataContext = $this->dataContext;
|
|
339
|
+
$subEngine->variables = array_merge($this->variables, $props);
|
|
340
|
+
$subEngine->tagMap = $this->tagMap;
|
|
341
|
+
$subEngine->voidTags = $this->voidTags;
|
|
342
|
+
|
|
343
|
+
$tempCode = "TYPE THOTH\n";
|
|
344
|
+
foreach($buffer as $l) {
|
|
345
|
+
$tempCode .= str_repeat(" ", $baseIndent) . $l . "\n";
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
$tempFile = tempnam(sys_get_temp_dir(), 'thoth_comp_');
|
|
349
|
+
file_put_contents($tempFile, $tempCode);
|
|
350
|
+
$output = $subEngine->render($tempFile, true);
|
|
351
|
+
unlink($tempFile);
|
|
352
|
+
|
|
353
|
+
return $output;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
private function injectStateBindings($tag, $attrs) {
|
|
357
|
+
if (preg_match('/action="([^"]+)"/', $attrs, $match)) {
|
|
358
|
+
$action = $match[1];
|
|
359
|
+
$jsAction = "thothState.dispatch('{$action}')";
|
|
360
|
+
$attrs = preg_replace('/action="[^"]+"/', "onclick=\"{$jsAction}\"", $attrs);
|
|
361
|
+
}
|
|
362
|
+
return $attrs;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
private function injectStateText($text) {
|
|
366
|
+
foreach ($this->stateVars as $key => $val) {
|
|
367
|
+
if (strpos($text, "@{{$key}}") !== false) {
|
|
368
|
+
$text = str_replace("@{{$key}}", "<span data-thoth-state='{$key}'>{$val}</span>", $text);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return $text;
|
|
372
|
+
}
|
|
196
373
|
|
|
197
374
|
private function resolveDynamicData($text) {
|
|
198
375
|
$text = str_replace(array_keys($this->variables), array_values($this->variables), $text);
|
|
@@ -227,10 +404,6 @@ class ThothEngine {
|
|
|
227
404
|
return "<div style='font-family:sans-serif; background:#020617; color:#fff; height:100vh; display:flex; flex-direction:column; align-items:center; justify-content:center;'><h1>$title</h1><p style='color:#06b6d4'>$msg</p></div>";
|
|
228
405
|
}
|
|
229
406
|
|
|
230
|
-
/**
|
|
231
|
-
* Python-Style Traceback Overlay
|
|
232
|
-
* ุชุตู
ูู
ููุฏุณู ุฐูู ูุญุฏุฏ ุงูุฎุทุฃ ูุงูู
ูุงู ูุงูู
ูู ุจุงูุชูุตูู
|
|
233
|
-
*/
|
|
234
407
|
private function devErrorOverlay($msg, $line, $lineContent = "") {
|
|
235
408
|
$escapedContent = htmlspecialchars($lineContent);
|
|
236
409
|
return "
|
|
@@ -263,6 +436,32 @@ class ThothEngine {
|
|
|
263
436
|
$title = $this->dataContext['site_title'] ?? "THOTH Compiled System";
|
|
264
437
|
$desc = $this->dataContext['site_desc'] ?? "Architected by Abdelfatah Abdelhamed";
|
|
265
438
|
|
|
439
|
+
$stateJson = json_encode($this->stateVars);
|
|
440
|
+
$stateScript = "
|
|
441
|
+
<script>
|
|
442
|
+
// THOTH Frontend State Engine v12.0
|
|
443
|
+
const thothState = {
|
|
444
|
+
data: $stateJson,
|
|
445
|
+
dispatch: function(actionStr) {
|
|
446
|
+
if(actionStr.startsWith('set:')) {
|
|
447
|
+
let logic = actionStr.replace('set:', '').split('=');
|
|
448
|
+
let key = logic[0];
|
|
449
|
+
let expr = logic[1];
|
|
450
|
+
if(expr.includes('+1')) this.data[key] = parseInt(this.data[key]) + 1;
|
|
451
|
+
else if(expr.includes('-1')) this.data[key] = parseInt(this.data[key]) - 1;
|
|
452
|
+
else this.data[key] = expr;
|
|
453
|
+
this.render();
|
|
454
|
+
}
|
|
455
|
+
},
|
|
456
|
+
render: function() {
|
|
457
|
+
document.querySelectorAll('[data-thoth-state]').forEach(el => {
|
|
458
|
+
let key = el.getAttribute('data-thoth-state');
|
|
459
|
+
if(this.data[key] !== undefined) el.innerText = this.data[key];
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
</script>";
|
|
464
|
+
|
|
266
465
|
$liveReload = $this->devMode ? "<script>
|
|
267
466
|
let lastMod = null;
|
|
268
467
|
setInterval(async () => {
|
|
@@ -279,9 +478,9 @@ class ThothEngine {
|
|
|
279
478
|
" <meta charset='UTF-8'>\n" .
|
|
280
479
|
" <meta name='viewport' content='width=device-width, initial-scale=1.0'>\n" .
|
|
281
480
|
" <meta name='description' content='$desc'>\n" .
|
|
282
|
-
" <meta name='generator' content='THOTH Sovereign Engine
|
|
481
|
+
" <meta name='generator' content='THOTH Sovereign Engine 12.0.0'>\n" .
|
|
283
482
|
" <title>$title</title>\n" .
|
|
284
|
-
"</head>\n<body>\n$body\n$liveReload</body>\n</html>";
|
|
483
|
+
"</head>\n<body style=\"margin:0; font-family:sans-serif;\">\n$body\n$stateScript\n$liveReload</body>\n</html>";
|
|
285
484
|
}
|
|
286
485
|
}
|
|
287
486
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thoth-markup-lang",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "THOTH Sovereign Suite (
|
|
3
|
+
"version": "12.0.1",
|
|
4
|
+
"description": "THOTH Sovereign Suite v12.0.0 (The Sovereign Cloud): The ultimate indentation-based reactive web engine. Features native API Fetch Engine, Smart Routing (SPA builder), Native Layouts (Flexbox), Sovereign Components, State Management, Python-style tracebacks, and an ultra-high-performance runtime. Engineered by Engineer Abdelfatah Abdelhamed.",
|
|
5
5
|
"main": "thoth.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"thoth": "./thoth.js"
|
|
@@ -14,13 +14,26 @@
|
|
|
14
14
|
"serve": "node thoth.js serve --port 3000 --strict",
|
|
15
15
|
"validate": "node thoth.js validate --all",
|
|
16
16
|
"auth-setup": "node thoth.js auth --init",
|
|
17
|
-
"version": "echo THOTH
|
|
17
|
+
"version": "echo THOTH v12.0.0 The Sovereign Cloud Intelligence Suite"
|
|
18
18
|
},
|
|
19
19
|
"keywords": [
|
|
20
20
|
"thoth",
|
|
21
21
|
"thoth-lang",
|
|
22
22
|
"markup-language",
|
|
23
23
|
"sovereign-engine",
|
|
24
|
+
"sovereign-cloud",
|
|
25
|
+
"api-fetch",
|
|
26
|
+
"data-fetching",
|
|
27
|
+
"rest-api",
|
|
28
|
+
"web-engine",
|
|
29
|
+
"smart-routing",
|
|
30
|
+
"spa-builder",
|
|
31
|
+
"layout-engine",
|
|
32
|
+
"flexbox-grid",
|
|
33
|
+
"core-framework",
|
|
34
|
+
"sovereign-components",
|
|
35
|
+
"state-management",
|
|
36
|
+
"reactive-ui",
|
|
24
37
|
"pulse-edition",
|
|
25
38
|
"python-style-traceback",
|
|
26
39
|
"smart-error-handling",
|
|
@@ -59,4 +72,4 @@
|
|
|
59
72
|
"publishConfig": {
|
|
60
73
|
"access": "public"
|
|
61
74
|
}
|
|
62
|
-
}
|
|
75
|
+
}
|
package/thoth.js
CHANGED
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* THOTH Engine
|
|
4
|
+
* THOTH Engine v12.0.0 - The Sovereign Cloud (Intelligence Suite)
|
|
5
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
13
|
* 6. Python-Style Traceback: ู
ุชุชุจุน ุฃุฎุทุงุก ุฐูู ูุฏููู ุฌุฏุงู.
|
|
14
|
-
* 7. Ultra-Fast Parser: ุชุณุฑูุน ุฎูุงุฑุฒู
ูุงุช ุงูู Indentation
|
|
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.
|
|
15
20
|
*/
|
|
16
21
|
|
|
17
22
|
const fs = require('fs');
|
|
18
23
|
const path = require('path');
|
|
19
24
|
const http = require('http');
|
|
25
|
+
const https = require('https');
|
|
20
26
|
|
|
21
27
|
// --- ููุงุณ ุชุชุจุน ุงูุฃุฎุทุงุก ุงูุฐูู (Python-Style Error Traceback) ---
|
|
22
28
|
class ThothSyntaxError extends Error {
|
|
@@ -36,17 +42,17 @@ const TAG_MAP = {
|
|
|
36
42
|
'Header': 'header', 'Footer': 'footer', 'Article': 'article', 'Aside': 'aside',
|
|
37
43
|
'Link': 'a', 'Image': 'img', 'Button': 'button', 'List': 'ul', 'Item': 'li',
|
|
38
44
|
'Input': 'input', 'Form': 'form', 'Label': 'label', 'Break': 'br', 'Line': 'hr',
|
|
39
|
-
'Main': 'main', 'Layout': 'section'
|
|
45
|
+
'Main': 'main', 'Layout': 'section',
|
|
46
|
+
'Row': 'div', 'Column': 'div'
|
|
40
47
|
};
|
|
41
48
|
|
|
42
49
|
const VOID_ELEMENTS = ['img', 'br', 'hr', 'input', 'meta', 'link'];
|
|
43
50
|
|
|
44
|
-
// --- ุณูุงู ุงูุชุดุบูู ุงูุณูุงุฏู ---
|
|
45
|
-
let
|
|
46
|
-
let config = {
|
|
51
|
+
// --- ุณูุงู ุงูุชุดุบูู ุงูุณูุงุฏู ุงูุนุงู
---
|
|
52
|
+
let globalConfig = {
|
|
47
53
|
devMode: process.argv.includes('--dev') || process.argv.includes('serve'),
|
|
48
54
|
port: 3000,
|
|
49
|
-
currentUserRole: 'admin',
|
|
55
|
+
currentUserRole: 'admin',
|
|
50
56
|
strictMode: true
|
|
51
57
|
};
|
|
52
58
|
|
|
@@ -59,25 +65,38 @@ if (!command || (!target && command !== 'serve')) {
|
|
|
59
65
|
process.exit(1);
|
|
60
66
|
}
|
|
61
67
|
|
|
62
|
-
/**
|
|
63
|
-
* ุนุฑุถ ุฅุฑุดุงุฏุงุช ุงูุงุณุชุฎุฏุงู
ุงูุชูููุฉ
|
|
64
|
-
*/
|
|
65
68
|
function displayUsage() {
|
|
66
69
|
const yellow = '\x1b[33m';
|
|
67
70
|
const cyan = '\x1b[36m';
|
|
68
71
|
const reset = '\x1b[0m';
|
|
69
72
|
console.log(yellow + 'โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ' + reset);
|
|
70
|
-
console.log('\x1b[1m\x1b[32m THOTH INTELLIGENCE SUITE
|
|
73
|
+
console.log('\x1b[1m\x1b[32m THOTH INTELLIGENCE SUITE v12.0.0 (The Sovereign Cloud) \x1b[0m');
|
|
71
74
|
console.log(cyan + ' Lead Architect: Engineer Abdelfatah Abdelhamed' + reset);
|
|
72
75
|
console.log(yellow + 'โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ' + reset);
|
|
73
76
|
console.log(' Usage:');
|
|
74
77
|
console.log(' thoth build [file].thoth (Production Compilation)');
|
|
75
|
-
console.log(' thoth serve [file].thoth (Live
|
|
78
|
+
console.log(' thoth serve [file].thoth (Live SPA Server + Traceback)');
|
|
79
|
+
}
|
|
80
|
+
|
|
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
|
+
});
|
|
76
98
|
}
|
|
77
99
|
|
|
78
|
-
/**
|
|
79
|
-
* ู
ุนุงูุฌุฉ ุงูุจูุงูุงุช ุงูุฏููุงู
ูููุฉ @{{key}} ู @Variable (Fast Regex)
|
|
80
|
-
*/
|
|
81
100
|
const DATA_REGEX = /@\{\{([^}]+)\}\}/g;
|
|
82
101
|
function resolveData(text, context, variables = {}) {
|
|
83
102
|
let resolved = text;
|
|
@@ -90,54 +109,138 @@ function resolveData(text, context, variables = {}) {
|
|
|
90
109
|
});
|
|
91
110
|
}
|
|
92
111
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
+
}
|
|
99
119
|
}
|
|
120
|
+
return processedText;
|
|
121
|
+
}
|
|
100
122
|
|
|
101
|
-
|
|
102
|
-
const
|
|
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
|
+
|
|
133
|
+
/**
|
|
134
|
+
* ุงูู
ุญุฑู ุงูุฃุณุงุณู (ุชุญูู ุฅูู Async/Await ูุฏุนู
ุงูุณุญุงุจุฉ ุงูุณูุงุฏูุฉ)
|
|
135
|
+
*/
|
|
136
|
+
async function compileThothEngine(sourceContent, inputPath, isDev = false, isSubCall = false, inheritedContext = {}, inheritedComponents = {}, requestedRoute = '/') {
|
|
137
|
+
const lines = sourceContent.split(/\r?\n/);
|
|
103
138
|
|
|
104
|
-
// --- ุงูุชุญูู ู
ู ุดุฑุท ุงูุณูุงุฏุฉ ุงูุฃูู ---
|
|
105
139
|
if (lines[0].trim() !== "TYPE THOTH") {
|
|
106
|
-
throw new ThothSyntaxError("Architectural Identity Error: Missing 'TYPE THOTH' protocol
|
|
140
|
+
throw new ThothSyntaxError("Architectural Identity Error: Missing 'TYPE THOTH' protocol.", 1, lines[0], inputPath);
|
|
107
141
|
}
|
|
108
142
|
|
|
109
143
|
let htmlContent = "";
|
|
110
144
|
let stack = [];
|
|
111
|
-
|
|
145
|
+
|
|
146
|
+
let dataContext = { ...inheritedContext.dataContext };
|
|
147
|
+
let variables = { ...inheritedContext.variables };
|
|
148
|
+
let stateVars = { ...inheritedContext.stateVars };
|
|
149
|
+
let componentsContext = { ...inheritedComponents };
|
|
150
|
+
|
|
112
151
|
let rawScope = { active: false, type: '', indent: 0 };
|
|
113
152
|
let skipIndent = -1;
|
|
114
153
|
let repeatScope = { active: false, key: '', indent: 0, buffer: [] };
|
|
154
|
+
|
|
155
|
+
let componentScope = { active: false, name: '', indent: 0, buffer: [] };
|
|
115
156
|
|
|
116
157
|
for (let i = 1; i < lines.length; i++) {
|
|
117
158
|
const lineNum = i + 1;
|
|
118
159
|
let line = lines[i];
|
|
119
160
|
|
|
120
|
-
// ุชุณุฑูุน ุงูุชุดุงู ุงูู
ุณุงูุงุช (ุฃุณุฑุน ู
ู Regex search)
|
|
121
161
|
const trimmed = line.trimStart();
|
|
122
162
|
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
123
163
|
const indent = line.length - trimmed.length;
|
|
124
164
|
const fullyTrimmed = trimmed.trimEnd();
|
|
125
165
|
|
|
126
|
-
// --- 1. Middleware / Auth Guard ---
|
|
127
166
|
if (skipIndent !== -1) {
|
|
128
167
|
if (indent > skipIndent) continue;
|
|
129
168
|
else skipIndent = -1;
|
|
130
169
|
}
|
|
131
170
|
|
|
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 ---
|
|
132
182
|
const authMatch = fullyTrimmed.match(/Auth="([^"]+)"/);
|
|
133
183
|
if (authMatch) {
|
|
134
|
-
if (authMatch[1] !==
|
|
184
|
+
if (authMatch[1] !== globalConfig.currentUserRole && authMatch[1] !== 'guest') {
|
|
135
185
|
skipIndent = indent;
|
|
136
186
|
continue;
|
|
137
187
|
}
|
|
138
188
|
}
|
|
139
189
|
|
|
140
|
-
// ---
|
|
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) ---
|
|
141
244
|
if (repeatScope.active) {
|
|
142
245
|
if (indent > repeatScope.indent) {
|
|
143
246
|
repeatScope.buffer.push(line);
|
|
@@ -147,9 +250,10 @@ function compileThoth(inputPath, isDev = false) {
|
|
|
147
250
|
if(!Array.isArray(list)) {
|
|
148
251
|
throw new ThothSyntaxError(`DataMappingError: '${repeatScope.key}' is not a valid Array in Context.`, lineNum, line, inputPath);
|
|
149
252
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
+
}
|
|
153
257
|
repeatScope.active = false;
|
|
154
258
|
repeatScope.buffer = [];
|
|
155
259
|
}
|
|
@@ -164,15 +268,14 @@ function compileThoth(inputPath, isDev = false) {
|
|
|
164
268
|
continue;
|
|
165
269
|
}
|
|
166
270
|
|
|
167
|
-
// ---
|
|
271
|
+
// --- 7. DataSource & Variables ---
|
|
168
272
|
if (fullyTrimmed.startsWith('DataSource:')) {
|
|
169
273
|
const jsonFileName = fullyTrimmed.split(':')[1].trim();
|
|
170
274
|
const dPath = path.resolve(path.dirname(inputPath), jsonFileName);
|
|
171
|
-
if (!fs.existsSync(dPath)) {
|
|
172
|
-
throw new ThothSyntaxError(`MissingDataError: DataSource '${jsonFileName}' not found.`, lineNum, line, inputPath);
|
|
173
|
-
}
|
|
275
|
+
if (!fs.existsSync(dPath)) throw new ThothSyntaxError(`MissingDataError: DataSource '${jsonFileName}' not found.`, lineNum, line, inputPath);
|
|
174
276
|
try {
|
|
175
|
-
|
|
277
|
+
const parsedData = JSON.parse(fs.readFileSync(dPath, 'utf8'));
|
|
278
|
+
dataContext = { ...dataContext, ...parsedData };
|
|
176
279
|
} catch(e) {
|
|
177
280
|
throw new ThothSyntaxError(`JSONParseError: Invalid JSON format in '${jsonFileName}'.`, lineNum, line, inputPath);
|
|
178
281
|
}
|
|
@@ -182,14 +285,23 @@ function compileThoth(inputPath, isDev = false) {
|
|
|
182
285
|
if (fullyTrimmed.startsWith('Var ')) {
|
|
183
286
|
const vParts = fullyTrimmed.substring(4).split(':');
|
|
184
287
|
if (vParts.length === 2) variables['@' + vParts[0].trim()] = vParts[1].trim();
|
|
185
|
-
else throw new ThothSyntaxError(`VariableError: Invalid Var syntax
|
|
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;
|
|
186
299
|
continue;
|
|
187
300
|
}
|
|
188
301
|
|
|
189
302
|
line = resolveData(line, dataContext, variables);
|
|
190
303
|
const processedTrimmed = line.trim();
|
|
191
304
|
|
|
192
|
-
// --- 4. Raw Code Injection (CSS/JS) ---
|
|
193
305
|
if (rawScope.active) {
|
|
194
306
|
if (indent <= rawScope.indent && processedTrimmed !== "") {
|
|
195
307
|
rawScope.active = false;
|
|
@@ -200,7 +312,6 @@ function compileThoth(inputPath, isDev = false) {
|
|
|
200
312
|
}
|
|
201
313
|
}
|
|
202
314
|
|
|
203
|
-
// --- ุฎูุงุฑุฒู
ูุฉ ุชุญููู ุงููุตู ุงูุฐูู (Strict Parser) ---
|
|
204
315
|
let colonIdx = -1;
|
|
205
316
|
let inQuotes = false;
|
|
206
317
|
for (let j = 0; j < processedTrimmed.length; j++) {
|
|
@@ -213,7 +324,7 @@ function compileThoth(inputPath, isDev = false) {
|
|
|
213
324
|
|
|
214
325
|
const firstSpace = instr.indexOf(' ');
|
|
215
326
|
const tagName = firstSpace !== -1 ? instr.substring(0, firstSpace) : instr;
|
|
216
|
-
|
|
327
|
+
let attrs = firstSpace !== -1 ? instr.substring(firstSpace).trim() : "";
|
|
217
328
|
|
|
218
329
|
if (tagName === "StyleSheet" || tagName === "Scripting") {
|
|
219
330
|
rawScope.active = true;
|
|
@@ -223,74 +334,134 @@ function compileThoth(inputPath, isDev = false) {
|
|
|
223
334
|
continue;
|
|
224
335
|
}
|
|
225
336
|
|
|
226
|
-
//
|
|
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
|
+
|
|
227
352
|
while (stack.length > 0 && stack[stack.length - 1].indent >= indent) {
|
|
228
353
|
htmlContent += `</${stack.pop().name}>\n`;
|
|
229
354
|
}
|
|
230
355
|
|
|
231
356
|
const tag = TAG_MAP[tagName] || tagName.toLowerCase();
|
|
232
|
-
|
|
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
|
+
|
|
233
383
|
const open = `<${tag}${cleanAttrs ? ' ' + cleanAttrs : ''}>`;
|
|
234
384
|
|
|
235
385
|
if (VOID_ELEMENTS.includes(tag)) {
|
|
236
386
|
htmlContent += ' '.repeat(indent) + open + '\n';
|
|
237
387
|
} else if (val) {
|
|
238
|
-
|
|
388
|
+
const finalVal = injectStateText(val, stateVars);
|
|
389
|
+
htmlContent += ' '.repeat(indent) + `${open}${finalVal}</${tag}>\n`;
|
|
239
390
|
} else {
|
|
240
391
|
htmlContent += ' '.repeat(indent) + open + '\n';
|
|
241
392
|
stack.push({ name: tag, indent: indent });
|
|
242
393
|
}
|
|
243
394
|
}
|
|
244
395
|
|
|
245
|
-
|
|
396
|
+
if (componentScope.active) componentsContext[componentScope.name] = [...componentScope.buffer];
|
|
246
397
|
if (repeatScope.active) {
|
|
247
398
|
const list = dataContext[repeatScope.key] || [];
|
|
248
|
-
|
|
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
|
+
}
|
|
249
403
|
}
|
|
250
404
|
|
|
251
405
|
while (stack.length > 0) htmlContent += `</${stack.pop().name}>\n`;
|
|
252
406
|
|
|
253
|
-
return
|
|
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;
|
|
254
419
|
}
|
|
255
420
|
|
|
256
421
|
/**
|
|
257
422
|
* ู
ุนุงูุฌุฉ ุงูู Buffer ุฏุงุฎู ุงูู Loop
|
|
258
423
|
*/
|
|
259
|
-
function processBuffer(buffer,
|
|
260
|
-
let
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
let pLine = resolveData(l, item, variables);
|
|
265
|
-
const t = pLine.trim();
|
|
266
|
-
let cIdx = t.indexOf(':'); // Fast path for loops
|
|
267
|
-
let cmdStr = cIdx !== -1 ? t.substring(0, cIdx).trim() : t;
|
|
268
|
-
let valStr = cIdx !== -1 ? t.substring(cIdx + 1).trim() : "";
|
|
269
|
-
|
|
270
|
-
const space = cmdStr.indexOf(' ');
|
|
271
|
-
const tag = TAG_MAP[cmdStr.substring(0, space === -1 ? cmdStr.length : space)] || cmdStr.toLowerCase();
|
|
272
|
-
|
|
273
|
-
while (bStack.length > 0 && bStack[bStack.length - 1].indent >= ind) res += `</${bStack.pop().name}>\n`;
|
|
274
|
-
|
|
275
|
-
const op = `<${tag}${space !== -1 ? ' ' + cmdStr.substring(space).trim() : ''}>`;
|
|
276
|
-
if (VOID_ELEMENTS.includes(tag)) res += ' '.repeat(ind) + op + '\n';
|
|
277
|
-
else if (valStr) res += ' '.repeat(ind) + `${op}${valStr}</${tag}>\n`;
|
|
278
|
-
else { res += ' '.repeat(ind) + op + '\n'; bStack.push({ name: tag, indent: ind }); }
|
|
279
|
-
});
|
|
280
|
-
while (bStack.length > 0) res += `</${bStack.pop().name}>\n`;
|
|
281
|
-
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;
|
|
282
429
|
}
|
|
283
430
|
|
|
284
431
|
/**
|
|
285
|
-
* ุชูููุฏ ูููู HTML5 ุงูู
ุนูุงุฑู
|
|
432
|
+
* ุชูููุฏ ูููู HTML5 ุงูู
ุนูุงุฑู
|
|
286
433
|
*/
|
|
287
|
-
function generateBoilerplate(content, isDev) {
|
|
434
|
+
function generateBoilerplate(content, dataContext, stateVars, isDev) {
|
|
288
435
|
const title = dataContext.site_title || "THOTH Sovereign Architecture";
|
|
289
436
|
const desc = dataContext.site_desc || "Engineered by Abdelfatah Abdelhamed";
|
|
437
|
+
const stateJson = JSON.stringify(stateVars);
|
|
290
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
|
+
|
|
291
462
|
const liveReload = isDev ? `
|
|
292
463
|
<script>
|
|
293
|
-
console.log('%c THOTH
|
|
464
|
+
console.log('%c THOTH CLOUD DEV MODE: ACTIVE ', 'background:#06b6d4;color:#000;font-weight:bold;');
|
|
294
465
|
let lastMod = null;
|
|
295
466
|
setInterval(async () => {
|
|
296
467
|
try {
|
|
@@ -302,26 +473,24 @@ function generateBoilerplate(content, isDev) {
|
|
|
302
473
|
}, 1500);
|
|
303
474
|
</script>` : "";
|
|
304
475
|
|
|
305
|
-
return `<!DOCTYPE html>
|
|
476
|
+
return { html: `<!DOCTYPE html>
|
|
306
477
|
<html lang="ar" dir="rtl">
|
|
307
478
|
<head>
|
|
308
479
|
<meta charset="UTF-8">
|
|
309
480
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
310
481
|
<meta name="description" content="${desc}">
|
|
311
|
-
<meta name="generator" content="THOTH Sovereign Engine
|
|
482
|
+
<meta name="generator" content="THOTH Sovereign Engine v12.0.0">
|
|
312
483
|
<meta name="author" content="Engineer Abdelfatah Abdelhamed">
|
|
313
484
|
<title>${title}</title>
|
|
314
485
|
</head>
|
|
315
|
-
<body style="margin:0; background:#020617; color:#f8fafc;">
|
|
486
|
+
<body style="margin:0; background:#020617; color:#f8fafc; font-family:sans-serif;">
|
|
316
487
|
${content}
|
|
488
|
+
${stateEngineScript}
|
|
317
489
|
${liveReload}
|
|
318
490
|
</body>
|
|
319
|
-
</html
|
|
491
|
+
</html>`};
|
|
320
492
|
}
|
|
321
493
|
|
|
322
|
-
/**
|
|
323
|
-
* ุฏุงูุฉ ุชูููุฏ ูุงุฌูุฉ ุชุชุจุน ุงูุฃุฎุทุงุก (Browser Overlay)
|
|
324
|
-
*/
|
|
325
494
|
function getBrowserTracebackHTML(e) {
|
|
326
495
|
if (e.name === 'ThothSyntaxError') {
|
|
327
496
|
const escapedContent = e.lineContent.replace(/</g, '<').replace(/>/g, '>');
|
|
@@ -353,12 +522,9 @@ function getBrowserTracebackHTML(e) {
|
|
|
353
522
|
</body>`;
|
|
354
523
|
}
|
|
355
524
|
|
|
356
|
-
/**
|
|
357
|
-
* ุทุจุงุนุฉ ุงูุฃุฎุทุงุก ูู ุงูุชูุฑู
ููุงู
|
|
358
|
-
*/
|
|
359
525
|
function printTerminalError(e) {
|
|
360
526
|
if (e.name === 'ThothSyntaxError') {
|
|
361
|
-
console.error('\x1b[31m%s\x1b[0m', `\nโ ๏ธ THOTH Traceback
|
|
527
|
+
console.error('\x1b[31m%s\x1b[0m', `\nโ ๏ธ THOTH Traceback:`);
|
|
362
528
|
console.error('\x1b[90m%s\x1b[0m', ` File "${e.filePath}", line ${e.lineNum}, in <module>`);
|
|
363
529
|
console.error(` ${e.lineContent}`);
|
|
364
530
|
console.error('\x1b[31m%s\x1b[0m', ` ^`);
|
|
@@ -370,14 +536,17 @@ function printTerminalError(e) {
|
|
|
370
536
|
|
|
371
537
|
// --- ุทุจูุฉ ุงูุชูููุฐ ---
|
|
372
538
|
if (command === 'serve') {
|
|
373
|
-
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
|
+
|
|
374
542
|
try {
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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() });
|
|
381
550
|
res.end(html);
|
|
382
551
|
} catch (e) {
|
|
383
552
|
printTerminalError(e);
|
|
@@ -386,20 +555,25 @@ if (command === 'serve') {
|
|
|
386
555
|
}
|
|
387
556
|
});
|
|
388
557
|
|
|
389
|
-
server.listen(
|
|
558
|
+
server.listen(globalConfig.port, () => {
|
|
390
559
|
console.log('\x1b[36m%s\x1b[0m', `โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ`);
|
|
391
|
-
console.log(` โ SERVER ACTIVE: http://localhost:${
|
|
560
|
+
console.log(` โ SERVER ACTIVE: http://localhost:${globalConfig.port}`);
|
|
392
561
|
console.log(` โ ARCHITECTURE: ${target}`);
|
|
393
|
-
console.log(` โ MODE:
|
|
562
|
+
console.log(` โ MODE: The Sovereign Cloud v12.0.0`);
|
|
394
563
|
console.log('\x1b[36m%s\x1b[0m', `โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ`);
|
|
395
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
|
+
})();
|
|
396
577
|
} else {
|
|
397
|
-
|
|
398
|
-
const out = compileThoth(target, false);
|
|
399
|
-
fs.writeFileSync(target.replace('.thoth', '.html'), out);
|
|
400
|
-
console.log(`\x1b[32m [SUCCESS] Architecture materialized: ${target.replace('.thoth', '.html')}\x1b[0m`);
|
|
401
|
-
} catch (e) {
|
|
402
|
-
printTerminalError(e);
|
|
403
|
-
process.exit(1);
|
|
404
|
-
}
|
|
578
|
+
displayUsage();
|
|
405
579
|
}
|