Files
streamyfin/metro.config.js
2025-09-22 03:22:22 +02:00

238 lines
6.5 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");
const path = require("node:path");
/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);
// =======================================================
// STREAMYFIN METRO CONFIG - PERFORMANCE OPTIMIZED 🚀
// =======================================================
// Advanced configuration for multi-platform Jellyfin client
// Optimized for media streaming, TV support, and Bun
// =======================================================
// HERMES + ADVANCED PERFORMANCE
// ==============================
config.transformer.hermesParser = true;
// CPU optimization (your existing setting)
const os = require("node:os");
config.maxWorkers = Math.max(1, os.cpus().length - 1);
// JAVASCRIPT OPTIMIZATION (Safe & Stable)
// ========================================
config.transformer = {
...config.transformer,
hermesParser: true,
// NEW: Inline requires for 15-30% startup improvement
inlineRequires: true,
// NEW: Minification optimized for streaming apps
minifierConfig: {
// Keep function names in dev for better debugging
keep_fnames: process.env.NODE_ENV === "development",
mangle: {
keep_fnames: process.env.NODE_ENV === "development",
// Optimize for Hermes bytecode
properties: false, // Safer for dynamic property access in streaming
},
// Compress optimized for media apps
compress: {
// Remove console logs in production
drop_console: process.env.NODE_ENV === "production",
// Keep class names for error reporting
keep_classnames: true,
// Preserve function names for performance profiling
keep_fnames: process.env.NODE_ENV === "development",
},
},
};
// RESOLVER OPTIMIZATIONS ENHANCED
// ===============================
config.resolver = {
...config.resolver,
// NEW: Package exports (stable in recent Metro)
unstable_enablePackageExports: true,
// ENHANCED: Extensions optimized for Streamyfin
assetExts: [
...config.resolver.assetExts,
// Video formats (enhanced for Jellyfin)
"mkv",
"mp4",
"avi",
"mov",
"wmv",
"flv",
"webm",
"m4v",
"mpg",
"mpeg",
// Audio formats
"mp3",
"wav",
"flac",
"aac",
"m4a",
"ogg",
"wma",
"opus",
// Subtitle files (complete for media)
"srt",
"vtt",
"ass",
"ssa",
"sub",
"idx",
"sbv",
"ttml",
// Database/Cache
"db",
"sqlite",
"realm",
"json5",
// Fonts (TV optimized)
"woff2",
"woff",
"eot",
"otf",
// Images (enhanced for thumbnails)
"avif",
"heic",
"heif", // Modern formats
],
sourceExts: [
...config.resolver.sourceExts,
"mjs",
"cjs", // Modern JS support
],
// NEW: Platform prioritization for performance
platforms: ["ios", "android", "native", "web", "tv"],
};
// SERIALIZER OPTIMIZATIONS (Production)
// ====================================
if (process.env.NODE_ENV === "production") {
config.serializer = {
...config.serializer,
// NEW: Module IDs optimized for caching
createModuleIdFactory: () => {
return (path) => {
// Shorter module IDs for smaller bundles
return require("node:crypto")
.createHash("sha1")
.update(path)
.digest("hex")
.substring(0, 8);
};
},
// NEW: Bundle pre-loading for streaming apps
getModulesRunBeforeMainModule: (_entryFilePath) => [
// Pre-load critical modules for faster TTI
require.resolve("react-native/Libraries/Core/InitializeCore"),
],
// Web bundle splitting (if applicable)
...(process.env.EXPO_PLATFORM === "web" && {
// Experimental code splitting for web
experimentalSerializerHook: () => {},
}),
};
}
// TV PLATFORM ENHANCEMENTS
// ========================
if (process.env?.EXPO_TV === "1") {
const originalSourceExts = config.resolver.sourceExts;
const tvSourceExts = [
...originalSourceExts.map((ext) => `tv.${ext}`),
...originalSourceExts,
];
config.resolver.sourceExts = tvSourceExts;
// NEW: TV-specific optimizations
config.transformer = {
...config.transformer,
// Optimize transforms for TV hardware
experimentalImportSupport: false, // Reduce complexity on TV
// Use legacy transformer for better TV compatibility
allowOptionalDependencies: true,
};
console.log("📺 TV platform optimized for Streamyfin");
console.log(`📁 TV extensions: ${tvSourceExts.slice(0, 6).join(", ")}...`);
}
// DEVELOPMENT ENHANCEMENTS
// ========================
if (process.env.NODE_ENV === "development") {
// NEW: Enhanced error reporting
config.reporter = {
update: (event) => {
if (event.type === "bundle_build_failed") {
console.error(
"🔴 Streamyfin Bundle Build Failed:",
event.error.message,
);
} else if (event.type === "bundle_build_done") {
console.log(
"✅ Streamyfin Bundle Ready:",
event.bundleDetails?.bundleSize || "Unknown size",
);
}
},
};
console.log("🚀 Streamyfin Metro Config - OPTIMIZED VERSION");
console.log(`📦 Workers: ${config.maxWorkers}`);
console.log(`🎯 Hermes: ${config.transformer.hermesParser}`);
console.log(`⚡ Inline requires: ${config.transformer.inlineRequires}`);
console.log(
`📺 TV support: ${process.env.EXPO_TV === "1" ? "ENABLED" : "DISABLED"}`,
);
}
// STREAMING APP SPECIFIC OPTIMIZATIONS
// ===================================
// NEW: Cache hints for better performance
if (typeof config.cacheStores === "undefined") {
// Only add if not causing issues
try {
const MetroCache = require("metro-cache");
config.cacheStores = [
new MetroCache.FileStore({
root: path.join(os.tmpdir(), "streamyfin-metro-cache"),
}),
];
} catch (_e) {
// Fallback: use default cache
console.log(" Using default Metro cache (custom cache not available)");
}
}
// NEW: Network request optimizations for streaming
config.server = {
...config.server,
// Enhanced request handling for media assets
enhanceMiddleware: (middleware, _server) => {
// Add caching headers for static assets
return (req, res, next) => {
if (req.url?.match(/\.(mp4|mkv|jpg|jpeg|png|webp)$/)) {
res.setHeader("Cache-Control", "public, max-age=31536000");
}
return middleware(req, res, next);
};
},
};
module.exports = config;