Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature request: return new data from update #162

Open
skyqrose opened this issue Apr 3, 2023 · 1 comment
Open

feature request: return new data from update #162

skyqrose opened this issue Apr 3, 2023 · 1 comment

Comments

@skyqrose
Copy link

skyqrose commented Apr 3, 2023

I'm using the atomic update function, but after the update I want to keep the update value. Currently, it returns Promise<void>, and I want it to return Promise<T | undefined>.

My use case is persisting state in a React app. When I update the React state, I also update the data in IDB, and I want to keep IDB and React in sync.

There are two workarounds, and I'm using both:

  • Keep the data in javascript state (which I'm doing anyway) and then also call the update function on the JS state. This works, but I'm worried that the state could drift apart.
  • Reload the data from IDB after every update (and overwrite any data in React). This keeps React and IDB in sync, but means I'm making two calls to IDB. It doesn't cause any race conditions for me but it could for other use cases.

My workaround (roughly):

const [state, setState] = useState<T | undefined>(undefined)
// ...
async () => {
  setState((oldData) => update(oldData));
  await IDB.update(key, update);
  const newData = await IDB.get(key);
  setState(newData);
}

I would prefer to do:

const [state, setState] = useState<T | undefined>(undefined)
// ...
async () => {
  const newData = await IDB.update(key, update);
  setState(newData);
}

I think this feature would be especially useful for people who aren't keeping the data around in their app state, and just want to do something with the data after an update.

It would technically be a breaking change. People probably aren't doing anything with the specific void value that update currently returns, but it could cause typescript builds to fail if the signature changes. One way to mitigate that would be to add a new separate updateAndGet function, and leave update unchanged.

@skyqrose
Copy link
Author

skyqrose commented Apr 6, 2023

I ran into another example:

const data = await IDB.get(key);
if (isOutdated(data)) {
  await IDB.del(key);
  return null;
} else {
  return data;
}

The get and del aren't atomic, so there's a race condition if someone else writes other data to that key inbetween. I'd like to do the get, check, and delete in a single update:

const data = await IDB.update(key, (data) => {
  if (isOutdated(data)) {
    return null;
  else {
    return data;
  }
});
return data;

(setting to null and deleting aren't quite the same thing but that's not important for this example).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant