Skip to content

Commit 493b649

Browse files
committed
CancellationToken and check if cached item is indeed base64 encoded.
1 parent 039da32 commit 493b649

5 files changed

Lines changed: 59 additions & 40 deletions

File tree

Src/Drogecode.Blazor.ExpireStorage/Interfaces/IJsStorageService.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ namespace Drogecode.Blazor.ExpireStorage;
33
public interface IJsStorageService
44
{
55
T RetrieveItem<T>(string storageKey, StorageLocation storage, T defaultIfNull);
6-
Task StoreItem<T>(string storageKey, StorageLocation storageLocation, T itemToStore);
7-
Task<T?> RetrieveItem<T>(string storageKey, StorageLocation storageLocation);
8-
Task RemoveItem(string storageKey, StorageLocation storageLocation);
6+
Task<T?> RetrieveItem<T>(string storageKey, StorageLocation storageLocation, CancellationToken clt = default);
7+
Task StoreItem<T>(string storageKey, StorageLocation storageLocation, T itemToStore, CancellationToken clt = default);
8+
Task RemoveItem(string storageKey, StorageLocation storageLocation, CancellationToken clt = default);
99
}

Src/Drogecode.Blazor.ExpireStorage/Services/JsStorageService.cs

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Buffers.Text;
12
using System.Text;
23
using System.Text.Json;
34
using Microsoft.JSInterop;
@@ -16,65 +17,83 @@ public JsStorageService(IJSRuntime jsRuntime)
1617

1718
public T RetrieveItem<T>(string storageKey, StorageLocation storage, T defaultIfNull)
1819
{
19-
var base64String = storage switch
20+
var stringFromCache = storage switch
2021
{
2122
StorageLocation.BrowserLocal => ((IJSInProcessRuntime)_jsRuntime).Invoke<string?>("localStorage.getItem", storageKey) ?? string.Empty,
2223
StorageLocation.BrowserSession => ((IJSInProcessRuntime)_jsRuntime).Invoke<string?>("sessionStorage.getItem", storageKey) ?? string.Empty,
2324
_ => _pageCache[storageKey]
2425
};
25-
if (string.IsNullOrEmpty(base64String)) return defaultIfNull;
26-
var utf8Byes = Convert.FromBase64String(base64String);
27-
var jsonString = Encoding.UTF8.GetString(utf8Byes);
26+
if (string.IsNullOrEmpty(stringFromCache)) return defaultIfNull;
27+
28+
string jsonString;
29+
if (Base64.IsValid(stringFromCache))
30+
{
31+
var utf8Byes = Convert.FromBase64String(stringFromCache);
32+
jsonString = Encoding.UTF8.GetString(utf8Byes);
33+
}
34+
else
35+
{
36+
jsonString = stringFromCache;
37+
}
2838

2939
if (string.IsNullOrEmpty(jsonString)) return defaultIfNull;
3040

3141
return JsonSerializer.Deserialize<T>(jsonString) ?? defaultIfNull;
3242
}
3343

34-
public async Task StoreItem<T>(string storageKey, StorageLocation storageLocation, T itemToStore)
44+
public async Task<T?> RetrieveItem<T>(string storageKey, StorageLocation storageLocation, CancellationToken clt = default)
45+
{
46+
var stringFromCache = storageLocation switch
47+
{
48+
StorageLocation.BrowserLocal => await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", clt, storageKey) ?? string.Empty,
49+
StorageLocation.BrowserSession => await _jsRuntime.InvokeAsync<string?>("sessionStorage.getItem", clt, storageKey) ?? string.Empty,
50+
_ => _pageCache.TryGetValue(storageKey, out string? cachedItem) ? cachedItem : string.Empty
51+
};
52+
string jsonString;
53+
if (Base64.IsValid(stringFromCache))
54+
{
55+
var utf8Byes = Convert.FromBase64String(stringFromCache);
56+
jsonString = Encoding.UTF8.GetString(utf8Byes);
57+
}
58+
else
59+
{
60+
jsonString = stringFromCache;
61+
}
62+
63+
if (string.IsNullOrEmpty(jsonString)) return default;
64+
65+
return JsonSerializer.Deserialize<T>(jsonString) ?? default;
66+
}
67+
68+
public async Task StoreItem<T>(string storageKey, StorageLocation storageLocation, T itemToStore, CancellationToken clt = default)
3569
{
3670
var utf8Byes = JsonSerializer.SerializeToUtf8Bytes<T>(itemToStore);
3771
var base64String = Convert.ToBase64String(utf8Byes);
3872

3973
switch (storageLocation)
4074
{
4175
case StorageLocation.BrowserLocal:
42-
await _jsRuntime.InvokeVoidAsync("localStorage.setItem", storageKey, base64String);
76+
await _jsRuntime.InvokeVoidAsync("localStorage.setItem", clt, storageKey, base64String);
4377
break;
4478
case StorageLocation.BrowserSession:
45-
await _jsRuntime.InvokeVoidAsync("sessionStorage.setItem", storageKey, base64String);
79+
await _jsRuntime.InvokeVoidAsync("sessionStorage.setItem", clt, storageKey, base64String);
4680
break;
4781
default:
4882
_pageCache[storageKey] = base64String;
4983
break;
5084
}
5185
}
5286

53-
public async Task<T?> RetrieveItem<T>(string storageKey, StorageLocation storageLocation)
54-
{
55-
var base64String = storageLocation switch
56-
{
57-
StorageLocation.BrowserLocal => await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", storageKey) ?? string.Empty,
58-
StorageLocation.BrowserSession => await _jsRuntime.InvokeAsync<string?>("sessionStorage.getItem", storageKey) ?? string.Empty,
59-
_ => _pageCache.TryGetValue(storageKey, out string? cachedItem) ? cachedItem : string.Empty
60-
};
61-
if (string.IsNullOrEmpty(base64String)) return default;
62-
var utf8Byes = Convert.FromBase64String(base64String);
63-
var jsonString = Encoding.UTF8.GetString(utf8Byes);
64-
65-
return string.IsNullOrEmpty(jsonString) ? default : JsonSerializer.Deserialize<T>(jsonString);
66-
}
67-
6887

69-
public async Task RemoveItem(string storageKey, StorageLocation storageLocation)
88+
public async Task RemoveItem(string storageKey, StorageLocation storageLocation, CancellationToken clt = default)
7089
{
7190
switch (storageLocation)
7291
{
7392
case StorageLocation.BrowserLocal:
74-
await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", storageKey);
93+
await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", clt, storageKey);
7594
break;
7695
case StorageLocation.BrowserSession:
77-
await _jsRuntime.InvokeVoidAsync("sessionStorage.removeItem", storageKey);
96+
await _jsRuntime.InvokeVoidAsync("sessionStorage.removeItem", clt, storageKey);
7897
break;
7998
default:
8099
_pageCache.Remove(storageKey);

Src/Drogecode.Blazor.ExpireStorage/Services/LocalStorageExpireService.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,34 +97,34 @@ private async Task DeleteExpiredCache()
9797
}
9898
}
9999

100-
public async ValueTask<T?> GetItemAsync<T>(string key, CancellationToken cancellationToken = default)
100+
public async ValueTask<T?> GetItemAsync<T>(string key, CancellationToken clt = default)
101101
{
102-
var value = await _jsStorageService.RetrieveItem<ExpiryStorageModel<T?>>(key, StorageLocation.BrowserLocal);
102+
var value = await _jsStorageService.RetrieveItem<ExpiryStorageModel<T?>>(key, StorageLocation.BrowserLocal, clt);
103103
if (value is null || value.Data is null)
104104
return default(T);
105105
if (value.Ttl < DateTime.UtcNow.Ticks)
106106
{
107107
ConsoleHelper.WriteLine($"localstorage deleting {key}, expired {new DateTime(value.Ttl)} on trying to get");
108-
await _jsStorageService.RemoveItem(key, StorageLocation.BrowserLocal);
108+
await _jsStorageService.RemoveItem(key, StorageLocation.BrowserLocal, clt);
109109
return default(T);
110110
}
111111

112112
var result = value.Data;
113113
return result;
114114
}
115115

116-
public async ValueTask SetItemAsync<T>(string key, T data, DateTime expire, CancellationToken cancellationToken = default)
116+
public async ValueTask SetItemAsync<T>(string key, T data, DateTime expire, CancellationToken clt = default)
117117
{
118118
var value = new ExpiryStorageModel<T>
119119
{
120120
Data = data,
121121
Ttl = expire.Ticks,
122122
};
123-
await _jsStorageService.StoreItem(key, StorageLocation.BrowserLocal, value);
123+
await _jsStorageService.StoreItem(key, StorageLocation.BrowserLocal, value, clt);
124124
}
125125

126126
public async Task DeleteItemAsync(string key, CancellationToken clt)
127127
{
128-
await _jsStorageService.RemoveItem(key, StorageLocation.BrowserLocal);
128+
await _jsStorageService.RemoveItem(key, StorageLocation.BrowserLocal, clt);
129129
}
130130
}

Src/Drogecode.Blazor.ExpireStorage/Services/SessionExpireService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public SessionExpireService(IJsStorageService jsStorageService)
1313

1414
public async ValueTask<T?> GetItemAsync<T>(string key, CancellationToken clt = default)
1515
{
16-
var value = await _jsStorageService.RetrieveItem<ExpiryStorageModel<T?>>(key, StorageLocation.BrowserSession);
16+
var value = await _jsStorageService.RetrieveItem<ExpiryStorageModel<T?>>(key, StorageLocation.BrowserSession, clt);
1717
var ttl = DateTime.UtcNow.Ticks;
1818
if (value is null || value.Data is null || value.Ttl <= ttl) return default;
1919
var result = value.Data;
@@ -27,6 +27,6 @@ public async ValueTask SetItemAsync<T>(string key, T data, DateTime expire, Canc
2727
Data = data,
2828
Ttl = expire.Ticks
2929
};
30-
await _jsStorageService.StoreItem(key, StorageLocation.BrowserSession, value);
30+
await _jsStorageService.StoreItem(key, StorageLocation.BrowserSession, value, clt);
3131
}
3232
}

Tests/Drogecode.Blazor.ExpireStorage.Tests/Mocks/MockJsStorageService.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public MockJsStorageService(IMemoryCache memoryCache)
1111
_memoryCache = memoryCache;
1212
}
1313

14-
public T RetrieveItem<T>(string storageKey, StorageLocation storageLocation, T defaultIfNull) where T : notnull
14+
public T RetrieveItem<T>(string storageKey, StorageLocation storageLocation, T defaultIfNull)
1515
{
1616
if (_memoryCache.TryGetValue(storageKey + storageLocation, out object? value))
1717
{
@@ -29,12 +29,12 @@ public T RetrieveItem<T>(string storageKey, StorageLocation storageLocation, T d
2929
return defaultIfNull;
3030
}
3131

32-
public async Task StoreItem<T>(string storageKey, StorageLocation storageLocation, T itemToStore) where T : notnull
32+
public async Task StoreItem<T>(string storageKey, StorageLocation storageLocation, T itemToStore, CancellationToken clt = default)
3333
{
3434
_memoryCache.Set(storageKey + storageLocation, itemToStore);
3535
}
3636

37-
public async Task<T?> RetrieveItem<T>(string storageKey, StorageLocation storageLocation)
37+
public async Task<T?> RetrieveItem<T>(string storageKey, StorageLocation storageLocation, CancellationToken clt = default)
3838
{
3939
if (_memoryCache.TryGetValue(storageKey + storageLocation, out object? value))
4040
{
@@ -52,7 +52,7 @@ public async Task StoreItem<T>(string storageKey, StorageLocation storageLocatio
5252
return default;
5353
}
5454

55-
public async Task RemoveItem(string storageKey, StorageLocation storageLocation)
55+
public async Task RemoveItem(string storageKey, StorageLocation storageLocation, CancellationToken clt = default)
5656
{
5757
_memoryCache.Remove(storageKey + storageLocation);
5858
}

0 commit comments

Comments
 (0)