Skip to content

5.1.0

Latest

Choose a tag to compare

@github-actions github-actions released this 18 Jul 04:00

Added

  • ManualTestClock gained deterministic wait primitives:
    waitForSleepers(atLeast:), waitForSleepRegistrations(toReach:), and the
    gated advance(by:onceSleepersReach:). They suspend on the sleep
    registration event itself, replacing the yield-count and wall-clock
    polling that time-sensitive tests previously needed before advancing the
    clock. sleepRegistrationCount is now public to support the
    registration-count wait.
  • PhaseMap.derivedGraph now carries a suggested root when exactly one
    declared source phase never appears as a transition target, so the
    root-inferring validate / validationReport overloads work directly on
    acyclic topologies instead of always reporting .missingRoot. Cyclic
    topologies can pass the entry phase explicitly through the new
    PhaseMap.derivedGraph(root:).

CI

  • actions/checkout is now pinned to one SHA (v6.0.3) across every
    workflow; ci.yml and docs.yml had silently stayed on v6.0.2 while cd.yml
    moved ahead. The pin gate now also requires a human-readable release-tag
    comment next to each SHA and rejects the same action pinned to different
    SHAs in different workflows. Documentation builds now also run for pull
    requests targeting develop, so DocC regressions surface before the
    release branch.

Tests

  • The composition primitives gained dedicated behavioral coverage
    (ReducerCompositionTests): declaration-order cumulative mutation,
    builder branch/optional semantics, effect merging and lifting through
    Scope, the IfLet/IfCaseLet missing-child .ignore policy, and
    id-routing through ForEachReducer/ForEachIdentifiedReducer. These
    semantics were previously pinned only indirectly through feature
    fixtures and env-gated perf benchmarks.

Documentation

  • The consumer guides, canonical sample tests, and
    ARCHITECTURE_CONTRACT.md now teach the deterministic ManualTestClock
    waits instead of sleeperCount polling with yield counts or wall-clock
    sleeps; the sample's hand-rolled polling helper is removed.
  • RELEASING.md reflects the published 5.0.0 state, binding documentation
    names binding(_:to:) as the canonical spelling across all READMEs, and
    deliberate runtime/diagnostic boundaries (SelectionCache retention,
    composite task priority, phase-totality scope) are recorded next to the
    code they describe.

Deprecated

  • PhaseMapExpectedTrigger.predicate(_:sampleAction:) is deprecated in
    favor of the identical init(_:sampleAction:). The factory never took a
    predicate closure; coverage has always been decided by running the sample
    action through the declared transitions.

Fixed

  • @InnoFlow now accepts the Self-qualified body signature
    var body: some Reducer<Self.State, Self.Action> and the
    module-qualified constraint spellings InnoFlow.Reducer /
    InnoFlowCore.Reducer. All of these resolve to the same declarations, so
    the qualified forms were being rejected incorrectly. Qualification
    through any other base type is still refused, and the diagnostics name
    the accepted spellings.

Changed

  • EffectTask.potentialCancellationIDs is now computed once at effect
    construction (children carry their own cached sets, so composition costs
    O(children)) instead of re-walking the whole effect tree with fresh Set
    allocations on every execution. Subtrees containing a .lazyMap node
    keep the access-time walk so laziness is preserved.

  • IdentifiedArray.remove(ids:) now removes the batch in a single filter
    pass with one index rebuild (O(n + k)) instead of paying an O(n) element
    shift plus an O(n) index rebuild per removed id (O(n·k)). Semantics are
    unchanged: missing ids are skipped, duplicates are tolerated, and
    insertion order is preserved.

  • The per-action dispatch entry points of the composition primitives
    (Reduce, Scope, IfLet, IfCaseLet, ForEachReducer,
    ForEachIdentifiedReducer) and the O(1) IdentifiedArray accessors are
    now @inlinable, so feature modules that import InnoFlowCore get
    cross-module specialization on the reducer hot path instead of paying an
    unspecialized generic call per composition node per action.
    EffectTask.isNone is now public (previously package) because the
    inlined Reduce.reduce body needs it to skip .none children.

  • swift-syntax is now constrained to the single toolchain line
    "603.0.0"..<"604.0.0" instead of an exact pin, so consumer graphs that
    carry other macro packages can resolve a shared 603.x patch. Maintainer
    reproducibility stays on Package.resolved, which keeps recording the
    verified 603.0.1; resolved-patch upgrades follow the release-hardening
    checklist in RELEASING.md because macro expansion snapshots track the
    SwiftSyntax test-support rendering.