onelaraveljs 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 (67) hide show
  1. package/README.md +87 -0
  2. package/docs/integration_analysis.md +116 -0
  3. package/docs/onejs_analysis.md +108 -0
  4. package/docs/optimization_implementation_group2.md +458 -0
  5. package/docs/optimization_plan.md +130 -0
  6. package/index.js +16 -0
  7. package/package.json +13 -0
  8. package/src/app.js +61 -0
  9. package/src/core/API.js +72 -0
  10. package/src/core/ChildrenRegistry.js +410 -0
  11. package/src/core/DOMBatcher.js +207 -0
  12. package/src/core/ErrorBoundary.js +226 -0
  13. package/src/core/EventDelegator.js +416 -0
  14. package/src/core/Helper.js +817 -0
  15. package/src/core/LoopContext.js +97 -0
  16. package/src/core/OneDOM.js +246 -0
  17. package/src/core/OneMarkup.js +444 -0
  18. package/src/core/Router.js +996 -0
  19. package/src/core/SEOConfig.js +321 -0
  20. package/src/core/SectionEngine.js +75 -0
  21. package/src/core/TemplateEngine.js +83 -0
  22. package/src/core/View.js +273 -0
  23. package/src/core/ViewConfig.js +229 -0
  24. package/src/core/ViewController.js +1410 -0
  25. package/src/core/ViewControllerOptimized.js +164 -0
  26. package/src/core/ViewIdentifier.js +361 -0
  27. package/src/core/ViewLoader.js +272 -0
  28. package/src/core/ViewManager.js +1962 -0
  29. package/src/core/ViewState.js +761 -0
  30. package/src/core/ViewSystem.js +301 -0
  31. package/src/core/ViewTemplate.js +4 -0
  32. package/src/core/helpers/BindingHelper.js +239 -0
  33. package/src/core/helpers/ConfigHelper.js +37 -0
  34. package/src/core/helpers/EventHelper.js +172 -0
  35. package/src/core/helpers/LifecycleHelper.js +17 -0
  36. package/src/core/helpers/ReactiveHelper.js +169 -0
  37. package/src/core/helpers/RenderHelper.js +15 -0
  38. package/src/core/helpers/ResourceHelper.js +89 -0
  39. package/src/core/helpers/TemplateHelper.js +11 -0
  40. package/src/core/managers/BindingManager.js +671 -0
  41. package/src/core/managers/ConfigurationManager.js +136 -0
  42. package/src/core/managers/EventManager.js +309 -0
  43. package/src/core/managers/LifecycleManager.js +356 -0
  44. package/src/core/managers/ReactiveManager.js +334 -0
  45. package/src/core/managers/RenderEngine.js +292 -0
  46. package/src/core/managers/ResourceManager.js +441 -0
  47. package/src/core/managers/ViewHierarchyManager.js +258 -0
  48. package/src/core/managers/ViewTemplateManager.js +127 -0
  49. package/src/core/reactive/ReactiveComponent.js +592 -0
  50. package/src/core/services/EventService.js +418 -0
  51. package/src/core/services/HttpService.js +106 -0
  52. package/src/core/services/LoggerService.js +57 -0
  53. package/src/core/services/StateService.js +512 -0
  54. package/src/core/services/StorageService.js +856 -0
  55. package/src/core/services/StoreService.js +258 -0
  56. package/src/core/services/TemplateDetectorService.js +361 -0
  57. package/src/core/services/Test.js +18 -0
  58. package/src/helpers/devWarnings.js +205 -0
  59. package/src/helpers/performance.js +226 -0
  60. package/src/helpers/utils.js +287 -0
  61. package/src/init.js +343 -0
  62. package/src/plugins/auto-plugin.js +34 -0
  63. package/src/services/Test.js +18 -0
  64. package/src/types/index.js +193 -0
  65. package/src/utils/date-helper.js +51 -0
  66. package/src/utils/helpers.js +39 -0
  67. package/src/utils/validation.js +32 -0
@@ -0,0 +1,292 @@
1
+ /**
2
+ * RenderEngine - Manages view rendering and scanning
3
+ * Handles render, virtual render, prerender, and DOM scanning
4
+ *
5
+ * Extracted from ViewController.js to improve maintainability
6
+ * @author GitHub Copilot
7
+ * @date 2025-12-29
8
+ */
9
+
10
+ import logger from '../services/LoggerService.js';
11
+ import OneMarkup from '../OneMarkup.js';
12
+ import { ATTR } from '../ViewConfig.js';
13
+
14
+ export class RenderEngine {
15
+ /**
16
+ * @param {ViewController} controller - Parent controller instance
17
+ */
18
+ constructor(controller) {
19
+ this.controller = controller;
20
+ }
21
+
22
+ /**
23
+ * Render the view
24
+ * @returns {string|Object} Rendered content
25
+ */
26
+ render() {
27
+ let renderFollowIDStart = this.controller._reactiveManager.followingIDs.length;
28
+ this.controller.commitConstructorData();
29
+ const result = this.controller.config.render.apply(this.controller, []);
30
+ this.controller.renderedContent = result;
31
+ let renderFollowIDEnd = this.controller._reactiveManager.followingIDs.length;
32
+ if (renderFollowIDEnd >= renderFollowIDStart) {
33
+ this.controller._reactiveManager.followingRenderIDs.push(...this.controller._reactiveManager.followingIDs.slice(renderFollowIDStart));
34
+ }
35
+
36
+ if (typeof result === 'string' && result.trim() !== '' && this.controller.isHtmlString(result)) {
37
+ this.controller.renderedContent = this.controller.addXRefViewToRootElements(result);
38
+ }
39
+ if (this.controller.isFirstClientRendering) {
40
+ this.controller.isFirstClientRendering = false;
41
+ if (this.controller._templateManager.wrapperConfig.enable) {
42
+ return this.controller.startWrapper(this.controller._templateManager.wrapperConfig.tag, this.controller._templateManager.wrapperConfig.attributes || {}) + this.controller.renderedContent + this.controller.endWrapper(this.controller._templateManager.wrapperConfig.tag);
43
+ }
44
+ }
45
+ return this.controller.renderedContent;
46
+ }
47
+
48
+ /**
49
+ * Virtual render the view with data (Scan version)
50
+ * @returns {string|Object} Virtual rendered content
51
+ */
52
+ virtualRender() {
53
+ this.controller.isScanning = true;
54
+ this.controller.isVirtualRendering = true;
55
+ let renderFollowIDStart = this.controller._reactiveManager.followingIDs.length;
56
+ this.controller.commitConstructorData();
57
+ let result = this.controller.config.render.apply(this.controller, []);
58
+ if (typeof result === 'string' && this.controller.isFirstClientRendering && this.controller._templateManager.wrapperConfig) {
59
+ result = this.controller.startWrapper(this.controller._templateManager.wrapperConfig.tag, this.controller._templateManager.wrapperConfig.attributes || {}) + result + this.controller.endWrapper(this.controller._templateManager.wrapperConfig.tag);
60
+ }
61
+ let renderFollowIDEnd = this.controller._reactiveManager.followingIDs.length;
62
+ if (renderFollowIDEnd >= renderFollowIDStart) {
63
+ this.controller._reactiveManager.followingRenderIDs.push(...this.controller._reactiveManager.followingIDs.slice(renderFollowIDStart));
64
+ }
65
+ this.controller.isVirtualRendering = false;
66
+ this.controller.isFirstClientRendering = false;
67
+ return result;
68
+ }
69
+
70
+ /**
71
+ * Prerender the view with data
72
+ * @param {Object} _data - Additional data to merge
73
+ * @returns {string|Object} Prerendered content
74
+ */
75
+ prerender(_data = {}) {
76
+ let renderFollowIDStart = this.controller._reactiveManager.followingIDs.length;
77
+ this.controller.commitConstructorData();
78
+ const result = this.controller.config.prerender.apply(this.controller, []);
79
+ let renderFollowIDEnd = this.controller._reactiveManager.followingIDs.length;
80
+ if (renderFollowIDEnd >= renderFollowIDStart) {
81
+ this.controller._reactiveManager.followingPrerenderIDs.push(...this.controller._reactiveManager.followingIDs.slice(renderFollowIDStart));
82
+ }
83
+ if (typeof result === 'string' && result.trim() !== '' && this.controller.isHtmlString(result)) {
84
+ return this.controller.addXRefViewToRootElements(result);
85
+ }
86
+ return result;
87
+ }
88
+
89
+ /**
90
+ * Virtual prerender the view with data (Scan version)
91
+ * @param {Object} _data - Additional data to merge
92
+ * @returns {string|Object} Virtual prerendered content
93
+ */
94
+ virtualPrerender(_data = {}) {
95
+ this.controller.isScanning = true;
96
+ this.controller.isVirtualRendering = true;
97
+ let renderFollowIDStart = this.controller._reactiveManager.followingIDs.length;
98
+ this.controller.commitConstructorData();
99
+ const result = this.controller.config.prerender.apply(this.controller, []);
100
+ let renderFollowIDEnd = this.controller._reactiveManager.followingIDs.length;
101
+ if (renderFollowIDEnd >= renderFollowIDStart) {
102
+ this.controller._reactiveManager.followingPrerenderIDs.push(...this.controller._reactiveManager.followingIDs.slice(renderFollowIDStart));
103
+ }
104
+ this.controller.isVirtualRendering = false;
105
+ this.controller.isScanning = false;
106
+ return result;
107
+ }
108
+
109
+ refresh(variableData = null) {
110
+ /**
111
+ * @type {ViewController}
112
+ */
113
+ const ctrl = this.controller;
114
+ /**
115
+ * @type {ViewManager}
116
+ */
117
+ const manager = ctrl.App.View;
118
+ if (ctrl.hasSuperView) {
119
+ const superView = ctrl.superView;
120
+ superView._lifecycleManager.unmounted();
121
+ ctrl.updateVariableData(variableData);
122
+ try {
123
+ const result = ctrl.render();
124
+ manager.emitChangedSections();
125
+ } catch (error) {
126
+ console.error(error);
127
+ }
128
+ superView._lifecycleManager.mounted();
129
+ }
130
+ else if (ctrl.wrapperConfig.enable) {
131
+ ctrl._lifecycleManager.unmounted();
132
+ ctrl.updateVariableData(variableData);
133
+ try {
134
+ const result = ctrl.render();
135
+ if (ctrl.rootElement) {
136
+ OneDOM.replaceContent(ctrl.rootElement, result);
137
+ this.refElements = Array.from(ctrl.rootElement.children);
138
+ }
139
+ else if (ctrl.markup) {
140
+ ctrl.markup.replaceContent(result);
141
+ this.refElements = ctrl.markup.nodes;
142
+
143
+ }
144
+ else {
145
+ console.error('No root element or markup found');
146
+ }
147
+ } catch (error) {
148
+ console.error(error);
149
+ }
150
+ ctrl._lifecycleManager.mounted();
151
+ }
152
+ else {
153
+ console.error('No root element or markup found');
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Scan view configuration and setup reactive components
159
+ * @param {Object} config - Scan configuration
160
+ */
161
+ scan(config) {
162
+ if (this.controller.isScanned) {
163
+ return;
164
+ }
165
+ this.controller.__scanData = config;
166
+ this.controller.isScanning = true;
167
+ const { viewId, data, attributes = [], events, outputComponents, children, parent } = config;
168
+
169
+ if (data && typeof data === 'object') {
170
+ this.controller.updateVariableData(data);
171
+ }
172
+
173
+ if (typeof viewId !== 'string' || viewId === '') {
174
+ logger.warn('⚠️ RenderEngine.scan: Invalid viewId', viewId);
175
+ return null;
176
+ }
177
+
178
+ // Setup Output Components
179
+ if (outputComponents && outputComponents.length > 0) {
180
+ this._setupOutputComponents(outputComponents, viewId);
181
+ }
182
+
183
+ // Setup Attribute Bindings
184
+ if (attributes && attributes.length > 0) {
185
+ this._setupAttributeBindings(attributes);
186
+ }
187
+
188
+ // Store Children References
189
+ if (children && children.length > 0) {
190
+ this._storeChildrenReferences(children);
191
+ }
192
+
193
+ this.controller.isScanned = true;
194
+ }
195
+
196
+ /**
197
+ * Find and store DOM elements for this view
198
+ * @param {string} viewId - View instance ID
199
+ */
200
+ scanDOMElements(viewId) {
201
+ if (this.controller.isMarkupScanned) {
202
+ return;
203
+ }
204
+ this.controller.isMarkupScanned = true;
205
+
206
+ if (this.controller.hasSuperView) {
207
+ return;
208
+ }
209
+ const wrpCfg = this.controller._templateManager.wrapperConfig;
210
+
211
+ if (wrpCfg.enable) {
212
+ if (wrpCfg.tag) {
213
+ // Custom wrapper tag
214
+ const rootElement = document.querySelector(
215
+ `${wrpCfg.tag}[data-wrap-view="${this.controller.path}"][${ATTR.KEYS.VIEW_WRAPPER}="${viewId}"]`
216
+ );
217
+ if (rootElement) {
218
+ this.controller.rootElement = rootElement;
219
+ const children = Array.from(rootElement.children);
220
+ this.controller.refElements = children;
221
+ }
222
+ } else {
223
+ // Use OneMarkup to find view boundary
224
+ const markup = OneMarkup.first('view', { name: this.controller.path, id: viewId });
225
+ if (markup) {
226
+ this.controller.markup = markup;
227
+ this.controller.refElements = markup.nodes && markup.nodes.length ? markup.nodes.filter(node => node.nodeType === Node.ELEMENT_NODE) : [];
228
+ }
229
+ }
230
+ } else {
231
+ // Standard view wrapper
232
+ const rootElement = document.querySelector(`[data-view-wrapper="${viewId}"]`);
233
+ if (rootElement) {
234
+ this.controller.rootElement = rootElement;
235
+ const children = Array.from(rootElement.children);
236
+ this.controller.refElements = children;
237
+ }
238
+ }
239
+
240
+ if (!this.controller.refElements || this.controller.refElements.length === 0) {
241
+ // logger.warn(`⚠️ RenderEngine.scanDOMElements: No elements found for ${this.controller.path} (${viewId})`);
242
+ }
243
+ }
244
+
245
+ /**
246
+ * Setup output components for reactive state updates
247
+ * @private
248
+ * @param {Array} outputComponents - Output component configurations
249
+ * @param {string} viewId - View instance ID
250
+ */
251
+ _setupOutputComponents(outputComponents, viewId) {
252
+ outputComponents.forEach(outputComponentConfig => {
253
+ const { id, stateKeys } = outputComponentConfig;
254
+ this.controller._reactiveManager.reactiveComponentConfig.push({
255
+ id,
256
+ stateKeys,
257
+ });
258
+ });
259
+ }
260
+
261
+ /**
262
+ * Setup attribute bindings
263
+ * @private
264
+ * @param {Array} attributeBindings - Attribute binding configurations
265
+ */
266
+ _setupAttributeBindings(attributeBindings) {
267
+ attributeBindings.forEach(binding => {
268
+ const { id, config } = binding;
269
+ this.controller._bindingManager.attributeConfigs.push({
270
+ id,
271
+ config,
272
+ });
273
+ });
274
+ }
275
+
276
+ /**
277
+ * Store children view references
278
+ * @private
279
+ * @param {Array} children - Children configurations
280
+ */
281
+ _storeChildrenReferences(children) {
282
+ this.controller.__storeChildrenReferences(children);
283
+ }
284
+
285
+ get App() {
286
+ return this.controller.App;
287
+ }
288
+
289
+ set App(value) {
290
+ devLog('RenderEngine.App is read-only.');
291
+ }
292
+ }