Skip to content

release: v10.18.0 — JP3D AsyncSequence progress reporting#454

Merged
SureshKViswanathan merged 1 commit into
mainfrom
v10.18.0-release-candidate
May 26, 2026
Merged

release: v10.18.0 — JP3D AsyncSequence progress reporting#454
SureshKViswanathan merged 1 commit into
mainfrom
v10.18.0-release-candidate

Conversation

@SureshKViswanathan

Copy link
Copy Markdown
Contributor

Summary

  • Ships progressStream() extensions on JP3DDecoder, JP3DROIDecoder, JP3DEncoder, JP3DStreamWriter — modern Swift-concurrency progress API alongside the existing setProgressCallback(_:) closure surface (both remain supported indefinitely).
  • Closes the deferred Phase 3 from v10.17.0's plan with focused MINOR scope so the AsyncStream lifecycle (race-free setup via async method, documented overwrite semantics) is implemented cleanly.
  • MINOR per RELEASING.md — pure additive surface, no existing API change, codestream bytes byte-identical to v10.17.0.

What's New

API Description
JP3DDecoder.progressStream() async, returns AsyncStream<JP3DDecoderProgress>
JP3DROIDecoder.progressStream() async, returns AsyncStream<JP3DDecoderProgress> (surface available; upstream body doesn't currently fire events — documented)
JP3DEncoder.progressStream() async, returns AsyncStream<JP3DEncoderProgress>
JP3DStreamWriter.progressStream() async, returns AsyncStream<JP3DStreamProgress>

Correctness gate (release mode)

  • V10_30_ProgressStreamParityTests 4/4 PASS (JP3DDecoder + JP3DEncoder deliver events; JP3DROIDecoder surface safe; setProgressCallback overwrite of progressStream's relay still fires)
  • swift test --filter JP3D regression 532/532 PASS (1 pre-existing skip)
  • J2KMedicalCorpusEncodePerformanceTests 2/2 PASS
  • J2KMedicalCorpusPerformanceTests 2/2 PASS
  • J2KStrictCrossCodecValidationTests 3/3 PASS

Mandatory commit gate: 7/7 PASS release mode.

Lifecycle design

  • async method → relay closure is installed on the actor before the stream is returned (no race window for early progress events).
  • Calling progressStream() twice overwrites the first stream's writer; first stream's continuation receives no further events but isn't explicitly finished (consumer's break/cancel terminates iteration).
  • setProgressCallback(_:) after progressStream() overwrites the stream-relay closure — use one or the other, not both.
  • Stream does NOT auto-finish at operation completion (decoder doesn't expose a separate "finished" event); consumers break based on observed progress or rely on Task cancellation.

Test plan

  • Mandatory pre-release gate (release mode)
  • Full JP3D regression sweep (532/532 PASS)
  • V10_30 parity tests (4/4 PASS — surface + lifecycle + overwrite semantics)
  • README.md updated (Current Version + Previous Release + Release Status paragraph)
  • getVersion() bumped 10.17.0 → 10.18.0

🤖 Generated with Claude Code

Ships progressStream() extensions on JP3DDecoder, JP3DROIDecoder,
JP3DEncoder, and JP3DStreamWriter — modern Swift-concurrency progress
API alongside the existing setProgressCallback(_:) closure surface
(both remain supported indefinitely). Closes the deferred Phase 3 from
v10.17.0's plan with focused MINOR scope.

The progressStream() method is `async` so the relay closure is
installed on the actor BEFORE the stream is returned — no race window
where early progress events get missed. Lifecycle behaviour explicitly
codified:

  * Calling progressStream() twice overwrites the first stream's
    writer (first stream's continuation receives no further events
    but isn't explicitly finished)
  * The stream doesn't auto-finish at operation completion
    (consumers break based on observed progress or rely on Task
    cancellation)
  * setProgressCallback(_:) after progressStream() overwrites the
    relay (use one or the other, not both)

Consumer pattern:

    let decoder = JP3DDecoder()
    let stream = await decoder.progressStream()

    async let observer: Void = {
        for await progress in stream {
            updateUI(progress)
        }
    }()

    let result = try await decoder.decode(data)
    _ = await observer

Validation:
- V10_30_ProgressStreamParityTests 4/4 PASS release mode
  * JP3DDecoder + JP3DEncoder deliver events during real operations
  * JP3DROIDecoder stream surface available + safe (decoder body
    doesn't currently fire progressCallback — pre-existing upstream
    gap, documented in test header)
  * setProgressCallback after progressStream still fires correctly
- swift test --filter JP3D regression 532/532 PASS
- Mandatory commit gate (release mode) 7/7 PASS

MINOR per RELEASING.md — pure additive surface: 4 new public extension
methods, zero existing API change, codestream bytes byte-identical to
v10.17.0, no perf change on warm or cold paths. Also bumps getVersion()
constant 10.17.0 → 10.18.0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@SureshKViswanathan SureshKViswanathan merged commit 8e02c84 into main May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant