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

Bits Laravel Package

glhd/bits

Generate unique 64-bit IDs in PHP for distributed systems. Create Twitter Snowflake, Sonyflake, or custom bit-sequence identifiers. Configure worker/datacenter IDs and a custom epoch to avoid collisions across servers.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the package:

    composer require glhd/bits
    
  2. Configure environment variables (critical for distributed systems):

    BITS_WORKER_ID=1       # Unique per worker (0-31)
    BITS_DATACENTER_ID=1   # Unique per datacenter (0-31)
    BITS_EPOCH=2023-01-01  # Default; adjust if testing with past dates
    
  3. First use case: Generate a Snowflake ID in a controller or service:

    use Glhd\Bits\Snowflake;
    
    $id = Snowflake::make(); // Returns Snowflake object
    $rawId = $id->id();      // Returns integer (e.g., 65898467809951744)
    

Where to Look First

  • README.md: Focus on the Usage and Configuration sections.
  • Snowflake class: Core functionality (e.g., toCarbon(), is()).
  • HasSnowflakes trait: For Eloquent model integration.
  • snowflake_id() helper: Convenience method for raw IDs.

Implementation Patterns

Core Workflows

1. Eloquent Model Integration

use Glhd\Bits\Database\HasSnowflakes;

class User extends Model
{
    use HasSnowflakes; // Auto-generates Snowflake on create

    protected $casts = [
        'id' => Snowflake::class, // Casts DB integer to Snowflake object
    ];
}
  • Pro Tip: Use HasSnowflakes for primary keys to avoid UUID/ULID overhead while maintaining sortability.

2. Time-Based Queries

Replace created_at comparisons with Snowflake IDs:

// Instead of:
User::where('created_at', '>', now()->subDays(7));

// Use:
User::where('id', '>', app(\Glhd\Bits\MakesSnowflakes::class)->firstForTimestamp(now()->subDays(7)));

3. Livewire Integration

Register the synthesizer in AppServiceProvider:

use Glhd\Bits\Support\Livewire\SnowflakeSynth;

public function boot(): void
{
    Livewire::propertySynthesizer(SnowflakeSynth::class);
}
  • Use Case: Pass Snowflake objects directly to Livewire components without serialization issues.

4. Custom Bit Allocation

Extend Bits for non-Snowflake formats (e.g., Sonyflake):

use Glhd\Bits\Bits;

$sonyflake = Bits::sonyflake()->make();

Integration Tips

  • Database: Use BIGINT for Snowflake IDs (64-bit storage).
  • APIs: Cast IDs to strings when sending to JavaScript (avoid Number precision issues).
  • Testing: Use Snowflake::setTestNow() to mock timestamps:
    Snowflake::setTestNow(now()->subHours(1));
    

Gotchas and Tips

Pitfalls

  1. Worker/Datacenter Limits:

    • Issue: Only 1024 workers (32 datacenters × 32 workers each) can run simultaneously.
    • Fix: Use BITS_WORKER_ID and BITS_DATACENTER_ID environment variables. For Lambda/Vapor, implement a locking mechanism (e.g., Redis) to avoid collisions.
  2. Epoch Mismatches:

    • Issue: Setting BITS_EPOCH to a future date throws an exception.
    • Fix: Use now()->subYears(5) for testing if time-traveling to the past.
  3. JavaScript Compatibility:

    • Issue: Raw Snowflake integers exceed Number.MAX_SAFE_INTEGER (~52 bits).
    • Fix: Always cast to string:
      return response()->json(['id' => (string) $snowflake->id]);
      
  4. Livewire Serialization:

    • Issue: Custom Bits objects may not serialize properly.
    • Fix: Use SnowflakeSynth (Snowflake) or BitsSynth (generic) in AppServiceProvider.

Debugging

  • Validate IDs: Use $snowflake->is($other) to compare IDs.
  • Extract Timestamps: Debug with $snowflake->toCarbon() to verify time components.
  • Sequence Conflicts: If IDs repeat, check for:
    • Missing BITS_WORKER_ID/BITS_DATACENTER_ID.
    • Clock skew (ensure all servers sync time via NTP).

Extension Points

  1. Custom Bit Formats:

    $customBits = Bits::custom()
        ->timestampBits(35)
        ->workerBits(6)
        ->sequenceBits(10)
        ->make();
    
  2. Sequence Resolvers:

    • Override the default counter with Redis or database-backed resolvers:
      $bits = Bits::snowflake()
          ->sequenceResolver(new \Glhd\Bits\Sequence\RedisSequenceResolver());
      
  3. Blueprint Macros:

    • Extend Laravel’s query builder:
      use Glhd\Bits\Support\BlueprintMacros;
      
      BlueprintMacros::register();
      // Now use `->whereSnowflakeGreaterThan()` in queries.
      

Config Quirks

  • Default Values: If BITS_EPOCH is unset, defaults to 2023-01-01.
  • Environment Overrides: Use .env or config files to override defaults:
    'bits' => [
        'epoch' => '2020-01-01',
    ],
    
  • Carbon Compatibility: Works with Carbon v2/v3; avoid mixing with Carbon::setTestNow() (use Snowflake::setTestNow() instead).

Performance

  • Benchmark: Snowflake generation is O(1) and faster than UUID/ULID for bulk inserts.
  • Bulk Inserts: Cast IDs to integers in queries to avoid object overhead:
    User::where('id', '>', $minId)->pluck('id'); // Faster than Snowflake objects
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope