Weave 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

Sequence Bundle Laravel Package

sylius/sequence-bundle

Sylius SequenceBundle generates and manages sequential numbering for Sylius resources, such as order numbers, with configurable generators and prefixes. It provides a flexible sequence system so each entity gets consistent, ordered identifiers.

View on GitHub
Deep Wiki
Context7

Getting Started

Read the source, not the docs. There is no usable documentation site for this repo, and it is archived/read-only. Start with composer.json (note the Symfony 2.x constraints and sylius/* deps), then Resources/config/ (the services.xml wiring), then Model/ and Doctrine/ (the Sequence entity plus its mapping). The PHP classes are thin; the behaviour lives in the DI wiring and the mapping.

Do not composer require this in a Laravel app. It is a Symfony bundle — it expects AppKernel registration, a sylius_sequence extension alias, Doctrine annotation/XML mapping, and compiler passes. Laravel has no equivalent boot path, no service provider, and Eloquent will not discover the entity. The realistic "getting started" is: read it as a specification for ~150 lines you write yourself.

First use case: per-type sequential document numbers — ORD-2024-000123, INV/2024/000001. That is essentially the whole of what this package ever did. Confirm your requirement first (see the gaplessness note below), then implement natively.

Schema::create('sequences', function (Blueprint $table) {
    $table->string('type')->primary();      // "order", "invoice_2024"
    $table->unsignedBigInteger('index')->default(0);
});

Implementation Patterns

Port the model, not the code. The transferable abstraction is: one row per sequence type, a monotonically increasing counter, and a format string applied at read time so presentation (prefix, padding, year token) can change without renumbering history.

Concurrency-safe generation is the entire point. The bundle solved this with a Doctrine entity flush inside a transaction; the Laravel equivalent is a row lock:

final class SequenceGenerator
{
    public function next(string $type, string $format = '{index}'): string
    {
        return DB::transaction(function () use ($type, $format) {
            DB::table('sequences')->insertOrIgnore(['type' => $type, 'index' => 0]);
            $current = DB::table('sequences')->where('type', $type)
                ->lockForUpdate()->value('index');

            DB::table('sequences')->where('type', $type)
                ->update(['index' => $current + 1]);

            return strtr($format, [
                '{index}' => str_pad((string) ($current + 1), 6, '0', STR_PAD_LEFT),
                '{year}'  => now()->format('Y'),
            ]);
        });
    }
}

Registry pattern for type keys. The bundle maps a sequence type name to a generator service. In Laravel that becomes a container tag, a match, or a small SequenceType enum. Keep type values as stable strings (order, invoice) — they are a database contract, not a class name. Never rename one without a data migration.

Reserve early, persist inside the same transaction. Generate the number while the order/invoice row is being created, in the same DB::transaction(). This is what keeps the counter co-transactional with the record it numbers, and it is the difference between gaps-on-rollback and duplicates-on-crash.

Formatting layer separate from the counter. Store the raw integer; format at the boundary. That lets you add INV/ prefixes or switch padding without touching stored history.

Gap-tolerant alternative: for order IDs where gaps are fine, skip the table entirely — Str::ulid(), Str::orderedUuid(), or a DB-native sequence. Keep the lock-based generator only for documents where ordering or gaplessness matters (invoices).

Gotchas and Tips

Gapless vs. gap-tolerant is a product decision, not a technical one. Gapless invoice numbering (common in EU tax jurisdictions) forbids holes caused by rollback, so the counter must be incremented in the same transaction as the document insert, and rollbacks must roll the counter back too. Order numbers usually tolerate gaps. The bundle's design implies this but does not solve it for you — decide per document type before writing code.

The row lock serializes all writers for that sequence. Fine at low volume; a bottleneck for high-throughput order creation across many app nodes. Options: separate counters per period/tenant (shard the lock), or Redis INCR with a durable write-through — but note Redis loss means either duplicate or skipped numbers, which is a policy question you must answer explicitly for invoices.

Never use a 32-bit counter. unsignedBigInteger for the index; 32-bit exhaustion in an invoice sequence is an annual problem at moderate volume.

Format-drift bugs are silent. Padding, year tokens, and reset logic that differ between a spike and the ported version produce numbers that look valid and only fail in accounting. Write concurrency and rollback tests before wiring into order/invoice creation, not after.

Archived = yours entirely. No CVE response, no PHP 8.x compat work, no upstream issues (the repo is a read-only subtree split of the Sylius monorepo, so history lives upstream). Do not vendor it as a "temporary" dependency — the maintenance burden of the concept is a table plus a transaction; the burden of the artifact is unbounded.

Extension points to reuse if you do port code: the sequence registry (type → generator) is the useful seam — it lets you swap in a Redis- or DB-native generator per type without changing call sites. Port formatting under MIT attribution if the license permits, but default to a clean implementation.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core