Skip to content

Releases: fatbobman/CoreDataEvolution

0.9.2

02 Jun 02:38

Choose a tag to compare

What's Changed

CoreDataEvolution 0.9.2 refines the MainActor Observation save-failure contract for saveObservedChanges.

  • saveObservedChanges now clears only CoreDataEvolution's staged Observation metadata when a save fails.
  • The failing Core Data context is no longer rolled back by the library; rollback, reset, retry, or continued editing remain application-level policy.
  • Registered producer cleanup now supports failure paths that know only the context, so CDE can discard staged producer metadata without touching user changes.
  • The public Observation docs now present saveObservedChanges as the actor-facing API for property-level Observation response, with clearer notes for direct saves and failure recovery.

Public API Highlights

No new public API surface is required for adopters. The existing Observation APIs remain the supported entry points:

  • @PersistentModel(observation: .mainActor)
  • CDEObservationDomain(container:)
  • CDEObservationDomain.saveObservedChanges(in:)
  • NSModelActor.saveObservedChanges(in:)
  • generated @NSModelActor init(observationDomain:) and saveObservedChanges()

Behavior Notes

On save failure, CDE now separates its own bookkeeping from business recovery:

  • CDE clears staged Observation tokens and rethrows the save error.
  • CDE does not call rollback() on the actor or context.
  • Callers choose whether to rollback, reset, retry, or keep editing.

This keeps property-level Observation cleanup deterministic without discarding app-owned changes.

Validation

  • bash Scripts/run-tests.sh --filter ObservationRuntimeCore
  • bash Scripts/run-tests.sh --filter ObservationIntegration
  • bash Scripts/run-tests.sh --filter MacroExpansionSnapshotTests
  • bash Scripts/run-tests.sh
  • bash Scripts/test-generated-flow.sh

0.9.1

02 Jun 01:42

Choose a tag to compare

What's Changed

0.9.1 is a focused patch release for the MainActor Observation rollout. It adds the Observation-aware generated @NSModelActor initializer and fixes the retained-domain teardown issue found during QA.

Highlights

  • @NSModelActor now generates init(observationDomain:) when initializer generation is enabled.

  • The generated initializer derives the container from CDEObservationDomain.modelContainer, creates a background context, registers it as an Observation producer, and retains the domain/registration for the actor's lifetime.

  • Generated actors also receive a no-argument saveObservedChanges().

    • Actors created with init(observationDomain:) use the retained registered-context save path.
    • Actors created with init(container:) fall back to modelContext.save() and emit a one-time warning that no CDE Observation metadata will be produced.
  • Inline construction is supported:

    let writer = ItemWriter(observationDomain: CDEObservationDomain(container: container))

Fixes

  • Fixed off-main teardown of a retained CDEObservationDomain by using isolated deinit.
  • Generated observed actors now invalidate their retained producer registration in deinit, and the domain removes invalidated registrations from its retained list.
  • Simplified the generated saveObservedChanges() path to remove the dead branch reported by QA.

Compatibility Notes

  • MainActor Observation is now gated with #if compiler(>=6.2).
  • The package tools-version and non-Observation features remain Swift 6.0-compatible.
  • Observation-specific APIs require a Swift 6.2+ compiler and the existing iOS 17 / macOS 14 platform families.
  • NSModelActor.saveObservedChanges(in:) remains available for custom or plain actor contexts that do not retain a producer registration.

Documentation

  • Updated Docs/NSModelActorGuide.md, Docs/ObservationGuide.md, and the DocC overview for the generated initializer, inline domain lifetime, fallback warning, custom initializer cleanup, and Swift compiler 6.2+ Observation requirement.

Validation

  • bash Scripts/run-tests.sh passed with 340 tests / 44 suites.
  • bash Scripts/test-generated-flow.sh passed, including external generated fixture build and run.
  • git diff --check passed.

0.9.0

01 Jun 05:54

Choose a tag to compare

What's Changed

CoreDataEvolution 0.9.0 adds opt-in MainActor Swift Observation for generated Core Data models.

  • Add @PersistentModel(observation: .mainActor) for iOS 17+ / macOS 14+ platform families.
  • Add CDEObservationDomain, a retained container-bound runtime that activates observation routing for container.viewContext.
  • Let SwiftUI and withObservationTracking read CoreDataEvolution-generated Core Data accessors directly, including relationship chains, without forcing extra ObservableObject projection layers into view structure.
  • Route saved changes with property-level precision when the producer can provide changed Core Data keys.
  • Support precise routes for plain viewContext.save(), NSModelActor.saveObservedChanges(in:), NSMainModelActor.saveObservedChanges(in:), registered ordinary background contexts, and wrapper-owned context saves.
  • Add lifecycle and fallback handling for rollback, refresh, reset, delete, temporary object ID rekeying, batch operations, unregistered contexts, and objectID-only merges.
  • Preserve precise local/background routes across store re-merges with CDEPreciseRouteEchoSuppression, including the common NSPersistentCloudKitContainer / Persistent History Tracking echo.
  • Add CDE_OBSERVATION_DEBUG and CDEObservationDomain.isDebugLoggingEnabled for opt-in unified logging diagnostics.
  • Add the public Docs/ObservationGuide.md, update README and DocC, and keep internal mechanism / implementation documents under Docs/Development.

Public API Highlights

  • PersistentModelObservationMode.mainActor
  • CDEObservationDomain(container:preciseRouteEchoSuppression:)
  • CDEObservationDomain.registerChangeProducer(context:)
  • CDEObservationDomain.newObservedBackgroundContext()
  • CDEObservationDomain.saveObservedChanges(in:)
  • CDEObservationDomain.rollbackObservedChanges()
  • CDEPreciseRouteEchoSuppression
  • NSModelActor.saveObservedChanges(in:)
  • NSMainModelActor.saveObservedChanges(in:)

Behavior Notes

  • Observation is opt-in. Plain @PersistentModel and explicit observation: .none keep the non-observable generated output.
  • Only CoreDataEvolution-generated accessors participate in observation. Raw @NSManaged properties and custom getters that bypass generated accessors are not observable.
  • Refresh is save-gated: generated setters write Core Data values, while SwiftUI refresh happens after save, merge, or lifecycle fallback.
  • Unregistered contexts, batch operations, and external CloudKit imports fall back to objectID / all-observable-key-path invalidation when changed-key metadata is unavailable.
  • Field-level precision is useful, but the main goal is cognitive clarity: SwiftUI can stay close to the persisted Core Data object graph, especially in relationship-heavy screens.

Validation

  • bash Scripts/run-tests.sh passed with com.apple.CoreData.ConcurrencyDebug=1 enabled: 334 tests / 44 suites.
  • bash Scripts/test-generated-flow.sh passed: generated source unchanged, conformance and exact validation both reported 0 errors / 0 warnings, and the external generated-flow fixture built and ran successfully.

0.8.12

30 May 00:10

Choose a tag to compare

What's Changed

  • Fix nested to-one typed path predicates such as Memo.path.itemData.item.note.id.equals(noteID).
  • Preserve composed persistent key paths across multi-hop to-one relationship chains.
  • Carry leaf storage metadata into predicate helpers so .raw values still use the RawRepresentable overload correctly.
  • Document multi-hop to-one predicate support in the Typed Path guide.

Validation: bash Scripts/run-tests.sh --filter TypedPath passed with 25 tests.

0.8.11

20 Mar 03:06

Choose a tag to compare

Add to-one predicate helpers

0.8.10

20 Mar 02:52

Choose a tag to compare

CoreDataEvolution 0.8.10

This release adds generated to-many relationship count accessors and completes the related tooling/config plumbing.

Added

  • @PersistentModel(generateToManyCount: Bool = true)
  • Generated relationshipNameCount accessors for to-many relationships
  • CLI/config support for generateToManyCount / --generate-to-many-count

Fixed

  • Preserve generateToManyCount through tooling IR generation
  • Forward generateToManyCount for inspect --config
  • Add regression coverage for generation policy and inspect config propagation

Verification

  • bash Scripts/run-tests.sh

0.8.9

19 Mar 14:17

Choose a tag to compare

Full Changelog: 0.8.8...0.8.9

0.8.8

19 Mar 13:59

Choose a tag to compare

Full Changelog: 0.8.7...0.8.8

0.8.7

19 Mar 13:31

Choose a tag to compare

Full Changelog: 0.8.6...0.8.7

0.8.6

19 Mar 12:24

Choose a tag to compare

Highlights

  • Allow required default-storage attributes without explicit defaults.
  • Normalize underscored runtime default literals in runtime schema building.
  • Add field-level validate optionality ignores via ignoreOptionality: true.
  • Skip formatting cde-tool managed generated files in the pre-commit hook to avoid exact-validation drift.

Included Commits

  • d33868f Allow required default-storage attributes
  • 229e841 Normalize underscored runtime default literals
  • 73e4034 Allow validate optionality ignores
  • 752fe6c Skip formatting cde-tool managed files