solid icon indicating copy to clipboard operation
solid copied to clipboard

Stores on the server aren't proxies

Open thetarnav opened this issue 2 years ago • 1 comments

Describe the bug

Both createMutable and createStore pass through the state object input as the returned value on the server.

image

This leads to referential and proxy checks to behave differently on client and server.

const [state, setState] = createStore({})

//                          CLIENT   |   SERVER
state === unwrap(state) //  false    |   true
$TRACK in state         //  true     |   false
$RAW in state           //  true     |   false
$PROXY in state         //  true     |   false
state[$PROXY]           //  (proxy)  |   undefined
state[$RAW]             //  (object) |   undefined

This is probably intentional for performance reasons, but it feels inconstant and may lead to random unpredictable bugs.

I've stumbled on it when making a primitive for observing changes to stores, which lead to a hydration error as the initial value on the server was an empty array, and the initial store state on the client.

export function createStoreDelta<T extends Static>(store: T): () => StoreDelta<T> {
  if (!($TRACK in store)) {
    return () => [];
  }

  const cache: StoreDeltaCache = {};
  return () => {
    CurrentDelta = [];
    compareStoreWithCache(store, cache, "root", []);
    return CurrentDelta;
  };
}

This is a very edge-casey thing which I probably need to work around better.

thetarnav avatar May 19 '23 16:05 thetarnav

Hmm you are right.. I didn't really want to add proxies.

That being said we can have most of these conditions pass without adding them except the first one. I don't know how important that is that it is equal when it otherwise wouldn't be. But the rest can be doctored on easily enough.

EDIT: Oh actually I guess not because of deep nesting. Yeah that is a bit annoying. I see ok, it might be unavoidable.

ryansolid avatar May 21 '23 20:05 ryansolid