Files
arcane_framework/CHANGELOG.md
T

632 lines
20 KiB
Markdown

## 2.1.0
### Authentication Service
- [NEW] Added `AuthenticationStatus.unknown` as the new default authentication state (replaces `unauthenticated` as default).
- [NEW] Added `AuthenticationStatus.isUnknown` getter to explicitly check for unknown state.
- [CHANGE] `AuthenticationStatus.isUnauthenticated` now returns `true` for both `unauthenticated` and `unknown` states (use `isUnknown` to distinguish).
- [CHANGE] `ArcaneAuthenticationService` now initializes with `AuthenticationStatus.unknown` instead of `unauthenticated`.
- [CHANGE] `ArcaneAuthenticationService.reset()` now resets status to `unknown`.
- [CHANGE] Updated tests to reflect new default status behavior.
## 2.0.6
### Arcane Framework
- [BREAKING] This package no longer exports the `Error` and `Ok` symbols from
the `result_monad` package.
#### Migration Steps (`Error`/`Ok`)
1. Add the `result_monad` package to your `pubspec.yaml` file.
2. Use the import `import 'package:result_monad/result_monad.dart';` to access
`Error` and `Ok` symbols.
## 2.0.5
### Arcane Framework
- [NEW] Added `Arcane.service` typed lookup entrypoint for provider-aware
service access:
- `Arcane.service.ofType<T>(context)`
- `Arcane.service.requiredOfType<T>(context)`
## 2.0.4
### Logging Service
- [NEW] Added `LogInterceptorCallback` typedef and updated `LogInterceptor`
callback-based APIs to use the shared callback type alias.
## 2.0.3
### Logging Service
- [CHANGE] `LogEvent` JSON serialization now delegates recursive nested
`metadata` / `extra` encode-decode handling to `arcane_helper_utils` JSON
extensions (`toJsonValue`, `toJsonMap`, `fromJsonValue`, `fromJsonMap`).
- [CHANGE] Refactored `LogInterceptor` to an interface-style contract with a
factory constructor for callback interceptors, so reusable class-based
interceptors can be implemented without superclass callback plumbing.
## 2.0.2
### Logging Service
- [BREAKING] Replaced the `@LoggingFeature(...)` annotation (compile-time only,
not readable at runtime in Flutter) with the `LoggerName` mixin.
Mix `LoggerName` into a `LoggingInterface` subclass and override
`name` to expose a runtime-accessible name inside `log()`.
#### Migration Steps (LoggingFeature)
1. Replace any `@LoggingFeature("...")` annotation with `with LoggerName` and
add an `@override String get name => '...';` getter to the class body.
Before:
```dart
@LoggingFeature("my-feature")
class MyLogger extends LoggingInterface {...}
```
After:
```dart
class MyLogger extends LoggingInterface with LoggerName {
@override
String get name => "my-feature";
}
```
## 2.0.1
### Arcane Framework
- [NEW] `ArcaneApp` now owns and publishes a live service registry for
provider-aware static lookups.
- [CHANGE] `Arcane.features`, `Arcane.auth`, `Arcane.theme`, and
`Arcane.environment` now prefer the live `ArcaneApp` registry instance when
available, then fall back to built-in singletons.
- [BREAKING] `Arcane` is now a static utility surface (no instantiable
singleton constructor).
- [BREAKING] Several `package:arcane_framework/src/...` import paths changed
(for example, `src/providers/...` -> `src/service/...` and
`src/services/reactive_theme/...` -> `src/services/theme/...`). Consumers
importing from `src` directly must update import paths.
- [NEW] Added optional `ArcaneApp.builder` callback (TransitionBuilder style)
for capturing provider-aware build contexts from within `ArcaneApp`.
- [DEPRECATED] `ArcaneApp.child` is now deprecated in favor of
`ArcaneApp.builder` (legacy child usage remains supported during migration).
- [DEPRECATED] `BuildContext.serviceOfType<T>()` is now deprecated in favor of
`BuildContext.service<T>()`.
### Environment Service
- [NEW] Added `ArcaneEnvironmentService` as a singleton `ArcaneService` instance.
- [CHANGE] Changed `ArcaneEnvironment` is no longer a `Cubit` and is now an
`InheritedWidget`.
- [NEW] Added `Arcane.environment` shortcut for direct environment access.
- [NEW] Added environment service to `Arcane.services` built-in list.
- [CHANGE] `ArcaneEnvironmentProvider` is now a `StatefulWidget` instead of a
`StatelessWidget` with a `BlocProvider`.
- [NEW] `ArcaneEnvironmentProvider` now provides methods for
`enableDebugMode()`, `disableDebugMode()` and `setEnvironment()`.
- [NEW] Added `environmentChanges` stream for realtime environment updates.
#### Migration Steps (ArcaneEnvironment)
1. The `state` getter has been removed from `ArcaneEnvironment`. If you previously accessed environment state via `Arcane.environment.state`, update your code to use the new API:
- **Before:**
```dart
final env = Arcane.environment.state;
```
- **After:**
```dart
final env = Arcane.environment.current;
```
2. If you were using `Cubit`-style APIs, migrate to the new `InheritedWidget`/`ValueNotifier`-based approach. See the README for updated usage examples.
### Authentication Service
- [BREAKING] `ArcaneAuthInterface.logout` now accepts optional
`onLoggedOut` callback parameters. `ArcaneAuthInterface` implementers must
update logout signature to accept optional `onLoggedOut`. See the migration
steps for further details.
- [NEW] Added `statusChanges` stream to observe `AuthenticationStatus` updates.
- [NEW] Added `signedInChanges` stream to observe sign-in state changes.
- [FIX] Added stream lifecycle cleanup in `dispose` with safe lazy recreation.
#### Migration Steps (ArcaneAuthInterface)
1. Update `ArcaneAuthInterface` implementations to accept the new optional
`onLoggedOut` callback parameter in `logout(...)`.
2. If your implementation performs cleanup side effects on logout, invoke
`onLoggedOut` when provided.
3. Run tests to confirm your authentication adapter still satisfies your
login/logout flows.
Before:
```dart
@override
Future<Result<void, String>> logout() async {
// ...
return Result.ok(null);
}
```
After:
```dart
@override
Future<Result<void, String>> logout({
Future<void> Function()? onLoggedOut,
}) async {
// ...
if (onLoggedOut != null) await onLoggedOut();
return Result.ok(null);
}
```
### Feature Flag Service
- [CHANGE] Renamed service class `ArcaneFeatureFlags` to
`ArcaneFeatureFlagService`.
- [NEW] Added backward compatibility typedef:
`typedef ArcaneFeatureFlags = ArcaneFeatureFlagService`.
- [NEW] Added `enabledFeaturesChanges` stream to observe enabled feature
updates in realtime.
- [FIX] Added stream lifecycle cleanup in `dispose` with safe lazy recreation.
- [NEW] Added `ArcaneFeatureFlagProvider` (`InheritedWidget`) and
`ArcaneFeatureFlagsProvider` (`StatefulWidget`) for first-class feature-flag
integration in the widget tree.
- [DEPRECATED] `ArcaneFeatureFlagsScope` has been renamed to
`ArcaneFeatureFlagProvider`.
- [NEW] Added `BuildContext` convenience accessors for feature flags, including
`context.featureFlags`, `context.maybeFeatureFlags`,
`context.isFeatureEnabled(...)`, and `context.isFeatureDisabled(...)`.
- [NEW] `ArcaneApp` now includes `ArcaneFeatureFlagsProvider` by default,
enabling rebuilds for widgets that depend on
`ArcaneFeatureFlagProvider.of(context)`.
- [UPDATE] README now documents `ArcaneFeatureFlagProvider` and `ArcaneApp`
provider composition.
### Theme Service
- [CHANGE] Renamed `ArcaneReactiveTheme` to `ArcaneThemeService` for clearer
naming.
- [NEW] Added backward compatibility typedef:
`typedef ArcaneReactiveTheme = ArcaneThemeService`.
- [FIX] Theme initialization now respects `ThemeMode.system` and initializes
`ThemeData` using the effective brightness.
- [FIX] `ArcaneThemeSwitcher` now initializes system-follow behavior once on
first dependency resolution.
- [FIX] `ArcaneThemeSwitcher` now defaults to `followSystemTheme(context)` when
mounted under `ArcaneApp`, so system-follow is enabled by default and system
brightness changes are handled framework-side (no app-level observer needed).
- [FIX] `switchTheme()` now toggles from the effective theme when current mode
is `ThemeMode.system` (system dark -> light, system light -> dark).
- [CHANGE] `context.isDarkMode` now reflects effective app theme brightness
(`Theme.of(context).brightness`) instead of raw platform brightness.
- [FIX] `followSystemTheme()` now reads platform brightness directly to avoid
coupling system-follow behavior to app theme overrides.
- [NEW] Added assignment-style theme setters: `Arcane.theme.dark = ...` and
`Arcane.theme.light = ...` (in addition to `setDarkTheme` /
`setLightTheme`).
- [FIX] Reactive theme stream controllers now close only during service dispose,
preventing stream shutdown when a single subscriber cancels.
- [FIX] Setting a theme (e.g., dark) while in the opposite mode (e.g., light) no
longer changes the current brightness or rendered theme. Only the active
mode's theme updates the rendered appearance.
- [NEW] Added `themeModeChanges` and `themeDataChanges` streams for realtime
theme updates.
#### Migration Steps (ArcaneThemeService)
1. Replace legacy `ThemeMode` reads from `Arcane.theme.systemTheme.value` with
`Arcane.theme.currentModeOf(context)` when configuring app `themeMode`.
Before:
```dart
MaterialApp(
theme: Arcane.theme.light,
darkTheme: Arcane.theme.dark,
themeMode: Arcane.theme.systemTheme.value,
)
```
After:
```dart
MaterialApp(
theme: Arcane.theme.light,
darkTheme: Arcane.theme.dark,
themeMode: Arcane.theme.currentModeOf(context),
)
```
### Arcane Logger
- [NEW] Added `logStream` for realtime log subscriptions.
- [NEW] Added explicit `dispose` cleanup for logger stream resources.
- [NEW] Added optional lifecycle capability via `LoggingInitializable` and
`LoggingInitialization`.
- [NEW] Added optional `feature` tag support via `@LoggingFeature(...)`
annotation.
- [NEW] Added a `skipAutodetection` parameter to `Arcane.log` (defaults to
`false`) that, when enabled, skips detection of the `module`, `method`, and
file/line number where logs originated from.
- [NEW] Added the `LogInterceptor` class which can (optionally) be added to
`ArcaneLogger` to pre-process log messages before they are sent to the
registered `ArcaneLoggingInterface`(s).
- [NEW] Added collection-style interceptor APIs:
`Arcane.logger.interceptors.add(...)`,
`Arcane.logger.interceptors.remove(...)`, and
`Arcane.logger.interceptors.clear()` with an optional `matcher` for
explicit type-scoped matching strategies, including subtype-inclusive
matching.
- [CHANGE] Updated `Arcane.log` metadata type from `Map<String, String>?` to
`Map<String, Object?>?` to support structured metadata values.
- [CHANGE] `initializeInterfaces()` now initializes only interfaces that
implement `LoggingInitializable`; other interfaces are skipped.
- [BREAKING] `LoggingInterface` no longer includes built-in singleton-style
initialization state.
#### Migration Steps (LoggingInterface)
1. Remove `initialized` and `init` from interfaces that do not require startup
work.
2. If an interface requires startup/lifecycle management, add
`LoggingInitialization` (or implement `LoggingInitializable`) and move
setup logic into `init()`.
3. Update `log(...)` implementations to guard behavior with `initialized` only
for interfaces that opted into initialization.
4. Run tests to verify interface registration and logging behavior still match
expectations.
Before:
```dart
class DebugConsole implements LoggingInterface {
@override
bool get initialized => true;
@override
Future<LoggingInterface?> init() async => this;
@override
void log(String message, {Map<String, Object?>? metadata, Level? level}) {}
}
```
After:
```dart
class DebugConsole extends LoggingInterface {
@override
void log(String message, {Map<String, Object?>? metadata, Level? level}) {}
}
```
- For SDK-backed loggers, opt into initialization with the mixin.
```dart
class ExternalLogger extends LoggingInterface with LoggingInitialization {
@override
Future<void> init() async {
if (initialized) return;
// Start SDK.
await super.init();
}
@override
void log(String message, {Map<String, Object?>? metadata, Level? level}) {
if (!initialized) return;
// Send to SDK.
}
}
```
- If desired, adopt `feature` for destination-aware filtering in interceptors.
#### Migration Steps (Arcane.log metadata)
1. Update `Arcane.log(...)` call sites that stringify metadata values only to
satisfy the previous `Map<String, String>` type.
2. Prefer passing native values (for example `int`, `bool`, `List`, or nested
`Map`) directly in `metadata` when useful.
3. If your logging destination expects only string metadata, convert
`Object?` values to strings at your logging boundary.
Before:
```dart
Arcane.log(
"Login attempt",
metadata: {
"attempt": attempt.toString(),
"rememberMe": rememberMe.toString(),
},
);
```
After:
```dart
Arcane.log(
"Login attempt",
metadata: {
"attempt": attempt,
"rememberMe": rememberMe,
},
);
```
### Dependencies
- [CHANGE] Updated `result_monad` from `^2.3.2` to `^4.0.0`.
- [CHANGE] Removed direct `flutter_bloc` dependency.
- [CHANGE] Updated `collection` from `^1.18.0` to `^1.19.0`.
## 2.0.0
- Version redacted. Use v2.0.1.
## 1.2.7
- Updated dependencies to latest
## 1.2.6
- Updated dependencies to latest
## 1.2.5
- Improved automatic metadata detection in `ArcaneLogger`
## 1.2.4
- Update package dependencies
## 1.2.3
- Added `ValueNotifier`s to both the `ArcaneAuthenticationService` and
`ArcaneFeatureFlags`. This enables the possibility of listening for changes to
either service.
### Example
```dart
// Listen to changes in the authentication status
Arcane.auth.isSignedIn.addListener(() {
if (Arcane.auth.isSignedIn.value) {
Arcane.log("User is signed in");
} else {
Arcane.log("User is signed out");
}
});
// Listen to changes in the enabled/disabled features
Arcane.features.notifier.addListener(() {
Arcane.log("Enabled features have been updated: ${Arcane.features.notifier.value}");
});
```
## 1.2.2
- Lowered minimum required collection dependency version to prevent forcing
users into the latest Flutter release
## 1.2.1
- Lowered minimum required SDK version to prevent forcing users into the latest
Flutter release
## 1.2.0
- Removed flutter_secure_storage dependency as it was unused
### Breaking Changes
The following methods have been moved outside of the ArcaneAuthInterface base
class:
- resendVerificationCode
- register
- confirmSignup
- resetPassword
These methods have been moved to mixin classes. To continue using them, please
update your ArcaneAuthInterface implementations.
- To use `resendVerificationCode`, `register` and `confirmSignup`, use the new
`ArcaneAuthAccountRegistration` mixin.
- To use `resetPassword`, use the new `ArcaneAuthPasswordManagement` mixin.
### Migration
In order to migrate your existing interfaces, update them from:
```dart
class MyAuthInterface implements ArcaneAuthInterface {}
```
to:
```dart
class MyAuthInterface
with ArcaneAuthAccountRegistration, ArcaneAuthPasswordManagement
implements ArcaneAuthInterface {}
```
If the methods that these mixins provide are not being used, the mixins can
safely be omitted. If only one of these mixins is required, the other can be
safely omitted.
This change should result in fewer lines of code for interface implementations
that do not require these additional features.
## 1.1.7
- Fixed an issue with the `ArcaneAuthenticationService` where an exception would
be thrown when attempting to access an authentication token while no
`ArcaneAuthInterface` was registered.
## 1.1.6
- Updated logging feature to indicate the feature which was enabled or disabled
within the log message, instead of only in the metadata.
## 1.1.5
- Update package dependencies. No code changes.
## 1.1.4
- Update package dependencies. No code changes.
## 1.1.3
- Arcane Auth no longer throws exceptions when log out fails, instead returning
a `Result<void, String>`. This behavior matches the login method.
## 1.1.2
- Removed Flutter exception handling from `ArcaneLoggingService`, as this
functionality should be defined by a users' interface.
### Migration
Add the following to your `ArcaneLoggingInterface`'s `init` method to replicate
the previous behavior:
```dart
// Handles unhandled Flutter errors by logging them.
FlutterError.onError = (errorDetails) {
Arcane.log(
errorDetails.exceptionAsString(),
level: Level.error,
module: errorDetails.library,
stackTrace: errorDetails.stack,
);
};
// Handles unhandled platform-specific errors by logging them.
PlatformDispatcher.instance.onError = (error, stack) {
Arcane.log(
"$error",
level: Level.error,
stackTrace: stack,
);
return false;
};
```
## 1.1.1+2
- Updated example in README
## 1.1.1+1
- Updated example in README
## 1.1.1
- [BREAKING] Updated ArcaneAuthInterface to make the `resendVerificationCode`,
`confirmSignup`, and `resetPassword` methods more versatile
Migration:
| Class | Migration path |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| ArcaneAuthInterface | `resendVerificationCode(String email)` -> `resendVerificationCode<T>({T? input})` |
| ArcaneAuthInterface | `confirmSignup({String email, String password})` -> `confirmSignup({String? email, String? password})` |
| ArcaneAuthInterface | `resetPassword({String email, String? newPassword, String? code})` -> `resetPassword({String? email, String? newPassword, String? code})` |
## 1.1.0
- [BREAKING] Updated the authentication service and interface to be more
versatile
Migration:
| Class | Migration path |
| ------------------- | -------------------------------------------------------------------------------------- |
| ArcaneAuthInterface | `loginWtihEmailAndPassword({String email, String password})` -> `login<T>({T? input})` |
| ArcaneAuthInterface | `signup({String email, String password})` -> `register<T>({T? input})` |
## 1.0.8
- Added the `extra` parameter to the `Arcane.log` shortcut method
## 1.0.7
- Added the `extra` parameter to the `LoggingInterface`
## 1.0.6+1
- Migrated linting rules to new
[arcane_analysis](https://pub.dev/packages/arcane_analysis) package.
## 1.0.6
- Removed get_it as a dependency
## 1.0.5+2
- Updated README and example project documentation
## 1.0.5+1
- Marked the `loginWithEmailAndPassword` method in `ArcaneAuthenticationService`
as deprecated and updated example project
## 1.0.5
- Added the ability to use a generic type for the login method in
ArcaneAuthenticationService
- Added the ability to reset the ArcaneAuthenticationService, which will
unregister the current interface and clear the authentication state
- Removed unused testing tooling (e.g., `@visibleForTesting`) from the codebase
- Migration guide: Remove usages of `setMocked` in your tests
## 1.0.4
- Resolved an issue with authentication using the ArcaneAuthenticationService
when logging in with an email and password
## 1.0.3+1
- Added example project
## 1.0.3
- Added the ability to switch back to the normal environment from the debug
environment in ArcaneEnvironment
- (breaking) Made the optional `onLoggedOut` callback a Future instead of a void
function in ArcaneAuthenticationService
- Added additional error handling to the login method in
ArcaneAuthenticationService
- Added support for following the system's theme in ArcaneTheme
- Removed the BuildContext parameter from the `switchTheme` method in
ArcaneTheme
## 1.0.2
- Migrated ArcaneAuthenticationService's isSignedIn to a ValueListenable
## 1.0.1+1
- Removed ID and secure storage services to improve platform compatibility
## 1.0.0
- Initial release