vladx 1.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 (42) hide show
  1. package/README.md +256 -0
  2. package/bin/cli.js +486 -0
  3. package/bin/vlad.js +539 -0
  4. package/bin/vladpm.js +710 -0
  5. package/bin/vladx.js +491 -0
  6. package/package.json +57 -0
  7. package/src/engine/jit-compiler.js +285 -0
  8. package/src/engine/vladx-engine.js +941 -0
  9. package/src/index.js +44 -0
  10. package/src/interpreter/interpreter.js +2114 -0
  11. package/src/lexer/lexer.js +658 -0
  12. package/src/lexer/optimized-lexer.js +106 -0
  13. package/src/lexer/regex-cache.js +83 -0
  14. package/src/parser/ast-nodes.js +472 -0
  15. package/src/parser/parser.js +1408 -0
  16. package/src/runtime/advanced-type-system.js +209 -0
  17. package/src/runtime/async-manager.js +252 -0
  18. package/src/runtime/builtins.js +143 -0
  19. package/src/runtime/bundler.js +422 -0
  20. package/src/runtime/cache-manager.js +126 -0
  21. package/src/runtime/data-structures.js +612 -0
  22. package/src/runtime/debugger.js +260 -0
  23. package/src/runtime/enhanced-module-system.js +196 -0
  24. package/src/runtime/environment-enhanced.js +272 -0
  25. package/src/runtime/environment.js +140 -0
  26. package/src/runtime/event-emitter.js +232 -0
  27. package/src/runtime/formatter.js +280 -0
  28. package/src/runtime/functional.js +359 -0
  29. package/src/runtime/io-operations.js +390 -0
  30. package/src/runtime/linter.js +374 -0
  31. package/src/runtime/logging.js +314 -0
  32. package/src/runtime/minifier.js +242 -0
  33. package/src/runtime/module-system.js +377 -0
  34. package/src/runtime/network-operations.js +373 -0
  35. package/src/runtime/profiler.js +295 -0
  36. package/src/runtime/repl.js +336 -0
  37. package/src/runtime/security-manager.js +244 -0
  38. package/src/runtime/source-map-generator.js +208 -0
  39. package/src/runtime/test-runner.js +394 -0
  40. package/src/runtime/transformer.js +277 -0
  41. package/src/runtime/type-system.js +244 -0
  42. package/src/runtime/vladx-object.js +250 -0
@@ -0,0 +1,422 @@
1
+ /**
2
+ * Bundle — Сборщик модулей
3
+ */
4
+
5
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
6
+ import { dirname, join, relative } from 'path';
7
+
8
+ export class Bundle {
9
+ constructor(options = {}) {
10
+ this.entry = options.entry;
11
+ this.output = options.output || 'bundle.vx';
12
+ this.format = options.format || 'esm'; // esm, cjs, iife, umd
13
+ this.minify = options.minify || false;
14
+ this.sourceMap = options.sourceMap || false;
15
+ this.moduleSystem = options.moduleSystem;
16
+ this.analyzed = new Map();
17
+ this.dependencyGraph = new Map();
18
+ this.importStatements = new Set();
19
+ }
20
+
21
+ /**
22
+ * Собрать модули в один файл
23
+ */
24
+ async build() {
25
+ if (!this.entry) {
26
+ throw new Error('Entry point is required');
27
+ }
28
+
29
+ const modules = await this.analyzeDependencies(this.entry);
30
+ const sorted = this.topologicalSort(modules);
31
+ const bundled = this.generateBundle(sorted);
32
+
33
+ if (this.sourceMap) {
34
+ const map = this.generateSourceMap(sorted);
35
+ bundled.sourceMap = map;
36
+ }
37
+
38
+ return bundled;
39
+ }
40
+
41
+ /**
42
+ * Анализировать зависимости
43
+ */
44
+ async analyzeDependencies(entryPath) {
45
+ const modules = new Map();
46
+
47
+ const analyze = async (filePath, parentPath = null) => {
48
+ if (modules.has(filePath)) {
49
+ return modules.get(filePath);
50
+ }
51
+
52
+ const source = readFileSync(filePath, 'utf-8');
53
+ const module = {
54
+ path: filePath,
55
+ source,
56
+ imports: [],
57
+ exports: [],
58
+ dependencies: new Set()
59
+ };
60
+
61
+ modules.set(filePath, module);
62
+
63
+ // Найти import и export statements
64
+ const importRegex = /(?:импорт|import)\s+([^;]+);/g;
65
+ const exportRegex = /(?:экспорт|export)\s+(?:поумолчанию|default)?\s+([^;]+);/g;
66
+
67
+ let match;
68
+ while ((match = importRegex.exec(source)) !== null) {
69
+ const importSpec = match[1].trim();
70
+ const depPath = this.extractImportPath(importSpec);
71
+
72
+ if (depPath) {
73
+ const resolvedPath = await this.resolvePath(depPath, filePath);
74
+ module.imports.push({
75
+ spec: importSpec,
76
+ path: depPath,
77
+ resolvedPath
78
+ });
79
+ module.dependencies.add(resolvedPath);
80
+
81
+ // Рекурсивно анализируем зависимости
82
+ if (!modules.has(resolvedPath)) {
83
+ await analyze(resolvedPath, filePath);
84
+ }
85
+ }
86
+ }
87
+
88
+ while ((match = exportRegex.exec(source)) !== null) {
89
+ module.exports.push(match[1].trim());
90
+ }
91
+
92
+ return module;
93
+ };
94
+
95
+ await analyze(entryPath);
96
+ return modules;
97
+ }
98
+
99
+ /**
100
+ * Извлечь путь из import statement
101
+ */
102
+ extractImportPath(importSpec) {
103
+ const fromMatch = importSpec.match(/(?:из|from)\s+['"]([^'"]+)['"]/);
104
+ return fromMatch ? fromMatch[1] : null;
105
+ }
106
+
107
+ /**
108
+ * Разрешить путь модуля
109
+ */
110
+ async resolvePath(importPath, currentPath) {
111
+ if (importPath.startsWith('./') || importPath.startsWith('../')) {
112
+ const resolved = join(dirname(currentPath), importPath);
113
+
114
+ // Проверяем расширения
115
+ const extensions = ['.vx', '.js'];
116
+ for (const ext of extensions) {
117
+ if (existsSync(resolved + ext)) {
118
+ return resolved + ext;
119
+ }
120
+ }
121
+
122
+ // Проверяем index.vx
123
+ const indexFile = join(resolved, 'index.vx');
124
+ if (existsSync(indexFile)) {
125
+ return indexFile;
126
+ }
127
+
128
+ return resolved;
129
+ }
130
+
131
+ // Для пакетов из node_modules
132
+ const nodeModulesPath = join(dirname(currentPath), 'node_modules', importPath);
133
+ if (existsSync(nodeModulesPath + '.vx')) {
134
+ return nodeModulesPath + '.vx';
135
+ }
136
+
137
+ throw new Error(`Не удалось разрешить модуль: ${importPath}`);
138
+ }
139
+
140
+ /**
141
+ * Топологическая сортировка зависимостей
142
+ */
143
+ topologicalSort(modules) {
144
+ const visited = new Set();
145
+ const result = [];
146
+ const visiting = new Set();
147
+
148
+ const visit = (module) => {
149
+ if (visiting.has(module.path)) {
150
+ throw new Error(`Циклическая зависимость: ${module.path}`);
151
+ }
152
+
153
+ if (visited.has(module.path)) {
154
+ return;
155
+ }
156
+
157
+ visiting.add(module.path);
158
+ visited.add(module.path);
159
+
160
+ for (const dep of module.dependencies) {
161
+ const depModule = modules.get(dep);
162
+ if (depModule) {
163
+ visit(depModule);
164
+ }
165
+ }
166
+
167
+ visiting.delete(module.path);
168
+ result.push(module);
169
+ };
170
+
171
+ for (const module of modules.values()) {
172
+ if (!visited.has(module.path)) {
173
+ visit(module);
174
+ }
175
+ }
176
+
177
+ return result.reverse();
178
+ }
179
+
180
+ /**
181
+ * Сгенерировать бандл
182
+ */
183
+ generateBundle(modules) {
184
+ let output = '';
185
+ const outputDir = dirname(this.output);
186
+
187
+ switch (this.format) {
188
+ case 'esm':
189
+ output = this.generateESM(modules, outputDir);
190
+ break;
191
+ case 'cjs':
192
+ output = this.generateCJS(modules, outputDir);
193
+ break;
194
+ case 'iife':
195
+ output = this.generateIIFE(modules, outputDir);
196
+ break;
197
+ case 'umd':
198
+ output = this.generateUMD(modules, outputDir);
199
+ break;
200
+ default:
201
+ throw new Error(`Неподдерживаемый формат: ${this.format}`);
202
+ }
203
+
204
+ if (this.minify) {
205
+ output = this.minify(output);
206
+ }
207
+
208
+ return {
209
+ code: output,
210
+ modules: modules.size,
211
+ format: this.format
212
+ };
213
+ }
214
+
215
+ /**
216
+ * Сгенерировать ESM формат
217
+ */
218
+ generateESM(modules, outputDir) {
219
+ let output = '';
220
+
221
+ // Все модули в одном файле с комментариями
222
+ output += '// VladX Bundle\n';
223
+ output += '// Generated by VladX Bundler\n\n';
224
+
225
+ for (const module of modules) {
226
+ const relativePath = relative(outputDir, module.path);
227
+ output += `// Module: ${relativePath}\n`;
228
+ output += this.rewriteImports(module, modules, outputDir);
229
+ output += '\n';
230
+ }
231
+
232
+ return output;
233
+ }
234
+
235
+ /**
236
+ * Сгенерировать CJS формат
237
+ */
238
+ generateCJS(modules, outputDir) {
239
+ let output = '';
240
+ const moduleMap = new Map();
241
+ let index = 0;
242
+
243
+ // Создаем map модулей
244
+ for (const module of modules) {
245
+ const id = `module_${index++}`;
246
+ moduleMap.set(module.path, id);
247
+ }
248
+
249
+ // IIFE обертка
250
+ output += '(function() {\n';
251
+ output += ' const modules = {};\n\n';
252
+
253
+ // Определяем модули
254
+ for (const module of modules) {
255
+ const id = moduleMap.get(module.path);
256
+ const rewritten = this.rewriteImportsCJS(module, moduleMap, outputDir);
257
+ output += ` ${id} = function(module, exports) {\n`;
258
+ output += ` ${rewritten}\n`;
259
+ output += ` };\n\n`;
260
+ }
261
+
262
+ // Инициализируем модули
263
+ for (const module of modules) {
264
+ const id = moduleMap.get(module.path);
265
+ output += ` ${id}(${id}, ${id}.exports = {});\n`;
266
+ }
267
+
268
+ output += '})();\n';
269
+
270
+ return output;
271
+ }
272
+
273
+ /**
274
+ * Сгенерировать IIFE формат
275
+ */
276
+ generateIIFE(modules, outputDir) {
277
+ let output = '';
278
+
279
+ output += '(function() {\n';
280
+ output += ' "use strict";\n\n';
281
+
282
+ for (const module of modules) {
283
+ const rewritten = this.rewriteImports(module, modules, outputDir);
284
+ output += ` ${rewrapped}\n\n`;
285
+ }
286
+
287
+ output += '})();\n';
288
+
289
+ return output;
290
+ }
291
+
292
+ /**
293
+ * Сгенерировать UMD формат
294
+ */
295
+ generateUMD(modules, outputDir) {
296
+ let output = '';
297
+
298
+ output += '(function(root, factory) {\n';
299
+ output += ' if (typeof define === "function" && define.amd) {\n';
300
+ output += ' define([], factory);\n';
301
+ output += ' } else if (typeof module === "object" && module.exports) {\n';
302
+ output += ' module.exports = factory();\n';
303
+ output += ' } else {\n';
304
+ output += ' root.VladX = factory();\n';
305
+ output += ' }\n';
306
+ output += '})(this, function() {\n\n';
307
+
308
+ output += this.generateCJS(modules, outputDir);
309
+
310
+ output += '\n});\n';
311
+
312
+ return output;
313
+ }
314
+
315
+ /**
316
+ * Переписать импорты для ESM
317
+ */
318
+ rewriteImports(module, modules, outputDir) {
319
+ let source = module.source;
320
+
321
+ for (const imp of module.imports) {
322
+ if (modules.has(imp.resolvedPath)) {
323
+ // Internal module - replace path
324
+ const relativePath = relative(outputDir, imp.resolvedPath);
325
+ source = source.replace(imp.spec, imp.spec.replace(imp.path, relativePath));
326
+ }
327
+ }
328
+
329
+ return source;
330
+ }
331
+
332
+ /**
333
+ * Переписать импорты для CJS
334
+ */
335
+ rewriteImportsCJS(module, moduleMap, outputDir) {
336
+ let source = module.source;
337
+
338
+ for (const imp of module.imports) {
339
+ if (moduleMap.has(imp.resolvedPath)) {
340
+ const id = moduleMap.get(imp.resolvedPath);
341
+ source = source.replace(imp.spec, id);
342
+ }
343
+ }
344
+
345
+ return source;
346
+ }
347
+
348
+ /**
349
+ * Минификация
350
+ */
351
+ minify(code) {
352
+ let minified = code;
353
+
354
+ // Удаляем комментарии
355
+ minified = minified.replace(/\/\*[\s\S]*?\*\//g, '');
356
+ minified = minified.replace(/\/\/.*$/gm, '');
357
+
358
+ // Удаляем лишние пробелы и переводы строк
359
+ minified = minified.replace(/\s+/g, ' ');
360
+ minified = minified.trim();
361
+
362
+ // Удаляем пробелы вокруг операторов
363
+ minified = minified.replace(/\s*([{};:,=+*/%&|^~!?<>])\s*/g, '$1');
364
+
365
+ return minified;
366
+ }
367
+
368
+ /**
369
+ * Сгенерировать source map
370
+ */
371
+ generateSourceMap(modules) {
372
+ const mappings = [];
373
+
374
+ let generatedLine = 1;
375
+ let generatedColumn = 0;
376
+
377
+ for (const module of modules) {
378
+ const lines = module.source.split('\n');
379
+
380
+ for (let i = 0; i < lines.length; i++) {
381
+ mappings.push({
382
+ generated: {
383
+ line: generatedLine,
384
+ column: generatedColumn
385
+ },
386
+ original: {
387
+ line: i + 1,
388
+ column: 0
389
+ },
390
+ source: module.path,
391
+ name: null
392
+ });
393
+
394
+ generatedLine++;
395
+ generatedColumn = 0;
396
+ }
397
+ }
398
+
399
+ return {
400
+ version: 3,
401
+ mappings,
402
+ sources: Array.from(modules.values()).map(m => m.path),
403
+ names: []
404
+ };
405
+ }
406
+
407
+ /**
408
+ * Записать бандл в файл
409
+ */
410
+ async write(bundled) {
411
+ writeFileSync(this.output, bundled.code, 'utf-8');
412
+
413
+ if (this.sourceMap && bundled.sourceMap) {
414
+ const mapPath = this.output + '.map';
415
+ writeFileSync(mapPath, JSON.stringify(bundled.sourceMap, null, 2), 'utf-8');
416
+ }
417
+
418
+ return this.output;
419
+ }
420
+ }
421
+
422
+ export default Bundle;
@@ -0,0 +1,126 @@
1
+ /**
2
+ * CacheManager — Управление кэшированием для повышения производительности
3
+ */
4
+
5
+ export class CacheManager {
6
+ constructor(options = {}) {
7
+ this.maxSize = options.maxSize || 1000;
8
+ this.ttl = options.ttl || 300000; // 5 минут по умолчанию
9
+ this.cache = new Map();
10
+ this.stats = {
11
+ hits: 0,
12
+ misses: 0,
13
+ evictions: 0
14
+ };
15
+ }
16
+
17
+ /**
18
+ * Получить значение из кэша
19
+ */
20
+ get(key) {
21
+ const entry = this.cache.get(key);
22
+
23
+ if (!entry) {
24
+ this.stats.misses++;
25
+ return undefined;
26
+ }
27
+
28
+ // Проверка TTL
29
+ if (this.ttl > 0 && Date.now() - entry.timestamp > this.ttl) {
30
+ this.cache.delete(key);
31
+ this.stats.misses++;
32
+ return undefined;
33
+ }
34
+
35
+ this.stats.hits++;
36
+ return entry.value;
37
+ }
38
+
39
+ /**
40
+ * Установить значение в кэш
41
+ */
42
+ set(key, value) {
43
+ // Проверка размера и LRU eviction
44
+ if (this.cache.size >= this.maxSize) {
45
+ this.evictLRU();
46
+ }
47
+
48
+ this.cache.set(key, {
49
+ value,
50
+ timestamp: Date.now(),
51
+ lastAccess: Date.now()
52
+ });
53
+ }
54
+
55
+ /**
56
+ * Удалить из кэша по ключу
57
+ */
58
+ delete(key) {
59
+ return this.cache.delete(key);
60
+ }
61
+
62
+ /**
63
+ * Очистить весь кэш
64
+ */
65
+ clear() {
66
+ this.cache.clear();
67
+ this.stats = {
68
+ hits: 0,
69
+ misses: 0,
70
+ evictions: 0
71
+ };
72
+ }
73
+
74
+ /**
75
+ * Evict наименее используемый элемент (LRU)
76
+ */
77
+ evictLRU() {
78
+ let lruKey = null;
79
+ let lruTime = Infinity;
80
+
81
+ for (const [key, entry] of this.cache) {
82
+ if (entry.lastAccess < lruTime) {
83
+ lruTime = entry.lastAccess;
84
+ lruKey = key;
85
+ }
86
+ }
87
+
88
+ if (lruKey) {
89
+ this.cache.delete(lruKey);
90
+ this.stats.evictions++;
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Получить статистику кэша
96
+ */
97
+ getStats() {
98
+ const total = this.stats.hits + this.stats.misses;
99
+ return {
100
+ ...this.stats,
101
+ hitRate: total > 0 ? (this.stats.hits / total * 100).toFixed(2) + '%' : '0%',
102
+ size: this.cache.size,
103
+ maxSize: this.maxSize
104
+ };
105
+ }
106
+
107
+ /**
108
+ * Очистка устаревших записей
109
+ */
110
+ prune() {
111
+ if (this.ttl <= 0) return;
112
+
113
+ const now = Date.now();
114
+ const keysToDelete = [];
115
+
116
+ for (const [key, entry] of this.cache) {
117
+ if (now - entry.timestamp > this.ttl) {
118
+ keysToDelete.push(key);
119
+ }
120
+ }
121
+
122
+ keysToDelete.forEach(key => this.cache.delete(key));
123
+ }
124
+ }
125
+
126
+ export default CacheManager;