WasmTextFileStore.cs 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. using Microsoft.JSInterop;
  2. using RackPeek.Domain.Persistence.Yaml;
  3. namespace RackPeek.Web.Viewer;
  4. public sealed class WasmTextFileStore(
  5. IJSRuntime js,
  6. HttpClient http) : ITextFileStore
  7. {
  8. private const string Prefix = "rackpeek:file:";
  9. public async Task<bool> ExistsAsync(string path)
  10. {
  11. var value = await js.InvokeAsync<string?>(
  12. "rackpeekStorage.get",
  13. Key(path));
  14. return !string.IsNullOrWhiteSpace(value);
  15. }
  16. public async Task<string> ReadAllTextAsync(string path)
  17. {
  18. Console.WriteLine($"WASM store read: {path}");
  19. var value = await js.InvokeAsync<string?>(
  20. "rackpeekStorage.get",
  21. Key(path));
  22. if (!string.IsNullOrWhiteSpace(value))
  23. {
  24. Console.WriteLine("Loaded from browser storage");
  25. return value;
  26. }
  27. Console.WriteLine("Storage empty — loading from wwwroot via HTTP");
  28. try
  29. {
  30. var result = await http.GetStringAsync(path);
  31. Console.WriteLine($"Loaded {result.Length} chars from HTTP");
  32. // optional auto-persist bootstrap
  33. if (!string.IsNullOrWhiteSpace(result))
  34. await WriteAllTextAsync(path, result);
  35. return result;
  36. }
  37. catch (Exception ex)
  38. {
  39. Console.WriteLine("HTTP load failed: " + ex.Message);
  40. throw; // TEMP — don't swallow during debug
  41. }
  42. }
  43. public async Task WriteAllTextAsync(string path, string contents)
  44. {
  45. await js.InvokeVoidAsync(
  46. "rackpeekStorage.set",
  47. Key(path),
  48. contents);
  49. }
  50. private static string Key(string path)
  51. {
  52. return Prefix + path;
  53. }
  54. }