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

Laravel Rewind Laravel Package

avocet-shores/laravel-rewind

Full version control for Eloquent models: rewind, fast-forward, restore, diff, and query point-in-time state. Uses hybrid diffs + snapshots for efficient storage and fast reconstruction, with locking for safe concurrent writes, batching, queues, and pruning.

View on GitHub
Deep Wiki
Context7
v0.9.0

New Features

  • Batch versioning -- Rewind::batch(fn) groups multiple model changes under a shared batch_uuid. Query with RewindVersion::inBatch($uuid).
  • Non-destructive restore -- Rewind::restore($model, $version) creates a new version from a previous version's state. Tracks VersionEventType::Restored and stores restored_from_version in meta.
  • Custom version model -- Set version_model in config to extend RewindVersion with custom columns, scopes, or accessors.

Migration

New batch_uuid column on the versions table. Publish and run:

php artisan vendor:publish --tag=laravel-rewind-migrations
php artisan migrate

New Config Keys

// Custom version model (must extend RewindVersion)
'version_model' => null,

Closes #54, #55, #56.

v0.8.0

New Features

  • Version diff/comparison API -- Compare any two versions with Rewind::diff($model, $from, $to), returns a structured VersionDiff DTO with changed, added, and removed attributes.
  • Custom metadata per version -- Attach arbitrary key-value data to versions via Rewind::withMeta(['reason' => '...']). Stored in a new meta JSON column. Metadata is automatically cleared after version creation.
  • Event type tracking -- Each version now records its event_type (created, updated, or deleted) in a dedicated column, making version history queryable by action type.
  • Query scopes on RewindVersion -- New scopes: forModel(), byUser(), ofType(), betweenDates(), betweenVersions() for filtering version records.
  • Version pruning system -- New rewind:prune command with --keep, --days, --model, --pretend, and --force options. Automatically converts the new oldest version to a snapshot to preserve navigability.
  • Auto-pruning -- Per-model $maxRewindVersions property and global max_versions config. Pruning is batched using snapshot_interval as a buffer to amortize transaction costs.
  • Configurable lock timeout handling -- New on_lock_timeout config with log, event, and throw modes. New RewindVersionLockTimeout event and LockTimeoutRewindException.
  • Composite database index -- (model_type, model_id, version) for faster version-scoped queries.

Bug Fixes

  • Fix soft delete version timestamp mismatch -- moved version creation to deleted event to capture exact database timestamp.
  • Fix queued listener serialization -- capture changes and wasRecentlyCreated at dispatch time so they survive SerializesModels round-trips.
  • Fix version pruning with gaps -- iterate actual version records instead of sequential integers.
  • Add transaction safety -- version creation, current_version update, and auto-prune are now atomic.
  • Add cache lock to goTo() for concurrency safety.
  • Use saveQuietly() when updating current_version to prevent unintended model events.

Architecture

  • New StateBuilder service consolidating all state reconstruction logic.
  • New RewindManagerInterface contract for dependency injection.
  • New VersionPruner service, PruneResult DTO, RewindContext singleton, SchemaHelper utility.
  • ApproachEngine now accepts Collection for use outside of model context.
  • Internal classes marked with [@internal](https://github.com/internal) to define public API boundary.

Housekeeping

  • Removed version field from composer.json (Packagist reads git tags).
  • Changed minimum-stability from dev to stable.
  • Added CONTRIBUTING.md.

New Config Options

Re-publish the config file to get all new options, or add them manually:

php artisan vendor:publish --tag="laravel-rewind-config" --force
Key Env Variable Default Description
user_id_cast LARAVEL_REWIND_USER_ID_CAST integer Eloquent cast for the user ID column. Set to string for UUID primary keys.
max_versions LARAVEL_REWIND_MAX_VERSIONS null Auto-prune old versions per model. null disables pruning.
prune_keep_versions LARAVEL_REWIND_PRUNE_KEEP null Default --keep value for the rewind:prune command.
prune_older_than_days LARAVEL_REWIND_PRUNE_DAYS null Default --days value for the rewind:prune command.
on_lock_timeout LARAVEL_REWIND_ON_LOCK_TIMEOUT log Lock failure behavior: log, event, or throw.
queue.tries LARAVEL_REWIND_QUEUE_TRIES 3 Retry attempts for the queued listener.
queue.timeout LARAVEL_REWIND_QUEUE_TIMEOUT 60 Timeout (seconds) for the queued listener.
queue.backoff -- [2, 10, 30] Backoff delays (seconds) between retries.

Migration Notes

This release adds two new nullable columns to the rewind_versions table: event_type (string) and meta (json).

New installations get these columns automatically via the existing migration.

Existing installations should publish and run the new upgrade migration:

php artisan vendor:publish --tag="laravel-rewind-migrations"
php artisan migrate

The upgrade migration is idempotent — it checks for existing columns before adding them, so it's safe to run even if you've already added the columns manually.

Full Changelog: https://github.com/avocet-shores/laravel-rewind/compare/v0.7.4...v0.8.0

v0.7.4
v0.7.3

What's Changed

New Contributors

Full Changelog: https://github.com/avocet-shores/laravel-rewind/compare/v0.7.2...v0.7.3

v0.7.2

What's Changed

New Contributors

Full Changelog: https://github.com/avocet-shores/laravel-rewind/compare/v0.7.1...v0.7.2

v0.7.1

What's Changed

Bug Fixes and Improvements

Docs

New Contributors

Full Changelog: https://github.com/avocet-shores/laravel-rewind/compare/v0.7.0...v0.7.1

v0.7.0

What's Changed

Full Changelog: https://github.com/avocet-shores/laravel-rewind/compare/v0.6.0...v0.7.0

v0.10.0

New Features

  • State transition tracking -- Designate fields as state fields via $rewindStateFields on your model. Rewind records structured from/to transitions alongside each version. Query with whereStateBecame(), whereStateWas(), whereStateChanged(), and whereStateTransition() scopes, or get a full timeline with $model->stateHistory($field).

Migration

New state_transitions column on the versions table. Publish and run:

php artisan vendor:publish --provider="AvocetShores\LaravelRewind\LaravelRewindServiceProvider"
php artisan migrate
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport