configwire 0.2.0
configwire: ^0.2.0 copied to clipboard
Pure-Dart ConfigWire client (fetch, cache, typed getters, realtime).
0.2.0 #
Changed #
- Breaking: scalar getters are now nullable with no silent default
(
lib/src/configwire_base.dart):getBoolreturnsbool?(wasbooldefaulting tofalse),getStringreturnsString?(was''),getIntreturnsint?(was0),getDoublereturnsdouble?(was0.0). A missing or mistyped key returnsnullunless an explicitfallback:is passed. Migration:cw.getBool('k')->cw.getBool('k') ?? false;cw.getString('k')->cw.getString('k') ?? '';cw.getInt('k')->cw.getInt('k') ?? 0;cw.getDouble('k')->cw.getDouble('k') ?? 0.0; or branch onnullto detect a missing/mistyped flag. - Breaking:
getList<T>returnsList<T>?(wasList<T>defaulting toconst []) andgetMap<T>returnsMap<String, T>?(wasMap<String, T>defaulting toconst {}). Thefallbackdefault is nownull, and the oldfallback: nullrethrow contract is removed: any error (missing key, mistyped value, mistyped element/entry) returnsfallback. Migration:cw.getList<String>('k')->cw.getList<String>('k') ?? const [];cw.getMap<int>('k')->cw.getMap<int>('k') ?? const {}; dropfallback: nullwhere it was used to rethrow. - Breaking:
RealtimeUpdater.disconnectSyncis now private (_disconnectSync). Usedisconnect()(async) instead. - Breaking: the fetch-event POST no longer sends the deprecated
'flag': ''key (lib/src/events.dart). ConfigWire server v0.1.0 removed per-event flag attribution (ingest takes kind/variant/userHash/version only;1790000008_drop_event_flagdropped theevents.flag/event_daily.flagcolumns), so payloads are now{"events":[{"kind":"fetch","variant":"", "userHash":"<sha256hex16>","version":1}]}. Requires server= v0.1.0; older servers need SDK <0.2.0.
0.1.2 #
Changed #
- Docs: expanded
README.mdto cover the full client surface (reading values, variants, fetch lifecycle, startup, targeting, realtime, analytics, logging, cache). No code change.
0.1.1 #
Changed #
- Deprecated per-event
flagattribution (lib/src/events.dart): analytics are env-wide, so the fetch-event POST keeps sending'flag': ''as a minimal backward-compat shim (pre-removal servers still validate the payload; new servers ignore it). No action needed; do not send per-flag keys.
0.1.0 #
Changed #
- Breaking:
TargetingContextis renamed toTargeting(lib/src/targeting.dart, still exported frompackage:configwire/configwire.dart). Targeting inputs live in exactly 3 places:ConfigWire(targeting: ...)seeds the sticky targeting at construction,setTargeting(Targeting targeting)replaces it wholesale, andupdateTargeting(userId: ..., platform: ..., ...)merges single fields — all without fetching.ensureInitialized()andfetchAndActivate({bool force})take no targeting param and always evaluate the stored targeting. Migrate:const TargetingContext(userId: 'u')->const Targeting(userId: 'u');fetchAndActivate(targeting: ...)->setTargeting(...); fetchAndActivate();, single-fieldfetchAndActivate(targeting: cw.targeting.copyWith(platform: 'ios'))->updateTargeting(platform: 'ios'); fetchAndActivate();. - Added
ConfigWire.updateTargeting({String? userId, String? platform, String? appVersion, String? locale, String? country, Map<String, Object?>? customAttrs}): merges the given non-null fields into the sticky targeting viacopyWithwithout fetching, so single-field updates no longer need a manual rebuild.
Added #
- Fetch-event version tracking (
lib/src/events.dart,lib/src/configwire_base.dart):postFetchEvent(...)takes a new optionalversion(int, defaults to0) and includes it in the fetch-event POST ({"events":[{"kind":"fetch","flag":"","variant":"", "userHash":"<sha256hex16(userId)>","version":1}]}).ConfigWire.fetchAndActivatepassesparsed.versionso stats can break fetches down per release version. Backward compatible: old servers ignore the unknownversionfield; old SDKs send noversionand the server records0. Analytics stays fire-and-forget (all failure modes swallowed).
0.0.5 #
Added #
- Opt-in verbose debug logging via
lite_logger(lib/src/cw_logger.dart, newlite_logger: ^0.3.0dependency). Off by default; passverbose: truetoConfigWire(...),RealtimeUpdater(...), orpostFetchEvent(...)to emit debug logs for init, cache hit/miss, fetch start/304/non-200/malformed/success, store-save failures, SSE connect/status/close, poll ticks, and the fetch-event POST. Messages are lazy closures so nothing is built whenverboseis false. TheapiKeyis never logged (only sent as theX-ConfigWire-Keyheader); caught errors are redacted before logging.ConfigWire(verbose: true)propagates to its realtime updater and fetch-event calls.
0.0.4 #
Changed #
ensureInitialized(lib/src/configwire_base.dart) is now idempotent and safe to call multiple times. Concurrent calls share the same in-flight initialization (single cache load + single forced fetch), and calls after the first attempt return immediately without re-loading the cache or re-fetching. Passing a non-nullcontextstill triggers a forcedfetchAndActivaterefresh with the new targeting, so retargeting viaensureInitializedkeeps working.
0.0.3 #
Added #
get<T>(lib/src/configwire_base.dart): generic typed getter. Returns the value forkeyasT, orfallbackwhen missing or mistyped. Coerces ints viatoDouble()whenTisdouble(parity withgetDouble). With nofallback, a missing/mistyped key returnsnullfor nullableTand throws a cast error for non-nullableT. Maps and lists are returned as defensive copies. Note: server collections decode asList<dynamic>/Map<String, dynamic>, so a directget<List<String>>over server values misses — usegetList/getMapfor those.getList<T>(lib/src/configwire_base.dart): typed list getter. Eagerly checks every element (plusint->doublecoercion whenTisdouble); defaultsfallbacktoconst []. On any error (missing key, mistyped value, or mistyped element) returnsfallback; whenfallbackis null the error is rethrown.getMap<T>(lib/src/configwire_base.dart): typed map getter. Eagerly checks every entry isString->T(plusint->doublecoercion whenTisdouble); defaultsfallbacktoconst {}. On any error (missing key, mistyped value, non-String key, or mistyped entry) returnsfallback; whenfallbackis null the error is rethrown.
Changed #
- Breaking:
getJSON(key)is removed. It returned an untypedMap<String, Object?>(or{}on miss/mistype). Migrate:getJSON('k')->getMap<Object?>('k'), or pick a value type such asgetMap<int>('k')/getMap<String>('k').
0.0.2 #
Added #
TargetingContext(lib/src/targeting.dart, exported frompackage:configwire/configwire.dart): carriesuserId,platform,appVersion,locale,country,customAttrsfor server-side rule evaluation. Empty fields are omitted from the fetch query;customAttrsis sent as?attrs=<json>. IncludescopyWith,empty, andtoQueryParameters().
Changed #
- Breaking:
fetchAndActivateandensureInitializednow take only{TargetingContext? context, bool force}. The flattenedString? userId/platform/appVersion/locale/countryandMap? customAttrsparams are removed. Migrate:fetchAndActivate(userId: 'u')->fetchAndActivate(context: const TargetingContext(userId: 'u')); single-field update ->fetchAndActivate(context: cw.targeting.copyWith(platform: 'ios')). - Targeting is sticky: a non-null
contextreplacescw.targetingfor this and all future fetches, includingconnectRealtimepoll/SSE refreshes (fetchAndActivate(force: true)reuses the stored context).setTargetingreplaces the stored context without fetching.
0.0.1 #
- Initial release of the pure-Dart
configwireclient.