inmanturbo/signal

The skeleton application for the Laravel framework.

Installs: 20

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 1

Forks: 0

Open Issues: 0

Type:project

v2.0.0 2024-10-24 17:32 UTC

This package is auto-updated.

Last update: 2024-10-24 17:39:12 UTC


README

Latest Version on Packagist Total Downloads

Usage

composer require inmanturbo/signal
php artisan signal:configure
php artisan signal:migrate
app(Signal::class)($command);
<?php

use Inmanturbo\Signal\EventWithData;
use Inmanturbo\Signal\Signal;
use Spatie\EventSourcing\AggregateRoots\AggregateRoot;
use Spatie\EventSourcing\Commands\AggregateUuid;
use Spatie\EventSourcing\Commands\HandledBy;
use Spatie\EventSourcing\Snapshots\EloquentSnapshot;
use Spatie\LaravelData\Data;

it('can add item to cart', function (): void {
    $product = new Product(
        '123',
        2,
        100,
    );

    app(Signal::class)(new AddCartItem(
        'fake-uuid',
        'fake-uuid2',
        $product,
    ));

    app(Signal::class)(new AddCartItem(
        'fake-uuid',
        'fake-uuid3',
        $product,
    ));

    $cart = CartAggregateRoot::retrieve('fake-uuid');

    $cart->snapshot();

    app(Signal::class)(AddCartItem::from([
        'cartUuid' => 'fake-uuid',
        'cartItemUuid' => 'fake-uuid4',
        'product' => $product,
    ]));

    $cart = CartAggregateRoot::retrieve('fake-uuid');

    expect($cart->total)->toBe(600);
    expect(count($cart->cartItems))->toBe(3);
    expect(EloquentSnapshot::count())->toBe(1);
});

class Product extends Data
{
    public function __construct(
        public string $sku,
        public int $quantity,
        public int $price,
    ) {}
}

class CartItemAdded extends EventWithData
{
    public function __construct(
        #[AggregateUuid]
        public string $cartUuid,
        public string $cartItemUuid,
        public Product $product,
    ) {}
}

#[HandledBy(CartAggregateRoot::class)]
class AddCartItem extends CartItemAdded
{
    //
}

class CartAggregateRoot extends AggregateRoot
{
    public $total;

    public array $cartItems;

    public function addItem(
        AddCartItem $addCartItem
    ): self {

        $this->recordThat(
            CartItemAdded::from($addCartItem->toArray()),
        );

        return $this;
    }

    public function applyAddItem(CartItemAdded $event)
    {
        $this->total += $amount = ($event->product->quantity * $event->product->price);

        $this->cartItems[] = (object) [
            'uuid' => $event->cartItemUuid,
            'product' => $event->product,
            'amount' => $amount,
        ];
    }
}