Skip to content

Commit 5e873a4

Browse files
committed
#1 Removed dependency on abandoned Blazored packages
1 parent 612c40b commit 5e873a4

20 files changed

Lines changed: 298 additions & 224 deletions

Demo/ExpireStorage.Demo.PWA/Models/StorageSettings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ public class StorageSettings
55
public string Key { get; set; } = "StorageKey";
66
public int LocalStorageDaysInFuture { get; set; } = 7;
77
public int SessionStorageMinutesInFuture { get; set; } = 10;
8+
public int ResponseDelayInMs { get; set; } = 0;
9+
public bool MockOffline { get; set; } = false;
810
}

Demo/ExpireStorage.Demo.PWA/Pages/Home.razor

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,20 @@
1212
<MudTextField T="string" @bind-Value="_storageSettings.Key" Label="Key to save with" />
1313
<MudTextField T="string" @bind-Value="_model.Data" Label="Text to save" />
1414
<MudSwitch T="bool" @bind-Value="_cachedRequest.OneCallPerSession" Label="One call per session" />
15-
<MudSwitch T="bool" @bind-Value="_cachedRequest.OneCallPerLocalStorage" Label="One call per cache" />
15+
<MudSwitch T="bool" @bind-Value="_cachedRequest.OneCallPerLocalStorage" Label="One call per local storage" />
1616
<MudNumericField T="int" @bind-Value="@_storageSettings.SessionStorageMinutesInFuture" Label="Expire session date (minutes)" />
1717
<MudNumericField T="int" @bind-Value="@_storageSettings.LocalStorageDaysInFuture" Label="Expire local storage (days)" />
1818
<MudSwitch T="bool" @bind-Value="_cachedRequest.IgnoreCache" Label="Ignore cache" />
1919
<MudSwitch T="bool" @bind-Value="_cachedRequest.CachedAndReplace" Label="Cached and replace" />
20-
<MudSwitch T="bool" @bind-Value="_cachedRequest.AlwaysCacheWhenOffline" Label="Always cache when offline" />
20+
<MudSwitch T="bool" @bind-Value="_cachedRequest.CacheWhenOffline" Label="Always cache when offline" />
2121
<MudSwitch T="bool" @bind-Value="_cachedRequest.RetryOnJsonException" Label="Retry on JSON exception" />
22+
<MudSwitch T="bool" @bind-Value="_storageSettings.MockOffline" Label="Mock offline" />
23+
<MudNumericField T="int" @bind-Value="@_storageSettings.ResponseDelayInMs" Label="Delay response (ms)" />
2224
</MudForm>
2325

2426
<MudButton Variant="Variant.Filled" Color="Color.Primary" DropShadow="false" OnClick="@Save">Save</MudButton>
2527

26-
<MudText>Offline: @ExpireStorageService.IsOffline</MudText>
28+
<MudText>Offline: @_isOffline</MudText>
2729
<MudText>Response: @_response</MudText>
2830
@if (_handledBy != HandledBy.None)
2931
{

Demo/ExpireStorage.Demo.PWA/Pages/Home.razor.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,20 @@ public sealed partial class Home : IDisposable
1818

1919
private string _response = string.Empty;
2020
private HandledBy _handledBy = HandledBy.None;
21+
private bool _isOffline = false;
22+
23+
24+
protected override void OnInitialized()
25+
{
26+
ExpireStorageService.LogToConsole = true;
27+
ExpireStorageService.IsOfflineChanged += OfflineChanged;
28+
}
2129

2230
private async Task Save()
2331
{
32+
_response = string.Empty;
33+
_handledBy = HandledBy.None;
34+
StateHasChanged();
2435
_cachedRequest.ExpireLocalStorage = DateTime.UtcNow.AddDays(_storageSettings.LocalStorageDaysInFuture);
2536
_cachedRequest.ExpireSession = DateTime.UtcNow.AddMinutes(_storageSettings.SessionStorageMinutesInFuture);
2637

@@ -31,13 +42,32 @@ private async Task Save()
3142
_cls.Token);
3243
_response = value?.Data ?? "No data";
3344
_handledBy = value?.HandledBy ?? HandledBy.None;
45+
StateHasChanged();
3446
}
3547

3648
// This function could be a call to a server side API.
3749
private async Task<DemoModelForStorage> FunctionToCall()
3850
{
51+
if (_storageSettings.ResponseDelayInMs > 0)
52+
{
53+
await Task.Delay(_storageSettings.ResponseDelayInMs);
54+
}
55+
56+
if (_storageSettings.MockOffline)
57+
{
58+
throw new HttpRequestException("Mock offline");
59+
}
60+
3961
return _model;
4062
}
63+
64+
65+
private Task OfflineChanged(bool newValue)
66+
{
67+
_isOffline = newValue;
68+
StateHasChanged();
69+
return Task.CompletedTask;
70+
}
4171

4272
public void Dispose()
4373
{

README.md

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
[![Nuget version](https://img.shields.io/nuget/v/Drogecode.Blazor.ExpireStorage.svg?logo=nuget)](https://www.nuget.org/packages/Drogecode.Blazor.ExpireStorage/)
22

33
# Drogecode.Blazor.ExpireStorage
4-
Adds a wrapper on top of [Blazored.LocalStorage](https://github.com/Blazored/LocalStorage) and [Blazored.SessionStorage](https://github.com/Blazored/SessionStorage) to expire items from localstorage and sessionstorage after a specified time.
54

6-
Blazored is archived, I will build my own implementation.
5+
Store api responses in localstorage and sessionstorage.
6+
7+
Configure if the api should be called or the cached value will be returned if available.
78

89
## Installing
910

10-
To install the package add the following line to you csproj file replacing x.x.x with the latest version number (found at the top of this file):
11+
To install the package, add the following line to the csproj file. Replacing x.x.x with the latest version number (found at the top of this file):
1112

1213
```
1314
<PackageReference Include="Drogecode.Blazor.ExpireStorage" Version="x.x.x" />
@@ -23,7 +24,7 @@ If you're using Visual Studio you can also install via the built in NuGet packag
2324

2425
## Setup
2526

26-
You will need to register the expire storage services with the service collection in your _Startup.cs_ file in Blazor Server.
27+
You will need to register the expire storage services with the service collection in your *Startup.cs* file in Blazor Server.
2728

2829
```c#
2930
public void ConfigureServices(IServiceCollection services)
@@ -32,7 +33,7 @@ public void ConfigureServices(IServiceCollection services)
3233
}
3334
```
3435

35-
Or in your _Program.cs_ file in Blazor WebAssembly.
36+
Or in your *Program.cs* file in Blazor WebAssembly.
3637

3738
```c#
3839
public static async Task Main(string[] args)
@@ -46,8 +47,6 @@ public static async Task Main(string[] args)
4647
}
4748
```
4849

49-
If you use Blazored.LocalStorage or Blazored.SessionStorage with configuration those will need to be registered before Drogecode.Blazor.ExpireStorage.
50-
5150
## Usage (Blazor WebAssembly)
5251
example
5352

@@ -75,27 +74,35 @@ example
7574
### CachedRequest
7675
You can give optional settings to the CachedRequest object.
7776

78-
* **OneCallPerSession** - If true, the result will be returned from sessionstorage if it is not expired. *Default: false*
7977
* **OneCallPerLocalStorage** - If true, the result will be returned from localstorage if it is not expired. *Default: false*
78+
* **OneCallPerSession** - If true, the result will be returned from sessionstorage if it is not expired. *Default: false*
79+
* **ExpireLocalStorage** - The DateTime the localstorage value will be expired. *Default: 7 days.*
80+
* **ExpireSessionStorage** - The DateTime the sessionstorage value will be expired. *Default: 15 minutes.*
8081
* **IgnoreCache** - If true, never return a cached result. *Default: false*
81-
* **ExpireLocalStorage** - The time to expire the result in localstorage. *Default: 7 days.*
82-
* **ExpireSessionStorage** - The time to expire the result in sessionstorage. *Default: 15 minutes.*
8382
* **CachedAndReplace** - If true, The cached result will be returned and the cache will be refreshed for the next call. *Default: false*
84-
* **AlwaysCacheWhenOffline** - If true, the cached result will be returned when offline, except when IgnoreCache is true. *Default: false*
85-
* **RetryOnJsonException** - If true, If a JSON exception occurs, the cache will be cleared and the request will be retried. *Default: true*
83+
* **CacheWhenOffline** - If true, the cached result will be returned when offline, except when IgnoreCache is true. *Default: false*
84+
* **RetryOnJsonException** - If true, If a JSON exception occurs, the cache will be cleared and the request will be retried once. This will minimize the effect if a breaking change was introduced in the JSON value. *Default: true*
8685

8786
### Global settings
8887

88+
#### Postfix
8989
On, for example, MainLayout.razor.cs, you can set the Postfix to be used for all requests. This is useful if you have multiple users using the same app from the same browser.
9090

9191
`ExpireStorageService.Postfix = userId.ToString();`
9292

93+
#### IsOffline
9394
ExpireStorageService knows two properties to monitor if the app is offline.
9495

95-
IsOffline is true when the last request had an `HttpRequestException`.
96+
IsOffline is true when the last request had an `HttpRequestException`, after a successful request IsOffline will be false.
9697

9798
`ExpireStorageService.IsOffline` and `ExpireStorageService.IsOfflineChanged`
9899

100+
#### LogToConsole
101+
102+
ExpireStorageService can log to the console if you want to see what is happening, *default: false*.
103+
104+
`ExpireStorageService.LogToConsole = true;`
105+
99106
### ICacheableResponse
100107

101108
If a response object implements ICacheableResponse, the HandledBy property will be set to `HandledBy.Cache` if the result was retrieved from cache and to `HandledBy.Default` if the default provided by the caller was used.
@@ -109,3 +116,13 @@ public class YourObjectResponse : ICacheableResponse
109116
...
110117
}
111118
```
119+
120+
## Cache
121+
122+
The cache is stored as a base64 string and serialized / deserialized using System.Text.Json.
123+
124+
### Cleanup
125+
126+
One minute after the app starts, the local storage cache will be cleared from all expired values.
127+
128+
Items that are expired but not yet deleted will not be returned.

Src/Drogecode.Blazor.ExpireStorage/Drogecode.Blazor.ExpireStorage.csproj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<RootNamespace>Drogecode.Blazor.ExpireStorage</RootNamespace>
8-
<Version>0.2.7</Version>
8+
<Version>1.0.0-rc1</Version>
99
<Title>Drogecode.Blazor.ExpireStorage</Title>
1010
<Authors>Taco Droogers</Authors>
1111
<PackageProjectUrl>https://github.com/Drogecode/Drogecode.Blazor.ExpireStorage</PackageProjectUrl>
@@ -15,6 +15,9 @@
1515
<PackageLicenseFile>LICENSE</PackageLicenseFile>
1616
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
1717
<NoWarn>$(NoWarn);1591</NoWarn>
18+
<Copyright>Taco Droogers</Copyright>
19+
<PackageLicenseUrl></PackageLicenseUrl>
20+
<PackageTags>Blazor</PackageTags>
1821
</PropertyGroup>
1922

2023
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
@@ -32,8 +35,6 @@
3235
<ItemGroup>
3336
<None Include="..\..\README.md" Pack="true" PackagePath="\" />
3437
<None Include="..\..\LICENSE" Pack="true" PackagePath="\" />
35-
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
36-
<PackageReference Include="Blazored.SessionStorage" Version="2.4.0" />
3738
<PackageReference Include="Microsoft.TypeScript.MSBuild" Version="6.0.3">
3839
<PrivateAssets>all</PrivateAssets>
3940
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

Src/Drogecode.Blazor.ExpireStorage/Enums/HandledBy.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ public enum HandledBy
44
{
55
None = 0,
66
Function = 1,
7-
Cache = 2,
8-
Default = 3
7+
LocalStorage = 2,
8+
Session = 3,
9+
Default = 4
910
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
namespace Drogecode.Blazor.ExpireStorage;
1+
namespace Drogecode.Blazor.ExpireStorage.Enums;
22

3-
internal enum StorageLocation
3+
public enum StorageLocation
44
{
55
BrowserLocal = 0,
6-
BrowserSession =1
6+
BrowserSession = 1
77
}
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using Blazored.LocalStorage;
2-
using Blazored.SessionStorage;
1+
using Drogecode.Blazor.ExpireStorage.Interfaces;
2+
using Drogecode.Blazor.ExpireStorage.Services;
33
using Microsoft.Extensions.DependencyInjection;
44
using Microsoft.Extensions.DependencyInjection.Extensions;
55

@@ -9,21 +9,19 @@ public static class BuilderHelper
99
{
1010
public static IServiceCollection AddExpireStorage(this IServiceCollection services)
1111
{
12-
services.AddBlazoredLocalStorage();
13-
services.AddBlazoredSessionStorage();
1412
services.TryAddScoped<ILocalStorageExpireService, LocalStorageExpireService>();
1513
services.TryAddScoped<ISessionExpireService, SessionExpireService>();
1614
services.TryAddScoped<IExpireStorageService, ExpireStorageService>();
15+
services.TryAddScoped<IExpireStorageJsService, ExpireStorageJsService>();
1716
return services;
1817
}
1918

2019
public static IServiceCollection AddExpireStorageAsSingleton(this IServiceCollection services)
2120
{
22-
services.AddBlazoredLocalStorageAsSingleton();
23-
services.AddBlazoredSessionStorageAsSingleton();
2421
services.TryAddSingleton<ILocalStorageExpireService, LocalStorageExpireService>();
2522
services.TryAddSingleton<ISessionExpireService, SessionExpireService>();
2623
services.TryAddSingleton<IExpireStorageService, ExpireStorageService>();
24+
services.TryAddSingleton<IExpireStorageJsService, ExpireStorageJsService>();
2725
return services;
2826
}
2927
}

Src/Drogecode.Blazor.ExpireStorage/Helpers/ConsoleHelper.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public static void WriteLine(Exception exception)
2626
public static void WriteLine(string message, Exception exception)
2727
{
2828
if (!LogToConsole) return;
29-
Console.WriteLine(message, exception);
29+
Console.WriteLine(message);
30+
Console.WriteLine(exception);
3031
}
3132
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using Drogecode.Blazor.ExpireStorage.Enums;
2+
3+
namespace Drogecode.Blazor.ExpireStorage.Interfaces;
4+
5+
public interface IExpireStorageJsService
6+
{
7+
T RetrieveItem<T>(string storageKey, StorageLocation storage, T defaultIfNull) where T : notnull;
8+
Task StoreItem<T>(string storageKey, StorageLocation storageLocation, T itemToStore) where T : notnull;
9+
Task<T?> RetrieveItem<T>(string storageKey, StorageLocation storageLocation);
10+
Task RemoveItem(string storageKey, StorageLocation storageLocation);
11+
}

0 commit comments

Comments
 (0)