Skip to content

Commit ad0cc94

Browse files
committed
misc: update Fusion to v3.1.11
1 parent 4128277 commit ad0cc94

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+316
-387
lines changed

docs/tutorial/Part11.md

+11-14
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ public virtual async Task<List<OrderHeaderDto>> GetMyOrders(Session session, Can
166166
var sessionInfo = await _auth.GetSessionInfo(session, cancellationToken);
167167
// You can use any of such methods
168168
var user = await _authService.GetUser(session, CancellationToken);
169+
user = user.AssertAuthenticated();
169170

170171
await using var dbContext = CreateDbContext();
171172

@@ -355,10 +356,12 @@ Services.TryAddTransient(c => c.GetRequiredService<ISessionProvider>().Session);
355356
So all we need is to make `ISessionResolver` to resolve `Session.Default` on the Blazor WASM client. One of ways to do this is to use this `App.razor` (your root Blazor component):
356357

357358
```cs --editable false
359+
@using Stl.OS
358360
@implements IDisposable
359361
@inject BlazorCircuitContext BlazorCircuitContext
362+
@inject ISessionProvider SessionProvider
360363

361-
<CascadingAuthState SessionId="@SessionId">
364+
<CascadingAuthState>
362365
<Router AppAssembly="@typeof(Program).Assembly">
363366
<Found Context="routeData">
364367
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
@@ -372,20 +375,16 @@ So all we need is to make `ISessionResolver` to resolve `Session.Default` on the
372375
</CascadingAuthState>
373376

374377
@code {
375-
[Parameter]
376-
public string SessionId { get; set; } = Session.Default.Id;
378+
private Theme Theme { get; } = new() { IsGradient = true, IsRounded = false };
377379

378-
protected override void OnInitialized()
379-
{
380-
if (!BlazorCircuitContext.IsPrerendering)
381-
BlazorCircuitContext.RootComponent = this;
382-
}
383-
384-
[Parameter]
380+
[Parameter]
385381
public string SessionId { get; set; } = Session.Default.Id;
386382

387383
protected override void OnInitialized()
388384
{
385+
SessionProvider.Session = OSInfo.IsWebAssembly
386+
? Session.Default
387+
: new Session(SessionId);
389388
if (!BlazorCircuitContext.IsPrerendering)
390389
BlazorCircuitContext.RootComponent = this;
391390
}
@@ -395,11 +394,9 @@ So all we need is to make `ISessionResolver` to resolve `Session.Default` on the
395394
}
396395
```
397396

398-
It works as follows:
399-
- If this component is created from Blazor Server, the correct `SessionId` is expected to be passed there. It's safe, coz this `SessionId` never leaves the server.
400-
- And if this component is created in Blazor WASM, it doesn't expect any `SessionId`, so `Session.Default.Id` will be used in this case.
397+
You can see that when this component is initialized, it sets `SessionProvider.Session` to the value it gets as a parameter &ndash; unless we're running Blazor WASM. In this case it sets it to `Session.Default`. Any attempt to resolve `Session` (either via `ISessionResolver`, or via service provider) will return this value.
401398

402-
You may notice that this component wraps its content into `CascadingAuthState`, which actually does the rest by setting `ISessionResolver.Session` to a `Session` with the specified `SessionId`. In addition, it makes Blazor authentication to work as expected as well by embedding its `ChildContent` into Blazor's `<CascadingAuthenticationState>`. If you are interested in details, see its source:
399+
You may notice that `App.razor` wraps its content into `CascadingAuthState`, which makes Blazor authentication to work as expected as well by embedding its `ChildContent` into Blazor's `<CascadingAuthenticationState>`. If you are interested in details, see its source:
403400
- https://github.com/servicetitan/Stl.Fusion/blob/master/src/Stl.Fusion.Blazor/Authentication/CascadingAuthState.razor
404401
405402
All of this implies you also need a bit special logic in `_Host.cshtml` to spawn `App.razor` on the server side:

docs/tutorial/Tutorial.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
</ItemGroup>
1919

2020
<ItemGroup>
21-
<PackageReference Include="Stl.Fusion.Client" Version="3.0.28" />
22-
<PackageReference Include="Stl.Fusion.Server" Version="3.0.28" />
21+
<PackageReference Include="Stl.Fusion.Client" Version="3.1.11" />
22+
<PackageReference Include="Stl.Fusion.Server" Version="3.1.11" />
2323
<PackageReference Include="System.CommandLine" Version="2.0.0-beta2.21617.1" />
2424
<PackageReference Include="System.CommandLine.DragonFruit" Version="0.4.0-alpha.21617.1" />
2525
</ItemGroup>

src/Blazor/Abstractions/Abstractions.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="6.0.6" />
1414
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="6.0.0" />
1515
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
16-
<PackageReference Include="Stl.Fusion.Client" Version="3.0.28" />
16+
<PackageReference Include="Stl.Fusion.Client" Version="3.1.11" />
1717
</ItemGroup>
1818

1919
</Project>
+12-49
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,27 @@
11
using System.ComponentModel.DataAnnotations;
22
using System.ComponentModel.DataAnnotations.Schema;
3-
using System.Text.Json.Serialization;
43
using Microsoft.EntityFrameworkCore;
54

65
namespace Samples.Blazor.Abstractions;
76

8-
public class LongKeyedEntity : IHasId<long>
9-
{
10-
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
11-
public long Id { get; set; }
12-
}
13-
7+
// Entity
148
[Index(nameof(UserId))]
159
[Index(nameof(CreatedAt))]
16-
public class ChatMessage : LongKeyedEntity
10+
public class ChatMessage
1711
{
18-
public long UserId { get; set; }
12+
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
13+
public long Id { get; set; }
14+
public string UserId { get; set; } = "";
1915
public DateTime CreatedAt { get; set; }
2016
[Required, MaxLength(4000)]
2117
public string Text { get; set; } = "";
2218
}
2319

24-
public class ChatPage
20+
public record ChatMessageList
2521
{
26-
[JsonIgnore]
27-
public long? MinMessageId { get; }
28-
[JsonIgnore]
29-
public long? MaxMessageId { get; }
3022
// Must be sorted by ChatMessage.Id
31-
public List<ChatMessage> Messages { get; }
32-
public Dictionary<long, ChatUser> Users { get; }
33-
34-
public ChatPage()
35-
: this(new List<ChatMessage>(), new Dictionary<long, ChatUser>()) { }
36-
[JsonConstructor]
37-
public ChatPage(List<ChatMessage> messages, Dictionary<long, ChatUser> users)
38-
{
39-
Messages = messages;
40-
Users = users;
41-
if (messages.Count > 0) {
42-
MinMessageId = messages.Min(m => m.Id);
43-
MaxMessageId = messages.Max(m => m.Id);
44-
}
45-
}
46-
}
47-
48-
// Not an entity!
49-
public class ChatUser : LongKeyedEntity
50-
{
51-
public static ChatUser None => new() { Id = -1, Name = "No user found" };
52-
53-
[Required, MaxLength(120)]
54-
public string Name { get; set; } = "";
55-
public bool IsValid => Id >= 0;
23+
public ImmutableArray<ChatMessage> Messages { get; init; } = ImmutableArray<ChatMessage>.Empty;
24+
public ImmutableDictionary<string, User> Users { get; init; } = ImmutableDictionary<string, User>.Empty;
5625
}
5726

5827
public interface IChatService
@@ -68,16 +37,10 @@ public PostCommand() : this("", Session.Null) { }
6837
Task<ChatMessage> Post(PostCommand command, CancellationToken cancellationToken = default);
6938

7039
// Queries
71-
[ComputeMethod(KeepAliveTime = 11)]
72-
Task<ChatUser> GetCurrentUser(Session session, CancellationToken cancellationToken = default);
73-
[ComputeMethod(KeepAliveTime = 1)]
74-
Task<ChatUser> GetUser(long id, CancellationToken cancellationToken = default);
75-
[ComputeMethod(KeepAliveTime = 61)]
40+
[ComputeMethod(KeepAliveTime = 10)]
41+
Task<ChatMessageList> GetChatTail(int length, CancellationToken cancellationToken = default);
42+
[ComputeMethod(KeepAliveTime = 60)]
7643
Task<long> GetUserCount(CancellationToken cancellationToken = default);
77-
[ComputeMethod(KeepAliveTime = 61)]
44+
[ComputeMethod(KeepAliveTime = 60)]
7845
Task<long> GetActiveUserCount(CancellationToken cancellationToken = default);
79-
[ComputeMethod(KeepAliveTime = 11)]
80-
Task<ChatPage> GetChatTail(int length, CancellationToken cancellationToken = default);
81-
[ComputeMethod(KeepAliveTime = 1)]
82-
Task<ChatPage> GetChatPage(long minMessageId, long maxMessageId, CancellationToken cancellationToken = default);
8346
}

src/Blazor/Client/Client.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<ItemGroup>
1313
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="6.0.0" />
1414
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
15-
<PackageReference Include="Stl.Fusion.Client" Version="3.0.28" />
15+
<PackageReference Include="Stl.Fusion.Client" Version="3.1.11" />
1616
</ItemGroup>
1717

1818
<ItemGroup>

src/Blazor/Client/Clients.cs

+13-19
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,39 @@ namespace Samples.Blazor.Client;
66
[BasePath("time")]
77
public interface ITimeClientDef
88
{
9-
[Get("getTime")]
9+
[Get(nameof(GetTime))]
1010
Task<DateTime> GetTime(CancellationToken cancellationToken = default);
11-
[Get("getUptime")]
11+
[Get(nameof(GetUptime))]
1212
Task<double> GetUptime(double updatePeriod, CancellationToken cancellationToken = default);
1313
}
1414

1515
[BasePath("screenshot")]
1616
public interface IScreenshotClientDef
1717
{
18-
[Get("getScreenshot")]
18+
[Get(nameof(GetScreenshot))]
1919
Task<Screenshot> GetScreenshot(int width, CancellationToken cancellationToken = default);
2020
}
2121

2222
[BasePath("chat")]
2323
public interface IChatClientDef
2424
{
2525
// Commands
26-
[Post("post")]
26+
[Post(nameof(Post))]
2727
Task<ChatMessage> Post([Body] IChatService.PostCommand command, CancellationToken cancellationToken = default);
2828

2929
// Queries
30-
[Get("getCurrentUser")]
31-
Task<ChatUser> GetCurrentUser(Session? session, CancellationToken cancellationToken = default);
32-
[Get("getUser")]
33-
Task<ChatUser> GetUser(long id, CancellationToken cancellationToken = default);
34-
[Get("getUserCount")]
30+
[Get(nameof(GetChatTail))]
31+
Task<ChatMessageList> GetChatTail(int length, CancellationToken cancellationToken = default);
32+
[Get(nameof(GetUserCount))]
3533
Task<long> GetUserCount(CancellationToken cancellationToken = default);
36-
[Get("getActiveUserCount")]
34+
[Get(nameof(GetActiveUserCount))]
3735
Task<long> GetActiveUserCount(CancellationToken cancellationToken = default);
38-
[Get("getChatTail")]
39-
Task<ChatPage> GetChatTail(int length, CancellationToken cancellationToken = default);
40-
[Get("getChatPage")]
41-
Task<ChatPage> GetChatPage(long minMessageId, long maxMessageId, CancellationToken cancellationToken = default);
4236
}
4337

4438
[BasePath("composer")]
4539
public interface IComposerClientDef
4640
{
47-
[Get("getComposedValue")]
41+
[Get(nameof(GetComposedValue))]
4842
Task<ComposedValue> GetComposedValue(string? parameter,
4943
Session session, CancellationToken cancellationToken = default);
5044
}
@@ -53,14 +47,14 @@ Task<ComposedValue> GetComposedValue(string? parameter,
5347
public interface ISumClientDef
5448
{
5549
// Commands
56-
[Post("reset")]
50+
[Post(nameof(Reset))]
5751
Task Reset(CancellationToken cancellationToken);
58-
[Post("accumulate")]
52+
[Post(nameof(Accumulate))]
5953
Task Accumulate(double value, CancellationToken cancellationToken);
6054

6155
// Queries
62-
[Get("getAccumulator")]
56+
[Get(nameof(GetAccumulator))]
6357
Task<double> GetAccumulator(CancellationToken cancellationToken);
64-
[Get("getSum")]
58+
[Get(nameof(GetSum))]
6559
Task<double> GetSum(double[] values, bool addAccumulator, CancellationToken cancellationToken);
6660
}

src/Blazor/ConsoleClient/ConsoleClient.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="Stl.Fusion.Client" Version="3.0.28" />
13+
<PackageReference Include="Stl.Fusion.Client" Version="3.1.11" />
1414
</ItemGroup>
1515

1616
<ItemGroup>

src/Blazor/ConsoleClient/Program.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
var stateFactory = services.StateFactory();
1010
var chat = services.GetRequiredService<IChatService>();
1111
var seenMessageIds = new ConcurrentDictionary<long, Unit>();
12-
using var timeState = stateFactory.NewComputed<ChatPage>(async (s, cancellationToken) => {
12+
using var timeState = stateFactory.NewComputed<ChatMessageList>(async (s, cancellationToken) => {
1313
var chatPage = await chat.GetChatTail(10, cancellationToken);
1414
foreach (var message in chatPage.Messages) {
1515
if (!seenMessageIds.TryAdd(message.Id, default))

src/Blazor/Server/Controllers/ChatController.cs

+2-14
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,8 @@ public Task<ChatMessage> Post([FromBody] IChatService.PostCommand command, Cance
2222
// Queries
2323

2424
[HttpGet, Publish]
25-
public Task<ChatUser> GetCurrentUser(Session session, CancellationToken cancellationToken = default)
26-
=> _chat.GetCurrentUser(session, cancellationToken);
27-
28-
[HttpGet, Publish]
29-
public Task<ChatUser> GetUser(long id, CancellationToken cancellationToken = default)
30-
=> _chat.GetUser(id, cancellationToken);
25+
public Task<ChatMessageList> GetChatTail(int length, CancellationToken cancellationToken = default)
26+
=> _chat.GetChatTail(length, cancellationToken);
3127

3228
[HttpGet, Publish]
3329
public Task<long> GetUserCount(CancellationToken cancellationToken = default)
@@ -36,12 +32,4 @@ public Task<long> GetUserCount(CancellationToken cancellationToken = default)
3632
[HttpGet, Publish]
3733
public Task<long> GetActiveUserCount(CancellationToken cancellationToken = default)
3834
=> _chat.GetActiveUserCount(cancellationToken);
39-
40-
[HttpGet, Publish]
41-
public Task<ChatPage> GetChatTail(int length, CancellationToken cancellationToken = default)
42-
=> _chat.GetChatTail(length, cancellationToken);
43-
44-
[HttpGet, Publish]
45-
public Task<ChatPage> GetChatPage(long minMessageId, long maxMessageId, CancellationToken cancellationToken = default)
46-
=> _chat.GetChatPage(minMessageId, maxMessageId, cancellationToken);
4735
}

src/Blazor/Server/Pages/_Host.cshtml

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
<script src="_content/Stl.Fusion.Blazor/scripts/fusionAuth.js"></script>
3030
<script>
3131
window.FusionAuth.schemas = "@authSchemas";
32-
window.FusionAuth.sessionId = "@sessionId";
3332
</script>
3433
</head>
3534
<body>

src/Blazor/Server/Server.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.6" />
2323
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
2424
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta13" />
25-
<PackageReference Include="Stl.Fusion.Server" Version="3.0.28" />
26-
<PackageReference Include="Stl.Fusion.EntityFramework" Version="3.0.28" />
25+
<PackageReference Include="Stl.Fusion.Server" Version="3.1.11" />
26+
<PackageReference Include="Stl.Fusion.EntityFramework" Version="3.1.11" />
2727
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.3.1" />
2828
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
2929
</ItemGroup>

src/Blazor/Server/Services/ChatService.cs

+12-32
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ public virtual async Task<ChatMessage> Post(
4141
}
4242

4343
text = await NormalizeText(text, cancellationToken);
44-
var user = await GetCurrentUser(session, cancellationToken);
45-
if (user == null)
46-
throw new AuthenticationException("Please sign in first.");
44+
var user = await _auth.GetUser(session, cancellationToken);
45+
user = user.AssertAuthenticated();
4746

4847
await using var dbContext = await CreateCommandDbContext(cancellationToken);
4948
var message = new ChatMessage() {
@@ -77,19 +76,7 @@ public virtual async Task<long> GetActiveUserCount(CancellationToken cancellatio
7776
.LongCountAsync(cancellationToken);
7877
}
7978

80-
public virtual async Task<ChatUser> GetCurrentUser(Session session, CancellationToken cancellationToken = default)
81-
{
82-
var user = await _auth.GetUser(session, cancellationToken);
83-
return ToChatUser(user);
84-
}
85-
86-
public virtual async Task<ChatUser> GetUser(long id, CancellationToken cancellationToken = default)
87-
{
88-
var user = await _authBackend.GetUser(default, id.ToString(), cancellationToken);
89-
return ToChatUser(user ?? throw new KeyNotFoundException());
90-
}
91-
92-
public virtual async Task<ChatPage> GetChatTail(int length, CancellationToken cancellationToken = default)
79+
public virtual async Task<ChatMessageList> GetChatTail(int length, CancellationToken cancellationToken = default)
9380
{
9481
await PseudoGetAnyChatTail();
9582
await using var dbContext = CreateDbContext();
@@ -103,16 +90,19 @@ public virtual async Task<ChatPage> GetChatTail(int length, CancellationToken ca
10390

10491
// Fetching users via GetUserAsync
10592
var userIds = messages.Select(m => m.UserId).Distinct().ToArray();
106-
var userTasks = userIds.Select(id => GetUser(id, cancellationToken));
107-
var users = await Task.WhenAll(userTasks);
93+
var userTasks = userIds.Select(async id => {
94+
var user = await _authBackend.GetUser(default, id, cancellationToken);
95+
return user.OrGuest("<Deleted user>").ToClientSideUser();
96+
});
97+
var users = (await Task.WhenAll(userTasks)).OfType<User>();
10898

10999
// Composing the end result
110-
return new ChatPage(messages, users.ToDictionary(u => u.Id));
100+
return new ChatMessageList() {
101+
Messages = messages.ToImmutableArray(),
102+
Users = users.ToImmutableDictionary(u => u.Id.Value),
103+
};
111104
}
112105

113-
public virtual Task<ChatPage> GetChatPage(long minMessageId, long maxMessageId, CancellationToken cancellationToken = default)
114-
=> throw new NotImplementedException();
115-
116106
// Helpers
117107

118108
[ComputeMethod]
@@ -141,14 +131,4 @@ private async ValueTask<string> NormalizeText(
141131
var jObject = JObject.Parse(json);
142132
return jObject.Value<string>("quoteText")!;
143133
}
144-
145-
private ChatUser ToChatUser(User? user)
146-
{
147-
if (user == null || !long.TryParse(user.Id, out var userId))
148-
return ChatUser.None;
149-
return new() {
150-
Id = userId,
151-
Name = user.Name,
152-
};
153-
}
154134
}

0 commit comments

Comments
 (0)