effector-storage icon indicating copy to clipboard operation
effector-storage copied to clipboard

Need to add batching for query adapter

Open yumauri opened this issue 3 years ago • 2 comments

Several states, persisted in the query string, causes several history updates, even if updates were happen (almost) simultaneously. If you have two stores, persisted in query string, and they both updates — you will have two history records (when using default pushState method). Thus if you want to go back using "⬅️Back" button — you will have to click it twice, to revert both stores in the original state. Sometimes it can lead to nasty cyclic updates, if two stores are dependant from each other.

yumauri avatar Jul 20 '21 21:07 yumauri

To think about API like this:

persist({
 store: {
   page: $page,
   count: $count
 }
})

in that case it is theoretically possible to batch updates of two stores

yumauri avatar Feb 04 '22 11:02 yumauri

const pagination = restore({
  page: 1,
  count: 10,
})

persist({
  store: pagination
})

pagination.page.on(changePage, …)
pagination.count.on(changeCount, …)

const $pagination = combine(pagination)

yumauri avatar Feb 04 '22 11:02 yumauri

I've added timeout option to query adapter, it works like throttle, and should solve this issue.

There are some questions about how it should work with different URL change methods, for example, if one store is persisted with pushState and timeout=100 and other store — with locationAssign and timeout=10, and those two stores got updated one by one:

persist({
  store: $page,
  key: 'page',
  method: pushState,
  timeout: 100
})
persist({
  store: $count,
  key: 'count',
  method: locationAssign,
  timeout: 10
})

$page.setState('2')
$count.setState('20')

If batching will be separate (by method), then calling location.assign after 10 milliseconds will lost changing of page, it will not be stored in query string (because webpage will be refreshed, throwing away any JS runtime).

So, I decided to use shared buffer for any query string changes, because, regardless of change URL method, query string itself is a single instance, like, single medium.

So, in example above, page update will be flushed to query string along with count update — after 10 milliseconds, even when you specify timeout=100 for it. It is required in order to not loose updates.

yumauri avatar Apr 30 '23 15:04 yumauri

Will be published in version 6.0.0

yumauri avatar Apr 30 '23 15:04 yumauri

Released 🎉

yumauri avatar May 08 '23 12:05 yumauri