@reidelsaltres/pureper 0.1.157 → 0.1.160

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 (88) hide show
  1. package/out/foundation/api/Observer.d.ts +30 -0
  2. package/out/foundation/api/Observer.d.ts.map +1 -1
  3. package/out/foundation/api/Observer.js +48 -0
  4. package/out/foundation/api/Observer.js.map +1 -1
  5. package/out/foundation/engine/BalancedParser.d.ts +58 -0
  6. package/out/foundation/engine/BalancedParser.d.ts.map +1 -0
  7. package/out/foundation/engine/BalancedParser.js +301 -0
  8. package/out/foundation/engine/BalancedParser.js.map +1 -0
  9. package/out/foundation/engine/EscapeHandler.d.ts +27 -0
  10. package/out/foundation/engine/EscapeHandler.d.ts.map +1 -0
  11. package/out/foundation/engine/EscapeHandler.js +47 -0
  12. package/out/foundation/engine/EscapeHandler.js.map +1 -0
  13. package/out/foundation/engine/Expression.d.ts +83 -0
  14. package/out/foundation/engine/Expression.d.ts.map +1 -0
  15. package/out/foundation/engine/Expression.js +256 -0
  16. package/out/foundation/engine/Expression.js.map +1 -0
  17. package/out/foundation/engine/Rule.d.ts +83 -0
  18. package/out/foundation/engine/Rule.d.ts.map +1 -0
  19. package/out/foundation/engine/Rule.js +69 -0
  20. package/out/foundation/engine/Rule.js.map +1 -0
  21. package/out/foundation/engine/Scope.d.ts +57 -0
  22. package/out/foundation/engine/Scope.d.ts.map +1 -0
  23. package/out/foundation/engine/Scope.js +147 -0
  24. package/out/foundation/engine/Scope.js.map +1 -0
  25. package/out/foundation/engine/TemplateEngine.d.ts +79 -0
  26. package/out/foundation/engine/TemplateEngine.d.ts.map +1 -0
  27. package/out/foundation/engine/TemplateEngine.js +187 -0
  28. package/out/foundation/engine/TemplateEngine.js.map +1 -0
  29. package/out/foundation/engine/TemplateInstance.d.ts +121 -0
  30. package/out/foundation/engine/TemplateInstance.d.ts.map +1 -0
  31. package/out/foundation/engine/TemplateInstance.js +255 -0
  32. package/out/foundation/engine/TemplateInstance.js.map +1 -0
  33. package/out/foundation/engine/exceptions/TemplateExceptions.d.ts +21 -0
  34. package/out/foundation/engine/exceptions/TemplateExceptions.d.ts.map +1 -0
  35. package/out/foundation/engine/exceptions/TemplateExceptions.js +26 -0
  36. package/out/foundation/engine/exceptions/TemplateExceptions.js.map +1 -0
  37. package/out/foundation/engine/index.d.ts +18 -0
  38. package/out/foundation/engine/index.d.ts.map +1 -0
  39. package/out/foundation/engine/index.js +19 -0
  40. package/out/foundation/engine/index.js.map +1 -0
  41. package/out/foundation/engine/rules/attribute/EventRule.d.ts +22 -0
  42. package/out/foundation/engine/rules/attribute/EventRule.d.ts.map +1 -0
  43. package/out/foundation/engine/rules/attribute/EventRule.js +129 -0
  44. package/out/foundation/engine/rules/attribute/EventRule.js.map +1 -0
  45. package/out/foundation/engine/rules/attribute/InjectionRule.d.ts +20 -0
  46. package/out/foundation/engine/rules/attribute/InjectionRule.d.ts.map +1 -0
  47. package/out/foundation/engine/rules/attribute/InjectionRule.js +108 -0
  48. package/out/foundation/engine/rules/attribute/InjectionRule.js.map +1 -0
  49. package/out/foundation/engine/rules/attribute/RefRule.d.ts +23 -0
  50. package/out/foundation/engine/rules/attribute/RefRule.d.ts.map +1 -0
  51. package/out/foundation/engine/rules/attribute/RefRule.js +98 -0
  52. package/out/foundation/engine/rules/attribute/RefRule.js.map +1 -0
  53. package/out/foundation/engine/rules/syntax/ExpressionRule.d.ts +19 -0
  54. package/out/foundation/engine/rules/syntax/ExpressionRule.d.ts.map +1 -0
  55. package/out/foundation/engine/rules/syntax/ExpressionRule.js +82 -0
  56. package/out/foundation/engine/rules/syntax/ExpressionRule.js.map +1 -0
  57. package/out/foundation/engine/rules/syntax/ForRule.d.ts +19 -0
  58. package/out/foundation/engine/rules/syntax/ForRule.d.ts.map +1 -0
  59. package/out/foundation/engine/rules/syntax/ForRule.js +226 -0
  60. package/out/foundation/engine/rules/syntax/ForRule.js.map +1 -0
  61. package/out/foundation/engine/rules/syntax/IfRule.d.ts +17 -0
  62. package/out/foundation/engine/rules/syntax/IfRule.d.ts.map +1 -0
  63. package/out/foundation/engine/rules/syntax/IfRule.js +220 -0
  64. package/out/foundation/engine/rules/syntax/IfRule.js.map +1 -0
  65. package/out/foundation/worker/Router.d.ts.map +1 -1
  66. package/out/foundation/worker/Router.js.map +1 -1
  67. package/out/index.d.ts +3 -0
  68. package/out/index.d.ts.map +1 -1
  69. package/out/index.js +3 -0
  70. package/out/index.js.map +1 -1
  71. package/package.json +1 -1
  72. package/src/foundation/api/Observer.ts +60 -0
  73. package/src/foundation/engine/BalancedParser.ts +353 -0
  74. package/src/foundation/engine/EscapeHandler.ts +54 -0
  75. package/src/foundation/engine/Expression.ts +285 -0
  76. package/src/foundation/engine/Rule.ts +136 -0
  77. package/src/foundation/engine/Scope.ts +166 -0
  78. package/src/foundation/engine/TemplateEngine.ts +243 -0
  79. package/src/foundation/engine/TemplateInstance.ts +355 -0
  80. package/src/foundation/engine/exceptions/TemplateExceptions.ts +27 -0
  81. package/src/foundation/engine/rules/attribute/EventRule.ts +171 -0
  82. package/src/foundation/engine/rules/attribute/InjectionRule.ts +140 -0
  83. package/src/foundation/engine/rules/attribute/RefRule.ts +119 -0
  84. package/src/foundation/engine/rules/syntax/ExpressionRule.ts +102 -0
  85. package/src/foundation/engine/rules/syntax/ForRule.ts +267 -0
  86. package/src/foundation/engine/rules/syntax/IfRule.ts +261 -0
  87. package/src/foundation/worker/Router.ts +1 -1
  88. package/src/index.ts +9 -0
@@ -0,0 +1,108 @@
1
+ import { AttributeRule } from '../../Rule.js';
2
+ import Expression from '../../Expression.js';
3
+ import { InvalidDynamicRuleUsage } from '../../exceptions/TemplateExceptions.js';
4
+ /**
5
+ * InjectionRule - обработка @injection[type]="expression"
6
+ * Инжектирует элемент в целевой элемент (найденный по @[ref]).
7
+ * type: 'head' = prepend, 'tail' = append
8
+ */
9
+ export default class InjectionRule extends AttributeRule {
10
+ name = 'injection';
11
+ priority = 200; // Выполняется в самом конце
12
+ find(template) {
13
+ const results = [];
14
+ // Match @injection[head] or @injection[tail]
15
+ const pattern = /@injection\[(head|tail)\]\s*=/gi;
16
+ let match;
17
+ while ((match = pattern.exec(template)) !== null) {
18
+ const idx = match.index;
19
+ // Check for @@ escape
20
+ if (idx > 0 && template[idx - 1] === '@') {
21
+ continue;
22
+ }
23
+ const injectionType = match[1].toLowerCase();
24
+ // Find quote char after =
25
+ let pos = idx + match[0].length;
26
+ while (pos < template.length && /\s/.test(template[pos])) {
27
+ pos++;
28
+ }
29
+ const quoteChar = template[pos];
30
+ if (quoteChar !== '"' && quoteChar !== "'") {
31
+ continue;
32
+ }
33
+ // Find matching closing quote
34
+ const contentStart = pos + 1;
35
+ pos++;
36
+ while (pos < template.length && template[pos] !== quoteChar) {
37
+ pos++;
38
+ }
39
+ if (pos >= template.length)
40
+ continue;
41
+ const content = template.slice(contentStart, pos);
42
+ const fullMatch = template.slice(idx, pos + 1);
43
+ results.push({
44
+ fullMatch,
45
+ start: idx,
46
+ end: pos + 1,
47
+ data: {
48
+ type: injectionType,
49
+ expression: content,
50
+ attributeMatch: fullMatch
51
+ }
52
+ });
53
+ }
54
+ return results;
55
+ }
56
+ execute(match, scope) {
57
+ const data = match.data;
58
+ const expr = new Expression(data.expression);
59
+ const targetRefName = expr.execute(scope);
60
+ // Check if Observable - not allowed for @injection
61
+ if (targetRefName && typeof targetRefName === 'object' && typeof targetRefName.subscribe === 'function') {
62
+ throw new InvalidDynamicRuleUsage('@injection', '@injection does not support Observable values. The target reference must be static.');
63
+ }
64
+ if (typeof targetRefName !== 'string') {
65
+ console.error(`[InjectionRule] Expression must return a string (reference name), got: ${typeof targetRefName}`);
66
+ return { output: '' };
67
+ }
68
+ // Store injection info for postprocessing
69
+ const encodedTarget = encodeURIComponent(targetRefName);
70
+ return {
71
+ output: `data-injection-type="${data.type}" data-injection-target="${encodedTarget}"`,
72
+ observables: []
73
+ };
74
+ }
75
+ supportsObservable() {
76
+ return false;
77
+ }
78
+ /**
79
+ * Постобработка: выполнить инжекцию элементов
80
+ */
81
+ static processInjections(root, scope) {
82
+ // Find all elements with injection attributes
83
+ const injectElements = root.querySelectorAll('[data-injection-type][data-injection-target]');
84
+ for (const element of Array.from(injectElements)) {
85
+ const type = element.getAttribute('data-injection-type');
86
+ const targetRefName = decodeURIComponent(element.getAttribute('data-injection-target') || '');
87
+ if (!targetRefName)
88
+ continue;
89
+ // Get target element from scope
90
+ const targetElement = scope.get(targetRefName);
91
+ if (!targetElement || !(targetElement instanceof Element)) {
92
+ console.warn(`[InjectionRule] Target element "${targetRefName}" not found in scope or is not an Element`);
93
+ continue;
94
+ }
95
+ // Remove injection attributes
96
+ element.removeAttribute('data-injection-type');
97
+ element.removeAttribute('data-injection-target');
98
+ // Perform injection
99
+ if (type === 'head') {
100
+ targetElement.prepend(element);
101
+ }
102
+ else {
103
+ targetElement.append(element);
104
+ }
105
+ }
106
+ }
107
+ }
108
+ //# sourceMappingURL=InjectionRule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InjectionRule.js","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/attribute/InjectionRule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { AttributeRule } from '../../Rule.js';
2
+ import type { RuleMatch, RuleResult } from '../../Rule.js';
3
+ import Scope from '../../Scope.js';
4
+ /**
5
+ * RefRule - обработка @[ref]="expression"
6
+ * Добавляет HTML элемент в Scope под указанным именем.
7
+ */
8
+ export default class RefRule extends AttributeRule {
9
+ readonly name = "ref";
10
+ readonly priority = 5;
11
+ find(template: string): RuleMatch[];
12
+ execute(match: RuleMatch, scope: Scope): RuleResult;
13
+ supportsObservable(): boolean;
14
+ /**
15
+ * Постобработка: привязать реальный элемент к Scope
16
+ */
17
+ static bindElement(element: Element, refName: string, scope: Scope): void;
18
+ /**
19
+ * Очистка: установить ref в null если элемент удалён
20
+ */
21
+ static unbindElement(refName: string, scope: Scope): void;
22
+ }
23
+ //# sourceMappingURL=RefRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RefRule.d.ts","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/attribute/RefRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,MAAM,gBAAgB,CAAC;AAInC;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,aAAa;IAC9C,SAAgB,IAAI,SAAS;IAC7B,SAAgB,QAAQ,KAAK;IAEtB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE;IA6DnC,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,UAAU;IAwBnD,kBAAkB,IAAI,OAAO;IAIpC;;OAEG;WACW,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAIhF;;OAEG;WACW,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;CAKnE"}
@@ -0,0 +1,98 @@
1
+ import { AttributeRule } from '../../Rule.js';
2
+ import Expression from '../../Expression.js';
3
+ import { InvalidDynamicRuleUsage } from '../../exceptions/TemplateExceptions.js';
4
+ /**
5
+ * RefRule - обработка @[ref]="expression"
6
+ * Добавляет HTML элемент в Scope под указанным именем.
7
+ */
8
+ export default class RefRule extends AttributeRule {
9
+ name = 'ref';
10
+ priority = 5; // Выполняется очень рано
11
+ find(template) {
12
+ const results = [];
13
+ // Match @[ref]=" or @[ref]='
14
+ const opener = '@[ref]=';
15
+ let i = 0;
16
+ while (i < template.length) {
17
+ const idx = template.toLowerCase().indexOf(opener.toLowerCase(), i);
18
+ if (idx === -1)
19
+ break;
20
+ // Check for @@ escape
21
+ if (idx > 0 && template[idx - 1] === '@') {
22
+ i = idx + 1;
23
+ continue;
24
+ }
25
+ // Find quote char after =
26
+ let pos = idx + opener.length;
27
+ while (pos < template.length && /\s/.test(template[pos])) {
28
+ pos++;
29
+ }
30
+ const quoteChar = template[pos];
31
+ if (quoteChar !== '"' && quoteChar !== "'") {
32
+ i = idx + 1;
33
+ continue;
34
+ }
35
+ // Find matching closing quote (handle nested quotes)
36
+ const contentStart = pos + 1;
37
+ pos++;
38
+ // Simple: find the closing quote that matches
39
+ while (pos < template.length && template[pos] !== quoteChar) {
40
+ pos++;
41
+ }
42
+ if (pos >= template.length) {
43
+ i = idx + 1;
44
+ continue;
45
+ }
46
+ const content = template.slice(contentStart, pos);
47
+ const fullMatch = template.slice(idx, pos + 1);
48
+ results.push({
49
+ fullMatch,
50
+ start: idx,
51
+ end: pos + 1,
52
+ data: {
53
+ expression: content,
54
+ attributeMatch: fullMatch
55
+ }
56
+ });
57
+ i = pos + 1;
58
+ }
59
+ return results;
60
+ }
61
+ execute(match, scope) {
62
+ const exprCode = match.data?.expression;
63
+ const expr = new Expression(exprCode);
64
+ const refName = expr.execute(scope);
65
+ // Check if Observable - not allowed for @[ref]
66
+ if (refName && typeof refName === 'object' && typeof refName.subscribe === 'function') {
67
+ throw new InvalidDynamicRuleUsage('@[ref]', '@[ref] does not support Observable values. The reference name must be static.');
68
+ }
69
+ if (typeof refName !== 'string') {
70
+ console.error(`[RefRule] Expression must return a string (variable name), got: ${typeof refName}`);
71
+ return { output: '' };
72
+ }
73
+ // Store placeholder - actual element will be set during DOM processing
74
+ // For now, return the attribute without the @[ref] syntax
75
+ return {
76
+ output: `data-ref="${refName}"`,
77
+ observables: []
78
+ };
79
+ }
80
+ supportsObservable() {
81
+ return false;
82
+ }
83
+ /**
84
+ * Постобработка: привязать реальный элемент к Scope
85
+ */
86
+ static bindElement(element, refName, scope) {
87
+ scope.set(refName, element);
88
+ }
89
+ /**
90
+ * Очистка: установить ref в null если элемент удалён
91
+ */
92
+ static unbindElement(refName, scope) {
93
+ if (scope.has(refName)) {
94
+ scope.set(refName, null);
95
+ }
96
+ }
97
+ }
98
+ //# sourceMappingURL=RefRule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RefRule.js","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/attribute/RefRule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { SyntaxRule } from '../../Rule.js';
2
+ import type { RuleMatch, RuleResult } from '../../Rule.js';
3
+ import Scope from '../../Scope.js';
4
+ /**
5
+ * ExpressionRule - обработка @(Expression)
6
+ * Выводит результат выражения как строку.
7
+ * Автоматически отслеживает Observable и разворачивает их значения.
8
+ */
9
+ export default class ExpressionRule extends SyntaxRule {
10
+ readonly name = "expression";
11
+ readonly priority = 50;
12
+ find(template: string): RuleMatch[];
13
+ execute(match: RuleMatch, scope: Scope): RuleResult;
14
+ /**
15
+ * Асинхронная версия execute
16
+ */
17
+ executeAsync(match: RuleMatch, scope: Scope): Promise<RuleResult>;
18
+ }
19
+ //# sourceMappingURL=ExpressionRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpressionRule.d.ts","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/syntax/ExpressionRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,MAAM,gBAAgB,CAAC;AAKnC;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,UAAU;IAClD,SAAgB,IAAI,gBAAgB;IACpC,SAAgB,QAAQ,MAAM;IAEvB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE;IAWnC,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,UAAU;IA+C1D;;OAEG;IACU,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC;CAwBjF"}
@@ -0,0 +1,82 @@
1
+ import { SyntaxRule } from '../../Rule.js';
2
+ import Expression from '../../Expression.js';
3
+ import BalancedParser from '../../BalancedParser.js';
4
+ import { isObservable } from '../../../api/Observer.js';
5
+ /**
6
+ * ExpressionRule - обработка @(Expression)
7
+ * Выводит результат выражения как строку.
8
+ * Автоматически отслеживает Observable и разворачивает их значения.
9
+ */
10
+ export default class ExpressionRule extends SyntaxRule {
11
+ name = 'expression';
12
+ priority = 50; // Выполняется после блочных правил
13
+ find(template) {
14
+ const matches = BalancedParser.parseExpressions(template);
15
+ return matches.map(m => ({
16
+ fullMatch: template.slice(m.start, m.end),
17
+ start: m.start,
18
+ end: m.end,
19
+ data: { expression: m.content }
20
+ }));
21
+ }
22
+ execute(match, scope) {
23
+ const code = match.data?.expression;
24
+ if (!code || code.trim() === '') {
25
+ return { output: '' };
26
+ }
27
+ const expr = new Expression(code);
28
+ // Находим Observable, используемые в выражении
29
+ const observables = expr.findObservables(scope);
30
+ // Check for async
31
+ if (expr.isAsyncExpression()) {
32
+ // Return promise wrapper - engine should handle this
33
+ const promise = expr.executeAsync(scope).then(result => {
34
+ if (result === undefined || result === null) {
35
+ return '';
36
+ }
37
+ return String(result);
38
+ });
39
+ // For now, return placeholder - proper async handling in engine
40
+ return {
41
+ output: '',
42
+ observables,
43
+ children: []
44
+ };
45
+ }
46
+ const result = expr.execute(scope);
47
+ // Если результат сам Observable (например @(counter)), отслеживаем его
48
+ if (isObservable(result)) {
49
+ return {
50
+ output: String(result.getObject?.() ?? result),
51
+ observables: [...observables, result]
52
+ };
53
+ }
54
+ if (result === undefined || result === null) {
55
+ return { output: '', observables };
56
+ }
57
+ return { output: String(result), observables };
58
+ }
59
+ /**
60
+ * Асинхронная версия execute
61
+ */
62
+ async executeAsync(match, scope) {
63
+ const code = match.data?.expression;
64
+ if (!code || code.trim() === '') {
65
+ return { output: '' };
66
+ }
67
+ const expr = new Expression(code);
68
+ const observables = expr.findObservables(scope);
69
+ const result = await expr.executeAsync(scope);
70
+ if (isObservable(result)) {
71
+ return {
72
+ output: String(result.getObject?.() ?? result),
73
+ observables: [...observables, result]
74
+ };
75
+ }
76
+ if (result === undefined || result === null) {
77
+ return { output: '', observables };
78
+ }
79
+ return { output: String(result), observables };
80
+ }
81
+ }
82
+ //# sourceMappingURL=ExpressionRule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpressionRule.js","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/syntax/ExpressionRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,UAAU,MAAM,qBAAqB,CAAC;AAC7C,OAAO,cAAc,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,UAAU;IAClC,IAAI,GAAG,YAAY,CAAC;IACpB,QAAQ,GAAG,EAAE,CAAC,CAAC,mCAAmC;IAE3D,IAAI,CAAC,QAAgB;QACxB,MAAM,OAAO,GAAG,cAAc,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAE1D,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACrB,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC;YACzC,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE;SAClC,CAAC,CAAC,CAAC;IACR,CAAC;IAEM,OAAO,CAAC,KAAgB,EAAE,KAAY;QACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,UAAoB,CAAC;QAE9C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC9B,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAC1B,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;QAElC,+CAA+C;QAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAEhD,kBAAkB;QAClB,IAAI,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;YAC3B,qDAAqD;YACrD,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;gBACnD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;oBAC1C,OAAO,EAAE,CAAC;gBACd,CAAC;gBACD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC;YAEH,gEAAgE;YAChE,OAAO;gBACH,MAAM,EAAE,EAAE;gBACV,WAAW;gBACX,QAAQ,EAAE,EAAE;aACf,CAAC;QACN,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAEnC,uEAAuE;QACvE,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,OAAO;gBACH,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,IAAI,MAAM,CAAC;gBAC9C,WAAW,EAAE,CAAC,GAAG,WAAW,EAAE,MAAM,CAAC;aACxC,CAAC;QACN,CAAC;QAED,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1C,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;QACvC,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACnD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,YAAY,CAAC,KAAgB,EAAE,KAAY;QACpD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,UAAoB,CAAC;QAE9C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC9B,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAC1B,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAE9C,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,OAAO;gBACH,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,IAAI,MAAM,CAAC;gBAC9C,WAAW,EAAE,CAAC,GAAG,WAAW,EAAE,MAAM,CAAC;aACxC,CAAC;QACN,CAAC;QAED,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1C,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC;QACvC,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACnD,CAAC;CACJ"}
@@ -0,0 +1,19 @@
1
+ import { SyntaxRule } from '../../Rule.js';
2
+ import type { RuleMatch, RuleResult } from '../../Rule.js';
3
+ import Scope from '../../Scope.js';
4
+ /**
5
+ * ForRule - обработка @for
6
+ * Варианты:
7
+ * 1. @for(item in collection) { ... }
8
+ * 2. @for(idx, item in collection) { ... }
9
+ * 3. @for(i in 5) { ... } - числовая итерация 0..4
10
+ */
11
+ export default class ForRule extends SyntaxRule {
12
+ readonly name = "for";
13
+ readonly priority = 10;
14
+ find(template: string): RuleMatch[];
15
+ private parseForStatement;
16
+ private skipString;
17
+ execute(match: RuleMatch, scope: Scope, engine?: any): RuleResult;
18
+ }
19
+ //# sourceMappingURL=ForRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForRule.d.ts","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/syntax/ForRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,MAAM,gBAAgB,CAAC;AAkBnC;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,UAAU;IAC3C,SAAgB,IAAI,SAAS;IAC7B,SAAgB,QAAQ,MAAM;IAEvB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE;IAqC1C,OAAO,CAAC,iBAAiB;IAwFzB,OAAO,CAAC,UAAU;IAeX,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,UAAU;CA+F3E"}
@@ -0,0 +1,226 @@
1
+ import { SyntaxRule } from '../../Rule.js';
2
+ import Expression from '../../Expression.js';
3
+ import { InvalidTemplateEngineSyntaxException } from '../../exceptions/TemplateExceptions.js';
4
+ import { isObservable } from '../../../api/Observer.js';
5
+ /**
6
+ * ForRule - обработка @for
7
+ * Варианты:
8
+ * 1. @for(item in collection) { ... }
9
+ * 2. @for(idx, item in collection) { ... }
10
+ * 3. @for(i in 5) { ... } - числовая итерация 0..4
11
+ */
12
+ export default class ForRule extends SyntaxRule {
13
+ name = 'for';
14
+ priority = 10; // Выполняется раньше всех
15
+ find(template) {
16
+ const results = [];
17
+ const lowerTemplate = template.toLowerCase();
18
+ let i = 0;
19
+ while (i < template.length) {
20
+ const idx = lowerTemplate.indexOf('@for', i);
21
+ if (idx === -1)
22
+ break;
23
+ // Check for @@ escape
24
+ if (idx > 0 && template[idx - 1] === '@') {
25
+ i = idx + 1;
26
+ continue;
27
+ }
28
+ const parsed = this.parseForStatement(template, idx);
29
+ if (parsed) {
30
+ results.push({
31
+ fullMatch: template.slice(parsed.start, parsed.end),
32
+ start: parsed.start,
33
+ end: parsed.end,
34
+ data: {
35
+ variant: parsed.variant,
36
+ variables: parsed.variables,
37
+ expression: parsed.expression,
38
+ block: parsed.block
39
+ }
40
+ });
41
+ i = parsed.end;
42
+ }
43
+ else {
44
+ i = idx + 1;
45
+ }
46
+ }
47
+ return results;
48
+ }
49
+ parseForStatement(template, start) {
50
+ let pos = start + 4; // '@for'.length
51
+ // Skip whitespace
52
+ while (pos < template.length && /\s/.test(template[pos])) {
53
+ pos++;
54
+ }
55
+ // Expect (
56
+ if (template[pos] !== '(')
57
+ return null;
58
+ // Parse balanced parentheses
59
+ const conditionStart = pos + 1;
60
+ pos++;
61
+ let depth = 1;
62
+ while (pos < template.length && depth > 0) {
63
+ const ch = template[pos];
64
+ if (ch === '"' || ch === "'" || ch === '`') {
65
+ pos = this.skipString(template, pos, ch);
66
+ continue;
67
+ }
68
+ if (ch === '(')
69
+ depth++;
70
+ else if (ch === ')')
71
+ depth--;
72
+ pos++;
73
+ }
74
+ if (depth !== 0)
75
+ return null;
76
+ const conditionContent = template.slice(conditionStart, pos - 1).trim();
77
+ // Parse condition: "var in expr" or "idx, var in expr"
78
+ const inMatch = conditionContent.match(/^(.+?)\s+in\s+(.+)$/);
79
+ if (!inMatch)
80
+ return null;
81
+ const varPart = inMatch[1].trim();
82
+ const expression = inMatch[2].trim();
83
+ // Parse variables
84
+ let variables;
85
+ let variant;
86
+ if (varPart.includes(',')) {
87
+ // Indexed variant: "idx, item"
88
+ variables = varPart.split(',').map(v => v.trim());
89
+ if (variables.length !== 2)
90
+ return null;
91
+ variant = 'indexed';
92
+ }
93
+ else {
94
+ variables = [varPart];
95
+ variant = 'single'; // Will be determined at execution time if numeric
96
+ }
97
+ // Skip whitespace
98
+ while (pos < template.length && /\s/.test(template[pos])) {
99
+ pos++;
100
+ }
101
+ // Expect {
102
+ if (template[pos] !== '{')
103
+ return null;
104
+ // Parse balanced braces
105
+ const blockStart = pos + 1;
106
+ pos++;
107
+ depth = 1;
108
+ while (pos < template.length && depth > 0) {
109
+ const ch = template[pos];
110
+ if (ch === '"' || ch === "'" || ch === '`') {
111
+ pos = this.skipString(template, pos, ch);
112
+ continue;
113
+ }
114
+ if (ch === '{')
115
+ depth++;
116
+ else if (ch === '}')
117
+ depth--;
118
+ pos++;
119
+ }
120
+ if (depth !== 0)
121
+ return null;
122
+ const block = template.slice(blockStart, pos - 1);
123
+ return { start, end: pos, variant, variables, expression, block };
124
+ }
125
+ skipString(input, pos, quote) {
126
+ pos++;
127
+ while (pos < input.length) {
128
+ if (input[pos] === '\\') {
129
+ pos += 2;
130
+ continue;
131
+ }
132
+ if (input[pos] === quote) {
133
+ return pos + 1;
134
+ }
135
+ pos++;
136
+ }
137
+ return pos;
138
+ }
139
+ execute(match, scope, engine) {
140
+ const data = match.data;
141
+ const observables = [];
142
+ const outputs = [];
143
+ // Evaluate expression
144
+ const expr = new Expression(data.expression);
145
+ // Находим Observable в выражении
146
+ const exprObservables = expr.findObservables(scope);
147
+ observables.push(...exprObservables);
148
+ let collection = expr.execute(scope);
149
+ // Check if Observable
150
+ if (isObservable(collection)) {
151
+ observables.push(collection);
152
+ collection = collection.getObject?.() ?? collection;
153
+ }
154
+ // Determine iteration type
155
+ if (typeof collection === 'number') {
156
+ // Numeric iteration: 0 to collection-1
157
+ if (data.variant === 'indexed') {
158
+ throw new InvalidTemplateEngineSyntaxException('@for with numeric value does not support indexed variant (idx, var). Use single variable.');
159
+ }
160
+ const count = Math.floor(collection);
161
+ if (count < 0) {
162
+ throw new InvalidTemplateEngineSyntaxException(`@for numeric value must be non-negative, got: ${count}`);
163
+ }
164
+ for (let i = 0; i < count; i++) {
165
+ const localScope = scope.createChild({ [data.variables[0]]: i });
166
+ if (engine) {
167
+ const result = engine.processTemplate(data.block, localScope);
168
+ outputs.push(result.output);
169
+ if (result.observables)
170
+ observables.push(...result.observables);
171
+ }
172
+ else {
173
+ outputs.push(data.block);
174
+ }
175
+ }
176
+ }
177
+ else if (Array.isArray(collection) || (collection && typeof collection[Symbol.iterator] === 'function')) {
178
+ // Array or iterable
179
+ const items = Array.isArray(collection) ? collection : Array.from(collection);
180
+ if (data.variant === 'indexed') {
181
+ // (idx, item in collection)
182
+ items.forEach((item, idx) => {
183
+ const localScope = scope.createChild({
184
+ [data.variables[0]]: idx,
185
+ [data.variables[1]]: item
186
+ });
187
+ if (engine) {
188
+ const result = engine.processTemplate(data.block, localScope);
189
+ outputs.push(result.output);
190
+ if (result.observables)
191
+ observables.push(...result.observables);
192
+ }
193
+ else {
194
+ outputs.push(data.block);
195
+ }
196
+ });
197
+ }
198
+ else {
199
+ // (item in collection)
200
+ items.forEach((item) => {
201
+ const localScope = scope.createChild({ [data.variables[0]]: item });
202
+ if (engine) {
203
+ const result = engine.processTemplate(data.block, localScope);
204
+ outputs.push(result.output);
205
+ if (result.observables)
206
+ observables.push(...result.observables);
207
+ }
208
+ else {
209
+ outputs.push(data.block);
210
+ }
211
+ });
212
+ }
213
+ }
214
+ else if (typeof collection === 'string') {
215
+ throw new InvalidTemplateEngineSyntaxException(`@for does not support string iteration. Got: "${collection}"`);
216
+ }
217
+ else if (collection === null || collection === undefined) {
218
+ // Empty result
219
+ }
220
+ else {
221
+ throw new InvalidTemplateEngineSyntaxException(`@for expression must return a number, array, or iterable. Got: ${typeof collection}`);
222
+ }
223
+ return { output: outputs.join(''), observables };
224
+ }
225
+ }
226
+ //# sourceMappingURL=ForRule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForRule.js","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/syntax/ForRule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { SyntaxRule } from '../../Rule.js';
2
+ import type { RuleMatch, RuleResult } from '../../Rule.js';
3
+ import Scope from '../../Scope.js';
4
+ /**
5
+ * IfRule - обработка @if/@elseif/@else
6
+ */
7
+ export default class IfRule extends SyntaxRule {
8
+ readonly name = "if";
9
+ readonly priority = 20;
10
+ find(template: string): RuleMatch[];
11
+ private parseIfChain;
12
+ private parseConditionBlock;
13
+ private parseElseBlock;
14
+ private skipString;
15
+ execute(match: RuleMatch, scope: Scope, engine?: any): RuleResult;
16
+ }
17
+ //# sourceMappingURL=IfRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IfRule.d.ts","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/syntax/IfRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,MAAM,gBAAgB,CAAC;AAgBnC;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,UAAU;IAC1C,SAAgB,IAAI,QAAQ;IAC5B,SAAgB,QAAQ,MAAM;IAEvB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE;IAiC1C,OAAO,CAAC,YAAY;IA2CpB,OAAO,CAAC,mBAAmB;IAgE3B,OAAO,CAAC,cAAc;IAiCtB,OAAO,CAAC,UAAU;IAeX,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,UAAU;CA+C3E"}