notrix/compass-elephant
notrix/compass-elephant is a Laravel/PHP package. Use it to add the package’s functionality to your application; see the repository README for installation, configuration, and usage guidance.
Assuming standard Composer conventions, the first steps are:
composer require notrix/compass-elephant
Then locate the integration surface before writing any application code:
composer.json – check the require block and PSR-4 autoload mappings to see what the package actually depends on and where its namespaces live.*ServiceProvider class and any Facade. If one exists, the package is designed to be resolved from the container rather than instantiated directly.config/ inside the package – if a config file ships with it, publish it with php artisan vendor:publish --provider="Notrix\\CompassElephant\\...ServiceProvider" and read every key before changing anything.README.md and src/ – with 0 stars and 0 dependents there is no community documentation to fall back on, so the source is the documentation. Read the main abstraction interface first; everything else is implementation detail.First use case: pick the one place in your app where you currently talk to "compass" directly, register the package's abstraction in the container, and resolve it once. The win is not the call itself — it's that the rest of the app now depends on an interface you control rather than on the package's concrete classes.
// AppServiceProvider::register()
$this->app->bind(
\Notrix\CompassElephant\CompassInterface::class,
fn ($app) => $app->make(\Notrix\CompassElephant\Compass::class)
);
(Verify the actual interface name in src/; the shape above is the pattern, not a guarantee.)
Depend on the interface, not the package. Wrap resolution in your own thin service class. If the package is abandoned next quarter, you change one binding instead of grepping fifty call sites.
final class CompassGateway
{
public function __construct(private CompassInterface $compass) {}
public function resolve(string $input): Result
{
return $this->compass->resolve($input);
}
}
Driver / adapter selection belongs in config. Abstraction layers almost always ship more than one backend. Map your config key to the concrete class in a single service provider method so staging and production can diverge without code changes:
$this->app->when(CompassGateway::class)
->needs(CompassInterface::class)
->give(fn () => match (config('compass.driver')) {
'native' => new NativeCompass(config('compass.options')),
default => throw new InvalidArgumentException('Unknown compass driver'),
});
Decorate for cross-cutting concerns. Logging, caching, and retries are exactly what an abstraction layer exists to absorb. Register a decorator around the real implementation:
$this->app->extend(CompassInterface::class, function ($inner) {
return new LoggingCompass($inner, $this->app['log']);
});
Fake it in tests. Because you bound an interface, $this->instance(CompassInterface::class, new FakeCompass()) gives you deterministic tests without touching the real backend. Do this on day one — it is the single highest-value reason to adopt a wrapper.
Use the facade (if present) only at the edges. Facades are convenient in controllers and Artisan commands; avoid them in domain services where constructor injection makes the dependency visible.
Integration tip: if the package exposes events or exceptions, catch the package's exception types at the boundary and rethrow your own domain exceptions. That keeps the abstraction leak-free and makes a future swap mechanical.
composer.json, commit composer.lock, and read the entire src/ tree — it is probably small enough to audit in an afternoon. Assume no upstream fixes and plan to fork or vendor if needed.config() inside a closure that runs at boot, run php artisan config:cache in staging and verify. A driver that worked in local can silently become the default under cache.app()->forgetInstance() in handle().dd(app(CompassInterface::class)) in tinker tells you instantly which concrete class you actually got. app()->getBindings() shows whether your binding or the package's won.register* method on the provider, or a config('compass.drivers.*') map. Prefer registering a custom driver over monkey-patching the package; it survives upgrades.composer update bumps this package, run your fake-backed tests first — they will catch signature changes before integration does.How can I help you explore Laravel packages today?