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);
}