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,272 @@
1
+ /**
2
+ * Dynamic View Loader
3
+ * Provides lazy loading and code splitting for views
4
+ *
5
+ * @module core/ViewLoader
6
+ * @author OneLaravel Team
7
+ * @since 2025-12-29
8
+ */
9
+
10
+ import logger from './services/LoggerService.js';
11
+ import { warn, invariant } from '../helpers/devWarnings.js';
12
+
13
+ /**
14
+ * View Loader - Handles dynamic view loading with caching
15
+ *
16
+ * @class ViewLoader
17
+ *
18
+ * @example
19
+ * const loader = new ViewLoader();
20
+ * const ViewClass = await loader.load('web.pages.home');
21
+ */
22
+ export class ViewLoader {
23
+ constructor() {
24
+ /**
25
+ * @type {Map<string, Function>}
26
+ * @private
27
+ */
28
+ this.viewCache = new Map();
29
+ /**
30
+ * @type {Object}
31
+ * @private
32
+ */
33
+ this.registry = {};
34
+ /**
35
+ * @type {Map<string, Promise<Function>>}
36
+ * @private
37
+ */
38
+ this.loadingPromises = new Map();
39
+
40
+ /**
41
+ * @type {Map<string, string>}
42
+ * @private
43
+ */
44
+ this.viewPathMap = new Map();
45
+ }
46
+
47
+ /**
48
+ * Set view registry
49
+ * @param {Object} registry
50
+ */
51
+ setRegistry(registry) {
52
+ this.registry = registry;
53
+ }
54
+
55
+ /**
56
+ * Register a view path mapping
57
+ *
58
+ * @param {string} viewPath - View path (e.g., 'web.pages.home')
59
+ * @param {string} filePath - File path (e.g., './views/WebPagesHome.js')
60
+ *
61
+ * @example
62
+ * loader.register('web.pages.home', './views/WebPagesHome.js');
63
+ */
64
+ register(viewPath, filePath) {
65
+ this.viewPathMap.set(viewPath, filePath);
66
+ }
67
+
68
+ /**
69
+ * Register multiple view mappings
70
+ *
71
+ * @param {Object<string, string>} mappings - View path to file path mappings
72
+ *
73
+ * @example
74
+ * loader.registerBulk({
75
+ * 'web.pages.home': './views/WebPagesHome.js',
76
+ * 'web.pages.about': './views/WebPagesAbout.js',
77
+ * });
78
+ */
79
+ registerBulk(mappings) {
80
+ Object.entries(mappings).forEach(([viewPath, filePath]) => {
81
+ this.register(viewPath, filePath);
82
+ });
83
+ }
84
+
85
+ /**
86
+ * Load a view dynamically
87
+ *
88
+ * @param {string} viewPath - View path
89
+ * @returns {Promise<Function>} View class/function
90
+ * @throws {Error} If view cannot be loaded
91
+ *
92
+ * @example
93
+ * const ViewClass = await loader.load('web.pages.home');
94
+ * const view = ViewClass(data, systemData);
95
+ */
96
+ async load(viewPath) {
97
+ invariant(viewPath, 'View path is required');
98
+
99
+ // Check cache first
100
+ if (this.viewCache.has(viewPath)) {
101
+ logger.debug(`[ViewLoader] Loading from cache: ${viewPath}`);
102
+ return this.viewCache.get(viewPath);
103
+ }
104
+
105
+ // Check if already loading
106
+ if (this.loadingPromises.has(viewPath)) {
107
+ logger.debug(`[ViewLoader] Waiting for in-progress load: ${viewPath}`);
108
+ return this.loadingPromises.get(viewPath);
109
+ }
110
+
111
+ // Get file path
112
+ const filePath = this.viewPathMap.get(viewPath);
113
+
114
+ if (!filePath) {
115
+ warn(false, `View path not registered: ${viewPath}`);
116
+ throw new Error(`[ViewLoader] View not found: ${viewPath}`);
117
+ }
118
+
119
+ // Create loading promise
120
+ const loadingPromise = this._loadViewModule(viewPath, filePath);
121
+ this.loadingPromises.set(viewPath, loadingPromise);
122
+
123
+ try {
124
+ const ViewClass = await loadingPromise;
125
+
126
+ // Cache the loaded view
127
+ this.viewCache.set(viewPath, ViewClass);
128
+ logger.debug(`[ViewLoader] Successfully loaded: ${viewPath}`);
129
+
130
+ return ViewClass;
131
+ } catch (error) {
132
+ logger.error(`[ViewLoader] Failed to load view: ${viewPath}`, error);
133
+ throw error;
134
+ } finally {
135
+ // Remove from loading promises
136
+ this.loadingPromises.delete(viewPath);
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Load view module using dynamic import from registry
142
+ *
143
+ * @param {string} viewPath - View path
144
+ * @param {string} filePath - File path (kept for backward compatibility)
145
+ * @returns {Promise<Function>} View class/function
146
+ * @private
147
+ */
148
+ async _loadViewModule(viewPath, filePath) {
149
+ logger.debug(`[ViewLoader] Loading module: ${viewPath}`);
150
+
151
+ try {
152
+ // Use this.registry for static analysis by webpack
153
+ const importFn = this.registry[viewPath];
154
+
155
+ if (!importFn) {
156
+ const errorMsg = `View "${viewPath}" not found in registry. Make sure view is registered via setRegistry()`;
157
+ logger.error(`[ViewLoader] ${errorMsg}`);
158
+ throw new Error(errorMsg);
159
+ }
160
+
161
+ // Load from registry (webpack can analyze this statically)
162
+ const module = await importFn();
163
+
164
+ // Get the view function from module
165
+ const ViewClass = module.default || module[this._getFunctionName(viewPath)];
166
+
167
+ if (!ViewClass) {
168
+ throw new Error(`View function not found in module: ${viewPath}`);
169
+ }
170
+
171
+ return ViewClass;
172
+ } catch (error) {
173
+ logger.error(`[ViewLoader] Import failed: ${viewPath}`, error);
174
+ throw new Error(`Failed to load view module: ${error.message}`);
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Convert view path to function name
180
+ *
181
+ * @param {string} viewPath - View path (e.g., 'web.pages.home')
182
+ * @returns {string} Function name (e.g., 'WebPagesHome')
183
+ * @private
184
+ */
185
+ _getFunctionName(viewPath) {
186
+ return viewPath
187
+ .split('.')
188
+ .map(part => part.charAt(0).toUpperCase() + part.slice(1))
189
+ .join('');
190
+ }
191
+
192
+ /**
193
+ * Preload views for better performance
194
+ *
195
+ * @param {Array<string>} viewPaths - View paths to preload
196
+ * @returns {Promise<void>}
197
+ *
198
+ * @example
199
+ * await loader.preload(['web.pages.home', 'web.pages.about']);
200
+ */
201
+ async preload(viewPaths) {
202
+ logger.debug('[ViewLoader] Preloading views:', viewPaths);
203
+
204
+ const promises = viewPaths.map(viewPath => {
205
+ return this.load(viewPath).catch(error => {
206
+ logger.warn(`[ViewLoader] Failed to preload: ${viewPath}`, error);
207
+ });
208
+ });
209
+
210
+ await Promise.all(promises);
211
+ }
212
+
213
+ /**
214
+ * Clear cache for a specific view or all views
215
+ *
216
+ * @param {string} [viewPath] - View path (if omitted, clears all)
217
+ *
218
+ * @example
219
+ * loader.clearCache('web.pages.home'); // Clear specific view
220
+ * loader.clearCache(); // Clear all
221
+ */
222
+ clearCache(viewPath = null) {
223
+ if (viewPath) {
224
+ this.viewCache.delete(viewPath);
225
+ logger.debug(`[ViewLoader] Cleared cache: ${viewPath}`);
226
+ } else {
227
+ this.viewCache.clear();
228
+ logger.debug('[ViewLoader] Cleared all cache');
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Get cache statistics
234
+ *
235
+ * @returns {Object} Cache stats
236
+ */
237
+ getCacheStats() {
238
+ return {
239
+ cached: this.viewCache.size,
240
+ loading: this.loadingPromises.size,
241
+ registered: this.viewPathMap.size,
242
+ };
243
+ }
244
+
245
+ /**
246
+ * Check if view is cached
247
+ *
248
+ * @param {string} viewPath - View path
249
+ * @returns {boolean}
250
+ */
251
+ isCached(viewPath) {
252
+ return this.viewCache.has(viewPath);
253
+ }
254
+
255
+ /**
256
+ * Check if view is currently loading
257
+ *
258
+ * @param {string} viewPath - View path
259
+ * @returns {boolean}
260
+ */
261
+ isLoading(viewPath) {
262
+ return this.loadingPromises.has(viewPath);
263
+ }
264
+ }
265
+
266
+ /**
267
+ * Global view loader instance
268
+ * @type {ViewLoader}
269
+ */
270
+ export const viewLoader = new ViewLoader();
271
+
272
+ export default viewLoader;