@reidelsaltres/pureper 0.1.156 → 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 (92) 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/component_api/Attribute.d.ts.map +1 -1
  6. package/out/foundation/component_api/Attribute.js +1 -0
  7. package/out/foundation/component_api/Attribute.js.map +1 -1
  8. package/out/foundation/engine/BalancedParser.d.ts +58 -0
  9. package/out/foundation/engine/BalancedParser.d.ts.map +1 -0
  10. package/out/foundation/engine/BalancedParser.js +301 -0
  11. package/out/foundation/engine/BalancedParser.js.map +1 -0
  12. package/out/foundation/engine/EscapeHandler.d.ts +27 -0
  13. package/out/foundation/engine/EscapeHandler.d.ts.map +1 -0
  14. package/out/foundation/engine/EscapeHandler.js +47 -0
  15. package/out/foundation/engine/EscapeHandler.js.map +1 -0
  16. package/out/foundation/engine/Expression.d.ts +83 -0
  17. package/out/foundation/engine/Expression.d.ts.map +1 -0
  18. package/out/foundation/engine/Expression.js +256 -0
  19. package/out/foundation/engine/Expression.js.map +1 -0
  20. package/out/foundation/engine/Rule.d.ts +83 -0
  21. package/out/foundation/engine/Rule.d.ts.map +1 -0
  22. package/out/foundation/engine/Rule.js +69 -0
  23. package/out/foundation/engine/Rule.js.map +1 -0
  24. package/out/foundation/engine/Scope.d.ts +57 -0
  25. package/out/foundation/engine/Scope.d.ts.map +1 -0
  26. package/out/foundation/engine/Scope.js +147 -0
  27. package/out/foundation/engine/Scope.js.map +1 -0
  28. package/out/foundation/engine/TemplateEngine.d.ts +79 -0
  29. package/out/foundation/engine/TemplateEngine.d.ts.map +1 -0
  30. package/out/foundation/engine/TemplateEngine.js +187 -0
  31. package/out/foundation/engine/TemplateEngine.js.map +1 -0
  32. package/out/foundation/engine/TemplateInstance.d.ts +121 -0
  33. package/out/foundation/engine/TemplateInstance.d.ts.map +1 -0
  34. package/out/foundation/engine/TemplateInstance.js +255 -0
  35. package/out/foundation/engine/TemplateInstance.js.map +1 -0
  36. package/out/foundation/engine/exceptions/TemplateExceptions.d.ts +21 -0
  37. package/out/foundation/engine/exceptions/TemplateExceptions.d.ts.map +1 -0
  38. package/out/foundation/engine/exceptions/TemplateExceptions.js +26 -0
  39. package/out/foundation/engine/exceptions/TemplateExceptions.js.map +1 -0
  40. package/out/foundation/engine/index.d.ts +18 -0
  41. package/out/foundation/engine/index.d.ts.map +1 -0
  42. package/out/foundation/engine/index.js +19 -0
  43. package/out/foundation/engine/index.js.map +1 -0
  44. package/out/foundation/engine/rules/attribute/EventRule.d.ts +22 -0
  45. package/out/foundation/engine/rules/attribute/EventRule.d.ts.map +1 -0
  46. package/out/foundation/engine/rules/attribute/EventRule.js +129 -0
  47. package/out/foundation/engine/rules/attribute/EventRule.js.map +1 -0
  48. package/out/foundation/engine/rules/attribute/InjectionRule.d.ts +20 -0
  49. package/out/foundation/engine/rules/attribute/InjectionRule.d.ts.map +1 -0
  50. package/out/foundation/engine/rules/attribute/InjectionRule.js +108 -0
  51. package/out/foundation/engine/rules/attribute/InjectionRule.js.map +1 -0
  52. package/out/foundation/engine/rules/attribute/RefRule.d.ts +23 -0
  53. package/out/foundation/engine/rules/attribute/RefRule.d.ts.map +1 -0
  54. package/out/foundation/engine/rules/attribute/RefRule.js +98 -0
  55. package/out/foundation/engine/rules/attribute/RefRule.js.map +1 -0
  56. package/out/foundation/engine/rules/syntax/ExpressionRule.d.ts +19 -0
  57. package/out/foundation/engine/rules/syntax/ExpressionRule.d.ts.map +1 -0
  58. package/out/foundation/engine/rules/syntax/ExpressionRule.js +82 -0
  59. package/out/foundation/engine/rules/syntax/ExpressionRule.js.map +1 -0
  60. package/out/foundation/engine/rules/syntax/ForRule.d.ts +19 -0
  61. package/out/foundation/engine/rules/syntax/ForRule.d.ts.map +1 -0
  62. package/out/foundation/engine/rules/syntax/ForRule.js +226 -0
  63. package/out/foundation/engine/rules/syntax/ForRule.js.map +1 -0
  64. package/out/foundation/engine/rules/syntax/IfRule.d.ts +17 -0
  65. package/out/foundation/engine/rules/syntax/IfRule.d.ts.map +1 -0
  66. package/out/foundation/engine/rules/syntax/IfRule.js +220 -0
  67. package/out/foundation/engine/rules/syntax/IfRule.js.map +1 -0
  68. package/out/foundation/worker/Router.d.ts.map +1 -1
  69. package/out/foundation/worker/Router.js.map +1 -1
  70. package/out/index.d.ts +3 -0
  71. package/out/index.d.ts.map +1 -1
  72. package/out/index.js +3 -0
  73. package/out/index.js.map +1 -1
  74. package/package.json +1 -1
  75. package/src/foundation/api/Observer.ts +60 -0
  76. package/src/foundation/component_api/Attribute.ts +1 -0
  77. package/src/foundation/engine/BalancedParser.ts +353 -0
  78. package/src/foundation/engine/EscapeHandler.ts +54 -0
  79. package/src/foundation/engine/Expression.ts +285 -0
  80. package/src/foundation/engine/Rule.ts +136 -0
  81. package/src/foundation/engine/Scope.ts +166 -0
  82. package/src/foundation/engine/TemplateEngine.ts +243 -0
  83. package/src/foundation/engine/TemplateInstance.ts +355 -0
  84. package/src/foundation/engine/exceptions/TemplateExceptions.ts +27 -0
  85. package/src/foundation/engine/rules/attribute/EventRule.ts +171 -0
  86. package/src/foundation/engine/rules/attribute/InjectionRule.ts +140 -0
  87. package/src/foundation/engine/rules/attribute/RefRule.ts +119 -0
  88. package/src/foundation/engine/rules/syntax/ExpressionRule.ts +102 -0
  89. package/src/foundation/engine/rules/syntax/ForRule.ts +267 -0
  90. package/src/foundation/engine/rules/syntax/IfRule.ts +261 -0
  91. package/src/foundation/worker/Router.ts +1 -1
  92. package/src/index.ts +9 -0
@@ -0,0 +1,255 @@
1
+ import { MutationObserver } from '../api/Observer.js';
2
+ /**
3
+ * PageTemplate - динамический шаблон страницы.
4
+ * Хранит обработанные Rule и поддерживает реактивное обновление.
5
+ *
6
+ * При изменении Observable все зависимые секции обновляются
7
+ * одновременно в одном событии onTemplateChange.
8
+ */
9
+ export default class TemplateInstance {
10
+ template;
11
+ scope;
12
+ sections = [];
13
+ fragment = null;
14
+ /** Observers for template changes */
15
+ changeObserver = new MutationObserver();
16
+ /** Группировка секций по Observable */
17
+ observableTrackings = new Map();
18
+ constructor(template, scope) {
19
+ this.template = template;
20
+ this.scope = scope;
21
+ }
22
+ /**
23
+ * Получить текущий шаблон
24
+ */
25
+ getTemplate() {
26
+ return this.template;
27
+ }
28
+ /**
29
+ * Установить новый шаблон (вызывает событие изменения)
30
+ */
31
+ setTemplate(newTemplate) {
32
+ const oldTemplate = this.template;
33
+ this.template = newTemplate;
34
+ this.changeObserver.notify({ oldValue: null, newValue: null, oldTemplate, newTemplate }, { oldValue: null, newValue: null, oldTemplate, newTemplate });
35
+ }
36
+ /**
37
+ * Получить Scope
38
+ */
39
+ getScope() {
40
+ return this.scope;
41
+ }
42
+ /**
43
+ * Подписаться на изменения шаблона
44
+ */
45
+ onTemplateChange(listener) {
46
+ const wrapper = (oldEvent, newEvent) => {
47
+ listener(newEvent.oldValue, newEvent.newValue, newEvent.oldTemplate, newEvent.newTemplate);
48
+ };
49
+ this.changeObserver.subscribe(wrapper);
50
+ return () => this.changeObserver.unsubscribe(wrapper);
51
+ }
52
+ /**
53
+ * Добавить секцию шаблона
54
+ */
55
+ addSection(section) {
56
+ this.sections.push(section);
57
+ }
58
+ /**
59
+ * Получить все секции
60
+ */
61
+ getSections() {
62
+ return this.sections;
63
+ }
64
+ /**
65
+ * Подписаться на Observable и автоматически пересоздавать секцию.
66
+ * Все секции, зависящие от одного Observable, обновляются разом.
67
+ */
68
+ trackObservable(observable, section, rebuild) {
69
+ // Проверяем, есть ли уже отслеживание для этого Observable
70
+ let tracking = this.observableTrackings.get(observable);
71
+ if (!tracking) {
72
+ // Создаём новое отслеживание
73
+ const listener = (newValue) => {
74
+ this.rebuildAllSectionsForObservable(observable, newValue);
75
+ };
76
+ observable.subscribe(listener);
77
+ tracking = {
78
+ observable,
79
+ sections: [],
80
+ unsubscribe: () => observable.unsubscribe(listener)
81
+ };
82
+ this.observableTrackings.set(observable, tracking);
83
+ }
84
+ // Добавляем секцию в отслеживание
85
+ tracking.sections.push({ section, rebuild });
86
+ // Возвращаем функцию отписки для этой конкретной секции
87
+ return () => {
88
+ if (tracking) {
89
+ tracking.sections = tracking.sections.filter(s => s.section !== section);
90
+ // Если больше нет секций, отписываемся от Observable
91
+ if (tracking.sections.length === 0) {
92
+ tracking.unsubscribe();
93
+ this.observableTrackings.delete(observable);
94
+ }
95
+ }
96
+ };
97
+ }
98
+ /**
99
+ * Перестроить все секции, зависящие от Observable, за один раз
100
+ */
101
+ rebuildAllSectionsForObservable(observable, newValue) {
102
+ const tracking = this.observableTrackings.get(observable);
103
+ if (!tracking || tracking.sections.length === 0)
104
+ return;
105
+ const oldTemplate = this.template;
106
+ let currentTemplate = this.template;
107
+ // Собираем все замены: старый output -> новый output
108
+ // Сортируем по позиции в шаблоне (с конца), чтобы замены не сбивали индексы
109
+ const replacements = [];
110
+ for (const { section, rebuild } of tracking.sections) {
111
+ // Unsubscribe old nested observables
112
+ this.unsubscribeSectionNested(section);
113
+ // Rebuild section
114
+ const newResult = rebuild(section);
115
+ const oldOutput = section.result.output;
116
+ replacements.push({
117
+ oldOutput,
118
+ newOutput: newResult.output,
119
+ section
120
+ });
121
+ section.result = newResult;
122
+ }
123
+ // Применяем все замены
124
+ for (const { oldOutput, newOutput } of replacements) {
125
+ currentTemplate = currentTemplate.replace(oldOutput, newOutput);
126
+ }
127
+ this.template = currentTemplate;
128
+ // Одно событие для всех изменений
129
+ this.changeObserver.notify({ oldValue: null, newValue, oldTemplate, newTemplate: this.template }, { oldValue: null, newValue, oldTemplate, newTemplate: this.template });
130
+ }
131
+ /**
132
+ * Отписаться от вложенных Observable в секции (но не от главного)
133
+ */
134
+ unsubscribeSectionNested(section) {
135
+ // Отписываемся только от подписок, сохранённых непосредственно в секции
136
+ for (const sub of section.subscriptions) {
137
+ sub.unsubscribe();
138
+ }
139
+ section.subscriptions = [];
140
+ // Recursively unsubscribe children
141
+ for (const child of section.children) {
142
+ this.unsubscribeSectionNested(child);
143
+ }
144
+ }
145
+ /**
146
+ * Отписаться от всех Observable в секции
147
+ */
148
+ unsubscribeSection(section) {
149
+ for (const sub of section.subscriptions) {
150
+ sub.unsubscribe();
151
+ }
152
+ section.subscriptions = [];
153
+ // Recursively unsubscribe children
154
+ for (const child of section.children) {
155
+ this.unsubscribeSection(child);
156
+ }
157
+ }
158
+ /**
159
+ * Создать DocumentFragment из текущего шаблона
160
+ */
161
+ createFragment() {
162
+ if (typeof document === 'undefined') {
163
+ throw new Error('PageTemplate.createFragment() requires DOM environment');
164
+ }
165
+ const template = document.createElement('template');
166
+ template.innerHTML = this.template;
167
+ this.fragment = template.content.cloneNode(true);
168
+ return this.fragment;
169
+ }
170
+ /**
171
+ * Получить кэшированный DocumentFragment
172
+ */
173
+ getFragment() {
174
+ return this.fragment;
175
+ }
176
+ /**
177
+ * Пересоздать fragment
178
+ */
179
+ rebuildFragment() {
180
+ this.fragment = null;
181
+ return this.createFragment();
182
+ }
183
+ /**
184
+ * Очистить все подписки
185
+ */
186
+ dispose() {
187
+ // Отписываемся от всех Observable
188
+ for (const tracking of this.observableTrackings.values()) {
189
+ tracking.unsubscribe();
190
+ }
191
+ this.observableTrackings.clear();
192
+ // Очищаем секции
193
+ for (const section of this.sections) {
194
+ this.unsubscribeSection(section);
195
+ }
196
+ this.sections = [];
197
+ this.fragment = null;
198
+ }
199
+ /**
200
+ * Привязать refs после вставки в DOM
201
+ */
202
+ bindRefs(root) {
203
+ const refElements = root.querySelectorAll('[data-ref]');
204
+ for (const element of Array.from(refElements)) {
205
+ const refName = element.getAttribute('data-ref');
206
+ if (refName) {
207
+ this.scope.set(refName, element);
208
+ }
209
+ }
210
+ }
211
+ /**
212
+ * Обработать инжекции (@injection[head/tail])
213
+ * Должен вызываться после bindRefs
214
+ */
215
+ processInjections(root) {
216
+ // Find all elements with injection attributes
217
+ const injectElements = root.querySelectorAll('[data-injection-type][data-injection-target]');
218
+ for (const element of Array.from(injectElements)) {
219
+ const type = element.getAttribute('data-injection-type');
220
+ const targetRefName = decodeURIComponent(element.getAttribute('data-injection-target') || '');
221
+ if (!targetRefName)
222
+ continue;
223
+ // Get target element from scope
224
+ const targetElement = this.scope.get(targetRefName);
225
+ if (!targetElement || !(targetElement instanceof Element)) {
226
+ console.warn(`[PageTemplate] Injection target "${targetRefName}" not found in scope or is not an Element`);
227
+ continue;
228
+ }
229
+ // Remove injection attributes
230
+ element.removeAttribute('data-injection-type');
231
+ element.removeAttribute('data-injection-target');
232
+ // Perform injection
233
+ if (type === 'head') {
234
+ targetElement.prepend(element);
235
+ }
236
+ else {
237
+ targetElement.append(element);
238
+ }
239
+ }
240
+ }
241
+ /**
242
+ * Отвязать refs (установить null)
243
+ */
244
+ unbindRefs() {
245
+ for (const section of this.sections) {
246
+ if (section.rule.name === 'ref' && section.match.data?.expression) {
247
+ const refName = section.match.data.expression;
248
+ if (this.scope.has(refName)) {
249
+ this.scope.set(refName, null);
250
+ }
251
+ }
252
+ }
253
+ }
254
+ }
255
+ //# sourceMappingURL=TemplateInstance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateInstance.js","sourceRoot":"","sources":["../../../src/foundation/engine/TemplateInstance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * InvalidDynamicRuleUsage - исключение при использовании Observable
3
+ * в правилах, которые не поддерживают динамическое обновление.
4
+ * Например: @[ref], @injection
5
+ */
6
+ export declare class InvalidDynamicRuleUsage extends Error {
7
+ constructor(ruleName: string, message?: string);
8
+ }
9
+ /**
10
+ * InvalidTemplateEngineSyntaxException - исключение при синтаксических ошибках
11
+ * в шаблоне. Например: @if без boolean, @for с неверным типом.
12
+ */
13
+ export declare class InvalidTemplateEngineSyntaxException extends Error {
14
+ readonly line?: number;
15
+ readonly column?: number;
16
+ constructor(message: string, options?: {
17
+ line?: number;
18
+ column?: number;
19
+ });
20
+ }
21
+ //# sourceMappingURL=TemplateExceptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateExceptions.d.ts","sourceRoot":"","sources":["../../../../src/foundation/engine/exceptions/TemplateExceptions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;gBAClC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAIjD;AAED;;;GAGG;AACH,qBAAa,oCAAqC,SAAQ,KAAK;IAC3D,SAAgB,IAAI,CAAC,EAAE,MAAM,CAAC;IAC9B,SAAgB,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEpB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;CAM5E"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * InvalidDynamicRuleUsage - исключение при использовании Observable
3
+ * в правилах, которые не поддерживают динамическое обновление.
4
+ * Например: @[ref], @injection
5
+ */
6
+ export class InvalidDynamicRuleUsage extends Error {
7
+ constructor(ruleName, message) {
8
+ super(message ?? `Rule "${ruleName}" does not support Observable values. Use a static value instead.`);
9
+ this.name = 'InvalidDynamicRuleUsage';
10
+ }
11
+ }
12
+ /**
13
+ * InvalidTemplateEngineSyntaxException - исключение при синтаксических ошибках
14
+ * в шаблоне. Например: @if без boolean, @for с неверным типом.
15
+ */
16
+ export class InvalidTemplateEngineSyntaxException extends Error {
17
+ line;
18
+ column;
19
+ constructor(message, options) {
20
+ super(message);
21
+ this.name = 'InvalidTemplateEngineSyntaxException';
22
+ this.line = options?.line;
23
+ this.column = options?.column;
24
+ }
25
+ }
26
+ //# sourceMappingURL=TemplateExceptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateExceptions.js","sourceRoot":"","sources":["../../../../src/foundation/engine/exceptions/TemplateExceptions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAC9C,YAAY,QAAgB,EAAE,OAAgB;QAC1C,KAAK,CAAC,OAAO,IAAI,SAAS,QAAQ,mEAAmE,CAAC,CAAC;QACvG,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IAC1C,CAAC;CACJ;AAED;;;GAGG;AACH,MAAM,OAAO,oCAAqC,SAAQ,KAAK;IAC3C,IAAI,CAAU;IACd,MAAM,CAAU;IAEhC,YAAY,OAAe,EAAE,OAA4C;QACrE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sCAAsC,CAAC;QACnD,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;IAClC,CAAC;CACJ"}
@@ -0,0 +1,18 @@
1
+ export { default as TemplateEngine } from './TemplateEngine.js';
2
+ export { default as Scope } from './Scope.js';
3
+ export { default as Expression } from './Expression.js';
4
+ export { default as PageTemplate } from './PageTemplate.js';
5
+ export { default as BalancedParser } from './BalancedParser.js';
6
+ export { default as EscapeHandler } from './EscapeHandler.js';
7
+ export { default as Rule, SyntaxRule, AttributeRule } from './Rule.js';
8
+ export type { RuleMatch, RuleResult, RuleType } from './Rule.js';
9
+ export { default as ExpressionRule } from './rules/syntax/ExpressionRule.js';
10
+ export { default as IfRule } from './rules/syntax/IfRule.js';
11
+ export { default as ForRule } from './rules/syntax/ForRule.js';
12
+ export { default as RefRule } from './rules/attribute/RefRule.js';
13
+ export { default as EventRule } from './rules/attribute/EventRule.js';
14
+ export { default as InjectionRule } from './rules/attribute/InjectionRule.js';
15
+ export { InvalidDynamicRuleUsage, InvalidTemplateEngineSyntaxException } from './exceptions/TemplateExceptions.js';
16
+ export type { TemplateEngineOptions, ProcessResult } from './TemplateEngine.js';
17
+ export type { TemplateSection, TemplateChangeEvent } from './PageTemplate.js';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/foundation/engine/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACvE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGjE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAG9E,OAAO,EACH,uBAAuB,EACvB,oCAAoC,EACvC,MAAM,oCAAoC,CAAC;AAG5C,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAChF,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,19 @@
1
+ // Export all engine components
2
+ export { default as TemplateEngine } from './TemplateEngine.js';
3
+ export { default as Scope } from './Scope.js';
4
+ export { default as Expression } from './Expression.js';
5
+ export { default as PageTemplate } from './PageTemplate.js';
6
+ export { default as BalancedParser } from './BalancedParser.js';
7
+ export { default as EscapeHandler } from './EscapeHandler.js';
8
+ // Export Rule system
9
+ export { default as Rule, SyntaxRule, AttributeRule } from './Rule.js';
10
+ // Export concrete rules
11
+ export { default as ExpressionRule } from './rules/syntax/ExpressionRule.js';
12
+ export { default as IfRule } from './rules/syntax/IfRule.js';
13
+ export { default as ForRule } from './rules/syntax/ForRule.js';
14
+ export { default as RefRule } from './rules/attribute/RefRule.js';
15
+ export { default as EventRule } from './rules/attribute/EventRule.js';
16
+ export { default as InjectionRule } from './rules/attribute/InjectionRule.js';
17
+ // Export exceptions
18
+ export { InvalidDynamicRuleUsage, InvalidTemplateEngineSyntaxException } from './exceptions/TemplateExceptions.js';
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/foundation/engine/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE9D,qBAAqB;AACrB,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAGvE,wBAAwB;AACxB,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAE9E,oBAAoB;AACpB,OAAO,EACH,uBAAuB,EACvB,oCAAoC,EACvC,MAAM,oCAAoC,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { AttributeRule } from '../../Rule.js';
2
+ import type { RuleMatch, RuleResult } from '../../Rule.js';
3
+ import Scope from '../../Scope.js';
4
+ /**
5
+ * EventRule - обработка @on[eventName]="expression"
6
+ * Подписывает элемент на событие.
7
+ */
8
+ export default class EventRule extends AttributeRule {
9
+ readonly name = "event";
10
+ readonly priority = 30;
11
+ find(template: string): RuleMatch[];
12
+ execute(match: RuleMatch, scope: Scope): RuleResult;
13
+ /**
14
+ * Постобработка: привязать события к элементам
15
+ */
16
+ static bindEvents(element: Element, scope: Scope): (() => void)[];
17
+ /**
18
+ * Привязать событие с поддержкой Observable
19
+ */
20
+ static bindEventWithObservable(element: Element, eventName: string, exprCode: string, scope: Scope): () => void;
21
+ }
22
+ //# sourceMappingURL=EventRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventRule.d.ts","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/attribute/EventRule.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;AAWnC;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,aAAa;IAChD,SAAgB,IAAI,WAAW;IAC/B,SAAgB,QAAQ,MAAM;IAEvB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE;IAsDnC,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,UAAU;IAa1D;;OAEG;WACW,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE;IAkCxE;;OAEG;WACW,uBAAuB,CACjC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,GACb,MAAM,IAAI;CAqChB"}
@@ -0,0 +1,129 @@
1
+ import { AttributeRule } from '../../Rule.js';
2
+ import Expression from '../../Expression.js';
3
+ /**
4
+ * EventRule - обработка @on[eventName]="expression"
5
+ * Подписывает элемент на событие.
6
+ */
7
+ export default class EventRule extends AttributeRule {
8
+ name = 'event';
9
+ priority = 30;
10
+ find(template) {
11
+ const results = [];
12
+ // Match @on[eventName]="
13
+ const pattern = /@on\[([a-zA-Z]+)\]\s*=/gi;
14
+ let match;
15
+ while ((match = pattern.exec(template)) !== null) {
16
+ const idx = match.index;
17
+ // Check for @@ escape
18
+ if (idx > 0 && template[idx - 1] === '@') {
19
+ continue;
20
+ }
21
+ const eventName = match[1].toLowerCase();
22
+ // Find quote char after =
23
+ let pos = idx + match[0].length;
24
+ while (pos < template.length && /\s/.test(template[pos])) {
25
+ pos++;
26
+ }
27
+ const quoteChar = template[pos];
28
+ if (quoteChar !== '"' && quoteChar !== "'") {
29
+ continue;
30
+ }
31
+ // Find matching closing quote
32
+ const contentStart = pos + 1;
33
+ pos++;
34
+ while (pos < template.length && template[pos] !== quoteChar) {
35
+ pos++;
36
+ }
37
+ if (pos >= template.length)
38
+ continue;
39
+ const content = template.slice(contentStart, pos);
40
+ const fullMatch = template.slice(idx, pos + 1);
41
+ results.push({
42
+ fullMatch,
43
+ start: idx,
44
+ end: pos + 1,
45
+ data: {
46
+ eventName,
47
+ expression: content,
48
+ attributeMatch: fullMatch
49
+ }
50
+ });
51
+ }
52
+ return results;
53
+ }
54
+ execute(match, scope) {
55
+ const data = match.data;
56
+ // Generate data attribute for later DOM binding
57
+ // Actual event binding happens in postprocessing
58
+ const encodedExpr = encodeURIComponent(data.expression);
59
+ return {
60
+ output: `data-event-${data.eventName}="${encodedExpr}"`,
61
+ observables: []
62
+ };
63
+ }
64
+ /**
65
+ * Постобработка: привязать события к элементам
66
+ */
67
+ static bindEvents(element, scope) {
68
+ const unbinders = [];
69
+ // Find all data-event-* attributes
70
+ const attributes = Array.from(element.attributes);
71
+ for (const attr of attributes) {
72
+ if (attr.name.startsWith('data-event-')) {
73
+ const eventName = attr.name.slice('data-event-'.length);
74
+ const exprCode = decodeURIComponent(attr.value);
75
+ const handler = (event) => {
76
+ // Create local scope with event
77
+ const localScope = scope.createChild({ event });
78
+ const expr = new Expression(exprCode);
79
+ try {
80
+ expr.execute(localScope);
81
+ }
82
+ catch (error) {
83
+ console.error(`[EventRule] Error executing handler for ${eventName}:`, error);
84
+ }
85
+ };
86
+ element.addEventListener(eventName, handler);
87
+ unbinders.push(() => element.removeEventListener(eventName, handler));
88
+ // Optionally remove the data attribute
89
+ // element.removeAttribute(attr.name);
90
+ }
91
+ }
92
+ return unbinders;
93
+ }
94
+ /**
95
+ * Привязать событие с поддержкой Observable
96
+ */
97
+ static bindEventWithObservable(element, eventName, exprCode, scope) {
98
+ let currentHandler = null;
99
+ const setupHandler = () => {
100
+ // Remove old handler if exists
101
+ if (currentHandler) {
102
+ element.removeEventListener(eventName, currentHandler);
103
+ }
104
+ currentHandler = (event) => {
105
+ const localScope = scope.createChild({ event });
106
+ const expr = new Expression(exprCode);
107
+ try {
108
+ const result = expr.execute(localScope);
109
+ // If result is Observable, handle it
110
+ if (result && typeof result === 'object' && typeof result.subscribe === 'function') {
111
+ // Re-setup handler when Observable changes
112
+ result.subscribe(() => setupHandler());
113
+ }
114
+ }
115
+ catch (error) {
116
+ console.error(`[EventRule] Error executing handler for ${eventName}:`, error);
117
+ }
118
+ };
119
+ element.addEventListener(eventName, currentHandler);
120
+ };
121
+ setupHandler();
122
+ return () => {
123
+ if (currentHandler) {
124
+ element.removeEventListener(eventName, currentHandler);
125
+ }
126
+ };
127
+ }
128
+ }
129
+ //# sourceMappingURL=EventRule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventRule.js","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/attribute/EventRule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { AttributeRule } from '../../Rule.js';
2
+ import type { RuleMatch, RuleResult } from '../../Rule.js';
3
+ import Scope from '../../Scope.js';
4
+ /**
5
+ * InjectionRule - обработка @injection[type]="expression"
6
+ * Инжектирует элемент в целевой элемент (найденный по @[ref]).
7
+ * type: 'head' = prepend, 'tail' = append
8
+ */
9
+ export default class InjectionRule extends AttributeRule {
10
+ readonly name = "injection";
11
+ readonly priority = 200;
12
+ find(template: string): RuleMatch[];
13
+ execute(match: RuleMatch, scope: Scope): RuleResult;
14
+ supportsObservable(): boolean;
15
+ /**
16
+ * Постобработка: выполнить инжекцию элементов
17
+ */
18
+ static processInjections(root: Element | DocumentFragment, scope: Scope): void;
19
+ }
20
+ //# sourceMappingURL=InjectionRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InjectionRule.d.ts","sourceRoot":"","sources":["../../../../../src/foundation/engine/rules/attribute/InjectionRule.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;AAYnC;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,aAAa;IACpD,SAAgB,IAAI,eAAe;IACnC,SAAgB,QAAQ,OAAO;IAExB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE;IAsDnC,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,UAAU;IAyBnD,kBAAkB,IAAI,OAAO;IAIpC;;OAEG;WACW,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;CA8BxF"}