preload method
Probes the store and, when available, loads names into the snapshot
(parallel reads; individual misses/errors simply stay absent — a
keychain must never break startup).
Returns a SecureKeyPreloadReport classifying every requested name
(found / absent / error + diagnostic) so the host can surface a
boot where the config references store keys but none resolved, instead
of the silent absence gh-1059 shipped with. Stores offering
SecureKeyDiagnostics get the classification from the backend;
plain stores (and thrown errors) degrade to absent / error outcomes.
Implementation
Future<SecureKeyPreloadReport> preload(Iterable<String> names) async {
final requested = names.toSet().toList();
if (!await probe()) {
return SecureKeyPreloadReport(storeAvailable: false, outcomes: const []);
}
final store = _store!;
final SecureKeyDiagnostics? diagnostics = store is SecureKeyDiagnostics
? store as SecureKeyDiagnostics
: null;
final outcomes = await Future.wait(
requested.map((name) async {
try {
if (diagnostics != null) return await diagnostics.readDetailed(name);
return await _plainOutcome(store, name);
} on Object catch (error) {
// A single unreadable entry must not fail the whole preload.
return SecureKeyReadOutcome(
name,
SecureKeyReadStatus.error,
error: secureKeyDiagnosticLine(error.toString()),
);
}
}),
);
for (final outcome in outcomes) {
final value = outcome.value;
if (outcome.status == SecureKeyReadStatus.found &&
value != null &&
value.isNotEmpty) {
_snapshot[outcome.name] = value;
}
}
return SecureKeyPreloadReport(storeAvailable: true, outcomes: outcomes);
}