Skip to content

Conversation

0xcadams
Copy link
Member

@0xcadams 0xcadams commented Jul 18, 2025

There was a usability issue with the online status with Zero. React doesn't rerender when Zero's online property updates. This proposes an API, onOnline, to make it easier to listen for updates to this. And an accompanying hook in React/SolidJS, useZeroOnline.

Copy link

vercel bot commented Jul 18, 2025

@0xcadams is attempting to deploy a commit to the Rocicorp Team on Vercel.

A member of the Team first needs to authorize it.


const raceResult = await promiseRace([sleep(5000), result.server]);
if (raceResult === 0) {
// TODO show toast
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want this to be a toast?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we should rely on a new global onError handler that Matt is constantly wanting to add. It is half-implemented in the codebase right now, but we got distracted by API design questions and never finished it.

I don't want every mutator to have to do this kind of error handling manually.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense - agreed it would be much better to have this in onError. So I can add this toast later and only have this PR include online indicator, once the onError handler lands.

@aboodman
Copy link
Contributor

I'm confused - we already have onOnlineChange. Why not use that at the basis for useOnline?

@aboodman
Copy link
Contributor

aboodman commented Jul 18, 2025

@alexhking can you design an online indicator for zbugs? Note that people will probably copy whatever we do into their apps.

Here are my product thoughts:

  1. I do not (cannot stress enough how much I do not want this) want it to animate or throb or do anything when syncing. This just becomes a spinner and destroys the feeling of instant.
  2. I think when online, it should be invisible. Linear doesn't have an 'online' state. You assume it is online.
  3. I am not sure where it should go visually.
  4. As always I think it should be simple, minimal, tasteful.
  5. Maybe we should consider animations and transitions when going offline and returning online.

@0xcadams
Copy link
Member Author

I'm confused - we already have onOnlineChange. Why not use that at the basis for useOnline?

Yeah I can do that - it just means managing that state in two places and adds a new Context. Will change.

@aboodman
Copy link
Contributor

I'm confused - we already have onOnlineChange. Why not use that at the basis for useOnline?

Yeah I can do that - it just means managing that state in two places and adds a new Context. Will change.

I am missing something.... it seems trivial to wrap a hook around the existing feature. I don't get why any change is needed in zero.ts.

@aboodman
Copy link
Contributor

Oooh it is because there can be many hooks, but there can only be one onOnlineChange event. Yeah that was super ghetto, let's fix that. Good call. Will review PR with that frame.

Copy link
Contributor

@aboodman aboodman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I like this.


const raceResult = await promiseRace([sleep(5000), result.server]);
if (raceResult === 0) {
// TODO show toast
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we should rely on a new global onError handler that Matt is constantly wanting to add. It is half-implemented in the codebase right now, but we got distracted by API design questions and never finished it.

I don't want every mutator to have to do this kind of error handling manually.

@@ -0,0 +1,38 @@
export class Subscribable<
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to suggest nanoevent but this is so simple maybe it makes sense to have it in our codebase in case we want to change it.

@arv @tantaman ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also @arv just confirming there's nothing like this already in Replicache so we don't duplicate code?

* @param listener - The listener to subscribe to.
* @returns A function to unsubscribe the listener.
*/
addOnlineChangeListener = (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about onOnline and then we deprecate onOnlineChange.

);
}

this.#onOnlineChange = onOnlineChange;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking change but it is so simple to update I am supportive.

@0xcadams 0xcadams changed the title [WIP] - Offline Offline Jul 22, 2025
@0xcadams 0xcadams changed the title Offline feat(zero): offline Jul 22, 2025
@0xcadams 0xcadams marked this pull request as ready for review July 22, 2025 17:47
@0xcadams
Copy link
Member Author

@alexhking I changed the design based on the above comments. Open to feedback. See the description for the current design. I can add tooltip, etc.

@tantaman
Copy link
Contributor

@aboodman - should we just merge rather than having this open/blocked and fix forward? Seems annoying and unproductive to have to have PRs open for such a long time (having to rebase and resolve merge conflicts to revisit).

@alexhking
Copy link
Contributor

@alexhking I changed the design based on the above comments. Open to feedback. See the description for the current design. I can add tooltip, etc.

Hey Chase, for some reason I didn't get notified when you sent this last week. Checking out now and will give feedback.

@alexhking
Copy link
Contributor

@0xcadams @aboodman

Ok, after reviewing I have several questions and comments:

  • Do we want to completely remove the state of the visual representation of the user being logged in when offline?
  • If so, why are we still showing the log out control?
  • The “Offline” badge has a completely different style than the logged in user state, and I’m not sure why. Right now it seems to closely resemble what we use for labels, but with different padding.
  • It may be nice to add a tooltip to explain a bit more about what offline means and what limitations there are.

I would like to take a stab at redesigning this just a bit at least visually.

@aboodman
Copy link
Contributor

@aboodman - should we just merge rather than having this open/blocked and fix forward? Seems annoying and unproductive to have to have PRs open for such a long time (having to rebase and resolve merge conflicts to revisit).

Typically we would but just because Chase was new to the team I suggested he block on reviews and start conservatively. Will re-evaluate.

}
return login.loginState?.encoded;
},
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why this change is needed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not - an artifact of other changes made and then kept because it added type safety. Can remove

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does it improve about type safety? Currently for me I do not see any type errors in my env w/o this.

The reason I'm asking is because zbugs is a testbed for how we expect Zero to be used and I wasn't expecting this to be required of users.

/**
* `onOnlineChange` is called when the Zero instance's online status changes.
*
* @deprecated Use `onOnline` on the Zero instance instead. e.g.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nuts. @grgbkr had gone to a lot of trouble to pass in all the configuration to Zero. But I think didn't consider this problem/use-case. So maybe passing in all configuration cannot work.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can support both here. The adding/removal of listeners doesn't need to be all up-front. And this doesn't need to be deprecated.

Or, if it's better, we can move this all to the React/Solid layers. And continue to use onOnlineChange and track the online state with React Context.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will be very convoluted to track the listeners state in the React/Solid layers. I'm ok with this change.

The other to event listener type configs we currently have are onUpdateNeeded and onClientStateNotFound. Possibly these should move on to the Zero instance as well, and our general pattern would be event listeners on the Zero instance. I think these are unlikely to need multiple listeners like onOnline might, but it may just be more ergonomic to have them on Zero given React hooks. I think it would be good to build a UI for onUpdateNeeded to figure out what is most ergonomic.

@0xcadams
Copy link
Member Author

  • Do we want to completely remove the state of the visual representation of the user being logged in when offline?
  • If so, why are we still showing the log out control?
  • The “Offline” badge has a completely different style than the logged in user state, and I’m not sure why. Right now it seems to closely resemble what we use for labels, but with different padding.
  • It may be nice to add a tooltip to explain a bit more about what offline means and what limitations there are.

I would like to take a stab at redesigning this just a bit at least visually.

On these - I am completely open to the design you want to go with. I am still getting used to what design styles the team likes, so I did not put a lot of time into the design (this was a very loose copy of how Linear does it). Please let me know if you want me to add tooltip, etc.

@aboodman
Copy link
Contributor

@0xcadams @aboodman

Ok, after reviewing I have several questions and comments:

  • Do we want to completely remove the state of the visual representation of the user being logged in when offline?

I don't think so... is there some reason to do @0xcadams ? Prefer to keep login state looking the same while offline.

  • It may be nice to add a tooltip to explain a bit more about what offline means and what limitations there are.
    I would like to take a stab at redesigning this just a bit at least visually.

Please! Sounds great!

Copy link
Contributor

@aboodman aboodman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo type question.

@0xcadams 0xcadams enabled auto-merge (squash) July 30, 2025 17:52
Copy link

vercel bot commented Jul 30, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
replicache-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 30, 2025 6:02pm
zbugs ✅ Ready (Inspect) Visit Preview Jul 30, 2025 6:02pm

@0xcadams
Copy link
Member Author

I have removed all changes to zbugs so we can update the styling/display of offline in a future PR.

@aboodman
Copy link
Contributor

aboodman commented Jul 30, 2025 via email

@0xcadams 0xcadams disabled auto-merge July 30, 2025 17:57
@0xcadams
Copy link
Member Author

Sounds good - added back and merging and will note to follow up w/ @alexhking to get better styling here.

@0xcadams 0xcadams merged commit 5c91a63 into rocicorp:main Jul 30, 2025
11 checks passed
@0xcadams 0xcadams deleted the 0xcadams/offline branch July 30, 2025 18:11
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.

5 participants