init method
Implementation
Future<void> init() async {
try {
final raw = await _bundle.loadString(_assetPath);
final decoded = jsonDecode(raw);
if (decoded is Map) {
_config = decoded.cast<String, Object?>();
}
} catch (_) {
// No bundled asset (or invalid JSON) → keep the empty config; getters
// fall back to their own defaults instead of crashing.
}
final fetch = fetchRemote;
if (fetch == null) {
_schemaViolations = _validateSchema();
return;
}
try {
final remote = await fetch();
// ENH-58: merge, don't replace — a partial (or even empty) response
// must not wipe asset-default keys it simply didn't mention. A `null`
// entry is treated as "no override" for that key (see class doc).
_config = {
..._config,
for (final entry in remote.entries)
if (entry.value != null) entry.key: entry.value,
};
_source = RemoteConfigSource.remoteMerged;
} catch (_) {
// Network fetch failed → silently keep whatever config we had before
// this attempt (asset-only, or a previous successful merge).
_source = RemoteConfigSource.remoteFailed;
}
_schemaViolations = _validateSchema();
}