@noego/forge 0.0.21 → 0.0.23

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.
@@ -146,7 +146,46 @@ class BaseHTMLRender {
146
146
  }
147
147
  async renderHTML(data) {
148
148
  const template = Handlebars.compile(await this.getTemplate());
149
- return template(data);
149
+ let html = template(data);
150
+ const configJson = process.env.NOEGO_CONFIGURATION;
151
+ if (configJson) {
152
+ const configScript = `<script>window.__CONFIGURATION__ = ${configJson};<\/script>`;
153
+ if (html.includes("</head>")) {
154
+ html = html.replace("</head>", `${configScript}
155
+ </head>`);
156
+ } else if (html.includes("<body")) {
157
+ html = html.replace(/(<body[^>]*>)/, `$1
158
+ ${configScript}`);
159
+ } else {
160
+ html = configScript + "\n" + html;
161
+ }
162
+ }
163
+ html = html.replace(
164
+ /<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi,
165
+ (match, src) => {
166
+ return `<script type="module">
167
+ import initApp from '${src}';
168
+ function initializeApp() {
169
+ if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
170
+ const result = initApp();
171
+ if (result instanceof Promise) {
172
+ result.catch(err => console.error('Failed to initialize app:', err));
173
+ }
174
+ } else {
175
+ console.warn('App initialization skipped: initApp or window.__CONFIGURATION__ not available');
176
+ }
177
+ }
178
+ // Wait for DOM to be ready
179
+ if (document.readyState === 'loading') {
180
+ document.addEventListener('DOMContentLoaded', initializeApp);
181
+ } else {
182
+ // DOM already loaded
183
+ initializeApp();
184
+ }
185
+ <\/script>`;
186
+ }
187
+ );
188
+ return html;
150
189
  }
151
190
  }
152
191
  class DefaultHTMLRender extends BaseHTMLRender {
@@ -160,7 +199,46 @@ class LiveHTMLRender {
160
199
  }
161
200
  async renderHTML(data) {
162
201
  const template = Handlebars.compile(await this.getTemplate());
163
- return template(data);
202
+ let html = template(data);
203
+ const configJson = process.env.NOEGO_CONFIGURATION;
204
+ if (configJson) {
205
+ const configScript = `<script>window.__CONFIGURATION__ = ${configJson};<\/script>`;
206
+ if (html.includes("</head>")) {
207
+ html = html.replace("</head>", `${configScript}
208
+ </head>`);
209
+ } else if (html.includes("<body")) {
210
+ html = html.replace(/(<body[^>]*>)/, `$1
211
+ ${configScript}`);
212
+ } else {
213
+ html = configScript + "\n" + html;
214
+ }
215
+ }
216
+ html = html.replace(
217
+ /<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi,
218
+ (match, src) => {
219
+ return `<script type="module">
220
+ import initApp from '${src}';
221
+ function initializeApp() {
222
+ if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
223
+ const result = initApp();
224
+ if (result instanceof Promise) {
225
+ result.catch(err => console.error('Failed to initialize app:', err));
226
+ }
227
+ } else {
228
+ console.warn('App initialization skipped: initApp or window.__CONFIGURATION__ not available');
229
+ }
230
+ }
231
+ // Wait for DOM to be ready
232
+ if (document.readyState === 'loading') {
233
+ document.addEventListener('DOMContentLoaded', initializeApp);
234
+ } else {
235
+ // DOM already loaded
236
+ initializeApp();
237
+ }
238
+ <\/script>`;
239
+ }
240
+ );
241
+ return html;
164
242
  }
165
243
  async getTemplate() {
166
244
  const file_content = await fs$1.readFile(this.html_path, "utf8");
@@ -355,9 +433,28 @@ async function layout_requires_server(route, loader) {
355
433
  if (!layout) {
356
434
  return false;
357
435
  }
358
- const load_required = await Promise.all(layout.map(async (layout2) => {
359
- const component = await loader.load(layout2);
360
- return !!component.load;
436
+ const load_required = await Promise.all(layout.map(async (layoutPath) => {
437
+ const fullPath = loader.getComponentFullPath(layoutPath);
438
+ const { dir, name } = path.parse(fullPath);
439
+ const extensions = [".js", ".ts"];
440
+ for (const ext of extensions) {
441
+ const loaderFilePath = path.join(dir, `${name}.load${ext}`);
442
+ try {
443
+ if (fs.existsSync(loaderFilePath)) {
444
+ const module = await import(pathToFileURL(loaderFilePath).href);
445
+ if (typeof (module == null ? void 0 : module.default) === "function") {
446
+ return true;
447
+ }
448
+ }
449
+ } catch (error) {
450
+ }
451
+ }
452
+ try {
453
+ const component = await loader.load(layoutPath);
454
+ return !!component.load;
455
+ } catch {
456
+ return false;
457
+ }
361
458
  }));
362
459
  return load_required.some((required) => required);
363
460
  }
@@ -366,8 +463,27 @@ async function view_requires_server(route, loader) {
366
463
  if (!view) {
367
464
  return false;
368
465
  }
369
- const component = await loader.load(view);
370
- return !!component.load;
466
+ const fullPath = loader.getComponentFullPath(view);
467
+ const { dir, name } = path.parse(fullPath);
468
+ const extensions = [".js", ".ts"];
469
+ for (const ext of extensions) {
470
+ const loaderFilePath = path.join(dir, `${name}.load${ext}`);
471
+ try {
472
+ if (fs.existsSync(loaderFilePath)) {
473
+ const module = await import(pathToFileURL(loaderFilePath).href);
474
+ if (typeof (module == null ? void 0 : module.default) === "function") {
475
+ return true;
476
+ }
477
+ }
478
+ } catch (error) {
479
+ }
480
+ }
481
+ try {
482
+ const component = await loader.load(view);
483
+ return !!component.load;
484
+ } catch {
485
+ return false;
486
+ }
371
487
  }
372
488
  class ApiAdapter {
373
489
  constructor(manager) {
@@ -486,11 +602,19 @@ class ComponentManager {
486
602
  return layouts_components;
487
603
  }
488
604
  async getLayoutLoaders(route) {
489
- const layout_components = await this.getLayoutComponents(route);
490
- const layout_loaders = await Promise.all(layout_components.map(async (layout) => {
491
- return layout.load;
492
- }));
493
- return layout_loaders;
605
+ const layout_paths = route.layout || [];
606
+ const loaders_from_files = await Promise.all(
607
+ layout_paths.map((layoutPath) => this.resolveLoader(layoutPath))
608
+ );
609
+ const needs_fallback = loaders_from_files.some((loader) => !loader);
610
+ if (needs_fallback) {
611
+ const layout_components = await this.getLayoutComponents(route);
612
+ const old_style_loaders = layout_components.map((layout) => layout.load);
613
+ return loaders_from_files.map(
614
+ (loader, index) => loader || old_style_loaders[index] || null
615
+ );
616
+ }
617
+ return loaders_from_files;
494
618
  }
495
619
  async getViewComponent(route) {
496
620
  return await this.componentLoader.load(route.view);
@@ -514,30 +638,38 @@ class ComponentManager {
514
638
  view
515
639
  };
516
640
  }
517
- getLoaderFilePath(componentPath) {
641
+ getLoaderFilePath(componentPath, extension = ".js") {
518
642
  if (!componentPath) {
519
643
  return null;
520
644
  }
521
645
  const fullPath = this.componentLoader.getComponentFullPath(componentPath);
522
646
  const { dir, name } = path.parse(fullPath);
523
- return path.join(dir, `${name}.load.ts`);
647
+ return path.join(dir, `${name}.load${extension}`);
524
648
  }
525
649
  async resolveLoader(componentPath) {
526
- const loaderFilePath = this.getLoaderFilePath(componentPath);
527
- if (!loaderFilePath) {
650
+ if (!componentPath) {
528
651
  return null;
529
652
  }
530
- try {
531
- const module = await import(pathToFileURL(loaderFilePath).href);
532
- const loader = module == null ? void 0 : module.default;
533
- return typeof loader === "function" ? loader : null;
534
- } catch (error) {
535
- if ((error == null ? void 0 : error.code) === "MODULE_NOT_FOUND" || (error == null ? void 0 : error.code) === "ERR_MODULE_NOT_FOUND") {
536
- return null;
653
+ const extensions = [".js", ".ts"];
654
+ for (const ext of extensions) {
655
+ const loaderFilePath = this.getLoaderFilePath(componentPath, ext);
656
+ if (!loaderFilePath) {
657
+ continue;
658
+ }
659
+ try {
660
+ const module = await import(pathToFileURL(loaderFilePath).href);
661
+ const loader = module == null ? void 0 : module.default;
662
+ if (typeof loader === "function") {
663
+ return loader;
664
+ }
665
+ } catch (error) {
666
+ if ((error == null ? void 0 : error.code) === "MODULE_NOT_FOUND" || (error == null ? void 0 : error.code) === "ERR_MODULE_NOT_FOUND") {
667
+ continue;
668
+ }
669
+ console.error(`[ComponentManager] Failed to load loader for ${componentPath} (${ext}):`, error);
537
670
  }
538
- console.error(`[ComponentManager] Failed to load loader for ${componentPath}:`, error);
539
- return null;
540
671
  }
672
+ return null;
541
673
  }
542
674
  async getView(route) {
543
675
  const view = await this.componentLoader.load(route.view);