Skip to content

Releases: ExeQue/laravel-zipstream

1.1.2

Choose a tag to compare

@ExeQue ExeQue released this 17 Oct 12:18
ebe3502

Fixes #7: toResponse() no longer throws ini_set(): Cannot change zlib.output_compression - headers already sent after every download under PHP-FPM and other SAPIs that send output.

zlib.output_compression is turned off only when it is on, and it is left off afterwards. PHP refuses to change it once output has gone out, and it resets the setting itself when the request ends.

1.1.1

Choose a tag to compare

@ExeQue ExeQue released this 22 Sep 14:43
4308701

Documentation only: no code changed between 1.1.0 and this.

UPGRADE.md ships with the package, and the section covering 1.0 to 1.1 was written after 1.1.0 was tagged - so an application installing 1.1.0 got a guide that stopped at 1.0. This tag carries it.

It matters for the laravel-zipstream-upgrade Boost skill, which reads the guide from vendor/exeque/laravel-zipstream/UPGRADE.md rather than from the web.

1.1.0

Choose a tag to compare

@ExeQue ExeQue released this 22 Sep 14:29
b699d6d

An event handler takes the event first, and after it may ask for the archive it belongs to, or for anything the
container can build.

$zip->on(fn (ProcessError $e, ArchiveBuilder $zip, LoggerInterface $log) => $zip->abort());
$zip->on(fn (StreamedBytes $e, Container $app) => $app->make(ProgressStore::class)->put($e->context));

That saves closing over the builder to reach abort(), and saves a handler resolving its own dependencies.
Parameters are matched by type; anything the container cannot build and that has no default is refused when the
handler is registered rather than when it fires.

Existing handlers are unaffected. PHP passes extra arguments to a closure or a method without complaint.

Also in this release

  • The archive cannot be restructured from a handler. Entries are taken when a run starts, so one added while
    it writes would never reach the archive being produced. add() throws ArchiveFrozenException for the length
    of the run, and the builder reopens afterwards - including after an abort.
  • The event queue comes from the container, so an application can bind its own. A queue built by hand has no
    container, and a handler asking it for something throws with the name of what was missing.

Upgrading

Nothing to do for normal use. Two constructors changed for anyone building the pieces by hand rather than
resolving them: Builder takes the container as its third argument, and Pending::process() requires the
EventQueue it used to default.

Documentation

1.0.0

Choose a tag to compare

@ExeQue ExeQue released this 22 Sep 07:40
1f15f2a

Everything streams. An archive of any size is built while it is written, at constant memory, whether it goes to
a browser, a Laravel disk or a local path.

Upgrading from 0.x? Start with the upgrade guide. Every breaking change is there with before and after.

The fix this release started as

saveToDisk() built the whole archive into php://temp before writing a byte, so peak local disk - or memory,
when the temp directory was not writable - equalled the archive size. A 129 MB archive exhausted a default
128 MB memory_limit.

ZipStream pushes while Flysystem and the AWS SDK pull. The archive is now produced inside a Fiber that the
reader drives, so only one chunk is ever held. A failed write leaves nothing behind: the S3 multipart upload is
aborted, the key removed only if this call created it, and the original exception rethrown.

What else is new

  • Events are objects. A handler declares what it listens for by type-hinting its first parameter, and every
    event carries a frozen Context with the archive id, the entry being streamed and how far along it is.
  • Progress reports itself, throttled by bytes or by an interval, and renders as "10 of 125 files" or
    "5.00 KB of 64.00 MB" in thirty European languages.
  • abort() stops an archive from a handler; abort(discard: true) throws it away, upload and all.
  • fromDiskDirectory() and fromLocalDirectory() add a whole prefix from one listing, sizes included.
  • Zip::fake() records what an archive would have contained, so composition is testable without storage.
  • The response owns PHP's output layer - zlib, buffers, encoding, time limit - so a large download streams
    rather than stalls.
  • ArchiveBuilder declares the public surface, with tests that fail on anything public it does not cover.

Breaking changes

  • output(bool) split into toString() and toStream(); the stream is read-once and not seekable
  • EventType gone; $event->id is $event->context->id, and the event interfaces moved to Events\Contracts
  • zeroHeader(?bool) replaced by withZeroHeader(), withoutZeroHeader() and inheritZeroHeader()
  • Content-Type is application/zip, and a plain filename is no longer quoted
  • saveToDisk() takes $options, and DiskFile::make() takes a FilesystemAdapter
  • A failed write cleans up after itself, which includes deleting a path this call created
  • Three new config keys: progress_every, size_precision, manage_output

Documentation

exeque.github.io/laravel-zipstream - including driver pages for
S3 as both source and destination.

Throw on failed stream reads, route process errors through events

Choose a tag to compare

@ExeQue ExeQue released this 07 Jul 16:49

Full Changelog: 0.1.2...0.1.3

Add forward for `withoutVerification`

Choose a tag to compare

@ExeQue ExeQue released this 19 Apr 18:18

Full Changelog: 0.1.1...0.1.2

Skip verification

Choose a tag to compare

@ExeQue ExeQue released this 19 Apr 18:16

Full Changelog: 0.1.0...0.1.1

Added events system

Choose a tag to compare

@ExeQue ExeQue released this 16 Apr 12:19

Full Changelog: 0.0.5...0.1.0

Move Laravel Boost skill into the correct directory

Choose a tag to compare

@ExeQue ExeQue released this 25 Feb 21:37
0.0.5

Whoops!

Updated agent skill

Choose a tag to compare

@ExeQue ExeQue released this 25 Feb 21:27
0.0.4

docs: add examples for custom contracts and macros in Laravel ZipStre…