@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.
- package/dist/client.cjs +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.mjs +206 -212
- package/dist/client.mjs.map +1 -1
- package/dist/plugins-cjs/routing/html_render/html_render.js +90 -2
- package/dist/plugins-cjs/routing/html_render/html_render.js.map +1 -1
- package/dist/plugins-es/routing/html_render/html_render.js +90 -2
- package/dist/plugins-es/routing/html_render/html_render.js.map +1 -1
- package/dist/routing/html_render/html_render.js +90 -2
- package/dist/routing/html_render/html_render.js.map +1 -1
- package/dist-ssr/server.cjs +157 -25
- package/dist-ssr/server.cjs.map +1 -1
- package/dist-ssr/server.js +157 -25
- package/dist-ssr/server.js.map +1 -1
- package/package.json +1 -1
package/dist-ssr/server.js
CHANGED
|
@@ -146,7 +146,46 @@ class BaseHTMLRender {
|
|
|
146
146
|
}
|
|
147
147
|
async renderHTML(data) {
|
|
148
148
|
const template = Handlebars.compile(await this.getTemplate());
|
|
149
|
-
|
|
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
|
-
|
|
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 (
|
|
359
|
-
const
|
|
360
|
-
|
|
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
|
|
370
|
-
|
|
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
|
|
490
|
-
const
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
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
|
|
647
|
+
return path.join(dir, `${name}.load${extension}`);
|
|
524
648
|
}
|
|
525
649
|
async resolveLoader(componentPath) {
|
|
526
|
-
|
|
527
|
-
if (!loaderFilePath) {
|
|
650
|
+
if (!componentPath) {
|
|
528
651
|
return null;
|
|
529
652
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
const
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
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);
|