I was more talking about the method to achieve optimistic updates, rather than the concept of optimistic updates in general. That is, having the client and server code be identical where applicable, with client code being run in a prediction context.
I'm not a web expert but the optimistic updates I've seen in web stuff is more like, I'm gonna fetch this url and here's the data I expect back. Nothing wrong with that, but it's achieved in a different way, where the server is all about providing data and the client is all about managing state.
The OP is talking about maintaining a persistent connection to a server which is doing most of the state management. They detail things this does well (makes the server easier to write) and things it does poorly (makes optimistic updates harder) and a solution to the things it does poorly. So I'm drawing a parallel to other systems where state is managed on the server and must be predicted on the client.
The way I’ve always done it is that I have client side event handlers that perform the UI-visible side of the logic client side, but also asynchronously request the server to do it.
In simple cases, that logic simple sets a toggle or whatever. In slightly more advanced cases it might modify something such as appending to a list. But in some cases it could be performing more complex logic such as applying a filter to a list. Sometimes this logic is only done client side (if the filtering is view-only for example) and sometimes both client and server. Basically, if you remove all of the network requests, it would still look like it’s working, more or less.
Of course only logic that is needed for data to be correctly displayed in the UI is needed client side. Performing logic that is only used server side (even if it has later UI effects — only effects that the user expects immediately need local representation) is unnecessary client side.
Eg even in a game, you might not want to run, for example, bot AI speculatively on every client but rather just the movement prediction like for other players, while everything else may be needed for rendering.
Haven't used it in years, but Meteor.js worked like this. Even to the point where it had a client-side database implementation that mirrored (parts of) the server-side database.
It would apply the updates optimistically to the client side DB, and the much of code that sat between the database could be shared between client and server. Neat stuff, even if overall Meteor wasn't my favourite thing to work with.
I'm not a web expert but the optimistic updates I've seen in web stuff is more like, I'm gonna fetch this url and here's the data I expect back. Nothing wrong with that, but it's achieved in a different way, where the server is all about providing data and the client is all about managing state.
The OP is talking about maintaining a persistent connection to a server which is doing most of the state management. They detail things this does well (makes the server easier to write) and things it does poorly (makes optimistic updates harder) and a solution to the things it does poorly. So I'm drawing a parallel to other systems where state is managed on the server and must be predicted on the client.