Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,36 @@ class CreateUser extends SpotlightCommand
}
```

## Laravel Octane compatibility

Spotlight keeps its registered commands in a static list that is populated once when the package (or your own
service provider) boots. Under Octane, provider `boot()` methods only run **once per worker**, not once per
request, so anything you pass to `registerCommand`, `registerCommandIf`, or `registerCommandUnless` from a service
provider is evaluated a single time when the worker starts.

This is fine for conditions that don't change at runtime (e.g. config values or feature flags resolved at boot),
but it means you should **not** base these calls on per-request state such as the authenticated user:

```php
// Bad under Octane: `auth()->check()` is only evaluated once, when the worker boots,
// so every request served by that worker will see the result frozen at boot time.
Spotlight::registerCommandIf(auth()->check(), CreateUser::class);
```

Instead, always register the command unconditionally and use the `shouldBeShown` method described above to decide
per-request whether it should be visible. `shouldBeShown` is resolved through the container on every render, so it
correctly reflects the current request/user under Octane:

```php
Spotlight::registerCommand(CreateUser::class);
```

```php
public function shouldBeShown(Request $request): bool
{
return $request->user()?->can('create user') ?? false;
}
```

## Configuration

Expand Down
8 changes: 8 additions & 0 deletions src/Spotlight.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ class Spotlight extends Component

public static function registerCommand(string $command): void
{
// Under Octane, service provider boot() methods only run once per
// worker instead of once per request, so this guards against
// duplicate/unbounded growth of the static command list if a
// provider is ever booted more than once within the same worker.
if (collect(self::$commands)->contains(fn (SpotlightCommand $registered) => $registered::class === $command)) {
return;
}

tap(new $command, function (SpotlightCommand $command) {
self::$commands[] = $command;
});
Expand Down