npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@hadyfayed/filament-react-wrapper

v3.2.0

Published

Enterprise React integration for Laravel/Filament - Smart asset loading, 90%+ React-PHP function mapping, no-plugin Filament integration

Readme

React Wrapper for Laravel/Filament

npm version License: MIT TypeScript Laravel Filament

A comprehensive React integration system for Laravel and Filament applications, providing seamless component registration, state management, and real-time synchronization with built-in memory leak prevention and infinite loop protection.

🚀 Features

  • 🔧 Universal Component System - Register and render React components anywhere in your Laravel app
  • 🎯 Advanced State Management - Built-in state management with persistence and Livewire sync
  • ⚡ Performance Optimized - Lazy loading, memoization, efficient re-rendering, and memory leak prevention
  • 🛡️ Type Safe - Full TypeScript support with comprehensive type definitions
  • 🔄 Real-time Sync - Bidirectional data flow with Livewire components
  • 📦 Zero Config - Works out of the box with sensible defaults
  • 🎨 Filament Ready - Native integration with Filament admin panels
  • 🧩 Extensible - Plugin system with middleware support
  • 🔒 Security First - XSS protection, input validation, and secure prop handling
  • 🚫 Loop Protection - Built-in infinite loop detection and prevention
  • 🧠 Memory Safe - Automatic cleanup and bounded data structures

📦 Installation

Quick Start

# Install packages
npm install @hadyfayed/filament-react-wrapper
composer require hadyfayed/filament-react-wrapper

# Enhanced DX (recommended)
npm install --save-dev vite-plugin-filament-react

💡 Pro Tip: Use with vite-plugin-filament-react for enhanced developer experience with auto-discovery, dev tools, and performance optimization.

Laravel Setup

  1. Add to your JavaScript entry:
// resources/js/app.js
import '@hadyfayed/filament-react-wrapper';
  1. Update Vite config (with plugin):
// vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';
import filamentReact from 'vite-plugin-filament-react';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
        react(),
        filamentReact(), // Auto-discovery and dev tools
    ],
});
  1. Optional: Register the Filament plugin:
// app/Providers/Filament/AdminPanelProvider.php
use HadyFayed\ReactWrapper\FilamentReactWrapperPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            FilamentReactWrapperPlugin::make(),
        ]);
}
  1. Add to your app.js:
import '@hadyfayed/filament-react-wrapper';
  1. Build your assets:
npm run build

🎯 Quick Start

1. Register a React Component

import { componentRegistry } from '@hadyfayed/filament-react-wrapper';
import MyComponent from './components/MyComponent';

// Simple registration
componentRegistry.register({
  name: 'MyComponent',
  component: MyComponent,
  defaultProps: {
    message: 'Hello World!'
  }
});

2. Use in Blade Templates

<!-- Basic usage -->
<div data-react-component="MyComponent"></div>

<!-- With props -->
<div 
  data-react-component="MyComponent"
  data-react-props='{"title": "Custom Title", "count": 5}'
></div>

<!-- With state synchronization -->
<div 
  data-react-component="MyComponent"
  data-react-state-path="user.preferences"
  data-react-props='{"userId": {{ $user->id }}}'
></div>

3. Use in Filament

use HadyFayed\ReactWrapper\Components\ReactComponent;

class EditUser extends EditRecord
{
    protected function getHeaderActions(): array
    {
        return [
            ReactComponent::make('UserProfileEditor')
                ->props([
                    'userId' => $this->record->id,
                    'editable' => true
                ])
                ->statePath('userProfile')
        ];
    }
}

📚 Component Registration

Basic Registration

import { componentRegistry } from '@hadyfayed/filament-react-wrapper';

componentRegistry.register({
  name: 'UserCard',
  component: UserCard,
  defaultProps: {
    showAvatar: true,
    size: 'medium'
  },
  metadata: {
    category: 'user',
    description: 'Displays user information in a card format',
    tags: ['user', 'display', 'card']
  }
});

Advanced Registration with Lazy Loading

componentRegistry.register({
  name: 'HeavyComponent',
  component: () => import('./components/HeavyComponent'),
  isAsync: true,
  config: {
    lazy: true,
    cache: true,
    preload: false
  },
  metadata: {
    category: 'charts',
    description: 'Advanced data visualization component'
  }
});

Bulk Registration

import { registerComponents } from '@hadyfayed/filament-react-wrapper';

const components = [
  { name: 'Button', component: Button },
  { name: 'Modal', component: Modal },
  { name: 'Form', component: Form }
];

registerComponents(components);

Registration from Laravel/PHP

You can also register React components from the Laravel/PHP side, which is useful for package authors or when you want to manage component registration through Laravel configuration:

Service Provider Registration

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use HadyFayed\ReactWrapper\Services\ReactComponentRegistry;

class ReactComponentServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $registry = app(ReactComponentRegistry::class);

        // Register components with PHP
        $registry->register([
            'name' => 'UserCard',
            'component_path' => 'resources/js/components/UserCard.tsx',
            'default_props' => [
                'showAvatar' => true,
                'size' => 'medium'
            ],
            'metadata' => [
                'category' => 'user',
                'description' => 'Displays user information in a card format',
                'tags' => ['user', 'display', 'card']
            ]
        ]);

        // Register multiple components
        $registry->registerMany([
            [
                'name' => 'ProductCard',
                'component_path' => 'resources/js/components/ProductCard.tsx',
                'default_props' => ['showPrice' => true],
                'metadata' => ['category' => 'product']
            ],
            [
                'name' => 'OrderSummary', 
                'component_path' => 'resources/js/components/OrderSummary.tsx',
                'is_async' => true,
                'config' => ['lazy' => true, 'cache' => true]
            ]
        ]);
    }
}

Configuration-Based Registration

Add to config/react-wrapper.php:

<?php

return [
    'components' => [
        'auto_register' => true,
        'scan_directories' => [
            'resources/js/components',
            'resources/js/widgets'
        ],
        'registered_components' => [
            'UserProfile' => [
                'component_path' => 'resources/js/components/UserProfile.tsx',
                'default_props' => ['editable' => false],
                'config' => ['lazy' => false, 'cache' => true],
                'metadata' => [
                    'category' => 'user',
                    'description' => 'User profile management component'
                ]
            ],
            'DataTable' => [
                'component_path' => 'resources/js/components/DataTable.tsx',
                'is_async' => true,
                'default_props' => [
                    'pageSize' => 10,
                    'sortable' => true
                ],
                'config' => [
                    'lazy' => true,
                    'cache' => true,
                    'preload' => false
                ]
            ]
        ]
    ]
];

Artisan Command for Registration

Generate component registration via Artisan:

# Create a new React component with auto-registration
php artisan make:react-component UserDashboard --register

# Register an existing component
php artisan react:register ProductCard --path=resources/js/components/ProductCard.tsx

# Register multiple components from a directory
php artisan react:scan resources/js/components --register

Facade Usage

Use the ReactWrapper facade for quick registration:

<?php

use HadyFayed\ReactWrapper\Facades\ReactWrapper;

// In a controller, middleware, or service
class ComponentController extends Controller
{
    public function registerComponent()
    {
        ReactWrapper::register([
            'name' => 'DynamicChart',
            'component_path' => 'resources/js/charts/DynamicChart.tsx',
            'default_props' => [
                'type' => 'line',
                'animated' => true
            ],
            'config' => [
                'lazy' => true,
                'cache' => false // Don't cache dynamic components
            ]
        ]);

        return response()->json(['message' => 'Component registered successfully']);
    }

    public function getRegisteredComponents()
    {
        $components = ReactWrapper::getRegistered();
        return response()->json($components);
    }
}

Package Integration

For Laravel package authors:

<?php

namespace YourPackage\Providers;

use Illuminate\Support\ServiceProvider;
use HadyFayed\ReactWrapper\Services\ReactComponentRegistry;

class YourPackageServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Register package components automatically
        $this->registerPackageComponents();
        
        // Publish package components
        $this->publishes([
            __DIR__.'/../resources/js/components' => resource_path('js/vendor/your-package'),
        ], 'your-package-components');
    }

    protected function registerPackageComponents()
    {
        $registry = app(ReactComponentRegistry::class);

        $packageComponents = [
            'PackageWidget' => [
                'component_path' => 'js/vendor/your-package/PackageWidget.tsx',
                'default_props' => ['theme' => 'package-default'],
                'metadata' => [
                    'category' => 'package-widgets',
                    'package' => 'your-package',
                    'version' => '1.0.0'
                ]
            ]
        ];

        foreach ($packageComponents as $name => $config) {
            $registry->register(array_merge($config, ['name' => $name]));
        }
    }
}

Dynamic Registration in Filament

Register components dynamically in Filament resources:

<?php

namespace App\Filament\Resources;

use Filament\Resources\Resource;
use HadyFayed\ReactWrapper\Services\ReactComponentRegistry;

class UserResource extends Resource
{
    public static function boot()
    {
        parent::boot();
        
        // Register resource-specific components
        app(ReactComponentRegistry::class)->register([
            'name' => 'UserResourceChart',
            'component_path' => 'resources/js/filament/UserResourceChart.tsx',
            'default_props' => [
                'resource' => 'users',
                'metric' => 'registrations'
            ]
        ]);
    }

    public static function form(Form $form): Form
    {
        return $form->schema([
            ReactField::make('user_analytics')
                ->component('UserResourceChart')
                ->props(['userId' => fn($record) => $record?->id])
                ->visible(fn($record) => $record !== null)
        ]);
    }
}

🎯 State Management

Using State Manager Provider

import { StateManagerProvider, useStateManager } from '@hadyfayed/filament-react-wrapper';

function App() {
  return (
    <StateManagerProvider
      initialState={{ user: { name: 'John' } }}
      onStateChange={(state) => console.log('State changed:', state)}
      syncPath="app.state"
    >
      <MyComponent />
    </StateManagerProvider>
  );
}

function MyComponent() {
  const { state, setState, getState } = useStateManager();
  
  const updateUser = () => {
    setState('user.name', 'Jane Doe');
  };
  
  return (
    <div>
      <p>User: {getState('user.name')}</p>
      <button onClick={updateUser}>Update Name</button>
    </div>
  );
}

Using State Path Hook

import { useStatePath } from '@hadyfayed/filament-react-wrapper';

function UserProfile() {
  const [user, setUser] = useStatePath('user', { name: '', email: '' });
  
  return (
    <form>
      <input
        value={user.name}
        onChange={(e) => setUser(prev => ({ ...prev, name: e.target.value }))}
      />
      <input
        value={user.email}
        onChange={(e) => setUser(prev => ({ ...prev, email: e.target.value }))}
      />
    </form>
  );
}

Global State Manager

import { globalStateManager } from '@hadyfayed/filament-react-wrapper';

// Set global state
globalStateManager.setState('app.theme', 'dark');

// Get global state
const theme = globalStateManager.getState('app.theme');

// Subscribe to changes
const unsubscribe = globalStateManager.subscribe('app.theme', (newTheme) => {
  console.log('Theme changed to:', newTheme);
});

// Clean up
unsubscribe();

💾 State Persistence

Using Persisted State Hook

import { usePersistedState } from '@hadyfayed/filament-react-wrapper';

function ThemeSelector() {
  const [theme, setTheme] = usePersistedState('theme', 'light', {
    storage: 'localStorage',
    syncWithLivewire: true,
    livewirePath: 'user.theme'
  });
  
  return (
    <select value={theme} onChange={(e) => setTheme(e.target.value)}>
      <option value="light">Light</option>
      <option value="dark">Dark</option>
    </select>
  );
}

Manual Persistence Service

import { statePersistenceService } from '@hadyfayed/filament-react-wrapper';

// Register a persistence config
statePersistenceService.register({
  key: 'userPreferences',
  storage: 'localStorage',
  syncWithLivewire: true,
  livewirePath: 'user.preferences',
  debounceMs: 500,
  transformer: {
    serialize: (data) => JSON.stringify(data),
    deserialize: (data) => JSON.parse(data)
  }
});

// Save data
statePersistenceService.save('userPreferences', {
  theme: 'dark',
  language: 'en'
});

// Load data
const preferences = statePersistenceService.load('userPreferences');

🎨 Filament Integration

Creating Filament Components

<?php

namespace App\Filament\Components;

use HadyFayed\ReactWrapper\Components\ReactComponent;

class UserDashboard extends ReactComponent
{
    protected string $component = 'UserDashboard';
    
    public static function make(string $component = null): static
    {
        return new static($component ?? static::$component);
    }
    
    public function userId(int $userId): static
    {
        $this->props(['userId' => $userId]);
        return $this;
    }
    
    public function editable(bool $editable = true): static
    {
        $this->props(['editable' => $editable]);
        return $this;
    }
}

Using in Filament Pages

use App\Filament\Components\UserDashboard;

class Dashboard extends Page
{
    protected static string $view = 'filament.pages.dashboard';
    
    protected function getHeaderWidgets(): array
    {
        return [
            UserDashboard::make()
                ->userId(auth()->id())
                ->editable(true)
                ->statePath('dashboard.user')
        ];
    }
}

Form Field Integration

use HadyFayed\ReactWrapper\Forms\Components\ReactField;

class UserForm extends Form
{
    public function form(Form $form): Form
    {
        return $form->schema([
            ReactField::make('profile_editor')
                ->component('UserProfileEditor')
                ->props([
                    'allowImageUpload' => true,
                    'maxImageSize' => '2MB'
                ])
                ->statePath('profile')
                ->reactive()
                ->afterStateUpdated(function ($state) {
                    // Handle state updates
                    $this->user->update($state);
                })
        ]);
    }
}

🔧 Advanced Features

Middleware System

import { componentRegistry } from '@hadyfayed/filament-react-wrapper';

// Global middleware
componentRegistry.addMiddleware((component, props, context) => {
  // Add analytics tracking
  return (componentProps) => {
    React.useEffect(() => {
      analytics.track('component_rendered', {
        component: context.metadata.name,
        props: Object.keys(componentProps)
      });
    }, []);
    
    return React.createElement(component, componentProps);
  };
});

// Component-specific middleware
componentRegistry.register({
  name: 'SecureComponent',
  component: SecureComponent,
  config: {
    middleware: [
      (component, props, context) => {
        // Add authentication check
        return (componentProps) => {
          if (!componentProps.user?.authenticated) {
            return React.createElement('div', null, 'Access Denied');
          }
          return React.createElement(component, componentProps);
        };
      }
    ]
  }
});

Error Handling

All components are automatically wrapped with error boundaries that provide:

  • Graceful error display
  • Error reporting to console
  • Retry functionality
  • Custom error handlers
componentRegistry.register({
  name: 'RiskyComponent',
  component: RiskyComponent,
  config: {
    onError: (error, componentName) => {
      // Custom error handling
      console.error(`Error in ${componentName}:`, error);
      // Report to error tracking service
      errorTracker.report(error, { component: componentName });
    }
  }
});

🚀 Performance & Memory Safety

Memory Leak Prevention

The system includes comprehensive protection against memory leaks:

// Automatic cleanup on component unmount
React.useEffect(() => {
  const unsubscribe = globalStateManager.subscribe('user.data', handleUserChange);
  
  return () => {
    unsubscribe(); // Automatic cleanup
  };
}, []);

// Bounded data structures prevent unlimited growth
// Maximum 1000 entries in persistence service with automatic cleanup

Infinite Loop Protection

Built-in protection against infinite loops in state updates:

// Circular notification detection
if (this._notifyingPaths.has(path)) {
  console.warn(`Circular notification detected for path: ${path}`);
  return; // Prevents infinite loops
}

Performance Optimizations

  • Memoization - Automatic memoization of components and state
  • Debouncing - Built-in debouncing for state changes and notifications
  • Lazy Loading - Code splitting for large components
  • Efficient Re-rendering - Smart prop comparison and update batching

🔒 Security Features

Input Validation

// Validate props before rendering
componentRegistry.register({
  name: 'SecureComponent',
  component: SecureComponent,
  config: {
    middleware: [
      (component, props, context) => {
        return (componentProps) => {
          // Validate props
          const validatedProps = validateProps(componentProps, {
            userId: 'number',
            email: 'email',
            role: ['admin', 'user', 'guest']
          });
          
          return React.createElement(component, validatedProps);
        };
      }
    ]
  }
});

XSS Prevention

// Sanitize HTML content
import DOMPurify from 'dompurify';

const SafeComponent = ({ htmlContent }) => {
  const sanitizedHTML = DOMPurify.sanitize(htmlContent);
  return <div dangerouslySetInnerHTML={{ __html: sanitizedHTML }} />;
};

🛠️ API Reference

Component Registry

interface IComponentRegistry {
  register(definition: IComponentDefinition): void;
  get(name: string): IComponentDefinition | undefined;
  create(name: string, props?: Record<string, any>): React.ComponentType<any> | null;
  has(name: string): boolean;
  unregister(name: string): boolean;
  clear(): void;
  getComponentNames(): string[];
  getStats(): ComponentStats;
  mount(componentName: string, containerId: string, props?: Record<string, any>): void;
  unmount(containerId: string): void;
  on(event: string, callback: Function, priority?: number): void;
  off(event: string, callback: Function): void;
}

State Manager

interface IStateManager {
  setState(path: string, value: any): void;
  updateState(path: string, updater: (current: any) => any): void;
  getState(path: string): any;
  resetState(newState?: StateManagerState): void;
  batchUpdate(updates: Array<{ path: string; value: any }>): void;
  subscribe(path: string, callback: (value: any) => void): () => void;
}

Hooks

// State Manager Hook
const useStateManager = (): StateManagerContextType => { ... };

// State Path Hook
const useStatePath = <T = any>(
  path: string,
  defaultValue?: T
): [T, (value: T | ((prev: T) => T)) => void] => { ... };

// Persisted State Hook
const usePersistedState = <T>(
  key: string,
  defaultValue: T,
  config?: Partial<StatePersistenceConfig>
): [T, (value: T | ((prev: T) => T)) => void] => { ... };

PHP/Laravel API

ReactComponentRegistry Service

<?php

namespace HadyFayed\ReactWrapper\Services;

interface ReactComponentRegistryInterface
{
    public function register(array $definition): void;
    public function registerMany(array $definitions): void;
    public function get(string $name): ?array;
    public function has(string $name): bool;
    public function unregister(string $name): bool;
    public function clear(): void;
    public function getRegistered(): array;
    public function getStats(): array;
    public function scan(string $directory): array;
}

ReactWrapper Facade

<?php

use HadyFayed\ReactWrapper\Facades\ReactWrapper;

// Register component
ReactWrapper::register([
    'name' => 'ComponentName',
    'component_path' => 'path/to/component.tsx',
    'default_props' => ['prop' => 'value'],
    'config' => ['lazy' => true, 'cache' => true],
    'metadata' => ['category' => 'widgets']
]);

// Register multiple components
ReactWrapper::registerMany($components);

// Get component definition
$definition = ReactWrapper::get('ComponentName');

// Check if component exists
$exists = ReactWrapper::has('ComponentName');

// Get all registered components
$components = ReactWrapper::getRegistered();

// Get registration statistics
$stats = ReactWrapper::getStats();

// Scan directory for components
$found = ReactWrapper::scan('resources/js/components');

ReactField Form Component

<?php

use HadyFayed\ReactWrapper\Forms\Components\ReactField;

ReactField::make('field_name')
    ->component('ComponentName')           // React component name
    ->props(['key' => 'value'])           // Component props
    ->defaultProps(['default' => true])   // Default props
    ->statePath('form.field')             // State synchronization path
    ->height(400)                         // Container height
    ->width('100%')                       // Container width
    ->reactive()                          // Make field reactive
    ->live()                             // Enable live updates
    ->debounce(300)                      // Debounce updates (ms)
    ->afterStateUpdated(fn($state) => ...) // State change callback
    ->visible(fn($get) => $get('show'))   // Conditional visibility
    ->disabled(fn($get) => !$get('edit')) // Conditional disable
    ->required()                          // Mark as required
    ->columnSpan(2)                       // Grid column span
    ->extraAttributes(['class' => 'custom']); // Additional HTML attributes

ReactWidget

<?php

use HadyFayed\ReactWrapper\Widgets\ReactWidget;

class CustomWidget extends ReactWidget
{
    protected string $component = 'WidgetComponent';
    
    protected function getProps(): array
    {
        return [
            'title' => 'Widget Title',
            'data' => $this->getData(),
            'config' => $this->getConfig()
        ];
    }
    
    protected function getHeight(): ?string
    {
        return '300px';
    }
    
    protected function getStatePath(): ?string
    {
        return 'widgets.custom';
    }
    
    public static function canView(): bool
    {
        return auth()->user()?->can('view-widgets') ?? false;
    }
}

Configuration Options

<?php

// config/react-wrapper.php
return [
    'debug' => env('REACT_WRAPPER_DEBUG', false),
    'cache_components' => env('REACT_WRAPPER_CACHE', true),
    'preload_components' => env('REACT_WRAPPER_PRELOAD', false),
    'max_state_size' => env('REACT_WRAPPER_MAX_STATE_SIZE', 1000),
    
    'components' => [
        'auto_register' => true,
        'scan_directories' => [
            'resources/js/components',
            'resources/js/widgets'
        ],
        'registered_components' => [
            // Component definitions
        ]
    ],
    
    'memory_safety' => [
        'max_subscriptions_per_path' => 100,
        'cleanup_interval' => 300000, // 5 minutes
        'enable_loop_detection' => true,
    ],
    
    'security' => [
        'validate_props' => true,
        'sanitize_html' => true,
        'max_prop_size' => 1024 * 1024, // 1MB
    ]
];

Artisan Commands

# Create React component with registration
php artisan make:react-component ComponentName --register

# Register existing component
php artisan react:register ComponentName --path=resources/js/components/ComponentName.tsx

# Scan and register components from directory
php artisan react:scan resources/js/components --register

# List registered components
php artisan react:list

# Clear component registry
php artisan react:clear

# Show component statistics
php artisan react:stats

# Generate component registration file
php artisan react:export --output=bootstrap-components.php

Event Hooks

<?php

use HadyFayed\ReactWrapper\Events\ComponentRegistered;
use HadyFayed\ReactWrapper\Events\ComponentRendered;

// Listen for component registration
Event::listen(ComponentRegistered::class, function ($event) {
    Log::info('Component registered: ' . $event->componentName);
});

// Listen for component rendering
Event::listen(ComponentRendered::class, function ($event) {
    // Track component usage
    Analytics::track('component_rendered', [
        'component' => $event->componentName,
        'props' => $event->props
    ]);
});

🐛 Debugging & Troubleshooting

Enable Debug Mode

// Enable debug logging
window.ReactWrapperConfig = {
  debug: true,
  logLevel: 'verbose'
};

Common Issues

Component Not Found

// Check if component is registered
if (!componentRegistry.has('MyComponent')) {
  console.log('Available components:', componentRegistry.getComponentNames());
}

// Check component statistics
console.log('Registry stats:', componentRegistry.getStats());

State Not Syncing

// Check Livewire connection
if (!window.workflowDataSync) {
  console.warn('Livewire sync not available');
}

// Monitor state changes
globalStateManager.subscribe('', (state) => {
  console.log('Global state changed:', state);
});

Memory Leaks

// Monitor subscription counts
console.log('Active subscriptions:', globalStateManager.subscribers.size);

// Monitor active components
console.log('Active components:', universalReactRenderer.getActiveContainers());

📊 Testing

Unit Testing Components

import { render, screen } from '@testing-library/react';
import { componentRegistry } from '@hadyfayed/filament-react-wrapper';
import MyComponent from './MyComponent';

describe('Component Registry', () => {
  beforeEach(() => {
    componentRegistry.clear();
  });

  test('registers and creates component', () => {
    componentRegistry.register({
      name: 'TestComponent',
      component: MyComponent
    });

    expect(componentRegistry.has('TestComponent')).toBe(true);
    
    const Component = componentRegistry.create('TestComponent', { title: 'Test' });
    expect(Component).toBeDefined();
  });
});

Integration Testing

import { StateManagerProvider, useStatePath } from '@hadyfayed/filament-react-wrapper';

const TestComponent = () => {
  const [value, setValue] = useStatePath('test.value', 'initial');
  return (
    <div>
      <span data-testid="value">{value}</span>
      <button onClick={() => setValue('updated')}>Update</button>
    </div>
  );
};

test('state management works', () => {
  render(
    <StateManagerProvider>
      <TestComponent />
    </StateManagerProvider>
  );
  
  expect(screen.getByTestId('value')).toHaveTextContent('initial');
  
  fireEvent.click(screen.getByText('Update'));
  expect(screen.getByTestId('value')).toHaveTextContent('updated');
});

🚀 Deployment

Production Build

# Build for production
npm run build

# Laravel asset compilation
php artisan filament:assets

Environment Configuration

// config/react-wrapper.php
return [
    'debug' => env('REACT_WRAPPER_DEBUG', false),
    'cache_components' => env('REACT_WRAPPER_CACHE', true),
    'preload_components' => env('REACT_WRAPPER_PRELOAD', false),
    'max_state_size' => env('REACT_WRAPPER_MAX_STATE_SIZE', 1000),
    'memory_safety' => [
        'max_subscriptions_per_path' => 100,
        'cleanup_interval' => 300000, // 5 minutes
        'enable_loop_detection' => true,
    ],
];

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/hadyfayed/filament-react-wrapper.git

# Install dependencies
npm install
composer install

# Run tests
npm test
php artisan test

# Start development server
npm run dev
php artisan serve

Code Style

We use ESLint and Prettier for code formatting:

npm run lint
npm run format

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Built with ❤️ for the Laravel and React communities
  • Inspired by modern component architecture patterns
  • Special thanks to all contributors and maintainers

📞 Support