{"id":28959505,"url":"https://github.com/egyjs/progressive-json-php","last_synced_at":"2025-06-24T00:02:54.819Z","repository":{"id":298789858,"uuid":"1001150327","full_name":"egyjs/progressive-json-php","owner":"egyjs","description":"🚀 Progressive JSON for PHP \u0026 Laravel — stream REST/HTTP responses in real time. No more waiting. Just instant structure, lazy-loaded data, and blazing-fast UX.","archived":false,"fork":false,"pushed_at":"2025-06-23T00:38:36.000Z","size":1406,"stargazers_count":30,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-23T01:28:23.266Z","etag":null,"topics":["json","json-stream","laravel","php","php-library","progressive-json","progressive-json-stream"],"latest_commit_sha":null,"homepage":"https://medium.com/@egyjs/streaming-json-elegantly-in-php-introducing-progressive-json-streamer-fe55895cd2b9","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/egyjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-12T22:52:42.000Z","updated_at":"2025-06-23T00:37:27.000Z","dependencies_parsed_at":"2025-06-12T23:43:47.316Z","dependency_job_id":"ec79ffc1-398f-4268-909d-54271c88d083","html_url":"https://github.com/egyjs/progressive-json-php","commit_stats":null,"previous_names":["egyjs/progressive-json-php"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/egyjs/progressive-json-php","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egyjs%2Fprogressive-json-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egyjs%2Fprogressive-json-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egyjs%2Fprogressive-json-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egyjs%2Fprogressive-json-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/egyjs","download_url":"https://codeload.github.com/egyjs/progressive-json-php/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egyjs%2Fprogressive-json-php/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261577970,"owners_count":23179765,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json","json-stream","laravel","php","php-library","progressive-json","progressive-json-stream"],"created_at":"2025-06-24T00:01:54.516Z","updated_at":"2025-06-24T00:02:54.812Z","avatar_url":"https://github.com/egyjs.png","language":"PHP","funding_links":["https://github.com/sponsors/egyjs"],"categories":[],"sub_categories":[],"readme":"# Progressive JSON Streaming for PHP APIs\n\n**TL;DR:** Progressive JSON Streaming sends data incrementally to show users page structure instantly while slow API calls complete in the background.\n\n[![PHP Version](https://img.shields.io/badge/PHP-8.1%2B-blue?style=flat-square\u0026logo=php)](https://www.php.net/)[![Tests](https://img.shields.io/github/actions/workflow/status/egyjs/progressive-json-php/php-tests.yml?branch=master\u0026style=flat-square\u0026logo=github\u0026label=Tests)](https://github.com/egyjs/progressive-json-php/actions)\n[![Code Coverage](https://img.shields.io/codecov/c/github/egyjs/progressive-json-php?style=flat-square\u0026logo=codecov)](https://codecov.io/gh/egyjs/progressive-json-php)\n[![Latest Version](https://img.shields.io/packagist/v/egyjs/progressive-json-php?style=flat-square\u0026logo=packagist)](https://packagist.org/packages/egyjs/progressive-json-php)\n[![License](https://img.shields.io/github/license/egyjs/progressive-json-php?style=flat-square)](https://github.com/egyjs/progressive-json-php/blob/master/LICENSE)\n[![Sponsor on GitHub](https://img.shields.io/badge/Sponsor-❤_GitHub-ff69b4?style=flat-square\u0026logo=github)](https://github.com/sponsors/egyjs)\n\n![Progressive JSON Streamer Demo](/demo-of-progressive-json-streaming.gif)\n\n\u003e **Stream JSON responses progressively to improve user experience.** Send page structure instantly, then fill in slow data as it becomes available. Perfect for dashboards, homepages, and APIs mixing fast cached data with slow database queries.\n\nPerfect for dashboards, homepages, and any API where some data loads fast (cache) and some loads slow (database/external APIs).\n\n## The Problem\n\n```php\n// Traditional API: User waits 2000ms to see anything\n{\n  \"user\": \"...\",          // Ready in 50ms \n  \"posts\": \"...\",         // Ready in 200ms\n  \"analytics\": \"...\"      // Takes 2000ms ← Everything waits for this\n}\n```\n\n## The Solution\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n// Progressive API: User sees structure immediately, data fills in as ready\n$streamer = new ProgressiveJsonStreamer();\n\n$streamer-\u003edata([\n    'user' =\u003e '{$}',        // Placeholder\n    'posts' =\u003e '{$}',       // Placeholder  \n    'analytics' =\u003e '{$}'    // Placeholder\n]);\n\n$streamer-\u003eaddPlaceholders([\n    'user' =\u003e fn() =\u003e $cache-\u003eget(\"user_$id\"),           // 50ms\n    'posts' =\u003e fn() =\u003e Post::where('user_id', $id)-\u003eget(), // 200ms\n    'analytics' =\u003e fn() =\u003e $this-\u003egetAnalytics($id)      // 2000ms\n]);\n\nreturn $streamer-\u003easResponse();\n```\n\n**Result:** User sees page structure in 50ms, then data appears as it loads.\n\n## Installation\n\n```bash\ncomposer require egyjs/progressive-json-php\n```\n\n## Quick Start\n\n### 1. Basic Usage\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$streamer = new ProgressiveJsonStreamer();\n\n// Define structure with placeholders\n$streamer-\u003edata([\n    'profile' =\u003e '{$}',\n    'posts' =\u003e '{$}',\n    'notifications' =\u003e '{$}'\n]);\n\n// Define how to resolve each placeholder\n$streamer-\u003eaddPlaceholders([\n    'profile' =\u003e fn() =\u003e User::find($userId),\n    'posts' =\u003e fn() =\u003e Post::where('user_id', $userId)-\u003eget(),\n    'notifications' =\u003e fn() =\u003e $this-\u003egetNotifications($userId)\n]);\n\n// Stream the response\n$streamer-\u003esend(); // For pure PHP\n// OR\nreturn $streamer-\u003easResponse(); // For Laravel/Symfony\n```\n\n### 2. What the Client Receives\n\n```json\n// ⚡ Immediate response (structure shows instantly):\n{\n    \"profile\": \"$profile\",\n    \"posts\": \"$posts\", \n    \"notifications\": \"$notifications\"\n}\n\n// 🔄 Then data streams in as it's ready:\n// The client receives the above in chunks, each starting with /* $key */ followed by the actual data\n\n/* $profile */ \n{\"id\": 1, \"name\": \"John\"}\n\n\n/* $posts */\n[{\"id\": 1, \"title\": \"Hello World\"}]\n\n/* $notifications */\n[{\"type\": \"message\", \"text\": \"New comment\"}]\n```\n\n### 3. Frontend Integration\n\n```javascript\nasync function loadData() {\n    const response = await fetch('/api/dashboard');\n    const reader = response.body.getReader();\n    \n    // Parse initial structure\n    const initialChunk = await reader.read();\n    const structure = JSON.parse(new TextDecoder().decode(initialChunk.value));\n    \n    // Show loading UI immediately\n    updateUI(structure);\n    \n    // Parse progressive updates\n    while (true) {\n        const { done, value } = await reader.read();\n        if (done) break;\n        \n        const chunk = new TextDecoder().decode(value);\n        if (chunk.includes('/* $')) {\n            const [, key, data] = chunk.match(/\\/\\* \\$(\\w+) \\*\\/\\n(.+)/s) || [];\n            if (key \u0026\u0026 data) {\n                updateSection(key, JSON.parse(data));\n            }\n        }\n    }\n}\n```\n\n## When to Use\n\n**✅ Good for:**\n- Dashboard APIs with multiple data sources\n- Homepage APIs mixing cached and database data  \n- Any API where some data is fast, some is slow\n- Mobile apps (reduces HTTP requests)\n\n**❌ Skip if:**\n- All your data loads fast (\u003c100ms)\n- Using WebSockets/Server-Sent Events\n- Simple APIs with single data source\n\n## Framework Integration\n\n### Laravel\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\nclass DashboardController extends Controller\n{\n    public function dashboard()\n    {\n        $streamer = new ProgressiveJsonStreamer();\n        \n        $streamer-\u003edata([\n            'user' =\u003e '{$}',\n            'orders' =\u003e '{$}',\n            'analytics' =\u003e '{$}'\n        ]);\n        \n        $streamer-\u003eaddPlaceholders([\n            'user' =\u003e fn() =\u003e auth()-\u003euser(),\n            'orders' =\u003e fn() =\u003e Order::recent()-\u003eget(),\n            'analytics' =\u003e fn() =\u003e $this-\u003eanalytics-\u003egetUserStats()\n        ]);\n        \n        return $streamer-\u003easResponse();\n    }\n}\n```\n\n### Symfony\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\nclass ApiController extends AbstractController\n{\n    public function dashboard(): Response\n    {\n        $streamer = new ProgressiveJsonStreamer();\n        \n        $streamer-\u003edata(['user' =\u003e '{$}', 'stats' =\u003e '{$}']);\n        $streamer-\u003eaddPlaceholders([\n            'user' =\u003e fn() =\u003e $this-\u003egetUser(),\n            'stats' =\u003e fn() =\u003e $this-\u003egetStats()\n        ]);\n        \n        return $streamer-\u003easResponse();\n    }\n```\n\n## API Reference\n\n### Core Methods\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$streamer = new ProgressiveJsonStreamer();\n\n// Set structure with placeholders\n$streamer-\u003edata(['key' =\u003e '{$}']);\n\n// Add single placeholder resolver\n$streamer-\u003eaddPlaceholder('key', fn() =\u003e 'value');\n\n// Add multiple placeholder resolvers\n$streamer-\u003eaddPlaceholders([\n    'user' =\u003e fn() =\u003e User::find(1),\n    'posts' =\u003e fn() =\u003e Post::latest()-\u003eget()\n]);\n\n// Stream response\n$streamer-\u003esend();                    // Pure PHP\n// OR\nreturn $streamer-\u003easResponse();       // Symfony/Laravel\n```\n\n#### Configuration Methods\n\n\n##### `setMaxDepth(int $depth): self`\nSet maximum nesting depth for structure walking (default: 50).\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$streamer-\u003esetMaxDepth(100);\n```\n\n#### Output Methods\n\n##### `stream(): Generator`\nReturns a Generator that yields JSON chunks.\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\nforeach ($streamer-\u003estream() as $chunk) {\n    echo $chunk;\n}\n```\n\n##### `send(): void`\nStreams the response directly to output buffer (for pure PHP).\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$streamer-\u003esend(); // Sets headers and streams directly\n```\n\n##### `asResponse(): StreamedResponse`\nReturns a Symfony `StreamedResponse` for framework integration.\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\nreturn $streamer-\u003easResponse();\n```\n\n#### Utility Methods\n\n##### `getPlaceholderKeys(): array`\nGet all registered placeholder keys.\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$keys = $streamer-\u003egetPlaceholderKeys();\n// Returns: ['user.profile', 'user.posts', 'meta.timestamp']\n```\n\n##### `hasPlaceholder(string $key): bool`\nCheck if a placeholder exists.\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\nif ($streamer-\u003ehasPlaceholder('user.profile')) {\n    // Placeholder exists\n}\n```\n\n##### `removePlaceholder(string $key): self`\nRemove a specific placeholder.\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$streamer-\u003eremovePlaceholder('user.profile');\n```\n\n##### `clearPlaceholders(): self`\nRemove all placeholders.\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$streamer-\u003eclearPlaceholders();\n```\n\n##### `getStructure(): array`\nGet the current structure template.\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$structure = $streamer-\u003egetStructure();\n```\n\n---\n\n## 📋 **Common Use Cases**\n\n### **Admin Dashboard**\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$streamer-\u003edata([\n    'user' =\u003e '{$}',\n    'stats' =\u003e ['pageviews' =\u003e '{$}', 'revenue' =\u003e '{$}', 'conversions' =\u003e '{$}'],\n    'recent_orders' =\u003e '{$}',\n    'notifications' =\u003e '{$}'\n]);\n\n$streamer-\u003eaddPlaceholders([\n    'user' =\u003e fn() =\u003e Cache::get(\"user_{$userId}\"),              // Fast: cached\n    'stats.pageviews' =\u003e fn() =\u003e $this-\u003egetPageviews($userId),   // Medium: simple query\n    'recent_orders' =\u003e fn() =\u003e $this-\u003egetRecentOrders($userId),  // Medium: simple query\n    'stats.revenue' =\u003e fn() =\u003e $this-\u003ecalculateRevenue($userId), // Slow: calculations\n    'stats.conversions' =\u003e fn() =\u003e $this-\u003egetConversions($userId), // Slow: analytics\n    'notifications' =\u003e fn() =\u003e $this-\u003egetNotifications($userId)  // Very slow: external API\n]); // See Step 1 above for structure and resolver patterns\n```\n\n### **E-commerce Product Page**\n\n```php\n\u003c?php\n\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$streamer = new ProgressiveJsonStreamer();\n\n$streamer-\u003edata([\n    'product' =\u003e '{$}',              // Core product info\n    'inventory' =\u003e '{$}',            // Stock levels\n    'pricing' =\u003e '{$}',              // Dynamic pricing\n    'reviews' =\u003e '{$}',              // Customer reviews\n    'recommendations' =\u003e '{$}',      // ML recommendations\n    'related_products' =\u003e '{$}'      // Related items\n]);\n\n$streamer-\u003eaddPlaceholders([...]); // Similar pattern: fast cached data → complex queries → ML/external APIs\n```\n\n### **Social Media Feed**\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$streamer-\u003edata([\n    'user_profile' =\u003e '{$}',         // User info\n    'main_feed' =\u003e '{$}',            // Latest posts\n    'trending' =\u003e '{$}',             // Trending topics\n    'ads' =\u003e '{$}',                  // Targeted ads\n    'people_suggestions' =\u003e '{$}'    // Friend suggestions\n]);\n\n$streamer-\u003eaddPlaceholders([...]); // Pattern: profile cache → posts query → ML recommendations\n```\n\n---\n\n## 🎯 **Advanced Features**\n\n### **Error Handling**\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$streamer-\u003eaddPlaceholder('risky_data', function() {\n    // Validate permissions\n    if (!$this-\u003euser-\u003ecanAccess('sensitive_data')) {\n        throw new UnauthorizedException('Access denied');\n    }\n    \n    try {\n        return $this-\u003eexpensiveOperation();\n    } catch (Exception $e) {\n        throw new ProcessingException('Failed: ' . $e-\u003egetMessage());\n    }\n});\n```\n\nErrors are automatically serialized to JSON:\n```json\n/* $data */\n{\n    \"error\": true,\n    \"key\": \"data\",\n    \"message\": \"Failed: Connection timeout\",\n    \"type\": \"ProcessingException\"\n}\n```\n\n## Advanced Usage\n\n### Performance Optimization\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n// Order resolvers by speed (fast → slow)\n$streamer-\u003eaddPlaceholders([\n    'cached' =\u003e fn() =\u003e Cache::get('data'),          // ~1ms\n    'simple' =\u003e fn() =\u003e DB::table('users')-\u003ecount(), // ~10ms  \n    'complex' =\u003e fn() =\u003e $this-\u003eanalytics(),         // ~1000ms\n    'external' =\u003e fn() =\u003e $this-\u003eapiCall()           // ~2000ms\n]);\n```\n\n### Security\n\n```php\n$streamer-\u003eaddPlaceholder('sensitive', function() {\n    // Validate permissions\n    if (!$this-\u003euser-\u003ehasRole('admin')) {\n        throw new UnauthorizedException();\n    }\n    \n    // Rate limiting\n    $key = \"rate_limit:{$this-\u003euser-\u003eid}\";\n    if (Cache::get($key, 0) \u003e 100) {\n        throw new TooManyRequestsException();\n    }\n    Cache::increment($key, 1, 3600);\n    \n    return $this-\u003egetSensitiveData();\n});\n```\n\n### HTTP Headers\n\nThe library automatically sets streaming-optimized headers:\n\n```http\nContent-Type: application/x-json-stream\nCache-Control: no-cache, no-store, must-revalidate\nConnection: keep-alive\nX-Accel-Buffering: no\nX-Content-Type-Options: nosniff\n```\n\n## Common Use Cases\n\n### Dashboard API\n```php\n$streamer-\u003edata([\n    'user' =\u003e '{$}',\n    'metrics' =\u003e '{$}',\n    'alerts' =\u003e '{$}'\n]);\n\n$streamer-\u003eaddPlaceholders([\n    'user' =\u003e fn() =\u003e Cache::get(\"user_$id\"),      // Fast\n    'metrics' =\u003e fn() =\u003e $this-\u003egetMetrics($id),   // Medium\n    'alerts' =\u003e fn() =\u003e $this-\u003egetAlerts($id)      // Slow\n]);\n```\n\n### E-commerce Product Page\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$streamer-\u003edata([\n    'product' =\u003e '{$}',\n    'inventory' =\u003e '{$}',\n    'reviews' =\u003e '{$}',\n    'recommendations' =\u003e '{$}'\n]);\n\n$streamer-\u003eaddPlaceholders([\n    'product' =\u003e fn() =\u003e Product::find($id),                    // Fast\n    'inventory' =\u003e fn() =\u003e $this-\u003einventory-\u003egetStock($id),     // Medium\n    'reviews' =\u003e fn() =\u003e Review::where('product_id', $id)-\u003eget(), // Medium\n    'recommendations' =\u003e fn() =\u003e $this-\u003eml-\u003erecommend($id)       // Slow\n]);\n```\n\n## Troubleshooting\n\n| Problem | Solution |\n|---------|----------|\n| Stream cuts off early | Call `ob_end_clean()` before streaming |\n| Memory errors | Use pagination in resolvers |\n| Timeout errors | Increase `max_execution_time` |\n| CORS issues | Set CORS headers before streaming |\n| Parsing fails | Validate JSON in resolvers |\n\n### Debug Mode\n\n```php\n\u003c?php\nuse Egyjs\\ProgressiveJson\\ProgressiveJsonStreamer;\n\n$streamer-\u003eaddPlaceholder('debug', fn() =\u003e [\n    'memory' =\u003e memory_get_usage(true),\n    'time' =\u003e microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']\n]);\n```\n\n---\n\n## 📚 **Resources \u0026 Inspiration**\n\n- **Concept Origin:** [Dan Abramov's Progressive JSON](https://overreacted.io/progressive-json/)\n- **React Server Components:** Uses the same streaming pattern\n- **Similar Concepts:** Progressive JPEG loading, HTTP/2 Server Push\n- **Use Cases:** Netflix UI, Facebook feeds, Google search results\n\n---\n\n## 🧪 Testing\n\nThis library comes with comprehensive PHPUnit tests to ensure reliability and maintainability.\n\n### Running Tests\n\n```bash\n# Run all tests\ncomposer test\n\n# Run tests with coverage report\ncomposer test:coverage\n\n# Run tests with readable output\ncomposer test:watch\n\n# Direct PHPUnit commands\nvendor/bin/phpunit\nvendor/bin/phpunit --testdox\nvendor/bin/phpunit --coverage-text\n```\n\n### Test Coverage\n\nThe test suite includes:\n- ✅ Basic functionality tests\n- ✅ Error handling and edge cases\n- ✅ Nested structure handling\n- ✅ Stream generation and output\n- ✅ Symfony integration tests\n- ✅ Configuration and validation tests\n- ✅ **Laravel installation tests** (v9.x - v12.x)\n\nCoverage reports are generated in `build/coverage-html/` when running with coverage.\n\n### Laravel Installation Tests\n\nWe provide comprehensive installation tests for Laravel versions 9.x through 12.x:\n\n```bash\n# Run Laravel installation tests locally\n./scripts/test-laravel-installation.sh\n```\n\nThese tests verify:\n- Package installation via Composer\n- Autoloading and integration with Laravel\n- Performance and clean removal\n\nSee [`docs/LARAVEL_INSTALLATION_TESTS.md`](docs/LARAVEL_INSTALLATION_TESTS.md) for detailed information.\n\n### Continuous Integration\n\nGitHub Actions automatically runs tests on:\n- PHP 8.1, 8.2, 8.3, and 8.4\n- Laravel 9.x, 10.x, 11.x, and 12.x combinations\n- Push and Pull Request events\n- Multiple operating systems\n- Weekly scheduled runs\n\n---\n\n## 🤝 Contributing\n\nWe welcome contributions from everyone! Please read our [Contributing Guide](CONTRIBUTING.md) for detailed information on how to get started.\n\n**Quick Start:**\n1. Fork the repository\n2. Create a feature branch: `git checkout -b feature/name`\n3. Commit changes: `git commit -m 'Add feature'`\n4. Push to branch: `git push origin feature/name`\n5. Open a Pull Request\n\n**Important:**\n- Read our [Code of Conduct](CODE_OF_CONDUCT.md) \n- Follow our [Contributing Guidelines](CONTRIBUTING.md)\n- Include tests for new features\n- Update documentation as needed\n\nFor detailed setup instructions, coding standards, and development workflow, see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\n## 📄 License\n\nMIT License. See [LICENSE](LICENSE) for details.\n\n## Author\n\n**AbdulRahman El-zahaby (@egyjs)**  \n📧 el3zahaby@gmail.com  \n🐙 GitHub: [@egyjs](https://github.com/egyjs)\n\n---\n\n## 🙏 Acknowledgments\n\n- Symfony HttpFoundation for streaming response utilities\n- The PHP community for feedback and contributions\n\n---\n\n*Made with ❤️ by [egyjs](https://github.com/egyjs)  for the PHP community*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegyjs%2Fprogressive-json-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fegyjs%2Fprogressive-json-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegyjs%2Fprogressive-json-php/lists"}