Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: pmndrs/jotai
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.13.0
Choose a base ref
...
head repository: pmndrs/jotai
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.13.1
Choose a head ref
  • 7 commits
  • 26 files changed
  • 4 contributors

Commits on Jan 13, 2023

  1. docs: Optimized readme.md code format (#1681)

    * docs: formatting readme.md
    
    Optimized code format
    
    fix: formatting readme
    
    Revert "fix: formatting readme"
    
    This reverts commit 0770813.
    
    docs: formatting readme.md
    
    fix: formatting readme
    
    Revert "fix: formatting readme"
    
    This reverts commit 0770813.
    
    docs: formatting readme.md
    
    * docs: adding '...' to make it explicit that it's partial code
    
    * docs: Update readme.md
    AwesomeDevin authored Jan 13, 2023
    1
    Copy the full SHA
    ed866ae View commit details

Commits on Jan 14, 2023

  1. 1
    Copy the full SHA
    fd625d7 View commit details

Commits on Jan 15, 2023

  1. Update react experimental builds (#1682)

    * wip: update react experimental builds
    
    * drop some tests
    
    * fix ts
    
    * fix workflow file
    dai-shi authored Jan 15, 2023
    1
    Copy the full SHA
    02690db View commit details

Commits on Jan 16, 2023

  1. chore(benchmark): fix tool for v2 (#1687)

    * fix benchmarks for v1
    
    * migrate to v2
    dai-shi authored Jan 16, 2023
    1
    Copy the full SHA
    5bd4eb5 View commit details
  2. fix(react): delete pre-released v2 API devtools (#1686)

    * fix(react): delete v2 API devtools
    
    * remove one more file
    
    * empty commit
    dai-shi authored Jan 16, 2023
    1
    Copy the full SHA
    d7e0334 View commit details
  3. 1
    Copy the full SHA
    bb94299 View commit details
  4. 1.13.1

    dai-shi committed Jan 16, 2023
    1
    Copy the full SHA
    cce759f View commit details
14 changes: 3 additions & 11 deletions .github/workflows/test-multiple-versions.yml
Original file line number Diff line number Diff line change
@@ -25,10 +25,6 @@ jobs:
run: yarn test:ci
env:
PROVIDER_MODE: 'PROVIDER_LESS'
- name: Test Default with Versioned Write
run: yarn test:ci
env:
PROVIDER_MODE: 'VERSIONED_WRITE'

test_matrix:
runs-on: ubuntu-latest
@@ -42,13 +38,9 @@ jobs:
- 18.0.0
- 18.1.0
- 18.2.0
- 18.3.0-next-65e32e58b-20221019
- 0.0.0-experimental-65e32e58b-20221019
mode: [NORMAL, PROVIDER_LESS, VERSIONED_WRITE]
exclude:
- { react: 16.8.6, mode: VERSIONED_WRITE }
- { react: 16.9.0, mode: VERSIONED_WRITE }
- { react: 17.0.0, mode: VERSIONED_WRITE }
- 18.3.0-next-555ece0cd-20230112
- 0.0.0-experimental-555ece0cd-20230112
mode: [NORMAL, PROVIDER_LESS]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
2 changes: 1 addition & 1 deletion .github/workflows/test-old-typescript.yml
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ jobs:
- 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 tests/*/*/*.tsx
sed -i~ '1s/^/\/\/\/ <reference types="react\/experimental" \/>\nimport 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 tests/*/*/*.tsx
19 changes: 12 additions & 7 deletions benchmarks/simple-read.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
#!/usr/bin/env npx ts-node

import { add, complete, cycle, save, suite } from 'benny'
import { atom } from '../src/core/atom'
import type { PrimitiveAtom } from '../src/core/atom'
import { READ_ATOM, createStore } from '../src/core/store'
import { atom } from '../src/vanilla/atom'
import type { PrimitiveAtom } from '../src/vanilla/atom'
import { createStore } from '../src/vanilla/store'

declare global {
// eslint-disable-next-line no-var
var __DEV__: boolean
}
globalThis.__DEV__ = false

const createStateWithAtoms = (n: number) => {
let targetAtom: PrimitiveAtom<number> | undefined
const initialValues = new Map()
const store = createStore()
for (let i = 0; i < n; ++i) {
const a = atom(i)
if (!targetAtom) {
targetAtom = a
}
initialValues.set(a, i)
store.set(a, i)
}
const store = createStore(initialValues)
if (!targetAtom) {
throw new Error()
}
@@ -28,7 +33,7 @@ const main = async () => {
`simple-read-${n}`,
add(`atoms=${10 ** n}`, () => {
const [store, targetAtom] = createStateWithAtoms(10 ** n)
return () => store[READ_ATOM](targetAtom)
return () => store.get(targetAtom)
}),
cycle(),
complete(),
19 changes: 12 additions & 7 deletions benchmarks/simple-write.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
#!/usr/bin/env npx ts-node

import { add, complete, cycle, save, suite } from 'benny'
import { atom } from '../src/core/atom'
import type { PrimitiveAtom } from '../src/core/atom'
import { WRITE_ATOM, createStore } from '../src/core/store'
import { atom } from '../src/vanilla/atom'
import type { PrimitiveAtom } from '../src/vanilla/atom'
import { createStore } from '../src/vanilla/store'

declare global {
// eslint-disable-next-line no-var
var __DEV__: boolean
}
globalThis.__DEV__ = false

const createStateWithAtoms = (n: number) => {
let targetAtom: PrimitiveAtom<number> | undefined
const initialValues = new Map()
const store = createStore()
for (let i = 0; i < n; ++i) {
const a = atom(i)
if (!targetAtom) {
targetAtom = a
}
initialValues.set(a, i)
store.set(a, i)
}
const store = createStore(initialValues)
if (!targetAtom) {
throw new Error()
}
@@ -28,7 +33,7 @@ const main = async () => {
`simple-write-${n}`,
add(`atoms=${10 ** n}`, () => {
const [store, targetAtom] = createStateWithAtoms(10 ** n)
return () => store[WRITE_ATOM](targetAtom, (c) => c + 1)
return () => store.set(targetAtom, (c) => c + 1)
}),
cycle(),
complete(),
25 changes: 13 additions & 12 deletions benchmarks/subscribe-write.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#!/usr/bin/env npx ts-node

import { add, complete, cycle, save, suite } from 'benny'
import { atom } from '../src/core/atom'
import type { PrimitiveAtom } from '../src/core/atom'
import {
READ_ATOM,
SUBSCRIBE_ATOM,
WRITE_ATOM,
createStore,
} from '../src/core/store'
import { atom } from '../src/vanilla/atom'
import type { PrimitiveAtom } from '../src/vanilla/atom'
import { createStore } from '../src/vanilla/store'

declare global {
// eslint-disable-next-line no-var
var __DEV__: boolean
}
globalThis.__DEV__ = false

const cleanupFns = new Set<() => void>()
const cleanup = () => {
@@ -24,9 +25,9 @@ const createStateWithAtoms = (n: number) => {
if (!targetAtom) {
targetAtom = a
}
store[READ_ATOM](a)
const unsub = store[SUBSCRIBE_ATOM](a, () => {
store[READ_ATOM](a)
store.get(a)
const unsub = store.sub(a, () => {
store.get(a)
})
cleanupFns.add(unsub)
}
@@ -43,7 +44,7 @@ const main = async () => {
add(`atoms=${10 ** n}`, () => {
cleanup()
const [store, targetAtom] = createStateWithAtoms(10 ** n)
return () => store[WRITE_ATOM](targetAtom, (c) => c + 1)
return () => store.set(targetAtom, (c) => c + 1)
}),
cycle(),
complete(),
1 change: 0 additions & 1 deletion docs/guides/migrating-to-v2-api.mdx
Original file line number Diff line number Diff line change
@@ -56,7 +56,6 @@ The new API is provided from different entry points:
- `jotai/vanilla`
- `jotai/vanilla/utils`
- `jotai/react`
- `jotai/react/devtools`
- `jotai/react/utils`

```js
4 changes: 1 addition & 3 deletions docs/integrations/urql.mdx
Original file line number Diff line number Diff line change
@@ -67,9 +67,7 @@ const UserData = () => {

#### Basic demo

FIXME: Update demo

<CodeSandbox id="zujf6" />
<CodeSandbox id="5rwunq" />

## atomsWithMutation

27 changes: 13 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "jotai",
"private": true,
"version": "1.13.0",
"version": "1.13.1",
"description": "👻 Next gen state management that will spook you",
"main": "./index.js",
"types": "./index.d.ts",
@@ -62,14 +62,13 @@
"build:vanilla:utils": "rollup -c --config-vanilla_utils",
"build:react": "rollup -c --config-react",
"build:react:utils": "rollup -c --config-react_utils",
"build:react:devtools": "rollup -c --config-react_devtools",
"postbuild": "yarn copy && yarn patch-ts3.4 && yarn patch-esm-ts && yarn patch-readme",
"prettier": "prettier '*.{js,json,md}' '{src,tests,benchmarks,docs}/**/*.{ts,tsx,md,mdx}' --write",
"prettier:ci": "prettier '*.{js,json,md}' '{src,tests,benchmarks,docs}/**/*.{ts,tsx,md,mdx}' --list-different",
"eslint": "eslint --fix '*.{js,json}' '{src,tests,benchmarks}/**/*.{ts,tsx}'",
"eslint:ci": "eslint '*.{js,json}' '{src,tests,benchmarks}/**/*.{ts,tsx}'",
"pretest": "tsc --noEmit",
"test": "jest && jest --setupFiles ./tests/setProviderLessMode.ts && jest --setupFiles ./tests/setVersionedWriteMode.ts",
"test": "jest && jest --setupFiles ./tests/setProviderLessMode.ts",
"test:ci": "jest",
"test:dev": "jest --watch --no-coverage",
"test:coverage:watch": "jest --watch",
@@ -151,8 +150,9 @@
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-replace": "^5.0.2",
"@rollup/plugin-terser": "^0.3.0",
"@rollup/plugin-typescript": "^11.0.0",
"@swc/core": "^1.3.25",
"@swc/core": "^1.3.26",
"@swc/jest": "^0.2.24",
"@tanstack/query-core": "^4.22.0",
"@testing-library/react": "^13.4.0",
@@ -165,17 +165,17 @@
"benny": "^3.7.1",
"concurrently": "^7.6.0",
"downlevel-dts": "^0.11.0",
"esbuild": "^0.16.16",
"eslint": "^8.31.0",
"esbuild": "^0.17.0",
"eslint": "^8.32.0",
"eslint-config-prettier": "^8.6.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-import": "^2.27.4",
"eslint-plugin-jest": "^27.2.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.31.11",
"eslint-plugin-react": "^7.32.0",
"eslint-plugin-react-hooks": "^4.6.0",
"graphql": "^16.6.0",
"immer": "^9.0.17",
"immer": "^9.0.18",
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.3.1",
"jotai-devtools": "^0.1.0",
@@ -190,23 +190,22 @@
"json": "^11.0.0",
"optics-ts": "^2.4.0",
"postinstall-postinstall": "^2.1.0",
"prettier": "^2.8.2",
"prettier": "^2.8.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"redux": "^4.2.0",
"rollup": "^3.9.1",
"rollup": "^3.10.0",
"rollup-plugin-esbuild": "^5.0.0",
"rollup-plugin-terser": "^7.0.2",
"rxjs": "^7.8.0",
"shx": "^0.3.4",
"ts-expect": "^1.3.0",
"ts-node": "^10.9.1",
"tslib": "^2.4.1",
"typescript": "^4.9.4",
"valtio": "^1.8.2",
"valtio": "^1.9.0",
"wonka": "^6.1.2",
"xstate": "^4.35.2",
"zustand": "^4.3.1"
"zustand": "^4.3.2"
},
"peerDependencies": {
"@babel/core": "*",
29 changes: 18 additions & 11 deletions readme.md
Original file line number Diff line number Diff line change
@@ -53,7 +53,8 @@ function Counter() {
return (
<h1>
{count}
<button onClick={() => setCount(c => c + 1)}>one up</button>
<button onClick={() => setCount((c) => c + 1)}>one up</button>
...
```
### Create derived atoms with computed values
@@ -68,6 +69,7 @@ const doubledCountAtom = atom((get) => get(countAtom) * 2)
function DoubleCounter() {
const [doubledCount] = useAtom(doubledCountAtom)
return <h2>{doubledCount}</h2>
}
```
## Recipes
@@ -96,17 +98,16 @@ const sum = atom((get) => atoms.map(get).reduce((acc, count) => acc + count))
You can make the read function an async function too.
```jsx
const urlAtom = atom("https://json.host.com")
const fetchUrlAtom = atom(
async (get) => {
const response = await fetch(get(urlAtom))
return await response.json()
}
)
const urlAtom = atom('https://json.host.com')
const fetchUrlAtom = atom(async (get) => {
const response = await fetch(get(urlAtom))
return await response.json()
})

function Status() {
// Re-renders the component after urlAtom changed and the async function above concludes
const [json] = useAtom(fetchUrlAtom)
...
```
### You can create a writable derived atom
@@ -117,7 +118,7 @@ value of an atom. `set` will update an atoms value.
```jsx
const decrementCountAtom = atom(
(get) => get(countAtom),
(get, set, _arg) => set(countAtom, get(countAtom) - 1),
(get, set, _arg) => set(countAtom, get(countAtom) - 1)
)

function Counter() {
@@ -126,18 +127,22 @@ function Counter() {
<h1>
{count}
<button onClick={decrement}>Decrease</button>
...
```
### Write only atoms
Just do not define a read function.
```jsx
const multiplyCountAtom = atom(null, (get, set, by) => set(countAtom, get(countAtom) * by))
const multiplyCountAtom = atom(null, (get, set, by) =>
set(countAtom, get(countAtom) * by)
)

function Controls() {
const [, multiply] = useAtom(multiplyCountAtom)
return <button onClick={() => multiply(3)}>triple</button>
}
```
### Async actions
@@ -155,7 +160,9 @@ const fetchCountAtom = atom(

function Controls() {
const [count, compute] = useAtom(fetchCountAtom)
return <button onClick={() => compute("http://count.host.com")}>compute</button>
return (
<button onClick={() => compute('http://count.host.com')}>compute</button>
...
```
## Installation notes
2 changes: 1 addition & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
@@ -2,9 +2,9 @@ const path = require('path')
const babelPlugin = require('@rollup/plugin-babel')
const resolve = require('@rollup/plugin-node-resolve')
const replace = require('@rollup/plugin-replace')
const terser = require('@rollup/plugin-terser')
const typescript = require('@rollup/plugin-typescript')
const { default: esbuild } = require('rollup-plugin-esbuild')
const { terser } = require('rollup-plugin-terser')
const createBabelConfig = require('./babel.config')

const extensions = ['.js', '.ts', '.tsx']
9 changes: 0 additions & 9 deletions src/react/devtools.ts

This file was deleted.

9 changes: 0 additions & 9 deletions src/react/devtools/types.ts

This file was deleted.

130 changes: 0 additions & 130 deletions src/react/devtools/useAtomDevtools.ts

This file was deleted.

57 changes: 0 additions & 57 deletions src/react/devtools/useAtomsDebugValue.ts

This file was deleted.

151 changes: 0 additions & 151 deletions src/react/devtools/useAtomsDevtools.ts

This file was deleted.

78 changes: 0 additions & 78 deletions src/react/devtools/useAtomsSnapshot.ts

This file was deleted.

25 changes: 0 additions & 25 deletions src/react/devtools/useGotoAtomsSnapshot.ts

This file was deleted.

9 changes: 7 additions & 2 deletions tests/core/transition.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { StrictMode, Suspense, useEffect, useTransition } from 'react'
/// <reference types="react/experimental" />

import { StrictMode, Suspense, use, useEffect, useTransition } from 'react'
import { fireEvent, render, waitFor } from '@testing-library/react'
import { atom, useAtom, useAtomValue, useSetAtom } from 'jotai'
import { getTestProvider } from '../testUtils'
@@ -8,8 +10,11 @@ const Provider = getTestProvider()
const describeWithUseTransition =
typeof useTransition === 'function' ? describe : describe.skip

// FIXME some tests are failing with react@experimental
const itWithoutUse = typeof use === 'function' ? it.skip : it

describeWithUseTransition('useTransition', () => {
it('no extra commit with useTransition (#1125)', async () => {
itWithoutUse('no extra commit with useTransition (#1125)', async () => {
const countAtom = atom(0)
let resolve = () => {}
const delayedAtom = atom(async (get) => {
6 changes: 4 additions & 2 deletions tests/react/abortable.test.tsx
Original file line number Diff line number Diff line change
@@ -47,8 +47,10 @@ describe('abortable atom test', () => {

fireEvent.click(getByText('button'))
fireEvent.click(getByText('button'))
resolve.splice(0).forEach((fn) => fn())
await findByText('count: 2')
await waitFor(() => {
resolve.splice(0).forEach((fn) => fn())
getByText('count: 2')
})
expect(abortedCount).toBe(1)

fireEvent.click(getByText('button'))
334 changes: 0 additions & 334 deletions tests/react/devtools/useAtomDevtools.test.tsx

This file was deleted.

814 changes: 0 additions & 814 deletions tests/react/devtools/useAtomsDevtools.test.tsx

This file was deleted.

206 changes: 0 additions & 206 deletions tests/react/devtools/useAtomsSnapshot.test.tsx

This file was deleted.

234 changes: 0 additions & 234 deletions tests/react/devtools/useGoToAtomsSnapshot.test.tsx

This file was deleted.

9 changes: 7 additions & 2 deletions tests/react/transition.test.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { StrictMode, Suspense, useEffect, useTransition } from 'react'
/// <reference types="react/experimental" />

import { StrictMode, Suspense, use, useEffect, useTransition } from 'react'
import { fireEvent, render, waitFor } from '@testing-library/react'
import { useAtom, useAtomValue, useSetAtom } from 'jotai/react'
import { atom } from 'jotai/vanilla'

const describeWithUseTransition =
typeof useTransition === 'function' ? describe : describe.skip

// FIXME some tests are failing with react@experimental
const itWithoutUse = typeof use === 'function' ? it.skip : it

describeWithUseTransition('useTransition', () => {
it('no extra commit with useTransition (#1125)', async () => {
itWithoutUse('no extra commit with useTransition (#1125)', async () => {
const countAtom = atom(0)
let resolve = () => {}
const delayedAtom = atom(async (get) => {
1 change: 0 additions & 1 deletion tests/setVersionedWriteMode.ts

This file was deleted.

639 changes: 317 additions & 322 deletions yarn.lock

Large diffs are not rendered by default.