Skip to content

Commit

Permalink
Fixed more issues
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib committed Feb 24, 2022
1 parent 1c36385 commit 3b7da64
Show file tree
Hide file tree
Showing 79 changed files with 11,576 additions and 2,123 deletions.
16 changes: 11 additions & 5 deletions src/StrawberryShake/Client/src/Core/Json/JsonResultPatcher.cs
Expand Up @@ -26,7 +26,7 @@ public void SetResponse(Response<JsonDocument> response)

public Response<JsonDocument> PatchResponse(Response<JsonDocument> response)
{
if (_response?.Body is null || response.Body!.RootElement.TryGetProperty(Data, out _))
if (_response?.Body is null || !response.Body!.RootElement.TryGetProperty(Data, out _))
{
throw new NotSupportedException(JsonResultPatcher_NoValidInitialResponse);
}
Expand Down Expand Up @@ -85,13 +85,15 @@ public Response<JsonDocument> PatchResponse(Response<JsonDocument> response)
var patchData = JsonObject.Create(dataProp)!;

#if NET5_0_OR_GREATER
foreach ((var key, JsonNode? value) in patchData)
foreach ((var key, JsonNode? value) in patchData.ToArray())
{
patchData.Remove(key);
current[key] = value;
}
#else
foreach (KeyValuePair<string, JsonNode?> prop in patchData)
foreach (KeyValuePair<string, JsonNode?> prop in patchData.ToArray())
{
patchData.Remove(prop.Key);
current[prop.Key] = prop.Value;
}
#endif
Expand All @@ -109,13 +111,15 @@ public Response<JsonDocument> PatchResponse(Response<JsonDocument> response)
else
{
#if NET5_0_OR_GREATER
foreach ((var key, JsonNode? value) in patchData)
foreach ((var key, JsonNode? value) in patchData.ToArray())
{
patchData.Remove(key);
element[key] = value;
}
#else
foreach (KeyValuePair<string, JsonNode?> prop in patchData)
foreach (KeyValuePair<string, JsonNode?> prop in patchData.ToArray())
{
patchData.Remove(prop.Key);
element[prop.Key] = prop.Value;
}
#endif
Expand All @@ -135,6 +139,8 @@ public Response<JsonDocument> PatchResponse(Response<JsonDocument> response)
using var writer = new Utf8JsonWriter(buffer);

_json.WriteTo(writer);
writer.Flush();

var json = JsonDocument.Parse(buffer.Body);

return new(json, response.Exception, false, response.HasNext, _extensions, _contextData);
Expand Down
Expand Up @@ -94,7 +94,6 @@ public IDisposable Subscribe(IObserver<IOperationResult<TResult>> observer)
{
Response<TData> patched = resultPatcher.PatchResponse(response);
result = resultBuilder.Build(patched);
_operationStore.Set(_request, result);
}
else
{
Expand Down
38 changes: 15 additions & 23 deletions src/StrawberryShake/Client/src/Core/OperationStore.cs
Expand Up @@ -259,42 +259,34 @@ private void OnEntityUpdate(EntityUpdate update)
private void OnUpdate(
IStoredOperation operation,
OperationUpdateKind kind)
{
OnUpdate(
=> OnUpdate(
new[]
{
new StoredOperationVersion(
operation.Request,
operation.LastResult,
operation.Subscribers,
operation.LastModified)
new StoredOperationVersion(
operation.Request,
operation.LastResult,
operation.Subscribers,
operation.LastModified)
},
kind);
}

private void OnUpdate(
IEnumerable<IStoredOperation> operations,
OperationUpdateKind kind)
{
OnUpdate(operations
.Select(t => new StoredOperationVersion(
t.Request,
t.LastResult,
t.Subscribers,
t.LastModified))
.ToArray(),
=> OnUpdate(
operations
.Select(t => new StoredOperationVersion(
t.Request,
t.LastResult,
t.Subscribers,
t.LastModified))
.ToArray(),
kind);
}

private void OnUpdate(
IReadOnlyList<StoredOperationVersion> operations,
OperationUpdateKind kind)
{
_updates.Writer.TryWrite(
new OperationUpdate(
kind,
operations));
}
=> _updates.Writer.TryWrite(new OperationUpdate(kind, operations));

public void Dispose()
{
Expand Down
7 changes: 6 additions & 1 deletion src/StrawberryShake/Client/src/Core/StoredOperation.cs
Expand Up @@ -12,6 +12,7 @@ internal class StoredOperation<T>
private readonly object _sync = new();
private ImmutableList<Subscription> _subscriptions = ImmutableList<Subscription>.Empty;
private bool _disposed;
private IOperationResult<T>? _lastResult;

public StoredOperation(OperationRequest request)
{
Expand All @@ -20,7 +21,11 @@ public StoredOperation(OperationRequest request)

public OperationRequest Request { get; }

public IOperationResult<T>? LastResult { get; private set; }
public IOperationResult<T>? LastResult
{
get => _lastResult;
private set => _lastResult = value;
}

IOperationResult? IStoredOperation.LastResult => LastResult;

Expand Down
151 changes: 74 additions & 77 deletions src/StrawberryShake/Client/src/Razor/DataComponent.cs
Expand Up @@ -2,99 +2,96 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Components;

namespace StrawberryShake.Razor
namespace StrawberryShake.Razor;

/// <summary>
/// A data component can be used to remove boiler plate from using reactive data operations.
/// </summary>
/// <typeparam name="TClientOrOperation">
/// The client or operation this component shall interact with.
/// </typeparam>
public abstract class DataComponent<TClientOrOperation> : ComponentBase, IDisposable
{
private readonly List<IDisposable> _subscriptions = new();
private bool _disposed;

/// <summary>
/// A data component can be used to remove boiler plate from using reactive data operations.
/// Gets the client or operation.
/// </summary>
/// <typeparam name="TClientOrOperation">
/// The client or operation this component shall interact with.
/// </typeparam>
public abstract class DataComponent<TClientOrOperation>
: ComponentBase
, IDisposable
{
private readonly List<IDisposable> _subscriptions = new();
private bool _disposed;

/// <summary>
/// Gets the client or operation.
/// </summary>
[Inject]
protected internal TClientOrOperation ClientOrOperation { get; internal set; } = default!;
[Inject]
protected internal TClientOrOperation ClientOrOperation { get; internal set; } = default!;

/// <summary>
/// Gets the data client.
/// </summary>
protected TClientOrOperation Client => ClientOrOperation;
/// <summary>
/// Gets the data client.
/// </summary>
protected TClientOrOperation Client => ClientOrOperation;

/// <summary>
/// Gets the data operation.
/// </summary>
protected TClientOrOperation Operation => ClientOrOperation;
/// <summary>
/// Gets the data operation.
/// </summary>
protected TClientOrOperation Operation => ClientOrOperation;

/// <summary>
/// Registers a data subscription with the component.
/// The component will dispose any registered subscription when it is disposed.
/// </summary>
/// <param name="subscribe">
/// The subscribe delegate creating a data subscription.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="subscribe"/> is <c>null</c>.
/// </exception>
public void Register(Func<TClientOrOperation, IDisposable> subscribe)
/// <summary>
/// Registers a data subscription with the component.
/// The component will dispose any registered subscription when it is disposed.
/// </summary>
/// <param name="subscribe">
/// The subscribe delegate creating a data subscription.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="subscribe"/> is <c>null</c>.
/// </exception>
public void Register(Func<TClientOrOperation, IDisposable> subscribe)
{
if (subscribe is null)
{
if (subscribe is null)
{
throw new ArgumentNullException(nameof(subscribe));
}

_subscriptions.Add(subscribe(ClientOrOperation));
throw new ArgumentNullException(nameof(subscribe));
}

/// <summary>
/// Registers a data subscription with the component.
/// The component will dispose any registered subscription when it is disposed.
/// </summary>
/// <param name="subscribe">
/// The subscribe delegate creating a data subscription.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="subscribe"/> is <c>null</c>.
/// </exception>
[Obsolete("Use Register(Func<TClientOrOperation, IDisposable> subscribe)")]
public void Subscribe(Func<TClientOrOperation, IDisposable> subscribe) =>
Register(subscribe);
_subscriptions.Add(subscribe(ClientOrOperation));
}

/// <summary>
/// Performs application-defined tasks associated with freeing,
/// releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Registers a data subscription with the component.
/// The component will dispose any registered subscription when it is disposed.
/// </summary>
/// <param name="subscribe">
/// The subscribe delegate creating a data subscription.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="subscribe"/> is <c>null</c>.
/// </exception>
[Obsolete("Use Register(Func<TClientOrOperation, IDisposable> subscribe)")]
public void Subscribe(Func<TClientOrOperation, IDisposable> subscribe) =>
Register(subscribe);

/// <summary>
/// Performs application-defined tasks associated with freeing,
/// releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Performs application-defined tasks associated with freeing,
/// releasing, or resetting unmanaged resources.
/// </summary>
protected void Dispose(bool disposing)
/// <summary>
/// Performs application-defined tasks associated with freeing,
/// releasing, or resetting unmanaged resources.
/// </summary>
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (!_disposed)
if (disposing)
{
if (disposing)
foreach (IDisposable subscription in _subscriptions)
{
foreach (var subscription in _subscriptions)
{
subscription.Dispose();
}
subscription.Dispose();
}

_disposed = true;
}

_disposed = true;
}
}
}

0 comments on commit 3b7da64

Please sign in to comment.