diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 3855a08..d9306d6 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -16,7 +16,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.1' + php-version: '8.3' coverage: none - name: Install composer dependencies diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml deleted file mode 100644 index caa2c03..0000000 --- a/.github/workflows/run-tests.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: run-tests - -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: true - matrix: - os: [ubuntu-latest, windows-latest] - php: [8.0, 8.1] - laravel: [9.*] - stability: [prefer-lowest, prefer-stable] - include: - - laravel: 10.* - testbench: 7.* - - name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo - coverage: none - - - name: Setup problem matchers - run: | - echo "::add-matcher::${{ runner.tool_cache }}/php.json" - echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - - - name: Install dependencies - run: | - composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update - composer update --${{ matrix.stability }} --prefer-dist --no-interaction - - - name: Execute tests - run: vendor/bin/pest diff --git a/README.md b/README.md index 9a3d0cb..f5d0025 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ We assume you've already got the Inertia adapter for Laravel installed. Controllers in Laravel are meant to be slim. We have Form Requests to extract our the validation & authorization logic and our display logic is in our views, so why do we still insist on making our controllers handle fetching the data for those views? -This is especially evident in Inertia applications due to the introduction of concepts like lazy props. +This is especially evident in Inertia applications due to the introduction of concepts like lazy and deferred props. Data providers extract the data composition for your Inertia views into their own classes. Inertia data providers may prove particularly useful if multiple routes or controllers within your application always needs a particular piece of data. @@ -65,8 +65,28 @@ class DemoController extends Controller Data providers can live anywhere, but we'll use `App/Http/DataProviders` for this example. The simplest data provider is just a class that extends `DataProvider`, any public methods or properties will be available to the page as data. +```php +formatName($this->demo->user->name); - }; + return Inertia::defer( + fn () => $this->demo->aHeavyCalculation() + ); } /* @@ -141,6 +162,19 @@ class DemoDataProvider extends DataProvider ); } + /* + * If a method returns a `Closure` it will be evaluated as a lazy property. + * ALWAYS included on first visit, OPTIONALLY included on partial reloads, ONLY evaluated when needed + * Additionally the callback methods are resolved through Laravel's service container, so any parameters will be automatically resolved. + * @see https://inertiajs.com/partial-reloads#lazy-data-evaluation + */ + public function quickLazyExample(): Closure + { + return function(InjectedDependency $example): string { + return $example->formatName($this->demo->user->name); + }; + } + /* * `protected` and `private` methods are not available to the page */ diff --git a/composer.json b/composer.json index 2bf1431..929ab12 100644 --- a/composer.json +++ b/composer.json @@ -21,10 +21,10 @@ "require": { "php": "^8.2", "spatie/laravel-package-tools": "^1.14.0", - "illuminate/contracts": "^11.0" + "illuminate/contracts": "^11.0|^12.0" }, "require-dev": { - "inertiajs/inertia-laravel": "<2", + "inertiajs/inertia-laravel": "^1.0|^2.0", "jetbrains/phpstorm-attributes": "^1.0", "nunomaduro/collision": "^v8.1", "larastan/larastan": "^v2.9", diff --git a/src/DataProvider.php b/src/DataProvider.php index e0d7a93..47db17f 100644 --- a/src/DataProvider.php +++ b/src/DataProvider.php @@ -7,6 +7,7 @@ use Closure; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Contracts\Support\Jsonable; +use Inertia\DeferProp; use Inertia\LazyProp; use Inertia\Response; use ReflectionClass; @@ -41,7 +42,7 @@ public function toArray(): array ->filter(fn (ReflectionMethod $method) => ! $method->isStatic() && ! in_array($method->name, $this->excludedMethods)) ->mapWithKeys(function (ReflectionMethod $method) { $returnType = $method->getReturnType(); - if ($returnType instanceof ReflectionNamedType && in_array($returnType->getName(), [LazyProp::class, Closure::class])) { + if ($returnType instanceof ReflectionNamedType && in_array($returnType->getName(), [DeferProp::class, LazyProp::class, Closure::class])) { return [$method->name => $method->invoke($this)]; }