Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Types Laravel Package

flow-php/types

Flow PHP type system library with typed value objects and type definitions for consistent, safe data handling across the Flow ecosystem. Designed for ETL pipelines, it helps enforce data contracts and reduce runtime type errors.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require flow-php/types
    

    Ensure your project uses PHP 8.3+, 8.4+, or 8.5+.

  2. First Use Case: Strongly Typed Collections Replace loose arrays with flow-php/types' Collection or Map:

    use Flow\Types\Collection;
    use Flow\Types\Map;
    
    $users = new Collection([
        new User('Alice', 30),
        new User('Bob', 25),
    ]);
    
    • Why? Enforces type consistency at runtime and improves IDE autocompletion.
  3. Key Entry Points

    • Documentation (official guide)
    • src/Types/ (core classes like Collection, Map, Result, Option)
    • src/ValueObjects/ (immutable value objects like Email, Uuid, Money)

Implementation Patterns

Core Workflows

  1. ETL Pipelines Use Result for error handling:

    use Flow\Types\Result;
    
    function validateEmail(string $email): Result<Email> {
        return Email::tryFrom($email)
            ->mapErr(fn($e) => new ValidationError($e->getMessage()));
    }
    
    • Pattern: Chain map(), mapErr(), and flatMap() for functional error handling.
  2. Immutable Data Replace mutable objects with value objects (e.g., Money, Email):

    $amount = new Money(100, 'USD');
    $amount->add(new Money(50, 'USD')); // Returns new instance, original unchanged.
    
    • Pattern: Use ->withX() methods for "copy-with" updates.
  3. Type-Safe Config Define configs as Map:

    $config = new Map([
        'database' => new Map(['host' => 'localhost', 'port' => 5432]),
        'cache' => new Map(['driver' => 'redis']),
    ]);
    
    • Pattern: Access via ->get('database.host') with runtime type checks.

Integration Tips

  • Laravel Services Inject Collection/Map into controllers/services:
    public function __construct(
        private Collection $users,
        private Map $settings
    ) {}
    
  • Validation Use Option for nullable fields:
    $user = new User(
        name: 'Alice',
        email: Option::some(new Email('alice@example.com')),
    );
    
  • API Responses Return Result for API errors:
    return response()->json($result->match(
        fn($data) => ['success' => true, 'data' => $data],
        fn($error) => ['success' => false, 'error' => $error->getMessage()]
    ));
    

Gotchas and Tips

Pitfalls

  1. Performance Overhead

    • Value objects (Email, Money) are immutable and may create copies on modification.
    • Fix: Cache frequently used instances or use ->equals() for comparisons.
  2. Static Analysis Conflicts

    • Some tools (e.g., PHPStan) may flag Collection/Map as "non-traversable."
    • Fix: Extend ArrayAccess or use @method PHPDoc annotations:
      /** @method mixed offsetGet(string $offset) */
      
  3. Serialization Quirks

    • Collection/Map rely on __serialize()/__unserialize().
    • Fix: Explicitly implement JsonSerializable for JSON APIs:
      $data = json_encode($collection->toArray());
      

Debugging Tips

  • Type Mismatches Use instanceof checks or is_a() for runtime validation:
    if ($value instanceof Email) { ... }
    
  • IDE Support Enable PHPStan/Psalm for full type hints. Example .phpstan.neon:
    includes:
        - vendor/flow-php/types/extension.neon
    

Extension Points

  1. Custom Value Objects Extend AbstractValueObject:
    class Domain extends AbstractValueObject {
        public function __construct(private string $value) {}
        public function getValue(): string { return $this->value; }
    }
    
  2. Collection Extensions Add custom methods via traits:
    trait FilterableCollection {
        public function filterByAge(int $age): static {
            return $this->filter(fn($user) => $user->getAge() >= $age);
        }
    }
    
  3. Result Matching Override match() for domain-specific logic:
    $result->match(
        fn($data) => logger()->info("Success: {$data}"),
        fn($error) => logger()->error("Failed: {$error}")
    );
    

Config Quirks

  • Default Values Use Map::withDefaults() for optional configs:
    $defaults = new Map(['timeout' => 30]);
    $config = new Map(['timeout' => 60], $defaults);
    
  • Environment Variables Parse env vars into typed objects:
    $email = Email::tryFrom(env('USER_EMAIL'))
        ->unwrapOrThrow(new InvalidArgumentException('Email missing!'));
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky