Skip to content

Releases: fatbobman/CoreDataEvolution

CoreDataEvolution 0.9.3

Choose a tag to compare

@fatbobman fatbobman released this 07 Jul 03:38

Highlights

  • Added public GitHub issue templates and a pull request template for bug reports, feature requests, documentation feedback, and contributions.
  • Updated README, DocC, and user guides to match the current API surface and generated-model workflow.
  • Added a public CDETool known limitations guide, separating user-facing tooling boundaries from internal TODO tracking.
  • Routed fallback save warnings through the Observation logger so diagnostics stay opt-in and consistent.
  • Kept CoreDataEvolutionClient as an internal smoke executable target instead of a package product.

Public Repository Cleanup

  • Removed maintainer-only workflow files, development notes, and local hook documentation from the public tree.
  • The shipped package products remain CoreDataEvolution, CoreDataEvolutionToolingCore, and cde-tool.

Compatibility

  • No minimum platform target changes.
  • No migration step is required for existing library consumers.

0.9.2

Choose a tag to compare

@fatbobman fatbobman released this 02 Jun 02:38

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

Choose a tag to compare

@fatbobman fatbobman released this 02 Jun 01:42

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

Choose a tag to compare

@fatbobman fatbobman released this 01 Jun 05:54

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

Choose a tag to compare

@fatbobman fatbobman released this 30 May 00:10

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

Choose a tag to compare

@fatbobman fatbobman released this 20 Mar 03:06
Add to-one predicate helpers

0.8.10

Choose a tag to compare

@fatbobman fatbobman released this 20 Mar 02:52

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

Choose a tag to compare

@fatbobman fatbobman released this 19 Mar 14:17

Full Changelog: 0.8.8...0.8.9

0.8.8

Choose a tag to compare

@fatbobman fatbobman released this 19 Mar 13:59

Full Changelog: 0.8.7...0.8.8

0.8.7

Choose a tag to compare

@fatbobman fatbobman released this 19 Mar 13:31

Full Changelog: 0.8.6...0.8.7