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

fix(vanilla): store should flush pending write triggered asynchronously and indirectly #2451

Merged

Conversation

iwoplaza
Copy link
Contributor

Related Issues or Discussions

Sorry for the onslaught of PRs, I believe this one to be an actual fix to a regression caused by the #2396 refactor

Summary

For this bug to occur a few things have to happen:

  1. An atom that we wish to update indirectly, e.g.
const emailAtom = atom('[email protected]')
  1. An atom that simply writes to the atom above in its write function, e.g.:
const updateEmailAtom = atom(null, (_get, set, value: string) => set(emailAtom, value.trim()))
  1. An atom that executes the above atom asynchronously, e.g.:
const initializeAndVerifyAtom = atom(null, async (_get, set, fields: FormFields) => {
  const email = fields.email
  await verifyEmail(email)
  
  // this write is no longer sync, so should be flushed immediately, but the
  // actual atom that will get set (emailAtom) thinks it is being set synchronously,
  // so it just adds itself to the non-existent top of `pendingStack`.
  set(updateEmailAtom, email)
})

Instead of tracking isSync in writeAtomState, we can use the length of pendingStack to determine if the atom we are currently updating will get flushed in a batch, or do we have to handle the flushing immediately.

Check List

  • yarn run prettier for formatting code and docs

Copy link

vercel bot commented Mar 12, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
jotai ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 13, 2024 10:34am

Copy link

codesandbox-ci bot commented Mar 12, 2024

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Copy link

github-actions bot commented Mar 12, 2024

LiveCodes Preview in LiveCodes

Latest commit: 8afafc9
Last updated: Mar 13, 2024 10:33am (UTC)

Playground Link
React demo https://livecodes.io?x=id/DYDC4JZRY

See documentations for usage instructions.

@dai-shi
Copy link
Member

dai-shi commented Mar 13, 2024

This one looks good.
Did you confirm if the new test passes before #2396 refactor?

The fix seems a little bit unexpected to me, but probably can't be helped. I'll take another look when I'm relaxed.

@iwoplaza
Copy link
Contributor Author

Can confirm that the new test passes before #2396, and fails right after.

@iwoplaza
Copy link
Contributor Author

I updated the solution a bit, so that it behaves more like how it did before #2396. Since before this fix, setAtomState was pushing to a pending stack item that did not exist (and therefore was never flushed). This new solution ensures there is a Set in the pending stack if the setter was called asynchronously (with no item in the pending stack)

@dai-shi
Copy link
Member

dai-shi commented Mar 13, 2024

the new one feels a little bit better.

@iwoplaza
Copy link
Contributor Author

What do you think about adding a console.warn('[Bug] tried to register flush onto an empty stack') outside of production mode, so:

const pendingStackTop = pendingStack[pendingStack.length - 1];
if (pendingStackTop) {
  pendingStackTop.add(a)
} else if (import.meta.env?.MODE !== 'production') {
  console.warn('[Bug] tried to register flush onto an empty stack')
}

instead of

pendingStack[pendingStack.length - 1]?.add(a)

might make it easier to catch bugs like this in the future, or to note running setAtomState without providing a value on the stack first is erroneous.

@dai-shi
Copy link
Member

dai-shi commented Mar 13, 2024

that sounds good. let's do it.

@iwoplaza
Copy link
Contributor Author

Scratch that, there are places where setting the state of a mounted atom should not cause it to be flushed immediately, like in the updatePromiseDependencies function. The store implementation is still a little hard for me to maneuver, where is that update to the dependencies flushed?

Comment on lines -584 to +587
const flushed = flushPending([a])
const flushed = flushPending(pendingStack.pop()!)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was skeptical about [a], so this looks good in code.

Copy link
Member

@dai-shi dai-shi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The store implementation is still a little hard for me to maneuver

Well, it's same for me.

@dai-shi dai-shi added this to the v2.7.1 milestone Mar 15, 2024
@dai-shi
Copy link
Member

dai-shi commented Mar 15, 2024

I was planning to release it with v2.8.0.
But, as #2454 is reported, let's ship v2.7.1.

@dai-shi dai-shi merged commit 9952649 into pmndrs:main Mar 15, 2024
34 checks passed
@iwoplaza iwoplaza deleted the fix/vanilla/non-sync-chained-atom-update-bug branch March 15, 2024 10:41
renovate bot referenced this pull request in turtton/volglass Mar 17, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@biomejs/biome](https://biomejs.dev)
([source](https://togithub.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome))
| [`1.5.3` ->
`1.6.1`](https://renovatebot.com/diffs/npm/@biomejs%2fbiome/1.5.3/1.6.1)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@biomejs%2fbiome/1.6.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@biomejs%2fbiome/1.6.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@biomejs%2fbiome/1.5.3/1.6.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@biomejs%2fbiome/1.5.3/1.6.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@types/node](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node)
([source](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node))
| [`18.19.22` ->
`18.19.24`](https://renovatebot.com/diffs/npm/@types%2fnode/18.19.22/18.19.24)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fnode/18.19.24?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2fnode/18.19.24?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2fnode/18.19.22/18.19.24?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fnode/18.19.22/18.19.24?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@types/react](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react)
([source](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react))
| [`18.2.64` ->
`18.2.66`](https://renovatebot.com/diffs/npm/@types%2freact/18.2.64/18.2.66)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2freact/18.2.66?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2freact/18.2.66?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2freact/18.2.64/18.2.66?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2freact/18.2.64/18.2.66?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[@types/react-dom](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react-dom)
([source](https://togithub.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom))
| [`18.2.21` ->
`18.2.22`](https://renovatebot.com/diffs/npm/@types%2freact-dom/18.2.21/18.2.22)
|
[![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2freact-dom/18.2.22?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2freact-dom/18.2.22?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2freact-dom/18.2.21/18.2.22?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2freact-dom/18.2.21/18.2.22?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [jotai](https://togithub.com/pmndrs/jotai) | [`2.7.0` ->
`2.7.1`](https://renovatebot.com/diffs/npm/jotai/2.7.0/2.7.1) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/jotai/2.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/jotai/2.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/jotai/2.7.0/2.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/jotai/2.7.0/2.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [postcss](https://postcss.org/)
([source](https://togithub.com/postcss/postcss)) | [`8.4.35` ->
`8.4.36`](https://renovatebot.com/diffs/npm/postcss/8.4.35/8.4.36) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/postcss/8.4.36?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/postcss/8.4.36?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/postcss/8.4.35/8.4.36?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/postcss/8.4.35/8.4.36?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom](https://togithub.com/JetBrains/kotlin-wrappers)
| `1.0.0-pre.710` -> `1.0.0-pre.715` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom/1.0.0-pre.715?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom/1.0.0-pre.715?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom/1.0.0-pre.710/1.0.0-pre.715?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom/1.0.0-pre.710/1.0.0-pre.715?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>biomejs/biome (@&#8203;biomejs/biome)</summary>

###
[`v1.6.1`](https://togithub.com/biomejs/biome/blob/HEAD/CHANGELOG.md#161-2024-03-12)

[Compare
Source](https://togithub.com/biomejs/biome/compare/560628b380b0b1f61303c8e5ca2175d3b4794089...4ed1cbe96bc9e6d7092e88dd0a54ff8ce78037e5)

##### CLI

##### Bug fixes

- CLI is now able to automatically search and resolve `biome.jsonc`
([#&#8203;2008](https://togithub.com/biomejs/biome/issues/2008)).
Contributed by [@&#8203;Sec-ant](https://togithub.com/Sec-ant)
- Fix a false positive where some files were counted as "fixed" even
though they weren't modified. Contributed by
[@&#8203;ematipico](https://togithub.com/ematipico)

##### Configuration

##### Bug fixes

- `json.formatter.trailingCommas` option now works in `overrides`
([#&#8203;2009](https://togithub.com/biomejs/biome/issues/2009)).
Contributed by [@&#8203;Sec-ant](https://togithub.com/Sec-ant)

##### Linter

##### New features

- Add rule
[noDoneCallback](https://biomejs.dev/linter/rules/no-done-callback),
this rule checks the function parameter of hooks & tests
for use of the done argument, suggesting you return a promise instead.
Contributed by [@&#8203;vasucp1207](https://togithub.com/vasucp1207)

    ```js
    beforeEach(done => {
      // ...
    });
    ```

##### Bug fixes

-
[useJsxKeyInIterable](https://biomejs.dev/linter/rules/use-jsx-key-in-iterable)
now recognizes function bodies wrapped in parentheses
([#&#8203;2011](https://togithub.com/biomejs/biome/issues/2011)).
Contributed by [@&#8203;Sec-ant](https://togithub.com/Sec-ant)

-
[useShorthandFunctionType](https://biomejs.dev/linter/rules/use-shorthand-function-type)
now preserves type parameters of generic interfaces when applying fixes
([#&#8203;2015](https://togithub.com/biomejs/biome/issues/2015)).
Contributed by [@&#8203;Sec-ant](https://togithub.com/Sec-ant)

- Code fixes of
[useImportType](https://biomejs.dev/linter/rules/use-import-type) and
[useExportType](https://biomejs.dev/linter/rules/use-export-type) now
handle multiline statements
([#&#8203;2041](https://togithub.com/biomejs/biome/issues/2041)).
Contributed by [@&#8203;Conaclos](https://togithub.com/Conaclos)

- [noRedeclare](https://biomejs.dev/linter/rules/no-redeclare) no longer
reports type parameter and parameter with identical names
([#&#8203;1992](https://togithub.com/biomejs/biome/issues/1992)).

    The following code is no longer reported:

    ```ts
    function f<a>(a: a) {}
    ```

    Contributed by [@&#8203;Conaclos](https://togithub.com/Conaclos)

- [noRedeclare](https://biomejs.dev/linter/rules/no-redeclare) now
reports duplicate type parameters in a same declaration.

    The following type parameters are now reported as a redeclaraion:

    ```ts
    function f<T, T>() {}
    ```

    Contributed by [@&#8203;Conaclos](https://togithub.com/Conaclos)

-
[noUndeclaredDependencies](https://biomejs.dev/linter/rules/no-undeclared-dependencies/)
now recognizes imports of subpath exports.

E.g., the following import statements no longer report errors if
`@mui/material` and `tailwindcss` are installed as dependencies:

    ```ts
    import Button from "@&#8203;mui/material/Button";
    import { fontFamily } from "tailwindcss/defaultTheme";
    ```

    Contributed by [@&#8203;Sec-ant](https://togithub.com/Sec-ant)

##### Parser

##### Bug fixes

- JavaScript lexer is now able to lex regular expression literals with
escaped non-ascii chars
([#&#8203;1941](https://togithub.com/biomejs/biome/issues/1941)).

    Contributed by [@&#8203;Sec-ant](https://togithub.com/Sec-ant)

###
[`v1.6.0`](https://togithub.com/biomejs/biome/blob/HEAD/CHANGELOG.md#160-2024-03-08)

[Compare
Source](https://togithub.com/biomejs/biome/compare/906de83449b5066554cd8e97c78a1f8e43749016...560628b380b0b1f61303c8e5ca2175d3b4794089)

##### Analyzer

##### New features

- Add partial for `.astro` files. Biome is able to sort imports inside
the frontmatter of the Astro files. Contributed
    by [@&#8203;ematipico](https://togithub.com/ematipico)

</details>

<details>
<summary>pmndrs/jotai (jotai)</summary>

### [`v2.7.1`](https://togithub.com/pmndrs/jotai/releases/tag/v2.7.1)

[Compare
Source](https://togithub.com/pmndrs/jotai/compare/v2.7.0...v2.7.1)

This fixes a regression in v2.7.0.

#### What's Changed

- fix(vanilla): store should flush pending write triggered
asynchronously and indirectly by
[@&#8203;iwoplaza](https://togithub.com/iwoplaza) in
[https://github.com/pmndrs/jotai/pull/2451](https://togithub.com/pmndrs/jotai/pull/2451)
- fix(utils): atomWithStorage to always run onMount by
[@&#8203;dai-shi](https://togithub.com/dai-shi) in
[https://github.com/pmndrs/jotai/pull/2455](https://togithub.com/pmndrs/jotai/pull/2455)

#### New Contributors

- [@&#8203;rothsandro](https://togithub.com/rothsandro) made their first
contribution in
[https://github.com/pmndrs/jotai/pull/2426](https://togithub.com/pmndrs/jotai/pull/2426)
- [@&#8203;NehalDamania](https://togithub.com/NehalDamania) made their
first contribution in
[https://github.com/pmndrs/jotai/pull/2441](https://togithub.com/pmndrs/jotai/pull/2441)
- [@&#8203;tien](https://togithub.com/tien) made their first
contribution in
[https://github.com/pmndrs/jotai/pull/2446](https://togithub.com/pmndrs/jotai/pull/2446)
- [@&#8203;ashuvssut](https://togithub.com/ashuvssut) made their first
contribution in
[https://github.com/pmndrs/jotai/pull/2445](https://togithub.com/pmndrs/jotai/pull/2445)

**Full Changelog**:
pmndrs/jotai@v2.7.0...v2.7.1

</details>

<details>
<summary>postcss/postcss (postcss)</summary>

###
[`v8.4.36`](https://togithub.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8436)

[Compare
Source](https://togithub.com/postcss/postcss/compare/8.4.35...e5ad9394daf38d0ef4acd7065f219b3cddace1df)

- Fixed `original.column are not numbers` error on broken previous
source map.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 1pm and before 5pm on Friday"
in timezone Asia/Tokyo, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://togithub.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/turtton/volglass).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4yNDUuMCIsInVwZGF0ZWRJblZlciI6IjM3LjI0NS4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
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

Successfully merging this pull request may close these issues.

2 participants