logux icon indicating copy to clipboard operation
logux copied to clipboard

SSR data loading

Open mrdimidium opened this issue 7 years ago • 10 comments

How would it be possible to upload a log to the server during server rendering?

mrdimidium avatar Jul 04 '18 16:07 mrdimidium

Right now there is not easy out-of-box solution.

You can you WebSocket to download it in old manner. Or you can use some other way and then just use store.add to set data manually.

Do you have a idea how to do it better?

ai avatar Jul 04 '18 16:07 ai

Maybe, I want to have SSR client, which takes user subscribes and return log.

mrdimidium avatar Jul 04 '18 16:07 mrdimidium

Seems, that one instance SSR Client from one ssr server decides the problem. I can load user subscribes from react code and give from ssr client.

mrdimidium avatar Jul 04 '18 16:07 mrdimidium

What is a problems right now? SSR client will load anything by the same WS way.

Do you need some Promise, which will be resolved when all subscriptions will be loaded?

ai avatar Jul 04 '18 16:07 ai

My code works isomorphic, it loads data isomorphic, but I can't create a Browser Client instance on the server. I need to load the log on the server without changing my client code (in promis, probably), serialize it and embed it in the client. On the client, I want to run it, combine it with the client log and start working with it.

mrdimidium avatar Jul 04 '18 16:07 mrdimidium

Without data on the server I can not build HTML

mrdimidium avatar Jul 04 '18 16:07 mrdimidium

but I can't create a Browser Client instance on the server

Why?

ai avatar Jul 04 '18 16:07 ai

You may need a WebSocket implementation:

yarn add ws
global.WebSocket = require('ws')

ai avatar Jul 04 '18 19:07 ai

@nikolay-govorov is that solution fit you?

ai avatar Jul 09 '18 09:07 ai

After the discussion with @droganov I am thinking about this API for SSR:

  1. Logux Server will have HTTP API. Anyway, we need it for WebSocket fallback.
  2. Logux Client by default will use HTTP API on missed global.WebSocket.
  3. Add client.ignoreSubscription = RegExp | action: Action => boolean to ignore unnecessary subscriptions on the server.
  4. Add client.isSubscribing to track all current subscriptions.
  5. Check that CrossTabClient will work in Node.js without browser API polyfills.
  6. Add the option to MemoryStore to pass initial actions to the log.
  7. Add log.getAll(): Promise<[Action, Meta][]>

Here is an SSR process:

  1. We load the normal Logux Client on the SSR server. Just need to specify userId and token. Optionally developer could specify client#ignoreSubscription in isNode if-statement.
  2. Logux Client automatically switches to HTTP mode. Collects all subscriptions, sends the single HTTP request to Logux Server and the server responds with the list of actions.
  3. SSR server waits for client.isSubscribing and then renders HTML again.
  4. SSR sends the final HTML and client.log.getAll() to the client.
  5. The client shows HTML, re-initialize Logux Client with received log and rehydrate React.
  6. Subscriptions on the client subscribing again, but since they have a log, they will send subscription requests with the since field to avoid re-loading existed data.

ai avatar Apr 18 '20 12:04 ai