@hadyfayed/filament-react-wrapper
Version:
Enterprise React integration for Laravel/Filament - Smart asset loading, 90%+ React-PHP function mapping, no-plugin Filament integration
1,577 lines (1,569 loc) • 69.4 kB
JavaScript
import { a as componentRegistry, u as universalReactRenderer } from './chunks/component-system-Bjje-CZe.js';
export { r as registerComponents } from './chunks/component-system-Bjje-CZe.js';
import { j as jsxRuntimeExports, g as globalStateManager } from './chunks/state-management-CLPmisQN.js';
export { S as StateManagerProvider, u as useStateManager, a as useStatePath, w as withStateManager } from './chunks/state-management-CLPmisQN.js';
import React, { useMemo, useEffect, useState, useCallback, createContext, useContext } from 'react';
class StatePersistenceService {
configs = /* @__PURE__ */ new Map();
debounceTimeouts = /* @__PURE__ */ new Map();
lastValues = /* @__PURE__ */ new Map();
maxMapSize = 1e3;
// Prevent unbounded growth
/**
* Register a state path for persistence
*/
register(config) {
if (this.configs.size >= this.maxMapSize) {
this.cleanupOldEntries();
}
this.configs.set(config.key, {
storage: "localStorage",
syncWithLivewire: false,
debounceMs: 300,
...config
});
this.loadFromStorage(config.key);
}
/**
* Save state value with persistence and sync
*/
async save(key, value) {
const config = this.configs.get(key);
if (!config) {
console.warn(`State persistence config not found for key: ${key}`);
return;
}
const lastValue = this.lastValues.get(key);
if (this.deepEqual(lastValue, value)) {
return;
}
this.lastValues.set(key, this.deepClone(value));
const existingTimeout = this.debounceTimeouts.get(key);
if (existingTimeout) {
clearTimeout(existingTimeout);
}
const timeout = setTimeout(async () => {
await this.performSave(key, value, config);
this.debounceTimeouts.delete(key);
}, config.debounceMs);
this.debounceTimeouts.set(key, timeout);
}
/**
* Load state value from storage
*/
async load(key) {
const config = this.configs.get(key);
if (!config) {
return null;
}
return Promise.resolve(this.loadFromStorage(key));
}
/**
* Clear all timeouts and perform immediate sync
*/
flush() {
this.debounceTimeouts.forEach((timeout, key) => {
clearTimeout(timeout);
const config = this.configs.get(key);
const value = this.lastValues.get(key);
if (config && value !== void 0) {
this.performSave(key, value, config);
}
});
this.debounceTimeouts.clear();
}
/**
* Unregister a state path
*/
unregister(key) {
const timeout = this.debounceTimeouts.get(key);
if (timeout) {
clearTimeout(timeout);
this.debounceTimeouts.delete(key);
}
this.configs.delete(key);
this.lastValues.delete(key);
}
/**
* Get all registered keys
*/
getRegisteredKeys() {
return Array.from(this.configs.keys());
}
/**
* Remove stored data for a key (alias for clear)
*/
async remove(key) {
this.clearSync(key);
}
/**
* Clear all stored data
*/
async clear() {
this.configs.clear();
this.lastValues.clear();
this.debounceTimeouts.forEach((timeout) => clearTimeout(timeout));
this.debounceTimeouts.clear();
if (typeof window !== "undefined") {
localStorage.clear();
sessionStorage.clear();
}
}
/**
* Clear stored data for a specific key
*/
clearSync(key) {
const config = this.configs.get(key);
if (!config) {
return;
}
if (config.storage !== "none") {
const storage = config.storage === "localStorage" ? localStorage : sessionStorage;
storage.removeItem(key);
}
this.lastValues.delete(key);
const timeout = this.debounceTimeouts.get(key);
if (timeout) {
clearTimeout(timeout);
this.debounceTimeouts.delete(key);
}
}
/**
* Perform the actual save operation
*/
async performSave(key, value, config) {
try {
const serializedValue = config.transformer?.serialize ? config.transformer.serialize(value) : value;
if (config.storage !== "none") {
this.saveToStorage(
key,
serializedValue,
config.storage
);
}
if (config.syncWithLivewire && config.livewirePath) {
this.syncWithLivewire(config.livewirePath, serializedValue);
}
console.log(`State persisted for key: ${key}`, serializedValue);
} catch (error) {
console.error(`Error persisting state for key: ${key}`, error);
}
}
/**
* Save to browser storage
*/
saveToStorage(key, value, storageType) {
const storage = storageType === "localStorage" ? localStorage : sessionStorage;
try {
storage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error(`Error saving to ${storageType}:`, error);
}
}
/**
* Load from browser storage
*/
loadFromStorage(key) {
const config = this.configs.get(key);
if (!config || config.storage === "none") {
return null;
}
const storage = config.storage === "localStorage" ? localStorage : sessionStorage;
try {
const stored = storage.getItem(key);
if (stored) {
const parsed = JSON.parse(stored);
const value = config.transformer?.deserialize ? config.transformer.deserialize(parsed) : parsed;
this.lastValues.set(key, this.deepClone(value));
return value;
}
} catch (error) {
console.error(`Error loading from ${config.storage}:`, error);
}
return null;
}
/**
* Sync with Livewire component
*/
syncWithLivewire(livewirePath, value) {
if (window.workflowDataSync) {
window.workflowDataSync(livewirePath, value);
} else {
console.warn("workflowDataSync not available for Livewire sync");
}
}
/**
* Deep equality check
*/
deepEqual(a, b) {
if (a === b) return true;
if (a == null || b == null) return a === b;
if (typeof a !== typeof b) return false;
if (typeof a === "object") {
if (Array.isArray(a) !== Array.isArray(b)) return false;
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (keysA.length !== keysB.length) return false;
for (const key of keysA) {
if (!keysB.includes(key) || !this.deepEqual(a[key], b[key])) {
return false;
}
}
return true;
}
return false;
}
/**
* Deep clone object
*/
deepClone(obj) {
if (obj === null || typeof obj !== "object") return obj;
if (obj instanceof Date) return new Date(obj);
if (Array.isArray(obj)) return obj.map((item) => this.deepClone(item));
const cloned = {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
cloned[key] = this.deepClone(obj[key]);
}
}
return cloned;
}
/**
* Clean up old entries to prevent memory leaks
*/
cleanupOldEntries() {
const keysToRemove = [];
this.configs.forEach((_config, key) => {
if (!this.debounceTimeouts.has(key)) {
keysToRemove.push(key);
}
});
keysToRemove.slice(0, 100).forEach((key) => {
this.configs.delete(key);
this.lastValues.delete(key);
});
if (this.configs.size >= this.maxMapSize) {
const allKeys = Array.from(this.configs.keys());
allKeys.slice(0, 100).forEach((key) => {
this.unregister(key);
});
}
}
}
const statePersistenceService = new StatePersistenceService();
if (typeof window !== "undefined") {
window.addEventListener("beforeunload", () => {
statePersistenceService.flush();
});
window.statePersistenceService = statePersistenceService;
}
function usePersistedState(key, defaultValue, config) {
const fullConfig = useMemo(
() => ({
key,
storage: "localStorage",
syncWithLivewire: false,
debounceMs: 300,
...config
}),
[key, config]
);
useEffect(() => {
statePersistenceService.register(fullConfig);
return () => statePersistenceService.unregister(key);
}, [key, fullConfig]);
const initialValue = useMemo(() => {
return defaultValue ?? {};
}, [defaultValue]);
const [value, setValue] = useState(() => initialValue);
useEffect(() => {
let mounted = true;
const loadPersistedValue = async () => {
try {
const loaded = await statePersistenceService.load(key);
if (mounted && loaded !== null) {
setValue(loaded);
}
} catch (error) {
console.error("Error loading persisted state:", error);
}
};
loadPersistedValue();
return () => {
mounted = false;
};
}, [key]);
const setter = useCallback(
(newValue) => {
setValue((prevValue) => {
const finalValue = typeof newValue === "function" ? newValue(prevValue) : newValue;
statePersistenceService.save(key, finalValue).catch((error) => {
console.error("Error persisting state:", error);
});
return finalValue;
});
},
[key]
);
return [value, setter];
}
class DevTools {
_isEnabled = false;
components = /* @__PURE__ */ new Map();
performanceMetrics = [];
stateHistory = [];
maxHistorySize = 1e3;
observers = /* @__PURE__ */ new Set();
constructor() {
this._isEnabled = this.shouldEnable();
if (this._isEnabled) {
this.initializeDevTools();
}
}
shouldEnable() {
return typeof window !== "undefined" && (typeof process !== "undefined" && process.env?.NODE_ENV === "development" || window.location.hostname === "localhost" || window.location.search.includes("react-wrapper-debug=true") || localStorage.getItem("react-wrapper-debug") === "true");
}
initializeDevTools() {
if (typeof window !== "undefined") {
window.__REACT_WRAPPER_DEV_TOOLS__ = this;
}
console.log(
"%c[React Wrapper] Dev Tools Enabled",
"color: #4F46E5; font-weight: bold; font-size: 12px;"
);
this.setupKeyboardShortcuts();
this.setupPerformanceObserver();
}
setupKeyboardShortcuts() {
if (typeof window === "undefined") return;
window.addEventListener("keydown", (event) => {
if (event.ctrlKey && event.shiftKey && event.key === "W") {
event.preventDefault();
this.showDebugPanel();
}
if (event.ctrlKey && event.shiftKey && event.key === "C") {
event.preventDefault();
this.logComponentInfo();
}
if (event.ctrlKey && event.shiftKey && event.key === "S") {
event.preventDefault();
this.logStateInfo();
}
});
}
setupPerformanceObserver() {
if (typeof window === "undefined" || !window.PerformanceObserver) return;
try {
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.name.startsWith("react-wrapper-")) {
this.recordPerformanceMetric({
componentName: entry.name.replace("react-wrapper-", ""),
mountTime: entry.startTime,
renderTime: entry.duration,
propsChanges: 0
// Will be updated separately
});
}
}
});
observer.observe({ entryTypes: ["measure"] });
} catch (error) {
console.warn("[React Wrapper] Performance observer not available:", error);
}
}
// Component tracking methods
trackComponentMount(name, props) {
if (!this._isEnabled) return;
const info = {
name,
props: { ...props },
mountTime: Date.now(),
renderCount: 1,
lastRenderTime: Date.now(),
errors: [],
warnings: []
};
this.components.set(name, info);
this.notifyObservers({
type: "component:mounted",
data: { name, props }
});
this.log(`Component mounted: ${name}`, props);
}
trackComponentRender(name, props) {
if (!this._isEnabled) return;
const info = this.components.get(name);
if (info) {
info.renderCount++;
info.lastRenderTime = Date.now();
info.props = { ...props };
}
this.notifyObservers({
type: "component:rendered",
data: { name, props, renderCount: info?.renderCount }
});
}
trackComponentUnmount(name) {
if (!this._isEnabled) return;
this.notifyObservers({
type: "component:unmounted",
data: { name }
});
this.log(`Component unmounted: ${name}`);
}
trackComponentError(name, error) {
if (!this._isEnabled) return;
const info = this.components.get(name);
if (info) {
info.errors.push(error);
}
this.notifyObservers({
type: "component:error",
data: { name, error }
});
this.error(`Component error in ${name}:`, error);
}
trackComponentWarning(name, warning) {
if (!this._isEnabled) return;
const info = this.components.get(name);
if (info) {
info.warnings.push(warning);
}
this.notifyObservers({
type: "component:warning",
data: { name, warning }
});
this.warn(`Component warning in ${name}:`, warning);
}
// State tracking methods
trackStateChange(path, oldValue, newValue, source = "unknown") {
if (!this._isEnabled) return;
const change = {
path,
oldValue,
newValue,
timestamp: Date.now(),
source
};
this.stateHistory.push(change);
if (this.stateHistory.length > this.maxHistorySize) {
this.stateHistory.shift();
}
this.notifyObservers({
type: "state:changed",
data: change
});
this.log(`State changed: ${path}`, { oldValue, newValue, source });
}
// Performance tracking methods
recordPerformanceMetric(metric) {
if (!this._isEnabled) return;
this.performanceMetrics.push(metric);
if (this.performanceMetrics.length > this.maxHistorySize) {
this.performanceMetrics.shift();
}
this.notifyObservers({
type: "performance:metric",
data: metric
});
if (metric.renderTime > 50) {
this.warn(`Slow render detected for ${metric.componentName}: ${metric.renderTime}ms`);
}
}
startPerformanceMeasure(name) {
if (!this.isEnabled || typeof performance === "undefined") return;
performance.mark(`react-wrapper-${name}-start`);
}
endPerformanceMeasure(name) {
if (!this.isEnabled || typeof performance === "undefined") return;
try {
performance.mark(`react-wrapper-${name}-end`);
performance.measure(
`react-wrapper-${name}`,
`react-wrapper-${name}-start`,
`react-wrapper-${name}-end`
);
} catch (error) {
this.warn("Performance measurement failed:", error);
}
}
// Information retrieval methods
getComponentInfo(name) {
if (!this.isEnabled) return void 0;
if (name) {
return this.components.get(name);
}
return Array.from(this.components.values());
}
getPerformanceMetrics(componentName) {
if (!this.isEnabled) return [];
if (componentName) {
return this.performanceMetrics.filter((m) => m.componentName === componentName);
}
return [...this.performanceMetrics];
}
getStateHistory(path) {
if (!this.isEnabled) return [];
if (path) {
return this.stateHistory.filter((change) => change.path.startsWith(path));
}
return [...this.stateHistory];
}
// Debug panel methods
showDebugPanel() {
if (!this._isEnabled) return;
const panel = this.createDebugPanel();
document.body.appendChild(panel);
}
createDebugPanel() {
const panel = document.createElement("div");
panel.id = "react-wrapper-debug-panel";
panel.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
width: 400px;
max-height: 600px;
background: white;
border: 2px solid #4F46E5;
border-radius: 8px;
box-shadow: 0 10px 25px rgba(0,0,0,0.1);
z-index: 10000;
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', monospace;
font-size: 12px;
overflow: hidden;
`;
const header = document.createElement("div");
header.style.cssText = `
background: #4F46E5;
color: white;
padding: 10px;
font-weight: bold;
display: flex;
justify-content: space-between;
align-items: center;
`;
header.innerHTML = `
<span>React Wrapper Dev Tools</span>
<button onclick="this.parentElement.parentElement.remove()" style="background: none; border: none; color: white; cursor: pointer; font-size: 16px;">×</button>
`;
const content = document.createElement("div");
content.style.cssText = "padding: 10px; max-height: 550px; overflow-y: auto;";
content.innerHTML = `
<div>
<h3>Components (${this.components.size})</h3>
${Array.from(this.components.entries()).map(([name, info]) => `
<div style="margin-bottom: 10px; padding: 8px; background: #f8f9fa; border-radius: 4px;">
<strong>${name}</strong><br>
Renders: ${info.renderCount}<br>
Errors: ${info.errors.length}<br>
Warnings: ${info.warnings.length}
</div>
`).join("")}
</div>
<div style="margin-top: 20px;">
<h3>Recent State Changes (${this.stateHistory.slice(-5).length})</h3>
${this.stateHistory.slice(-5).reverse().map((change) => `
<div style="margin-bottom: 8px; padding: 6px; background: #fff3cd; border-radius: 4px; font-size: 11px;">
<strong>${change.path}</strong><br>
${new Date(change.timestamp).toLocaleTimeString()}<br>
Source: ${change.source}
</div>
`).join("")}
</div>
<div style="margin-top: 20px;">
<h3>Performance</h3>
<div style="padding: 8px; background: #d1ecf1; border-radius: 4px;">
Components: ${this.components.size}<br>
Avg Render Time: ${this.getAverageRenderTime()}ms<br>
Slow Renders: ${this.getSlowRenderCount()}
</div>
</div>
`;
panel.appendChild(header);
panel.appendChild(content);
return panel;
}
getAverageRenderTime() {
if (this.performanceMetrics.length === 0) return "0";
const total = this.performanceMetrics.reduce((sum, metric) => sum + metric.renderTime, 0);
return (total / this.performanceMetrics.length).toFixed(2);
}
getSlowRenderCount() {
return this.performanceMetrics.filter((metric) => metric.renderTime > 50).length;
}
// Logging methods
logComponentInfo() {
if (!this._isEnabled) return;
console.group("%c[React Wrapper] Component Info", "color: #059669; font-weight: bold;");
this.components.forEach((info, name) => {
console.log(`${name}:`, info);
});
console.groupEnd();
}
logStateInfo() {
if (!this._isEnabled) return;
console.group("%c[React Wrapper] State History", "color: #DC2626; font-weight: bold;");
this.stateHistory.slice(-10).forEach((change) => {
console.log(`${change.path}:`, change);
});
console.groupEnd();
}
logPerformanceInfo() {
if (!this._isEnabled) return;
console.group("%c[React Wrapper] Performance Metrics", "color: #7C2D12; font-weight: bold;");
console.table(this.performanceMetrics.slice(-20));
console.groupEnd();
}
// Make logging methods public so they can be used by other services
log(message, data) {
if (data !== void 0) {
console.log(`%c[React Wrapper] ${message}`, "color: #4F46E5;", data);
} else {
console.log(`%c[React Wrapper] ${message}`, "color: #4F46E5;");
}
}
warn(message, ...args) {
console.warn(`%c[React Wrapper] ${message}`, "color: #D97706;", ...args);
}
error(message, ...args) {
console.error(`%c[React Wrapper] ${message}`, "color: #DC2626;", ...args);
}
// Observer pattern for external tools
subscribe(callback) {
this.observers.add(callback);
return () => this.observers.delete(callback);
}
notifyObservers(event) {
this.observers.forEach((callback) => {
try {
callback(event);
} catch (error) {
console.error("[React Wrapper] Observer error:", error);
}
});
}
// Public API methods
enable() {
this._isEnabled = true;
localStorage.setItem("react-wrapper-debug", "true");
this.initializeDevTools();
}
disable() {
this._isEnabled = false;
localStorage.removeItem("react-wrapper-debug");
const panel = document.getElementById("react-wrapper-debug-panel");
if (panel) {
panel.remove();
}
}
isEnabled() {
return this._isEnabled;
}
clear() {
this.components.clear();
this.performanceMetrics.length = 0;
this.stateHistory.length = 0;
}
// Memory usage tracking (if available)
getMemoryUsage() {
if (typeof performance !== "undefined" && performance.memory) {
return performance.memory.usedJSHeapSize;
}
return void 0;
}
}
const devTools = new DevTools();
class CodeSplittingService {
chunks = /* @__PURE__ */ new Map();
strategies = [];
prefetchRules = [];
cache = /* @__PURE__ */ new Map();
loadingQueue = /* @__PURE__ */ new Map();
maxCacheSize = 100;
maxConcurrentLoads = 3;
currentLoads = 0;
constructor() {
this.initializeDefaultStrategies();
this.setupIdleCallback();
this.setupIntersectionObserver();
}
/**
* Register a custom code splitting strategy
*/
registerStrategy(strategy) {
this.strategies.push(strategy);
devTools.log(`Code splitting strategy registered: ${strategy.name}`);
}
/**
* Add prefetch rules for predictive loading
*/
addPrefetchRule(rule) {
this.prefetchRules.push(rule);
devTools.log(`Prefetch rule added for trigger: ${rule.trigger}`);
}
/**
* Smart component loading with strategy selection
*/
async loadComponent(componentName, metadata = {}, forceStrategy) {
const startTime = performance.now();
try {
const cached = this.cache.get(componentName);
if (cached) {
this.updateChunkStats(componentName, 0, true);
return await cached;
}
const strategy = forceStrategy ? this.strategies.find((s) => s.name === forceStrategy) : this.selectStrategy(componentName, metadata);
if (!strategy) {
throw new Error(`No suitable strategy found for component: ${componentName}`);
}
const loadPromise = this.executeStrategy(strategy, componentName, metadata);
this.cache.set(componentName, loadPromise);
this.manageCacheSize();
this.executePrefetchRules(componentName);
const result = await loadPromise;
const loadTime = performance.now() - startTime;
this.updateChunkStats(componentName, loadTime, false);
return result;
} catch (error) {
this.cache.delete(componentName);
devTools.trackComponentError(componentName, error);
throw error;
}
}
/**
* Preload components based on priority
*/
preloadComponents(components, priority = 2 /* HIGH */) {
if (!this.loadingQueue.has(priority)) {
this.loadingQueue.set(priority, /* @__PURE__ */ new Set());
}
const queue = this.loadingQueue.get(priority);
components.forEach((component) => {
if (!this.cache.has(component)) {
queue.add(component);
}
});
this.processLoadingQueue();
}
/**
* Get bundle analysis and recommendations
*/
analyzeBundles() {
const chunks = Array.from(this.chunks.values());
const totalSize = chunks.reduce((sum, chunk) => sum + chunk.size, 0);
const totalLoadTime = chunks.reduce((sum, chunk) => sum + chunk.loadTime, 0);
const cacheHits = chunks.filter((chunk) => chunk.hitCount > 1).length;
return {
totalChunks: chunks.length,
totalSize,
averageLoadTime: chunks.length > 0 ? totalLoadTime / chunks.length : 0,
cacheHitRate: chunks.length > 0 ? cacheHits / chunks.length : 0,
mostUsedChunks: chunks.sort((a, b) => b.hitCount - a.hitCount).slice(0, 5),
leastUsedChunks: chunks.sort((a, b) => a.hitCount - b.hitCount).slice(0, 5),
recommendations: this.generateRecommendations(chunks)
};
}
/**
* Clear cache and reset statistics
*/
clearCache() {
this.cache.clear();
this.chunks.clear();
this.loadingQueue.clear();
devTools.log("Code splitting cache cleared");
}
/**
* Get chunk information
*/
getChunkInfo(componentName) {
if (componentName) {
return this.chunks.get(componentName) || null;
}
return Array.from(this.chunks.values());
}
initializeDefaultStrategies() {
this.registerStrategy({
name: "route-based",
condition: (componentName, metadata) => metadata?.category === "page" || componentName.toLowerCase().includes("page"),
chunkName: (componentName) => `route-${componentName.toLowerCase()}`,
priority: 2 /* HIGH */
});
this.registerStrategy({
name: "feature-based",
condition: (componentName, metadata) => metadata?.category === "feature" || this.isFeatureComponent(componentName),
chunkName: (componentName) => `feature-${this.extractFeatureName(componentName)}`,
priority: 3 /* MEDIUM */
});
this.registerStrategy({
name: "vendor-based",
condition: (componentName, metadata) => metadata?.external || this.isVendorComponent(componentName),
chunkName: (componentName) => `vendor-${this.extractVendorName(componentName)}`,
priority: 4 /* LOW */
});
this.registerStrategy({
name: "size-based",
condition: (componentName, metadata) => metadata?.size === "large" || this.isLargeComponent(componentName),
chunkName: (componentName) => `large-${componentName.toLowerCase()}`,
priority: 5 /* BACKGROUND */
});
this.registerStrategy({
name: "critical-path",
condition: (componentName, metadata) => metadata?.critical || this.isCriticalComponent(componentName),
chunkName: (componentName) => `critical-${componentName.toLowerCase()}`,
priority: 1 /* CRITICAL */,
preload: true
});
this.registerStrategy({
name: "default",
condition: () => true,
// Always matches
chunkName: (componentName) => `component-${componentName.toLowerCase()}`,
priority: 3 /* MEDIUM */
});
}
selectStrategy(componentName, metadata) {
return this.strategies.find(
(strategy) => strategy.condition(componentName, metadata)
);
}
async executeStrategy(strategy, componentName, _metadata) {
const chunkName = strategy.chunkName(componentName);
devTools.startPerformanceMeasure(`chunk-load-${chunkName}`);
try {
const module = await import(
/* webpackChunkName: "[request]" */
/* webpackMode: "lazy" */
`@/components/${componentName}`
);
devTools.endPerformanceMeasure(`chunk-load-${chunkName}`);
return module.default || module;
} catch (error) {
devTools.endPerformanceMeasure(`chunk-load-${chunkName}`);
throw new Error(`Failed to load component ${componentName}: ${error}`);
}
}
executePrefetchRules(triggerComponent) {
const matchingRules = this.prefetchRules.filter(
(rule) => rule.trigger === triggerComponent || new RegExp(rule.trigger).test(triggerComponent)
);
matchingRules.forEach((rule) => {
const shouldPrefetch = !rule.condition || rule.condition();
if (shouldPrefetch) {
const delay = rule.delay || 0;
setTimeout(() => {
this.preloadComponents(rule.prefetch, 2 /* HIGH */);
}, delay);
}
});
}
processLoadingQueue() {
if (this.currentLoads >= this.maxConcurrentLoads) {
return;
}
const priorities = [
1 /* CRITICAL */,
2 /* HIGH */,
3 /* MEDIUM */,
4 /* LOW */,
5 /* BACKGROUND */
];
for (const priority of priorities) {
const queue = this.loadingQueue.get(priority);
if (queue && queue.size > 0) {
const component = queue.values().next().value;
if (component) {
queue.delete(component);
this.currentLoads++;
this.loadComponent(component).finally(() => {
this.currentLoads--;
this.processLoadingQueue();
});
}
if (this.currentLoads >= this.maxConcurrentLoads) {
break;
}
}
}
}
updateChunkStats(componentName, loadTime, cacheHit) {
let chunk = this.chunks.get(componentName);
if (!chunk) {
chunk = {
id: componentName,
name: componentName,
size: 0,
// Would need to be calculated from actual bundle
loadTime,
dependencies: [],
priority: 3 /* MEDIUM */,
lastAccessed: Date.now(),
hitCount: 0
};
this.chunks.set(componentName, chunk);
}
chunk.lastAccessed = Date.now();
chunk.hitCount++;
if (!cacheHit) {
chunk.loadTime = (chunk.loadTime + loadTime) / 2;
}
}
manageCacheSize() {
if (this.cache.size <= this.maxCacheSize) {
return;
}
const chunks = Array.from(this.chunks.values()).sort((a, b) => a.lastAccessed - b.lastAccessed);
const toRemove = chunks.slice(0, this.cache.size - this.maxCacheSize);
toRemove.forEach((chunk) => {
this.cache.delete(chunk.id);
this.chunks.delete(chunk.id);
});
}
setupIdleCallback() {
if (typeof window === "undefined" || !window.requestIdleCallback) {
return;
}
const processIdleTasks = (deadline) => {
while (deadline.timeRemaining() > 0) {
const queue = this.loadingQueue.get(5 /* BACKGROUND */);
if (queue && queue.size > 0) {
const component = queue.values().next().value;
if (component) {
queue.delete(component);
this.loadComponent(component);
} else {
break;
}
} else {
break;
}
}
window.requestIdleCallback(processIdleTasks);
};
window.requestIdleCallback(processIdleTasks);
}
setupIntersectionObserver() {
if (typeof window === "undefined" || !window.IntersectionObserver) {
return;
}
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const componentName = entry.target.getAttribute("data-react-component");
if (componentName && !this.cache.has(componentName)) {
this.preloadComponents([componentName], 2 /* HIGH */);
}
}
});
},
{
rootMargin: "100px",
// Start loading when component is 100px away from viewport
threshold: 0.1
}
);
const containers = document.querySelectorAll("[data-react-component]");
containers.forEach((container) => observer.observe(container));
}
generateRecommendations(chunks) {
const recommendations = [];
const smallFrequentChunks = chunks.filter(
(chunk) => chunk.size < 1e4 && chunk.hitCount > 10
);
if (smallFrequentChunks.length > 1) {
recommendations.push({
type: "merge",
chunks: smallFrequentChunks.map((c) => c.name),
reason: "Small, frequently accessed chunks should be merged to reduce HTTP overhead",
estimatedSavings: smallFrequentChunks.length * 50
// Estimated ms saved
});
}
const largeChunks = chunks.filter((chunk) => chunk.size > 1e5);
largeChunks.forEach((chunk) => {
recommendations.push({
type: "split",
chunks: [chunk.name],
reason: "Large chunk should be split for better loading performance",
estimatedSavings: chunk.loadTime * 0.3
});
});
const criticalChunks = chunks.filter(
(chunk) => chunk.priority === 1 /* CRITICAL */ && chunk.hitCount > 5
);
if (criticalChunks.length > 0) {
recommendations.push({
type: "preload",
chunks: criticalChunks.map((c) => c.name),
reason: "Critical chunks with high usage should be preloaded",
estimatedSavings: criticalChunks.reduce((sum, chunk) => sum + chunk.loadTime, 0)
});
}
const unusedChunks = chunks.filter(
(chunk) => chunk.hitCount === 0 && Date.now() - chunk.lastAccessed > 864e5
// 24 hours
);
if (unusedChunks.length > 0) {
recommendations.push({
type: "remove",
chunks: unusedChunks.map((c) => c.name),
reason: "Unused chunks should be removed to reduce bundle size",
estimatedSavings: unusedChunks.reduce((sum, chunk) => sum + chunk.size, 0) / 1e3
// KB saved
});
}
return recommendations;
}
// Helper methods for component classification
isFeatureComponent(componentName) {
const featureKeywords = ["dashboard", "profile", "settings", "admin", "analytics"];
return featureKeywords.some(
(keyword) => componentName.toLowerCase().includes(keyword)
);
}
extractFeatureName(componentName) {
const featureKeywords = ["dashboard", "profile", "settings", "admin", "analytics"];
const feature = featureKeywords.find(
(keyword) => componentName.toLowerCase().includes(keyword)
);
return feature || "general";
}
isVendorComponent(componentName) {
const vendorKeywords = ["chart", "calendar", "editor", "map", "payment"];
return vendorKeywords.some(
(keyword) => componentName.toLowerCase().includes(keyword)
);
}
extractVendorName(componentName) {
const vendorKeywords = ["chart", "calendar", "editor", "map", "payment"];
const vendor = vendorKeywords.find(
(keyword) => componentName.toLowerCase().includes(keyword)
);
return vendor || "external";
}
isLargeComponent(componentName) {
const largeKeywords = ["grid", "table", "canvas", "visualization", "complex"];
return largeKeywords.some(
(keyword) => componentName.toLowerCase().includes(keyword)
);
}
isCriticalComponent(componentName) {
const criticalKeywords = ["header", "navigation", "layout", "auth", "error"];
return criticalKeywords.some(
(keyword) => componentName.toLowerCase().includes(keyword)
);
}
/**
* Preload component for better performance
*/
async preloadComponent(componentName) {
try {
await this.loadComponent(componentName);
} catch (error) {
console.error(`Failed to preload component ${componentName}:`, error);
}
}
/**
* Check if component is loaded
*/
isLoaded(componentName) {
return this.cache.has(componentName);
}
}
const codeSplittingService = new CodeSplittingService();
class ComponentVersioningService {
versions = /* @__PURE__ */ new Map();
aliases = /* @__PURE__ */ new Map();
// component@alias -> component@version
migrations = /* @__PURE__ */ new Map();
defaultVersions = /* @__PURE__ */ new Map();
compatibilityRules = /* @__PURE__ */ new Map();
constructor() {
this.setupDefaultAliases();
}
/**
* Register a new component version
*/
registerVersion(componentName, version, component, metadata = {}) {
if (!this.versions.has(componentName)) {
this.versions.set(componentName, /* @__PURE__ */ new Map());
}
const componentVersions = this.versions.get(componentName);
const fullMetadata = {
name: componentName,
description: metadata.description || "",
author: metadata.author || "Unknown",
createdAt: metadata.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
changelog: metadata.changelog || [],
tags: metadata.tags || [],
category: metadata.category || "general",
apiVersion: metadata.apiVersion || "1.0.0"
};
const componentVersion = {
version,
component,
metadata: fullMetadata,
deprecated: false,
dependencies: metadata.dependencies || []
};
componentVersions.set(version, componentVersion);
if (!this.defaultVersions.has(componentName) || version === "latest") {
this.defaultVersions.set(componentName, version);
}
devTools.log(`Component version registered: ${componentName}@${version}`);
}
/**
* Get version string for a component
*/
getVersion(componentName) {
return this.defaultVersions.get(componentName);
}
/**
* Get a specific component version object
*/
getComponentVersion(componentName, version) {
const componentVersions = this.versions.get(componentName);
if (!componentVersions) {
return null;
}
const resolvedVersion = this.resolveVersion(componentName, version);
if (!resolvedVersion) {
return null;
}
return componentVersions.get(resolvedVersion) || null;
}
/**
* Get all versions of a component
*/
getAllVersions(componentName) {
const componentVersions = this.versions.get(componentName);
if (!componentVersions) {
return [];
}
return Array.from(componentVersions.values()).sort((a, b) => this.compareVersions(b.version, a.version));
}
/**
* Get latest version of a component
*/
getLatestVersion(componentName) {
const versions = this.getAllVersions(componentName);
return versions.length > 0 ? versions[0] || null : null;
}
/**
* Check if component version exists
*/
hasVersion(componentName, version) {
return this.getComponentVersion(componentName, version) !== null;
}
/**
* Register version alias
*/
registerAlias(componentName, alias, version) {
const key = `${componentName}@${alias}`;
this.aliases.set(key, `${componentName}@${version}`);
devTools.log(`Version alias registered: ${key} -> ${componentName}@${version}`);
}
/**
* Deprecate a component version
*/
deprecateVersion(componentName, version, message, migrationPath) {
const componentVersion = this.getComponentVersion(componentName, version);
if (componentVersion) {
componentVersion.deprecated = true;
componentVersion.deprecationMessage = message;
componentVersion.migrationPath = migrationPath;
devTools.warn(`Component version deprecated: ${componentName}@${version}`, {
message,
migrationPath
});
}
}
/**
* Add migration function between versions
*/
addMigration(componentName, fromVersion, toVersion, migrationFn) {
const key = `${componentName}:${fromVersion}->${toVersion}`;
if (!this.migrations.has(key)) {
this.migrations.set(key, []);
}
this.migrations.get(key).push(migrationFn);
devTools.log(`Migration registered: ${key}`);
}
/**
* Migrate props from one version to another
*/
async migrateProps(componentName, fromVersion, toVersion, props) {
const result = {
success: false,
fromVersion,
toVersion,
migratedProps: { ...props },
warnings: [],
errors: [],
manualStepsRequired: false
};
try {
const migrationPath = this.findMigrationPath(componentName, fromVersion, toVersion);
if (migrationPath.length === 0) {
result.errors.push(`No migration path found from ${fromVersion} to ${toVersion}`);
return result;
}
let currentProps = { ...props };
for (const step of migrationPath) {
const migrations = this.migrations.get(step) || [];
for (const migration of migrations) {
try {
const [fromPart, toPart] = step.split("->");
const fromVersion2 = fromPart?.split(":")[1];
const toVersion2 = toPart;
if (!fromVersion2 || !toVersion2) {
result.errors.push(`Invalid migration step format: ${step}`);
return result;
}
const migrationResult = await migration(currentProps, {
componentName,
fromVersion: fromVersion2,
toVersion: toVersion2
});
currentProps = migrationResult.props;
result.warnings.push(...migrationResult.warnings || []);
if (migrationResult.manualStepsRequired) {
result.manualStepsRequired = true;
}
} catch (error) {
result.errors.push(`Migration failed at step ${step}: ${error}`);
return result;
}
}
}
result.migratedProps = currentProps;
result.success = result.errors.length === 0;
return result;
} catch (error) {
result.errors.push(`Migration error: ${error}`);
return result;
}
}
/**
* Check compatibility between versions
*/
checkCompatibility(componentName, fromVersion, toVersion) {
const result = {
compatible: true,
issues: [],
recommendations: [],
autoMigrationAvailable: false
};
const fromVersionObj = this.getComponentVersion(componentName, fromVersion);
const toVersionObj = this.getComponentVersion(componentName, toVersion);
if (!fromVersionObj || !toVersionObj) {
result.compatible = false;
result.issues.push({
severity: "error",
type: "version_not_found",
description: "One or both versions not found"
});
return result;
}
if (toVersionObj.breakingChanges) {
for (const change of toVersionObj.breakingChanges) {
result.issues.push({
severity: "warning",
type: "breaking_change",
description: change.description,
affectedProps: change.affectedProps,
solution: change.migration
});
}
}
const migrationPath = this.findMigrationPath(componentName, fromVersion, toVersion);
result.autoMigrationAvailable = migrationPath.length > 0;
if (!result.autoMigrationAvailable && result.issues.length > 0) {
result.compatible = false;
result.recommendations.push("Manual migration required due to breaking changes");
}
const rules = this.compatibilityRules.get(componentName) || [];
for (const rule of rules) {
const ruleResult = rule(fromVersionObj, toVersionObj);
if (ruleResult) {
result.issues.push(...ruleResult.issues);
result.recommendations.push(...ruleResult.recommendations);
if (ruleResult.issues.some((issue) => issue.severity === "error")) {
result.compatible = false;
}
}
}
return result;
}
/**
* Get version constraints satisfaction
*/
satisfiesConstraint(version, constraint) {
if (constraint.exact) {
return version === constraint.exact;
}
if (constraint.exclude && constraint.exclude.includes(version)) {
return false;
}
if (constraint.min && this.compareVersions(version, constraint.min) < 0) {
return false;
}
if (constraint.max && this.compareVersions(version, constraint.max) > 0) {
return false;
}
return true;
}
/**
* Find best matching version for constraint
*/
findBestVersion(componentName, constraint) {
const versions = this.getAllVersions(componentName);
for (const versionObj of versions) {
if (this.satisfiesConstraint(versionObj.version, constraint)) {
return versionObj.version;
}
}
return null;
}
/**
* Add compatibility rule
*/
addCompatibilityRule(componentName, rule) {
if (!this.compatibilityRules.has(componentName)) {
this.compatibilityRules.set(componentName, []);
}
this.compatibilityRules.get(componentName).push(rule);
}
/**
* Get component changelog
*/
getChangelog(componentName) {
const versions = this.getAllVersions(componentName);
const changelog = [];
for (const version of versions) {
changelog.push(...version.metadata.changelog);
}
return changelog.sort(
(a, b) => this.compareVersions(b.version, a.version)
);
}
/**
* Get version statistics
*/
getVersionStats(componentName) {
if (componentName) {
const versions = this.getAllVersions(componentName);
return {
componentName,
totalVersions: versions.length,
latestVersion: versions[0]?.version,
deprecatedVersions: versions.filter((v) => v.deprecated).length,
hasBreakingChanges: versions.some((v) => v.breakingChanges && v.breakingChanges.length > 0),
dependencies: versions[0]?.dependencies || []
};
}
const allComponents = Array.from(this.versions.keys());
return {
totalComponents: allComponents.length,
totalVersions: allComponents.reduce(
(sum, name) => sum + this.getAllVersions(name).length,
0
),
componentsWithMultipleVersions: allComponents.filter(
(name) => this.getAllVersions(name).length > 1
),
deprecatedVersions: allComponents.reduce(
(sum, name) => sum + this.getAllVersions(name).filter((v) => v.deprecated).length,
0
)
};
}
resolveVersion(componentName, version) {
if (!version || version === "latest") {
return this.defaultVersions.get(componentName) || null;
}
const aliasKey = `${componentName}@${version}`;
const aliasTarget = this.aliases.get(aliasKey);
if (aliasTarget) {
return aliasTarget.split("@")[1] || null;
}
return version;
}
compareVersions(a, b) {
const aParts = a.split(".").map(Number);
const bParts = b.split(".").map(Number);
for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
const aPart = aParts[i] || 0;
const bPart = bParts[i] || 0;
if (aPart !== bPart) {
return aPart - bPart;
}
}
return 0;
}
findMigrationPath(componentName, fromVersion, toVersion) {
const directPath = `${componentName}:${fromVersion}->${toVersion}`;
if (this.migrations.has(directPath)) {
return [directPath];
}
return [];
}
setupDefaultAliases() {
this.registerAlias("*", "stable", "latest");
this.registerAlias("*", "beta", "latest");
}
/**
* Set version for a component
*/
setVersion(componentName, version) {
this.defaultVersions.set(componentName, version);
}
/**
* Check if component version is compatible
*/
isCompatible(componentName, requiredVersion) {
const currentVersion = this.getVersion(componentName);
if (!currentVersion) {
return false;
}
const current = currentVersion.split(".").map(Number);
const required = requiredVersion.split(".").map(Number);
if (current[0] !== required[0]) {
return false;
}
if ((current[1] || 0) < (required[1] || 0)) {
return false;
}
if (current[1] === required[1] && (current[2] || 0) < (required[2] || 0)) {
return false;
}
return true;
}
}
const componentVersioningService = new ComponentVersioningService();
class ContextStateManager {
state = {};
subscribers = /* @__PURE__ */ new Map();
persistence;
namespace;
constructor(config) {
this.persistence = config.persistence;
this.namespace = config.namespace || "filament-react-state";
if (this.persistence) {
this.loadPersistedState();
}
}
setState(path, value) {
const keys = path.split(".");
let current = this.state;
for (let i = 0; i < keys.length - 1; i++) {
const key = keys[i];
if (key && !(key in current)) {
current[key] = {};
}
if (key) {
current = current[key];
}
}
const lastKey = keys[keys.length - 1];
if (lastKey) {
current[lastKey] = value;
}
if (this.persistence) {
this.persistState();
}
this.notifySubscribers(path, value);
}
getState(path) {
const keys = path.split(".");
let current = this.state;
for (const key of keys) {
if (current && typeof current === "object" && key && key in current) {
current = current[key];
} else {
return void 0;
}
}
return current;
}
subscribe(path, callback) {
if (!this.subscribers.has(path)) {
this.subscribers.set(path, /* @__PURE__ */ new Set());
}
this.subscribers.get(path).add(callback);
return () => {
const pathSubscribers = this.subscribers.get(path);
if (pathSubscribers) {
pathSubscribers.delete(callback);
if (pathSubscribers.size === 0) {
this.subscribers.delete(path);
}
}
};
}
reset() {
this.state = {};
if (this.persistence) {
localStorage.removeItem(this.namespace);
}
this.subscribers.clear();
}
batchUpdate(updates) {
updates.forEach(({ path, value }) => {
this.setState(path, value);
});
}
loadPersistedState() {
try {
const persisted = localStorage.getItem(this.namespace);
if (persisted) {
this.state = JSON.parse(persisted);
}
} catch (error) {
console.warn("Failed to load persisted state:", error);
}
}
persistState() {
try {
localStorage.setItem(this.namespace, JSON.stringify(this.state));
} catch (error) {
console.warn("Failed to persist state:", error);
}
}
notifySubscribers(path, value) {
const pathSubscribers = this.subscribers.get(path);
if (pathSubscribers) {
pathSubscribers.forEach((callback) => callback(value));
}
}
}
class ZustandStateManager {
store;
persistence;
namespace;
constructor(config) {
this.persistence = config.persistence;
this.namespace = config.namespace || "filament-react-state";
this.initializeZustandStore(config);
void this.persistence;
}
initializeZustandStore(config) {
try {
const { create } = require("zustand");
const { devtools, persist } = require("zustand/middleware");
let storeCreator = (set, get) => ({
state: {},
setState: (path, value) => {
set((state) => {
const newState = { ...state };
const keys = path.split(".");
let current = newState;
for (let i = 0; i < keys.length - 1; i++) {
const key = keys[i];
if (key && !(key in current)) {
current[key] = {};
}
if (key) {