Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!(realtime_client): Introduce type safe realtime methods #725

Merged
merged 17 commits into from
Dec 1, 2023

Conversation

dshukertjr
Copy link
Member

@dshukertjr dshukertjr commented Nov 22, 2023

What kind of change does this PR introduce?

  • This is just a proposal, and would love to hear what you think about this idea.

Currently, the realtime methods are not type safe. This is due to how channel.on() method has to be able to support postgres changes, broadcast, and presence.

The proposal is to introduce three different methods onPostgresChanges, onBroadcast, and onPresence that will each handle their respective realtime features. That way, we would be able to restrict what parameters to accept or the type of the payload.

The public API would look something like this:

final channel = supabase.channel('name');

channel
  .onPostgresChanges(
      event: PostgresChangeEvent.all,
      schema: 'public',
      table: 'my_table',
      filter: PostgresChangeFilter(
        type: PostgresChangeFilterType.eq,
        column: 'id',
        value: 1,
      ),
      callback: (PostgresChangePayload payload) {
        // `PostgresChangePayload` is a new class dedicated for this payload
        final Map<String, dynamic> newRecord = payload
            .newRecord; // Wanted to use `new`, but `new` is a reserved keyword in Dart, so couldn't use it.
        final Map<String, dynamic> oldRecord = payload.oldRecord;
      })
  .onBroadcast(
      event: 'broadcast_event',
      callback: (Map<String, dynamic> payload) {
        print(payload);
      })
  .onPresence(
      event: PresenceEvent.join,
      callback: (Map<String, dynamic> payload) {
        print(payload);
      })
  .subscribe();

await myChannel.sendBroadcastMessage(
  event: 'cursor-pos',
  payload: {'x': 30, 'y': 50},
);

Open to hearing any opinions about it. I'm sure the proposed public API isn't the best design either, so would love to hear anything regarding it as well.

@Vinzent03
Copy link
Collaborator

I think I really like the new design! I haven't worked much with presence or broadcast, but it was always strange to have all arguments for all realtime functionalities in one method. It's easier to read as well.

@dshukertjr
Copy link
Member Author

Sounds great! I will finish up this PR!

@dshukertjr dshukertjr changed the title [proposal] feat!(realtime_client): Introduce type safe realtime methods feat!(realtime_client): Introduce type safe realtime methods Nov 27, 2023
@dshukertjr dshukertjr marked this pull request as ready for review November 27, 2023 09:07
@dshukertjr
Copy link
Member Author

I have updated the filter to take PostgresChangeFilter object like this:

final channel = supabase.channel('name');

channel
  .onPostgresChanges(
      event: PostgresChangeEvent.all,
      schema: 'public',
      table: 'my_table',
      filter: PostgresChangeFilter(
        type: PostgresChangeFilterType.eq,
        column: 'id',
        value: 1,
      ),
      callback: (PostgresChangePayload payload) {
        // `PostgresChangePayload` is a new class dedicated for this payload
        final Map<String, dynamic> newRecord = payload
            .newRecord; // Wanted to use `new`, but `new` is a reserved keyword in Dart, so couldn't use it.
        final Map<String, dynamic> oldRecord = payload.oldRecord;
      })
  .onBroadcast(
      event: 'broadcast_event',
      callback: (Map<String, dynamic> payload) {
        print(payload);
      })
  .onPresence(
      event: PresenceEvent.join,
      callback: (Map<String, dynamic> payload) {
        print(payload);
      })
  .subscribe();

@dshukertjr dshukertjr requested review from DanMossa, bdlukaa and Vinzent03 and removed request for DanMossa, bdlukaa and Vinzent03 November 27, 2023 09:08
@dshukertjr
Copy link
Member Author

Also, currently we use the send() method to send broadcast messages, but since send() is used internally it has som extra arguments. I have created a sendBroadcastMessage() method to simplify the experience of using it.

await myChannel.sendBroadcastMessage(
  event: 'cursor-pos',
  payload: {'x': 30, 'y': 50},
);

@dshukertjr
Copy link
Member Author

Once this PR, #736, and #737 are in, I think we can finally release a stable v2. Will update the docs on supabase.com website too!

@dshukertjr dshukertjr requested a review from Vinzent03 November 30, 2023 03:37
@dshukertjr dshukertjr merged commit 182f7c9 into next Dec 1, 2023
8 checks passed
@dshukertjr dshukertjr deleted the feat/realtime branch December 1, 2023 02:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants