Nanostores in SSR

See original GitHub issue

Hi there!

I saw news on new release, saw allTasks API and decided to research, how nanostores is compatible with SSR

Loading of Node.js template in codesandbox takes forever for some reason, so i decided to create similiar reproduce with basic one: https://codesandbox.io/s/loving-wilson-4vp4r?file=/src/index.js (see index.js and console)

Idea is the same:

  1. Request happens
  2. Request-handler task is added to event-loop and starts some logic and web or db requests
  3. Once those web or db requests are over, state is recalculated with new data
  4. State injected in the app, which then rendered to string
  5. Resulting string sent as response

During all of these operations is important to isolate state that “belongs” to different requests from each other - otherwise data from one request will leak to the other

Nanostores have two issues there:

  1. States of nanostores are shared between requests, which then leads to data prepared for one request to show in another - in result rendered html-string is not correct.

  2. State of internal allTasks counter is also shared between all requests, which leads to weird bug: responses are not sent until all requests are handled, even if their data is ready.

Possible solutions:

  1. Many state-managers require creation of new instance of store/stores for every request, like this
const ssr = async (request) => {
 const stores = initStores()
 
 await stores.startLogic(request)
 
 return renderAppToString(stores)
}

This will effectively isolate requests from each other, because all of them will have their own instance of stores and all pending operations also will be bounded to this instance Mobx example: https://github.com/vercel/next.js/tree/master/examples/with-mobx-state-tree

  1. Some other state-managers, like effector, allow to create separate instance of app state in special way, allowing to reuse already initialized stores and connections, like this:
const ssr = async (request) => {
 // all stores and connections already defined somewhere
 const scope = fork()
 
 await allSettled(startLogic, { scope, params: request })
 
 return renderAppToString(scope)
}

Example: https://github.com/GTOsss/ssr-effector-next-example/blob/effector-react-form-ssr/src/pages/ssr.tsx

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:13 (8 by maintainers)

github_iconTop GitHub Comments

3reactions
Eddortcommented, Nov 23, 2021

I have another solution, but the documentation is very weak.

https://github.com/Eddort/nanostores-ssr

The main idea is to create a handler for each request (SSR function) and create a new context for each new request.

1reaction
AlexandrHoroshihcommented, Nov 23, 2021

I don’t think that wrapper would work - if user missed some store, then it will be missed from serialization and further hydration at the client, which is no good, if it, for example, was changed during SSR (on the other hand, it may make sense to ignore some stores in serialization, for e.g. internal stores of libraries)

Probably it should be a core feature, so all APIs of the library are aware of the scopes and can properly handle it 🤔

I don’t think that it is actually matter, if server context is isolated or not - the problem of collecting all parts of decentralized state of the app is still persists, since it is needed to hydrate app state at the client somehow anyway 🤔

Read more comments on GitHub >

github_iconTop Results From Across the Web

@nanostores/persistent - npm
A tiny persistent store for Nano Stores state manager. Latest version: 0.7.0, last published: 2 months ago.
Read more >
Nano stores - Best of JS
Nano Stores. A tiny state manager for React, React Native, Preact, Vue, Svelte, and vanilla JS. It uses many atomic stores and direct...
Read more >
Sharing State - Astro Documentation
Nano Stores ship the bare minimum JS you'll need (less than 1 KB) with zero dependencies. They're framework-agnostic. This means sharing state between ......
Read more >
@nanostores/solid - NPM Package Overview - Socket - Socket.dev
Nano Stores support SSR. Use standard strategies. import { isServer } from 'solid-js/web'; if (isServer) { settings.set(initialSettings); ...
Read more >
Sitnik the Developer on Twitter: "We released Nano Stores 0.5 ...
We released Nano Stores 0.5, a new version of tiny (200-900 bytes) state manager ... In tests or SSR, you can wait for...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found