Skip to content
CAI
Software that uses CAICheck a score

apple/swift-async-algorithms

70.1

Strong · 30 September 2026

16.9k

lines of production code

Swift

primary language

2

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a Swift library providing a comprehensive suite of operators and utilities for manipulating asynchronous sequences. It enables developers to perform complex stream processing tasks such as merging, zipping, debouncing, and buffering data, while also offering robust channel implementations for producer-consumer synchronization. The package includes extensive testing infrastructure and performance benchmarks to ensure the reliability and efficiency of these asynchronous algorithms.

How it got here

2022 — Async sequence operators and testing infrastructure

12 changes.

This period focused on expanding the AsyncAlgorithms library with new operators for combining, merging, and processing asynchronous sequences, such as zip, merge, combineLatest, and debounce. Significant effort was also dedicated to building a robust testing ecosystem, including comprehensive unit tests, performance benchmarks, and a visual diagram DSL for validating sequence behavior.

2023–2026 — AsyncAlgorithms and AsyncStreaming expansion

9 changes.

This period focused on expanding the AsyncAlgorithms library with new sequence operators like buffer, interspersed, and flatMapLatest, while significantly improving concurrency safety through a state-machine-based channel rewrite and the introduction of MultiProducerSingleConsumerAsyncChannel. It also introduced the new AsyncStreaming module, providing comprehensive reader/writer protocols and duplex channels for bidirectional stream management with independent backpressure strategies.

Features

Add AsyncSequence.flatMapLatest operator

The \AsyncSequence\ protocol now includes a \flatMapLatest\ method (available in AsyncAlgorithms 1.3) that transforms elements into new asynchronous sequences, emitting only elements from the most recently produced inner sequence. When a new element is emitted by the source sequence, any ongoing iteration on the previous inner sequence is automatically cancelled, and iteration begins on the new one. This allows consumers to easily handle scenarios where only the latest result of an asynchronous transformation is relevant, discarding stale or in-flight results.

Sources/AsyncAlgorithms/FlatMapLatest · high confidence

Add interspersed method to AsyncSequence

The \AsyncSequence\ protocol now includes an \interspersed\ method that returns a new asynchronous sequence with a specified separator inserted between elements. This feature supports inserting a static separator value, a synchronous closure, or an asynchronous closure to generate separators, and allows configuring the frequency of insertion via an \every\ parameter.

Sources/AsyncAlgorithms/Interspersed · high confidence

Introduce AsyncSequence validation diagram DSL and test infrastructure

The \Sources/AsyncSequenceValidation\ module now provides a new \AsyncSequenceValidationDiagram\ result builder and supporting types (Clock, Event, Expectation, Input, Test, Theme) that allow users to define asynchronous sequence tests using a visual diagram syntax. This DSL lets you specify expected inputs, operations, and outputs with tick-based timing, grouping, and error handling, while the internal \WorkQueue\ and \TaskDriver\ components drive the simulated clock and task execution to validate behavior against the specified diagram.

Sources/AsyncSequenceValidation · high confidence

Introduce MultiProducerSingleConsumerAsyncChannel with watermark backpressure

Adds the MultiProducerSingleConsumerAsyncChannel type (available on Swift 6.1+), a multi-producer, single-consumer async channel that supports watermark-based backpressure strategies. The channel allows multiple producers to send values while suspending producers when the buffer exceeds a high watermark and resuming them when it drops below a low watermark. It includes internal helpers like Disconnected for moving non-Sendable values across isolation regions and \_TinyArray for optimized storage, along with termination callbacks and error handling for finished channels.

Sources/AsyncAlgorithms/MultiProducerSingleConsumerChannel · high confidence

Introduce \`zip\` for combining two or three async sequences

Added \zip\ functions and their supporting types (\AsyncZip2Sequence\, \AsyncZip3Sequence\, \ZipStateMachine\, \ZipStorage\) to concurrently await and emit tuples of values from two or three \AsyncSequence\ inputs. The implementation uses a state machine and task group to manage upstream iteration and downstream demand, ensuring thread-safe coordination of the combined streams.

Sources/AsyncAlgorithms/Zip · high confidence

Introduce combineLatest for two and three asynchronous sequences

Adds the \combineLatest(\:\:)\ and \combineLatest(\:\:\_:)\ functions, which create asynchronous sequences that emit tuples of the latest values from two or three base \AsyncSequence\s. The implementation includes \AsyncCombineLatest2Sequence\ and \AsyncCombineLatest3Sequence\ types, along with the underlying \CombineLatestStateMachine\ and \CombineLatestStorage\ to manage concurrent iteration, buffering, and cancellation. These sequences emit values only after each base has emitted at least one value and finish when all bases are complete.

Sources/AsyncAlgorithms/CombineLatest · high confidence

Introduce debounce operator for asynchronous sequences

Adds a new \debounce\ method to \AsyncSequence\ that emits the latest element from the source sequence only after a specified quiescence period has elapsed. This allows users to filter out rapid, successive emissions by waiting for a pause in the data stream, configurable with a specific interval, optional tolerance, and a pluggable \Clock\ for testing or custom timing control.

Sources/AsyncAlgorithms/Debounce · high confidence

Introduce merge operator for two and three asynchronous sequences

Added \AsyncMerge2Sequence\ and \AsyncMerge3Sequence\ types, along with their corresponding \merge\ functions, allowing users to combine elements from two or three upstream \AsyncSequence\s into a single merged asynchronous sequence. The implementation uses a shared \MergeStateMachine\ and \MergeStorage\ to coordinate consumption of the upstream sequences, handling buffering, cancellation, and error propagation.

Sources/AsyncAlgorithms/Merge · high confidence

Introduces AsyncStreaming module with reader/writer protocols and duplex channel

Adds the new \AsyncStreaming\ module (available on macOS 27.0, iOS 27.0, watchOS 27.0, tvOS 27.0, visionOS 27.0, and requiring Swift 6.4+) providing \AsyncReader\ and \CallerAsyncReader\ protocols for consuming streams with callee-managed and caller-managed buffering, respectively, along with \AsyncWriter\ and \CallerAsyncWriter\ protocols for producing streams. The module includes \pipe\ convenience methods to transfer data between readers and writers, adapters to convert between caller-managed and callee-managed buffering styles, and a \DuplexAsyncChannel\ for bidirectional in-memory communication with independent backpressure strategies.

Sources/AsyncStreaming · high confidence

New AsyncSequence operators and utilities

The library introduces a suite of new asynchronous sequence operators: \adjacentPairs()\ to iterate over consecutive element pairs; \compacted()\ to filter out nil values; \chain(\:\:)\ and \chain(\:\:\:)\ to concatenate two or three sequences; \joined()\ and \joined(separator:)\ to flatten nested sequences; \reductions(\:)\ (inclusive) and \reductions(into:\:)\ (exclusive) to emit intermediate accumulation results; \chunked(ofCount:)\, \chunked(by:)\, and \chunked(on:)\ to group elements into collections based on count, grouping predicates, or projection uniqueness; \chunks(ofCount:or:)\ to split sequences by count or signal sequences; and \mapError(\:)\ to transform error types. Additionally, \AsyncBufferedByteIterator\ provides a high-performance iterator for reading byte streams.

Sources/AsyncAlgorithms · high confidence

New buffer operators for AsyncSequence

The \AsyncSequence\ protocol now includes a \buffer(policy:)\ method that allows you to control how elements are buffered during asynchronous iteration. You can choose from four policies: \bounded\ (pauses the upstream when the buffer is full), \unbounded\ (no limit), \bufferingNewest\ (discards oldest elements when full), and \bufferingOldest\ (discards newest elements when full). This feature is available starting with AsyncAlgorithms 1.0.

Sources/AsyncAlgorithms/Buffer · high confidence

Behavioural changes

Reimplemented channels with a state machine to fix potential deadlocks

The \AsyncChannel\ and \AsyncThrowingChannel\ implementations in the Channels module have been rewritten using a dedicated \ChannelStateMachine\ and \ChannelStorage\ to manage producer-consumer synchronization. This architectural change replaces the previous implementation to eliminate potential deadlocks that could occur when resuming continuations while holding locks, ensuring more robust back-pressure handling and concurrency safety for task-to-task communication.

Sources/AsyncAlgorithms/Channels · high confidence

Swift 5.8 support with strict concurrency and availability macros

The package now includes a dedicated Swift 5.8 build configuration that enables strict concurrency checking and defines availability macros for AsyncAlgorithms versions 1.0 through 1.3, mapping specific API sets to macOS 10.15/iOS 13.0 and later platforms including visionOS 2.0. This upgrade also updates the dependency on swift-collections to version 1.1.0 and refines the target structure by removing the separate AsyncSequenceValidation and AsyncAlgorithms\_XCTest product libraries in favor of internal targets, while adding support for additional platforms like Android, Linux, and WASI in test conditions.

(repo-wide) · high confidence

Test coverage

Added test support utilities for AsyncAlgorithms; Added tests for AsyncInterspersedSequence; Added tests for AsyncStreaming readers, writers, and channels; Added tests for MultiProducerSingleConsumerAsyncChannel source lifecycle; Added throughput performance tests for AsyncAlgorithms; Added unit tests for AsyncAlgorithms operators; Added validation test helpers for AsyncSequenceValidation.

Dependencies

Add AsyncStreaming product and update swift-collections dependency

The package now exposes a new \AsyncStreaming\ library product, which depends on \BasicContainers\, \ContainersPreview\, and \DequeModule\ from the \swift-collections\ package. The \swift-collections\ dependency is explicitly set to version 1.7.0, and the package configuration includes an \UnstableAsyncStreaming\ trait to enable source-unstable components in the \\_AsyncStreaming\ module.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 69 → 70 (+1.5)
  • Rubric changed (rubric-2026.09.11 → rubric-2026.09.18) — scores are not directly comparable.

Lenses

  • Code Health 89 → 89 (+0.0)
  • Architecture 98 → 92 (-5.6)
  • Maturity 74 → 73 (-1.9)
  • Readiness 50 → 55 (+5.2)
  • Security 100 → 100 (+0.0)
  • Performance 100 (new)

Resolved (4)

  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • Off-boarding risk: anonymized user #1
  • Orphaned files with no living knowledge

New (13)

  • Concentrated knowledge decay
  • Coverage not measured — Swift suite
  • Dependency hygiene PARTLY measured — SwiftPM pinning read, dependency currency NOT established
  • Inconsistent naming for adapter conversion methods. AsyncWriter converts to a caller-side writer via asCallerAsyncWriter(), while CallerAsyncWriter converts to an async writer via asAsyncWriter(). The directionality is clear, but the naming pattern is not symmetrical or parallel. asCallerAsyncWriter implies 'become a caller async writer', whereas asAsyncWriter implies 'become an async writer'. A more consistent pattern might be toCallerAsyncWriter and toAsyncWriter, or ensuring the suffix matches the target type exactly.
  • Inconsistent naming for equivalent operations across related types. AsyncReader uses pipe and pipe(copyingInto), while CallerAsyncReader uses pipe and pipe(bufferingInto). The semantic difference between 'copying' and 'buffering' is not immediately obvious from the names alone, and the verb 'pipe' is used for both, but the secondary action names differ (copyingInto vs bufferingInto).
  • Inconsistent naming strategy for buffer policies. bounded is a general term, while bufferingLatest and bufferingOldest are specific strategies. It is unclear if bounded implies a specific strategy (e.g., oldest) or is a generic factory. If bounded is a specific strategy, it should be named like the others (e.g., bufferingBounded or bufferingOldest if that's what it does). If it is a generic factory, the other two should perhaps be bufferingLatest and bufferingOldest under a bounded umbrella, or all should be specific strategies.
  • Most significant orphaned file (Sources/AsyncAlgorithms/CombineLatest/CombineLatestStateMachine.swift)
  • Most significant orphaned file (Sources/AsyncAlgorithms/Debounce/DebounceStateMachine.swift)
  • Most significant orphaned file (Sources/AsyncAlgorithms/Merge/MergeStateMachine.swift)
  • Off the main sequence: AsyncAlgorithms
  • Off-boarding risk: anonymized user #1
  • Projects may be oversized for their cohesion
  • TooManyMethods: AsyncSequence (Sources/AsyncAlgorithms/AsyncAdjacentPairsSequence.swift)

Changes since last survey

  • 2 commits — 0 feature/other, 2 fixes

By area

  • (root) — 1 commit
  • Tests/AsyncStreamingTests — 1 commit

Notable commits

  • fix: Fix compilation errors in AsyncStreaming (#459)
  • fix: fix for Swift Collections 1.7.0 (#456)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

apple/swift-async-algorithms was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 30 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 13713a4ffdee8abd929f92568ee9462a46ae26e0 — the exact code this score is about.
  • Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-cb25ca4feafa.