Skip to content

Commit

Permalink
Add interfaces for publicly facing classes
Browse files Browse the repository at this point in the history
  • Loading branch information
acupofjose committed Nov 6, 2022
1 parent 8f57edf commit cca23d2
Show file tree
Hide file tree
Showing 10 changed files with 266 additions and 126 deletions.
11 changes: 6 additions & 5 deletions Realtime/Channel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Timers;
using Newtonsoft.Json;
using Supabase.Realtime.Attributes;
using Supabase.Realtime.Interfaces;
using static Supabase.Realtime.Channel;

[assembly: InternalsVisibleTo("RealtimeTests")]
Expand All @@ -13,7 +14,7 @@ namespace Supabase.Realtime
/// <summary>
/// Class representation of a channel subscription
/// </summary>
public class Channel
public class Channel : IRealtimeChannel
{
/// <summary>
/// Channel state with associated string representations.
Expand Down Expand Up @@ -93,7 +94,7 @@ public enum ChannelState
/// </summary>
public bool HasJoinedOnce { get; private set; }

private Socket socket;
private IRealtimeSocket socket;

/// <summary>
/// The initial request to join a channel (repeated on channel disconnect)
Expand All @@ -119,7 +120,7 @@ public enum ChannelState
/// <param name="table"></param>
/// <param name="col"></param>
/// <param name="value"></param>
public Channel(Socket socket, ChannelOptions options)
public Channel(IRealtimeSocket socket, ChannelOptions options)
{
this.socket = socket;

Expand All @@ -138,9 +139,9 @@ public Channel(Socket socket, ChannelOptions options)
/// Subscribes to the channel given supplied Options/params.
/// </summary>
/// <param name="timeoutMs"></param>
public Task<Channel> Subscribe(int timeoutMs = Constants.DEFAULT_TIMEOUT)
public Task<IRealtimeChannel> Subscribe(int timeoutMs = Constants.DEFAULT_TIMEOUT)
{
var tsc = new TaskCompletionSource<Channel>();
var tsc = new TaskCompletionSource<IRealtimeChannel>();

if (hasJoinedOnce)
{
Expand Down
17 changes: 9 additions & 8 deletions Realtime/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Supabase.Realtime.Interfaces;

namespace Supabase.Realtime
{
Expand All @@ -17,7 +18,7 @@ namespace Supabase.Realtime
/// <example>
/// client = Client.Instance
/// </example>
public class Client
public class Client : IRealtimeClient<Socket, Channel>
{
/// <summary>
/// Contains all Realtime Channel Subscriptions - state managed internally.
Expand All @@ -37,8 +38,8 @@ public class Client
///
/// Most methods of the Client act as proxies to the Socket class.
/// </summary>
public Socket? Socket { get => socket; }
private Socket? socket;
public IRealtimeSocket? Socket { get => socket; }
private IRealtimeSocket? socket;

/// <summary>
/// Client Options - most of which are regarding Socket connection Options
Expand Down Expand Up @@ -112,7 +113,7 @@ public JsonSerializerSettings SerializerSettings
public Client(string realtimeUrl, ClientOptions? options = null)
{
this.realtimeUrl = realtimeUrl;

if (options == null)
options = new ClientOptions();

Expand All @@ -139,9 +140,9 @@ public Client(string realtimeUrl, ClientOptions? options = null)
/// Returns when socket has successfully connected.
/// </summary>
/// <returns></returns>
public Task<Client> ConnectAsync()
public Task<IRealtimeClient<Socket, Channel>> ConnectAsync()
{
var tsc = new TaskCompletionSource<Client>();
var tsc = new TaskCompletionSource<IRealtimeClient<Socket, Channel>>();

try
{
Expand Down Expand Up @@ -192,7 +193,7 @@ public Task<Client> ConnectAsync()
/// </summary>
/// <param name="callback"></param>
/// <returns></returns>
public Client Connect(Action<Client>? callback = null)
public IRealtimeClient<Socket, Channel> Connect(Action<IRealtimeClient<Socket, Channel>>? callback = null)
{
if (socket != null)
{
Expand Down Expand Up @@ -246,7 +247,7 @@ private void HandleSocketHeartbeat(object sender, SocketResponseEventArgs e)
/// <param name="code">Status Code</param>
/// <param name="reason">Reason for disconnect</param>
/// <returns></returns>
public Client Disconnect(WebSocketCloseStatus code = WebSocketCloseStatus.NormalClosure, string reason = "Programmatic Disconnect")
public IRealtimeClient<Socket, Channel> Disconnect(WebSocketCloseStatus code = WebSocketCloseStatus.NormalClosure, string reason = "Programmatic Disconnect")
{
if (socket != null)
{
Expand Down
31 changes: 31 additions & 0 deletions Realtime/Interfaces/IRealtimeChannel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Threading.Tasks;

namespace Supabase.Realtime.Interfaces
{
public interface IRealtimeChannel
{
bool HasJoinedOnce { get; }
bool IsClosed { get; }
bool IsErrored { get; }
bool IsJoined { get; }
bool IsJoining { get; }
bool IsLeaving { get; }
ChannelOptions Options { get; }
Channel.ChannelState State { get; }
string Topic { get; }

event EventHandler<ChannelStateChangedEventArgs> OnClose;
event EventHandler<SocketResponseEventArgs> OnDelete;
event EventHandler<ChannelStateChangedEventArgs> OnError;
event EventHandler<SocketResponseEventArgs> OnInsert;
event EventHandler<SocketResponseEventArgs> OnMessage;
event EventHandler<SocketResponseEventArgs> OnUpdate;
event EventHandler<ChannelStateChangedEventArgs> StateChanged;

void Push(string eventName, object payload, int timeoutMs = 10000);
void Rejoin(int timeoutMs = 10000);
Task<IRealtimeChannel> Subscribe(int timeoutMs = 10000);
void Unsubscribe();
}
}
31 changes: 31 additions & 0 deletions Realtime/Interfaces/IRealtimeClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net.WebSockets;
using System.Threading.Tasks;

namespace Supabase.Realtime.Interfaces
{
public interface IRealtimeClient<TSocket, TChannel>
where TSocket: IRealtimeSocket
where TChannel: IRealtimeChannel
{
ClientOptions Options { get; }
JsonSerializerSettings SerializerSettings { get; }
IRealtimeSocket? Socket { get; }
ReadOnlyDictionary<string, TChannel> Subscriptions { get; }

event EventHandler<SocketStateChangedEventArgs> OnClose;
event EventHandler<SocketStateChangedEventArgs> OnError;
event EventHandler<SocketStateChangedEventArgs> OnMessage;
event EventHandler<SocketStateChangedEventArgs> OnOpen;

Channel Channel(string database = "realtime", string? schema = null, string? table = null, string? column = null, string? value = null, Dictionary<string, string>? parameters = null);
IRealtimeClient<TSocket, TChannel> Connect(Action<IRealtimeClient<TSocket, TChannel>>? callback = null);
Task<IRealtimeClient<TSocket, TChannel>> ConnectAsync();
IRealtimeClient<TSocket, TChannel> Disconnect(WebSocketCloseStatus code = WebSocketCloseStatus.NormalClosure, string reason = "Programmatic Disconnect");
void Remove(TChannel channel);
void SetAuth(string jwt);
}
}
23 changes: 23 additions & 0 deletions Realtime/Interfaces/IRealtimePush.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;

namespace Supabase.Realtime.Interfaces
{
public interface IRealtimePush<TChannel, TSocketResponse>
where TChannel : IRealtimeChannel
where TSocketResponse: IRealtimeSocketResponse
{
TChannel Channel { get; }
string EventName { get; }
bool IsSent { get; }
SocketRequest? Message { get; }
object? Payload { get; }
string? Ref { get; }
IRealtimeSocketResponse? Response { get; }

event EventHandler<SocketResponseEventArgs>? OnMessage;
event EventHandler? OnTimeout;

void Resend(int timeoutMs = 10000);
void Send();
}
}
20 changes: 20 additions & 0 deletions Realtime/Interfaces/IRealtimeSocket.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Net.WebSockets;

namespace Supabase.Realtime.Interfaces
{
public interface IRealtimeSocket
{
bool IsConnected { get; }

event EventHandler<SocketResponseEventArgs> OnHeartbeat;
event EventHandler<SocketResponseEventArgs> OnMessage;
event EventHandler<SocketStateChangedEventArgs> StateChanged;

void Connect();
void Disconnect(WebSocketCloseStatus code = WebSocketCloseStatus.NormalClosure, string reason = "");
string MakeMsgRef();
void Push(SocketRequest data);
string ReplyEventName(string msgRef);
}
}
16 changes: 16 additions & 0 deletions Realtime/Interfaces/IRealtimeSocketResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Postgrest.Models;

namespace Supabase.Realtime.Interfaces
{
public interface IRealtimeSocketResponse
{
string? _event { get; set; }
Constants.EventType Event { get; }
SocketResponsePayload? Payload { get; set; }
string? Ref { get; set; }
string? Topic { get; set; }

T? Model<T>() where T : BaseModel, new();
T? OldModel<T>() where T : BaseModel, new();
}
}
14 changes: 7 additions & 7 deletions Realtime/Push.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Supabase.Realtime.Interfaces;
using System;
using System.Timers;

namespace Supabase.Realtime
Expand All @@ -9,7 +10,7 @@ namespace Supabase.Realtime
/// `Push` also adds additional functionality for retrying, timeouts, and listeners
/// for its associated response from the server.
/// </summary>
public class Push
public class Push : IRealtimePush<Channel, SocketResponse>
{
/// <summary>
/// Flag representing the `sent` state of a request.
Expand All @@ -25,7 +26,7 @@ public class Push
/// Invoked when this `Push` has not been responded to within the timeout interval.
/// </summary>
public event EventHandler? OnTimeout;
public SocketResponse? Response { get; private set; }
public IRealtimeSocketResponse? Response { get; private set; }

/// <summary>
/// The associated channel.
Expand All @@ -52,12 +53,11 @@ public class Push
/// </summary>
public string? Ref { get; private set; }

private string? msgRefEvent;
private int timeoutMs;
private Timer timer;

private string? msgRefEvent;

private Socket socket;
private IRealtimeSocket socket;

/// <summary>
/// Initilizes a single request that will be `Pushed` to the Socket server.
Expand All @@ -66,7 +66,7 @@ public class Push
/// <param name="eventName"></param>
/// <param name="payload"></param>
/// <param name="timeoutMs"></param>
public Push(Socket socket, Channel channel, string eventName, object? payload, int timeoutMs = Constants.DEFAULT_TIMEOUT)
public Push(IRealtimeSocket socket, Channel channel, string eventName, object? payload, int timeoutMs = Constants.DEFAULT_TIMEOUT)
{
this.socket = socket;

Expand Down
Loading

0 comments on commit cca23d2

Please sign in to comment.