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

feat(vanilla/react): New Jotai v2 API #1515

Merged
merged 87 commits into from
Dec 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
2a4928e
initial commit for new "async" api
dai-shi Oct 31, 2022
c612d0a
wip: fix react/basic tests
dai-shi Oct 31, 2022
8e1ac76
wip: cancel promise
dai-shi Oct 31, 2022
3418048
fix tests
dai-shi Oct 31, 2022
386a248
for a transition test
dai-shi Oct 31, 2022
17c64ed
ignore tests with old versions
dai-shi Oct 31, 2022
b13082a
fix typo
dai-shi Oct 31, 2022
c0f2100
add two tests
dai-shi Oct 31, 2022
d316d93
add provider test
dai-shi Nov 1, 2022
080425e
fix for react 16
dai-shi Nov 1, 2022
0a49038
add dependency test
dai-shi Nov 1, 2022
a71aa56
refactor
dai-shi Nov 1, 2022
68ef021
add items test
dai-shi Nov 1, 2022
0a0272c
add error test and some fixes
dai-shi Nov 1, 2022
2eca1e6
add onmount test
dai-shi Nov 1, 2022
26f8b46
add optimization test and minor fixes
dai-shi Nov 1, 2022
ec932a1
clean up tests/react
dai-shi Nov 1, 2022
ce981a3
Merge branch 'main' into feat/core/new-api
dai-shi Nov 1, 2022
00b4fe8
remove unstable prefix
dai-shi Nov 1, 2022
353055e
Merge branch 'main' into feat/core/new-api
dai-shi Nov 1, 2022
1d1e901
Merge branch 'main' into feat/core/new-api
dai-shi Nov 2, 2022
d9baaa6
delay one tick for a promise by default to avoid suspense
dai-shi Nov 2, 2022
7f6b8c0
fix transition test
dai-shi Nov 3, 2022
86a76c6
some improvements
dai-shi Nov 3, 2022
aa88c6f
Revert "some improvements"
dai-shi Nov 3, 2022
b178c4e
improve !sync and add abortable test
dai-shi Nov 3, 2022
330e271
retry function and really add abortable test
dai-shi Nov 3, 2022
eb7dd28
improve readAtomState performance
dai-shi Nov 3, 2022
ca3d8b7
hack tests
dai-shi Nov 3, 2022
9c74d76
Merge branch 'main' into feat/core/new-api
dai-shi Nov 4, 2022
4281db6
fix FIXMEs
dai-shi Nov 4, 2022
5999178
make setTimeout usage consistent
dai-shi Nov 4, 2022
93e6c96
refactor to use object getters for options
dai-shi Nov 4, 2022
e6b6277
improve test configs
dai-shi Nov 5, 2022
68daa8d
async2 test
dai-shi Nov 5, 2022
197d5d9
improve abortableAtom test
dai-shi Nov 5, 2022
66e3167
possibl improvement
dai-shi Nov 5, 2022
e567a8a
delay 1ms
dai-shi Nov 7, 2022
dc96c28
testing with different versions
dai-shi Nov 7, 2022
89a7e95
testing with different versions
dai-shi Nov 7, 2022
92d8dd8
Revert "testing with different versions"
dai-shi Nov 7, 2022
6958add
Revert "testing with different versions"
dai-shi Nov 7, 2022
6f6efcc
optional delay option
dai-shi Nov 7, 2022
9f06d32
fix test
dai-shi Nov 7, 2022
081e2dc
fix test
dai-shi Nov 7, 2022
06162dc
workaround test for VERSIONED_WRITE
dai-shi Nov 7, 2022
a73c679
test and fix retry
dai-shi Nov 7, 2022
dbf8e9a
tweak test
dai-shi Nov 7, 2022
4b356da
Merge branch 'main' into feat/core/new-api
dai-shi Nov 7, 2022
1565384
new jotai/react/devtools bundle
dai-shi Nov 7, 2022
7e7941e
new jotai/react/devtools bundle
dai-shi Nov 7, 2022
2e91aac
fix workflow file
dai-shi Nov 7, 2022
853c72b
fix workflow file 2
dai-shi Nov 7, 2022
c00214e
fix workflow file 3
dai-shi Nov 7, 2022
8f7ecb8
drop initialValues prop
dai-shi Nov 9, 2022
ed7b29f
wip: migration guide
dai-shi Nov 9, 2022
2c906a3
Merge branch 'main' into feat/core/new-api
dai-shi Nov 10, 2022
ef34820
addressed @Thisen comments
dai-shi Nov 12, 2022
db18ffc
revert force boolean
dai-shi Nov 13, 2022
07b0a13
lets simply call v2 api
dai-shi Nov 14, 2022
960a537
wip: utils
dai-shi Nov 14, 2022
eddcbc9
atomWithStorage delayInit is default/only behavior
dai-shi Nov 14, 2022
9b010a3
wip: fix some utils
dai-shi Nov 14, 2022
4c6735e
fix remaining tests
dai-shi Nov 14, 2022
8147f21
update docs
dai-shi Nov 14, 2022
cc29f54
fix ci tests
dai-shi Nov 14, 2022
2dbfd4e
order?
dai-shi Nov 14, 2022
b86acc7
oops build script
dai-shi Nov 14, 2022
9077eb8
refactor memoizeAtom
dai-shi Nov 16, 2022
ffc989e
add unwrapAtom util
dai-shi Nov 16, 2022
df2a83d
use common symbols
dai-shi Nov 17, 2022
b0df5d9
avoid any
dai-shi Nov 17, 2022
b46ab09
mark unwrapAtom unstable
dai-shi Nov 17, 2022
61e0263
remove deperecated feature
dai-shi Nov 17, 2022
7f7cce7
Merge branch 'main' into feat/core/new-api
dai-shi Nov 17, 2022
972d33d
refactor
dai-shi Nov 19, 2022
d31e6ef
add some tests
dai-shi Nov 19, 2022
9a49bea
trying to add a failing test
dai-shi Nov 20, 2022
8926889
remove it.only
dai-shi Nov 20, 2022
463d55d
update docs
dai-shi Nov 21, 2022
29bd64b
fix type
dai-shi Nov 21, 2022
00aeb2e
tweak test
dai-shi Nov 21, 2022
9adeb4a
update doc
dai-shi Nov 23, 2022
18730c7
fix devtools with useStore
dai-shi Nov 26, 2022
e8ad659
fix a typo in docs
dai-shi Nov 30, 2022
a520203
unstable comment in react and vanilla entry points
dai-shi Dec 1, 2022
e295e18
Merge branch 'main' into feat/core/new-api
dai-shi Dec 1, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/test-multiple-builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ jobs:
- name: Patch for DEV-ONLY
if: ${{ matrix.env == 'development' }}
run: |
sed -i~ "s/it[a-zA-Z]*('\[PRD-ONLY\]/it.skip('/" tests/*/*.tsx
sed -i~ "s/it[a-zA-Z]*('\[PRD-ONLY\]/it.skip('/" tests/*/*.tsx tests/*/*/*.tsx
- name: Patch for PRD-ONLY
if: ${{ matrix.env == 'production' }}
run: |
sed -i~ "s/it[a-zA-Z]*('\[DEV-ONLY\]/it.skip('/" tests/*/*.tsx
sed -i~ "s/it[a-zA-Z]*('\[DEV-ONLY\]/it.skip('/" tests/*/*.tsx tests/*/*/*.tsx
- name: Patch for CJS
if: ${{ matrix.build == 'cjs' }}
run: |
Expand All @@ -43,7 +43,7 @@ jobs:
if: ${{ matrix.build == 'esm' }}
run: |
sed -i~ "s/<rootDir>\/src\(.*\)\.ts/<rootDir>\/dist\/esm\1.js" package.json
sed -i~ "1s/^/import.meta.env=import.meta.env||{};import.meta.env.MODE='${NODE_ENV}';/" tests/*/*.tsx
sed -i~ "1s/^/import.meta.env=import.meta.env||{};import.meta.env.MODE='${NODE_ENV}';/" tests/*/*.tsx tests/*/*/*.tsx
env:
NODE_ENV: ${{ matrix.env }}
- name: Patch for UMD/SystemJS
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/test-multiple-versions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,13 @@ jobs:
- name: Patch for React 16
if: ${{ startsWith(matrix.react, '16.') }}
run: |
sed -i~ '1s/^/import React from "react";/' tests/*/*.tsx
sed -i~ '1s/^/import React from "react";/' tests/*/*.tsx src/*/*.tsx
sed -i~ 's/automatic/classic/' babel.config.js
sed -i~ 's/automatic/classic/' .swcrc
- name: Ignore Async API tests for Older React
if: ${{ matrix.react == '16.8.6' }} || ${{ matrix.mode != 'NORMAL' }}
run: |
rm -r tests/vanilla tests/react
- name: Test ${{ matrix.react }} ${{ matrix.mode }}
run: |
yarn add -D react@${{ matrix.react }} react-dom@${{ matrix.react }}
Expand Down
12 changes: 8 additions & 4 deletions .github/workflows/test-old-typescript.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,26 @@ jobs:
- run: yarn build
- name: Patch for Old TS
run: |
sed -i~ "s/\/\/ @ts-expect-error.*\[LATEST-TS-ONLY\]//" tests/*/*.tsx
sed -i~ "s/\/\/ @ts-expect-error.*\[LATEST-TS-ONLY\]//" tests/*/*.tsx tests/*/*/*.tsx
sed -i~ "s/\"exactOptionalPropertyTypes\": true,//" tsconfig.json
sed -i~ "s/\"jotai\": \[\"\.\/src\/index\.ts\"\],/\"jotai\": [\".\/dist\/ts3.4\/index.d.ts\"],/" tsconfig.json
sed -i~ "s/\"jotai\/\*\": \[\"\.\/src\/\*\.ts\"\]/\"jotai\/*\": [\".\/dist\/ts3.4\/*.d.ts\"]/" tsconfig.json
sed -i~ "s/\"include\": .*/\"include\": [\"src\/types.d.ts\", \"dist\/**\/*\", \"tests\/**\/*\"],/" tsconfig.json
- name: Patch for Older TS
if: ${{ matrix.typescript == '4.2.3' || matrix.typescript == '4.1.5' || matrix.typescript == '4.0.5' || startsWith(matrix.typescript, '3.') }}
run: |
sed -i~ '1s/^/import React from "react";/' tests/*/*.tsx
sed -i~ '1s/^/import React from "react";/' tests/*/*.tsx tests/*/*/*.tsx
sed -i~ "s/\"jsx\": \"react-jsx\",/\"jsx\": \"react\",/" tsconfig.json
sed -i~ "s/\"noUncheckedIndexedAccess\": true,//" tsconfig.json
sed -i~ "s/^import type /import /" tests/*/*.tsx
sed -i~ "s/^import type /import /" tests/*/*.tsx tests/*/*/*.tsx
sed -i~ "s/^.* from '\.\/utils\/waitForAll';//" dist/ts3.4/utils.d.ts
yarn json -I -f package.json -e "this.resolutions['@types/jest']='26.0.14'; this.resolutions['pretty-format']='25.5.0'; this.resolutions['@types/prettier']='2.4.2';"
yarn add -D @types/jest@26.0.14 pretty-format@25.5.0 @types/prettier@2.4.2
rm -r tests/query tests/urql tests/optics tests/xstate tests/valtio tests/zustand tests/utils/atomWithObservable.* tests/utils/waitForAll.*
rm -r tests/query tests/urql tests/optics tests/xstate tests/valtio tests/zustand tests/utils/atomWithObservable.* tests/utils/waitForAll.* tests/vanilla/utils/atomWithObservable.*
- name: Ignore Async API tests for Older TS
if: ${{ matrix.typescript == '3.7.5' }}
run: |
rm -r tests/vanilla tests/react
- name: Test ${{ matrix.typescript }}
run: |
yarn add -D typescript@${{ matrix.typescript }}
Expand Down
222 changes: 222 additions & 0 deletions docs/guides/migrating-to-v2-api.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
---
title: Migrating to Jotai v2 API
description: New "Async" API
nav: 3.13
---

RFC: https://github.com/pmndrs/jotai/discussions/1514

Jotai v1 is released at June 2022, and there has been various feedbacks.
React also proposes first-class support for promises.
Jotai v2 will have a new API.

Unfortunately, there are some breaking changes along with new features.

## What are new features

### Vanilla library

Jotai comes with vanilla (non-React) functions
and React functions separately.

### Store API

Jotai exposes store interface so that you can directly manipulate atom values.

```js
import { createStore } from 'jotai/vanilla'

const store = createStore()
store.set(fooAtom, 'foo')
```

You can also create your own React Context to pass a store.

### More flexible atom `write` function

The write function can accept multiple arguments,
and return a value.

```js
atom(
(get) => get(...),
(get, set, arg1, arg2, ...) => {
...
return someValue
}
)
```

## What are breaking

### Import statements

The new API is provided from different entry points:

- `jotai/vanilla`
- `jotai/vanilla/utils`
- `jotai/react`
- `jotai/react/devtools`
- `jotai/react/utils`

```js
import { atom } from 'jotai/vanilla'
import { useAtom } from 'jotai/react'
```

These new entry points are added in v1.11.0 as pre-release, which will continue to work after v2.0.0 release.

In v2.0.0, they are the defaults and old entry points simply refer to the new ones.

```js
// v2
import { atom } from 'jotai' // is same as 'jotai/vanilla'
import { useAtom } from 'jotai' // is same as 'jotai/react'
```

### Async atoms are no longer special

Async atoms are just normal atoms with promise values.
Atoms getter functions don't resolve promises.
On the other hand, `useAtom` hook continues to resolve promises.

### Writable atom type is changed (TypeScript only)

```ts
// Old
WritableAtom<Value, Arg, Result extends void | Promise<void>>

// New
WritableAtom<Value, Args extends unknown[], Result>
```

In general, we should avoid using `WritableAtom` type directly.

### Some functions are dropped

- Provider's `initialValues` prop is removed, because `store` is more flexible.
- Provider's scope props is removed, because you can create own context.
- `abortableAtom` util is removed, becuase the feature is included by default
- `waitForAll` util is removed, because `Promise.all` just works

## Migration guides

### Async atoms

`get` function for read function of async atoms
doesn't resolve promises, so you have to put `await`.

In short, the change is something like the following.
(If you are TypeScript users, types will tell where to changes.)

#### Previous API

```js
const asyncAtom = atom(async () => 'hello')
const derivedAtom = atom((get) => get(asyncAtom).toUppercase())
```

#### New API

```js
const asyncAtom = atom(async () => 'hello')
const derivedAtom = atom(async (get) => (await get(asyncAtom)).toUppercase())
```

### Provider's `initialValues` prop

#### Previous API

```jsx
const countAtom = atom(0)

<Provider initialValues={[[countAtom, 1]]}>
...
</Provider>
```

#### New API

```jsx
const countAtom = atom(0)
const store = createStore()
store.set(countAtom, 1)

<Provider store={store}>
...
</Provider>
```

### Provider's `scope` prop

#### Previous API

```jsx
const myScope = Symbol()

// Parent component
<Provider scope={myScope}>
...
</Provider>

// Child component
useAtom(..., myScope)
```

#### New API

```jsx
const MyContext = createContext()
const store = createStore()

// Parent component
<MyContext.Provider value={store}>
...
</MyContext.Provider>

// Child Component
const store = useContext(MyContext)
useAtom(..., { store })
```

### `abortableAtom` util

You no longer need the previous `abortableAtom` util,
because it's now supported with the normal `atom`.

#### Previous API

```js
const asyncAtom = abortableAtom(async (get, { signal }) => {
...
}
```

#### New API

```js
const asyncAtom = atom(async (get, { signal }) => {
...
}
```

### `waitForAll` util

You no longer need the previous `waitForAll` util,
because we can use native Promise APIs.

#### Previous API

```js
const allAtom = waitForAll([fooAtom, barAtom])
```

#### New API

```js
const allAtom = atom((get) => Promise.all([get(fooAtom), get(barAtom)]))
```

## Some other changes

- `atomWithStorage` util's `delayInit` is removed as being default.
Loading