fix
This commit is contained in:
parent
9bf393fee8
commit
0e85aa93a2
|
|
@ -11,7 +11,9 @@ const cache = {
|
||||||
export const _ = {
|
export const _ = {
|
||||||
url: "/_prasi/**",
|
url: "/_prasi/**",
|
||||||
async api() {
|
async api() {
|
||||||
|
|
||||||
const { req, res } = apiContext(this);
|
const { req, res } = apiContext(this);
|
||||||
|
console.log(`[DEBUG] _prasi called with pathname: ${req.url}`);
|
||||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
res.setHeader("Access-Control-Allow-Headers", "content-type");
|
res.setHeader("Access-Control-Allow-Headers", "content-type");
|
||||||
const gz = g.deploy.content;
|
const gz = g.deploy.content;
|
||||||
|
|
@ -34,13 +36,16 @@ export const _ = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
code: async () => {
|
code: async () => {
|
||||||
|
console.log(`[DEBUG] _prasi code called with pathname: ${req.url}`);
|
||||||
if (gz) {
|
if (gz) {
|
||||||
const path = parts.slice(1).join("/");
|
const path = parts.slice(1).join("/");
|
||||||
|
console.log(`[DEBUG] _prasi code path: ${path}`);
|
||||||
if (gz.code.site[path]) {
|
if (gz.code.site[path]) {
|
||||||
const type = mime.getType(path);
|
const type = mime.getType(path);
|
||||||
|
console.log(`[DEBUG] _prasi code type: ${type}`);
|
||||||
if (type) res.setHeader("content-type", type);
|
if (type) res.setHeader("content-type", type);
|
||||||
res.send(
|
res.send(
|
||||||
gz.code.site[path],
|
new TextDecoder().decode(gz.code.site[path]),
|
||||||
req.headers.get("accept-encoding") || ""
|
req.headers.get("accept-encoding") || ""
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,8 @@ export const createServer = async () => {
|
||||||
return api;
|
return api;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`[DEBUG] No API found, lookup for ${url.pathname}`);
|
||||||
|
|
||||||
if (g.deploy.router) {
|
if (g.deploy.router) {
|
||||||
const found = g.deploy.router.lookup(url.pathname);
|
const found = g.deploy.router.lookup(url.pathname);
|
||||||
if (found) {
|
if (found) {
|
||||||
|
|
@ -161,10 +163,14 @@ export const createServer = async () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`[DEBUG] No route found, check content for ${url.pathname}`);
|
||||||
|
|
||||||
if (g.deploy.content) {
|
if (g.deploy.content) {
|
||||||
const core = g.deploy.content.code.core;
|
const core = g.deploy.content.code.core;
|
||||||
const site = g.deploy.content.code.site;
|
const site = g.deploy.content.code.site;
|
||||||
const pub = g.deploy.content.public;
|
const pub = g.deploy.content.public;
|
||||||
|
//list all content
|
||||||
|
// console.log(`[DEBUG] Content paths: core=${Object.keys(core).join(", ")}, site=${Object.keys(site).join(", ")}, pub=${Object.keys(pub).join(", ")}`);
|
||||||
|
|
||||||
let pathname = url.pathname;
|
let pathname = url.pathname;
|
||||||
if (url.pathname[0] === "/") pathname = pathname.substring(1);
|
if (url.pathname[0] === "/") pathname = pathname.substring(1);
|
||||||
|
|
@ -188,6 +194,8 @@ export const createServer = async () => {
|
||||||
else if (site[pathname]) content = site[pathname];
|
else if (site[pathname]) content = site[pathname];
|
||||||
else if (pub[pathname]) content = pub[pathname];
|
else if (pub[pathname]) content = pub[pathname];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (content) {
|
if (content) {
|
||||||
return await serveWeb({
|
return await serveWeb({
|
||||||
content,
|
content,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { createResponse } from "service-srv";
|
||||||
import { g } from "../utils/global";
|
import { g } from "../utils/global";
|
||||||
|
|
||||||
export const serveAPI = async (url: URL, req: Request) => {
|
export const serveAPI = async (url: URL, req: Request) => {
|
||||||
|
console.log(`[DEBUG] serveAPI called with pathname: ${url.pathname}`);
|
||||||
let found = g.router.lookup(url.pathname);
|
let found = g.router.lookup(url.pathname);
|
||||||
if (!found?.url) {
|
if (!found?.url) {
|
||||||
if (!url.pathname.endsWith("/")) {
|
if (!url.pathname.endsWith("/")) {
|
||||||
|
|
|
||||||
|
|
@ -102,9 +102,8 @@ export const deploy = {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (g.deploy.content) {
|
if (g.deploy.content) {
|
||||||
// Skip Brotli compression entirely to prevent blocking server startup
|
startBrCompress();
|
||||||
console.log(`[DEBUG] Skipping Brotli compression to enable fast startup`);
|
console.log(`[DEBUG] Compression started`);
|
||||||
console.log(`[DEBUG] Brotli compression disabled - starting server immediately`);
|
|
||||||
|
|
||||||
if (exists(dir("public"))) {
|
if (exists(dir("public"))) {
|
||||||
await removeAsync(dir("public"));
|
await removeAsync(dir("public"));
|
||||||
|
|
@ -273,6 +272,7 @@ export const deploy = {
|
||||||
|
|
||||||
// Extract file data from ZIP buffer
|
// Extract file data from ZIP buffer
|
||||||
const fileContent = await this.extractFileFromZip(zipBuffer, entry);
|
const fileContent = await this.extractFileFromZip(zipBuffer, entry);
|
||||||
|
if(entry.filename.startsWith('server/')) console.log(`[DEBUG] File content preview: ${fileContent.slice(0, 100)}`);
|
||||||
|
|
||||||
if (entry.filename === 'metadata.json') {
|
if (entry.filename === 'metadata.json') {
|
||||||
console.log(`[DEBUG] ✓ Found metadata.json entry!`);
|
console.log(`[DEBUG] ✓ Found metadata.json entry!`);
|
||||||
|
|
@ -290,9 +290,6 @@ export const deploy = {
|
||||||
console.log(`[DEBUG] Successfully parsed metadata.json`);
|
console.log(`[DEBUG] Successfully parsed metadata.json`);
|
||||||
console.log(`[DEBUG] foundMetadata flag before setting: ${foundMetadata}`);
|
console.log(`[DEBUG] foundMetadata flag before setting: ${foundMetadata}`);
|
||||||
|
|
||||||
// Detect metadata inflation and identify problematic items
|
|
||||||
this.detectMetadataInflation(metadata);
|
|
||||||
|
|
||||||
// Update deploy content with metadata
|
// Update deploy content with metadata
|
||||||
g.deploy.content.layouts = metadata.layouts || [];
|
g.deploy.content.layouts = metadata.layouts || [];
|
||||||
g.deploy.content.pages = metadata.pages || [];
|
g.deploy.content.pages = metadata.pages || [];
|
||||||
|
|
@ -329,11 +326,8 @@ export const deploy = {
|
||||||
const binaryExtensions = ['.js', '.map', '.json'];
|
const binaryExtensions = ['.js', '.map', '.json'];
|
||||||
const isBinary = binaryExtensions.some(ext => relativePath.toLowerCase().endsWith(ext));
|
const isBinary = binaryExtensions.some(ext => relativePath.toLowerCase().endsWith(ext));
|
||||||
|
|
||||||
if (isBinary) {
|
|
||||||
g.deploy.content.code.server[relativePath] = fileContent;
|
|
||||||
} else {
|
|
||||||
g.deploy.content.code.server[relativePath] = new TextDecoder().decode(fileContent);
|
g.deploy.content.code.server[relativePath] = new TextDecoder().decode(fileContent);
|
||||||
}
|
|
||||||
} else if (entry.filename.startsWith('site/')) {
|
} else if (entry.filename.startsWith('site/')) {
|
||||||
const relativePath = entry.filename.slice(5); // Remove 'site/' prefix
|
const relativePath = entry.filename.slice(5); // Remove 'site/' prefix
|
||||||
const binaryExtensions = ['.js', '.css', '.map', '.json', '.woff', '.woff2', '.ttf'];
|
const binaryExtensions = ['.js', '.css', '.map', '.json', '.woff', '.woff2', '.ttf'];
|
||||||
|
|
@ -345,7 +339,7 @@ export const deploy = {
|
||||||
g.deploy.content.code.site[relativePath] = new TextDecoder().decode(fileContent);
|
g.deploy.content.code.site[relativePath] = new TextDecoder().decode(fileContent);
|
||||||
}
|
}
|
||||||
} else if (entry.filename.startsWith('core/')) {
|
} else if (entry.filename.startsWith('core/')) {
|
||||||
const relativePath = entry.filename.slice(6); // Remove 'core/' prefix
|
const relativePath = entry.filename.slice(5); // Remove 'core/' prefix
|
||||||
const binaryExtensions = ['.js', '.json'];
|
const binaryExtensions = ['.js', '.json'];
|
||||||
const isBinary = binaryExtensions.some(ext => relativePath.toLowerCase().endsWith(ext));
|
const isBinary = binaryExtensions.some(ext => relativePath.toLowerCase().endsWith(ext));
|
||||||
|
|
||||||
|
|
@ -354,13 +348,6 @@ export const deploy = {
|
||||||
} else {
|
} else {
|
||||||
g.deploy.content.code.core[relativePath] = new TextDecoder().decode(fileContent);
|
g.deploy.content.code.core[relativePath] = new TextDecoder().decode(fileContent);
|
||||||
}
|
}
|
||||||
} else if (entry.filename.startsWith('content/')) {
|
|
||||||
// Store content tree files for later processing
|
|
||||||
if (!g.deploy.content._contentTrees) {
|
|
||||||
g.deploy.content._contentTrees = {};
|
|
||||||
}
|
|
||||||
g.deploy.content._contentTrees[entry.filename] = new TextDecoder().decode(fileContent);
|
|
||||||
console.log(`[DEBUG] Loaded content tree file: ${entry.filename} (${fileContent.length} bytes)`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadedFiles++;
|
loadedFiles++;
|
||||||
|
|
@ -372,12 +359,6 @@ export const deploy = {
|
||||||
console.log(`[DEBUG] ZIP processing completed: ${loadedFiles} files loaded`);
|
console.log(`[DEBUG] ZIP processing completed: ${loadedFiles} files loaded`);
|
||||||
console.log(`[DEBUG] Final foundMetadata state: ${foundMetadata}`);
|
console.log(`[DEBUG] Final foundMetadata state: ${foundMetadata}`);
|
||||||
|
|
||||||
// Restore content_tree data from separate files if optimization was applied
|
|
||||||
if (g.deploy.content._contentTrees && Object.keys(g.deploy.content._contentTrees).length > 0) {
|
|
||||||
console.log(`[DEBUG] Restoring content_tree data from separate files...`);
|
|
||||||
this.restoreContentTrees(g.deploy.content);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!foundMetadata) {
|
if (!foundMetadata) {
|
||||||
console.log(`[DEBUG] Available files in ZIP (${zipEntries.length} total entries):`);
|
console.log(`[DEBUG] Available files in ZIP (${zipEntries.length} total entries):`);
|
||||||
for (const entry of zipEntries) {
|
for (const entry of zipEntries) {
|
||||||
|
|
@ -550,142 +531,6 @@ export const deploy = {
|
||||||
JSON.stringify(this.config, null, 2)
|
JSON.stringify(this.config, null, 2)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
detectMetadataInflation(metadata: any) {
|
|
||||||
console.log(`[INFLATION] Starting metadata inflation analysis...`);
|
|
||||||
|
|
||||||
const analyzeItems = (items: any[], type: string) => {
|
|
||||||
if (!items || !Array.isArray(items)) return [];
|
|
||||||
|
|
||||||
const results = [];
|
|
||||||
let totalSize = 0;
|
|
||||||
|
|
||||||
for (const item of items) {
|
|
||||||
const itemSize = JSON.stringify(item).length;
|
|
||||||
totalSize += itemSize;
|
|
||||||
|
|
||||||
// Check if this item has content_tree and calculate its size
|
|
||||||
const contentTreeSize = item.content_tree ? JSON.stringify(item.content_tree).length : 0;
|
|
||||||
|
|
||||||
if (itemSize > 100000 || contentTreeSize > 50000) { // 100KB total or 50KB content_tree
|
|
||||||
results.push({
|
|
||||||
id: item.id || 'unknown',
|
|
||||||
name: item.name || 'unnamed',
|
|
||||||
url: item.url || '',
|
|
||||||
totalSize: itemSize,
|
|
||||||
contentTreeSize: contentTreeSize,
|
|
||||||
hasContentTree: !!item.content_tree,
|
|
||||||
type: type
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`[INFLATION] ${type}: ${items.length} items, total ${(totalSize / 1024 / 1024).toFixed(2)}MB`);
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Analyze each type of content
|
|
||||||
const inflatedLayouts = analyzeItems(metadata.layouts || [], 'layout');
|
|
||||||
const inflatedPages = analyzeItems(metadata.pages || [], 'page');
|
|
||||||
const inflatedComponents = analyzeItems(metadata.components || [], 'component');
|
|
||||||
|
|
||||||
const allInflated = [...inflatedLayouts, ...inflatedPages, ...inflatedComponents];
|
|
||||||
|
|
||||||
if (allInflated.length > 0) {
|
|
||||||
console.log(`[INFLATION] ⚠️ Found ${allInflated.length} inflated items causing metadata bloat:`);
|
|
||||||
|
|
||||||
// Sort by size (largest first)
|
|
||||||
allInflated.sort((a, b) => b.totalSize - a.totalSize);
|
|
||||||
|
|
||||||
// Show top 10 biggest offenders
|
|
||||||
const topOffenders = allInflated.slice(0, 10);
|
|
||||||
for (const item of topOffenders) {
|
|
||||||
const sizeMB = (item.totalSize / 1024 / 1024).toFixed(2);
|
|
||||||
const contentTreeMB = (item.contentTreeSize / 1024 / 1024).toFixed(2);
|
|
||||||
const percentage = ((item.contentTreeSize / item.totalSize) * 100).toFixed(1);
|
|
||||||
|
|
||||||
console.log(`[INFLATION] 📊 ${item.type.toUpperCase()}: ${item.name || item.id}`);
|
|
||||||
console.log(`[INFLATION] Size: ${sizeMB}MB total (${contentTreeMB}MB content_tree = ${percentage}%)`);
|
|
||||||
if (item.url) console.log(`[INFLATION] URL: ${item.url}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Summary statistics
|
|
||||||
const totalInflatedSize = allInflated.reduce((sum, item) => sum + item.totalSize, 0);
|
|
||||||
const totalContentTreeSize = allInflated.reduce((sum, item) => sum + item.contentTreeSize, 0);
|
|
||||||
|
|
||||||
console.log(`[INFLATION] 📈 Summary:`);
|
|
||||||
console.log(`[INFLATION] Total inflated items: ${allInflated.length}/${metadata.pages?.length + metadata.components?.length + metadata.layouts?.length || 0}`);
|
|
||||||
console.log(`[INFLATION] Total bloat: ${(totalInflatedSize / 1024 / 1024).toFixed(2)}MB`);
|
|
||||||
console.log(`[INFLATION] Content-tree bloat: ${(totalContentTreeSize / 1024 / 1024).toFixed(2)}MB (${((totalContentTreeSize / totalInflatedSize) * 100).toFixed(1)}%)`);
|
|
||||||
|
|
||||||
if (metadata.optimization?.content_tree_removed) {
|
|
||||||
console.log(`[INFLATION] ✅ Optimization already applied: content_tree removed from metadata`);
|
|
||||||
console.log(`[INFLATION] Original: ${metadata.optimization.original_pages || 0} pages, ${metadata.optimization.original_components || 0} components, ${metadata.optimization.original_layouts || 0} layouts`);
|
|
||||||
console.log(`[INFLATION] Reason: ${metadata.optimization.reason}`);
|
|
||||||
} else {
|
|
||||||
console.log(`[INFLATION] ❌ No optimization detected - consider applying content_tree separation`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log(`[INFLATION] ✅ No significant inflation detected`);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`[INFLATION] Analysis completed`);
|
|
||||||
},
|
|
||||||
|
|
||||||
restoreContentTrees(content: any) {
|
|
||||||
if (!content._contentTrees) return;
|
|
||||||
|
|
||||||
console.log(`[RESTORE] Restoring content_tree data from ${Object.keys(content._contentTrees).length} files...`);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Restore layout content trees
|
|
||||||
if (content._contentTrees['content/layout-content-trees.json']) {
|
|
||||||
const layoutTrees = JSON.parse(content._contentTrees['content/layout-content-trees.json']);
|
|
||||||
let restoredLayouts = 0;
|
|
||||||
for (const layout of content.layouts || []) {
|
|
||||||
if (layoutTrees[layout.id]) {
|
|
||||||
layout.content_tree = layoutTrees[layout.id];
|
|
||||||
restoredLayouts++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(`[RESTORE] ✓ Restored content_tree for ${restoredLayouts} layouts`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore page content trees
|
|
||||||
if (content._contentTrees['content/page-content-trees.json']) {
|
|
||||||
const pageTrees = JSON.parse(content._contentTrees['content/page-content-trees.json']);
|
|
||||||
let restoredPages = 0;
|
|
||||||
for (const page of content.pages || []) {
|
|
||||||
if (pageTrees[page.id]) {
|
|
||||||
page.content_tree = pageTrees[page.id];
|
|
||||||
restoredPages++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(`[RESTORE] ✓ Restored content_tree for ${restoredPages} pages`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore component content trees
|
|
||||||
if (content._contentTrees['content/component-content-trees.json']) {
|
|
||||||
const componentTrees = JSON.parse(content._contentTrees['content/component-content-trees.json']);
|
|
||||||
let restoredComponents = 0;
|
|
||||||
for (const component of content.comps || []) {
|
|
||||||
if (componentTrees[component.id]) {
|
|
||||||
component.content_tree = componentTrees[component.id];
|
|
||||||
restoredComponents++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(`[RESTORE] ✓ Restored content_tree for ${restoredComponents} components`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up temporary storage
|
|
||||||
delete content._contentTrees;
|
|
||||||
|
|
||||||
console.log(`[RESTORE] ✅ Content tree restoration completed`);
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`[RESTORE] ❌ Failed to restore content trees:`, error.message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
has_gz() {
|
has_gz() {
|
||||||
if (this.config.deploy.ts) {
|
if (this.config.deploy.ts) {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue