Releases: unsignedapps/Vexil
Vexil 3 Alpha 1
This is an initial alpha release of Vexil 3.
Vexil 3 is a ground-up rewrite using Swift Macros and the Visitor Pattern to reduce usage of Mirror and memory usage as well as improving the overall performance.
Important
Vexillographer is not available in Alpha 1.
This is a preview release intended to allow early adopters to assess the impact to their codebase while we work on the remaining pieces in parallel. It has not been tested with production workloads yet (but all unit tests pass).
To learn more about Vexil 3 and what is changing see the Migrating Guide.
🚀 What's Changed
- A macro replacement for the
@Flag
property wrapper. - A macro replacement for the
@FlagGroup
property wrapper. - A
@FlagContainer
macro to replace theFlagContainer
protocol and generate conformance to the Visitor Pattern. - Use of AsyncSequence and AsyncStream under the hood to stream sets of changed flag keys.
- Lazy lookup of publisher flag values.
- Strict concurrency support.
- Dropped support for Flag Diagnostics. You can implement
FlagVisitor
and walk the hierarchy to collect this information yourself if required. - Dropped support for Swift <5.10, iOS <15, tvOS <15, macOS <12, watchOS <8.
📝 What's still to come before we go to beta
- Vexillographer is not yet available.
Swift 6 + Xcode 16 support.swift-testing migration.
Release 2.2.2: Bug fixes 🐛
🐛 Bug Fixes
🧰 Maintenance
- Removed deprecated macOS 10.15 and added latest Xcode versions under macOS 12 @bok- (#111)
- Changed from SwiftLint to SwiftFormat @bok- (#110)
🆕 New Contributors
A huge thanks to new contributors to this project!
@patANZx made their first contribution in #112
Full Changelog: v2.2.1...v2.2.2
Release 2.2.1: Slimming down 🤏
What’s Changed
🚀 Features
- Reduce code bloat from
FlagContainer
s @KeithBauerANZ (#106)
🧰 Maintenance
🆕 New Contributors
A huge thanks to new contributors to this project!
- @huwr made their first contribution in #105
- @KeithBauerANZ made their first contribution in #106
Full Changelog: v2.2.0...v2.2.1
Release 2.2.0: Flag Diagnostics 🔬
What’s Changed
This release is all about diagnostics! With great flexibility sometimes comes complexity, and even with a simple stack of a remote flag value provider and local user overrides it can sometimes be a chore to find out which flags are active and why.
This release adds:
- Point-in-time diagnostics using
flagPole.makeDiagnostics()
andtry snapshot.makeDiagnostics()
- Real-time diagnostics using
flagPole.makeDiagnosticsPublisher()
- A read-only view in Vexillographer by passing in
nil
as the source to edit.
Diagnostics should have almost no overhead unless you're actively using them, and even then it should be minimal. You can read more about Diagnostics in the documentation.
🚀 Features
- Added a read-only view to Vexillographer @bok- (#102)
- Added diagnostics for flag resolution and real-time updates @bok- (#101)
🐛 Bug Fixes
Release v2.1.0: Codable FlagValueDictionaries
🚩 Vexil v2
What’s Changed
💥 Breaking Changes
This release includes one breaking change:
FlagValueDictionary
now uses[String: BoxedFlagValue]
as its internal storage instead of[String: Any]
. This allows better interaction with the flag values, not just the keys, but will be a breaking change for anyone casting directly fromAny
. (#93)
🚀 Features
- Changed
FlagValueDictionary
to use[String: BoxedFlagValue]
as its internal storage @bok- (#93) - Added
Codable
support toBoxedFlagValue
@bok- (#91) - Added support for the standard Swift default setter syntax @bok- (#85)
🧰 Maintenance
Release 1.4: FlagValueSource Manipulation 🦥
What’s Changed
This release adds an optional parameter to FlagPole.snapshot(of:) to allow you to take a snapshot of just the flags that have been set on a specific FlagSource.
It also adds a two new methods:
- FlagPole.copyFlagValues(from:to:) to copy all flags from one
FlagValueSource
to another. - FlagPole.removeFlagValues(in:) to remove all of the flag values in a specific
FlagValueSource
.
It also adds a new supported means of publishing real-time flag value changes, in FlagValueSource.valuesDidChange(keys:). If your FlagValueSource
knows which flags have changed at any one time you can now emit a Set
of their keys and Vexil will re-use an existing Snapshot and only update those keys that have changed. This can cut down on the amount of computation required with large flag hierarchies. FlagValueSource.valueDidChange is maintained for backwards compatibility.
Our documentation website (https://vexil.unsignedapps.com/) is now powered by DocC 🎉
🚀 Features
- Support FlagValueSources publishing changes to individual flags @bok- (#81)
- Added support for removing/resetting all flag values in a given
FlagValueSource
@bok- (#80) - Added ability to create snapshots from specific sources, and to copy flag values between sources @bok- (#79)
📚 Documentation Changes
🧰 Maintenance
v1.3.6: More Bug Fixes 🐛
What’s Changed
🐛 Bug Fixes
When working with a Snapshot
it will dynamically create MutableFlagGroup
s to wrap any FlagGroup
so that you can manipulate flags throughout the hierarchy and their values would be saved back to the Snapshot
. However, we were using a weak
reference to the snapshot, so in cases where you weren't retaining the snapshot itself the MutableFlagGroup
would revert back to its defaults as the snapshot would be nil.
This is especially the case if you were using FlagPole.publisher
and mapping to one of the flag groups. For example, if you were using flagPole.publisher.map({ $0.mySubgroup }).removeDuplicates()
, the behaviour would not be what you would expect as the RemoveDuplicates
publisher would retain the MutableFlagGroup
, but the Snapshot
backing it would be lost.
Misc
v1.3.5: Bug Fixes 🐞
What’s Changed
🐛 Bug Fixes
We now filter the publisher of UserDefaults.didChangeNotification
to ensure that only the instance of UserDefaults
you are subscribed to will trigger changes to your flags. So if you're using an app group instance of UserDefaults
you will no longer see triggers when UIKit or other frameworks update UserDefaults.standard
.
This would also cause flag values to flop as different instance of UserDefaults
would have different flag values set.