Skip to content

Commit 71111b7

Browse files
dai-shiendash
andauthored
v2 (#810)
* prepare for the next major version * [v2] breaking: do not throw promises (#813) * [v2] breaking: do not throw promises * use use * fix CI hopefully * fix CI hopefully 2 * fix CI hopefully 3 * fix CI hopefully 4 * fix CI hopefully 5 * any type for simplicity * [v2] breaking: do not copy initial objects (#815) * [v2] breaking: do not copy initial objects * fix deepClone * refactor * ah we need it * deep clone * minor fix * breaking: require TS 4.5 at least (#817) * TS minimal requirement v4.5 * wip: test old ts * remove downlevel-dts * simplify test * simplify test 2 * simplify test 3 * wip: useMaybePromise * wip: useMaybePromise 2 * wip: useMaybePromise 3 * rename back * [v2] breaking: drop "module" condition (#818) * run prettier * [v2] breaking: require react 18 and drop use-sync-external-store (#819) * [v2] breaking: require react 18 and drop use-sync-external-store * drop tests pre react 18 * wip: cannot use react 17 for prd test * drop production test which is impossible * esm? * fix regex * fix sed * [v2] breaking: remove deprecated features (#820) * remove depreacated useProxy macro * revert plugin-transform * remove two more babel packages * revert babel core * remove proxyWithComputed * remove addComputed * remove devtools deprecated option * [v2] breaking: remove derive-valtio dependency (#821) * [v2] breaking: drop UMD/SystemJS builds and simplify babel config (#822) * [v2] breaking: drop UMD/SystemJS builds and simplify babel config * format * 2.0.0-alpha.0 * run prettier * 2.0.0-alpha.1 * simplify ts test script * update react canary version * remove depreacated proxyWithHistory * 2.0.0-alpha.2 * update react canary * [v2] export Snapshot type (#856) * 2.0.0-beta.0 * [v2] drop es5 (#865) * breaking: compatibility with memo (#866) * update yarn lock * 2.0.0-beta.1 * [v2] fix: make affected per proxy (#868) * 2.0.0-beta.2 * [v2] fix rollup config for cjs (#873) * 2.0.0-beta.3 * [v2] migration guide (#878) * fix workflow file * fix: explicit package.json type field (#882) * 2.0.0-beta.4 * fix(react): Change to useLayoutEffect in useSnapshot (#891) * Address spurious consistency check re-renders by using useLayoutEffect inside useSnapshot instead of useEffect * Move regression tests for useSnapshot perf improvement to optimization test file * Update tests/optimization.test.tsx --------- Co-authored-by: Daishi Kato <[email protected]> * 2.0.0-beta.5 * chore package.json --------- Co-authored-by: Christopher Swasey <[email protected]>
1 parent 30d5ea1 commit 71111b7

28 files changed

+525
-4114
lines changed

.github/workflows/test-multiple-builds.yml

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
fail-fast: false
1414
matrix:
1515
build: [cjs, esm]
16-
env: [development, production]
16+
env: [development] # [development, production]
1717
steps:
1818
- uses: actions/checkout@v3
1919
- uses: pnpm/action-setup@v2
@@ -26,10 +26,6 @@ jobs:
2626
cache-dependency-path: '**/pnpm-lock.yaml'
2727
- run: pnpm install --frozen-lockfile
2828
- run: pnpm build
29-
- name: Use React 17 for production test
30-
if: ${{ matrix.env == 'production' }}
31-
run: |
32-
3329
- name: Patch for DEV-ONLY
3430
if: ${{ matrix.env == 'development' }}
3531
run: |
@@ -44,27 +40,13 @@ jobs:
4440
if: ${{ matrix.build == 'cjs' }}
4541
run: |
4642
sed -i~ "s/resolve('\.\/src\(.*\)\.ts')/resolve('\.\/dist\1.js')/" vitest.config.ts
47-
sed -i~ "s/\"valtio\/vanilla\"/\"..\/..\/..\/..\/..\/..\/dist\/vanilla.js\"/" node_modules/derive-valtio/dist/index.umd.js
4843
- name: Patch for ESM
4944
if: ${{ matrix.build == 'esm' }}
5045
run: |
5146
sed -i~ "s/resolve('\.\/src\(.*\)\.ts')/resolve('\.\/dist\/esm\1.mjs')/" vitest.config.ts
5247
sed -i~ "1s/^/import.meta.env=import.meta.env||{};import.meta.env.MODE='${NODE_ENV}';/" tests/*.tsx
5348
env:
5449
NODE_ENV: ${{ matrix.env }}
55-
- name: Patch for UMD
56-
if: ${{ matrix.build == 'umd' }}
57-
run: |
58-
sed -i~ "s/resolve('\.\/src\(.*\)\.ts')/resolve('\.\/dist\/umd\1.${NODE_ENV}.js')/" vitest.config.ts
59-
sed -i~ "s/\"valtio\/vanilla\"/\"..\/..\/..\/..\/..\/..\/dist\/umd\/vanilla.${NODE_ENV}.js\"/" node_modules/derive-valtio/dist/index.umd.js
60-
env:
61-
NODE_ENV: ${{ matrix.env }}
62-
- name: Patch for SystemJS
63-
if: ${{ matrix.build == 'system' }}
64-
run: |
65-
sed -i~ "s/resolve('\.\/src\(.*\)\.ts')/resolve('\.\/dist\/system\1.${NODE_ENV}.js')/" vitest.config.ts
66-
env:
67-
NODE_ENV: ${{ matrix.env }}
6850
- name: Test ${{ matrix.build }} ${{ matrix.env }}
6951
run: |
7052
pnpm test:spec

.github/workflows/test-multiple-versions.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ jobs:
2929
fail-fast: false
3030
matrix:
3131
react:
32-
- 16.8.0
33-
- 16.9.0
34-
- 17.0.0
3532
- 18.0.0
3633
- 18.1.0
3734
- 18.2.0

.github/workflows/test-old-typescript.yml

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,6 @@ jobs:
2323
- 4.7.4
2424
- 4.6.4
2525
- 4.5.5
26-
- 4.4.4
27-
- 4.3.5
28-
- 4.2.3
29-
- 4.1.5
30-
- 4.0.5
31-
- 3.9.7
32-
- 3.8.3
33-
- 3.7.5
3426
steps:
3527
- uses: actions/checkout@v3
3628
- uses: pnpm/action-setup@v2
@@ -45,39 +37,12 @@ jobs:
4537
- run: pnpm build
4638
- name: Patch for Old TS
4739
run: |
48-
sed -i~ 's/\/\/ @ts-expect-error.*\[LATEST-TS-ONLY\]//' tests/*.tsx
49-
sed -i~ 's/"target":/"skipLibCheck":true,"target":/' tsconfig.json
50-
sed -i~ 's/"exactOptionalPropertyTypes": true,//' tsconfig.json
5140
sed -i~ 's/"moduleResolution": "bundler",/"moduleResolution": "node",/' tsconfig.json
5241
sed -i~ 's/"allowImportingTsExtensions": true,//' tsconfig.json
53-
sed -i~ 's/"valtio": \["\.\/src\/index\.ts"\],/"valtio": [".\/dist\/ts3.4\/index.d.ts"],/' tsconfig.json
54-
sed -i~ 's/"valtio\/\*": \["\.\/src\/\*\.ts"\]/"valtio\/*": [".\/dist\/ts3.4\/*.d.ts"]/' tsconfig.json
42+
sed -i~ 's/"valtio": \["\.\/src\/index\.ts"\],/"valtio": [".\/dist\/index.d.ts"],/' tsconfig.json
43+
sed -i~ 's/"valtio\/\*": \["\.\/src\/\*\.ts"\]/"valtio\/*": [".\/dist\/*.d.ts"]/' tsconfig.json
5544
sed -i~ 's/"include": .*/"include": ["src\/types.d.ts", "dist\/**\/*", "tests\/**\/*"],/' tsconfig.json
56-
- name: Patch for Older TS
57-
if: ${{ matrix.typescript == '4.4.4' ||matrix.typescript == '4.3.5' || matrix.typescript == '4.2.3' || matrix.typescript == '4.1.5' || matrix.typescript == '4.0.5' || startsWith(matrix.typescript, '3.') }}
58-
run: |
59-
sed -i~ 's/import\.meta\.env/(import.meta.env as any)/' tests/*.tsx
60-
sed -i~ '1s/^/import React from "react";/' tests/*.tsx
61-
sed -i~ 's/"jsx": "react-jsx"/"jsx": "react"/' tsconfig.json
62-
sed -i~ 's/"noUncheckedIndexedAccess": true,//' tsconfig.json
63-
pnpm json -I -f package.json -e "this.resolutions={}; this.resolutions['pretty-format']='25.5.0'; this.resolutions['@types/prettier']='2.4.2'; this.resolutions['@types/yargs']='17.0.13'; this.resolutions['@types/node']='18.11.18';"
64-
65-
rm -r tests/macro-vite.*
6645
- name: Install old TypeScript
67-
run: |
68-
pnpm add -D typescript@${{ matrix.typescript }}
69-
rm node_modules/.pnpm/parse5@*/node_modules/parse5/dist/*.d.ts
70-
- name: Patch testing setup for Old TS
71-
if: ${{ matrix.typescript == '4.4.4' || matrix.typescript == '4.3.5' || matrix.typescript == '4.2.3' || matrix.typescript == '4.1.5' || matrix.typescript == '4.0.5' || startsWith(matrix.typescript, '3.') }}
72-
run: |
73-
74-
- name: Patch testing setup for older TS
75-
if: ${{ matrix.typescript == '4.0.5' || startsWith(matrix.typescript, '3.') }}
76-
run: |
77-
pnpm add -D @testing-library/[email protected] @testing-library/[email protected]
78-
rm node_modules/vitest/dist/*.d.ts
79-
rm node_modules/.pnpm/@types+babel__traverse@*/node_modules/@types/babel__traverse/*.d.ts
80-
echo "declare module 'vitest'" >> ./src/types.d.ts
46+
run: pnpm add -D typescript@${{ matrix.typescript }}
8147
- name: Test ${{ matrix.typescript }}
82-
run: |
83-
pnpm test:types
48+
run: pnpm test:types

babel.config.js

Lines changed: 0 additions & 28 deletions
This file was deleted.

docs/guides/migrating-to-v2.mdx

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
title: 'How to Migrate to v2 from v1'
3+
---
4+
5+
# How to Migrate to v2 from v1
6+
7+
## Changes in v2
8+
9+
React 19 officially introduces the `use` hook to handle promises.
10+
Valtio v1 internally handled promises, which is no longer recommended.
11+
In Valtio v2, promises are not handled internally,
12+
and developers should explicitly use the `use` hook to manage promises.
13+
14+
Valtio v2 also introduces several changes in its design choices:
15+
16+
First, the behavior of `proxy(obj)` has changed. In v1, it was a pure function and deeply copied `obj`. In v2, it is an impure function and deeply modifies `obj`. Generally, reusing `obj` is not recommended, and if you have followed this convention, nothing will break.
17+
18+
Second, the behavior of `useSnapshot()` has been altered. Although it is a subtle change, it is less optimized to ensure compatibility with `useMemo` and the upcoming React compiler. The change may lead to extra re-renders in some edge cases, but it might not be noticeable.
19+
20+
Other notable changes to keep things updated and fresh include:
21+
22+
- Removal of all deprecated features
23+
- Requirement of React version 18 and above
24+
- Requirement of TypeScript version 4.5 and above
25+
- The build target updated to ES2018
26+
27+
## Migration for breaking changes
28+
29+
### Resolving promises
30+
31+
```js
32+
// v1
33+
import { proxy, useSnapshot } from 'valtio'
34+
35+
const state = proxy({ data: fetch(...).then((res) => res.json()) })
36+
37+
const Component = () => {
38+
const snap = useSnapshot(state)
39+
return <>{JSON.stringify(snap.data)}</>
40+
}
41+
```
42+
43+
```js
44+
// v2
45+
import { use } from 'react'
46+
import { proxy, useSnapshot } from 'valtio'
47+
48+
const state = proxy({ data: fetch(...).then((res) => res.json()) })
49+
50+
const Component = () => {
51+
const snap = useSnapshot(state)
52+
return <>{JSON.stringify(use(snap.data))}</>
53+
// If `data` is not an object, you can directly embed it in JSX.
54+
// return <>{snap.data}</>
55+
}
56+
```
57+
58+
### Impure `proxy(obj)`
59+
60+
```js
61+
// v1
62+
import { proxy } from 'valtio'
63+
64+
const state = proxy({ count: 1, obj: { text: 'hi' } })
65+
state.obj = { text: 'hello' }
66+
```
67+
68+
```js
69+
// v2
70+
import { proxy } from 'valtio'
71+
import { deepClone } from 'valtio/utils'
72+
73+
const state = proxy(deepClone({ count: 1, obj: { text: 'hi' } }))
74+
state.obj = deepClone({ text: 'hello' })
75+
```
76+
77+
Note that `deepClone` is unnecessary unless you are reusing the object.
78+
It is generally recommended to avoid reusing the object.
79+
80+
## Links
81+
82+
- https://github.com/pmndrs/valtio/discussions/703
83+
- https://github.com/pmndrs/valtio/pull/810

package.json

Lines changed: 25 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,27 @@
33
"description": "💊 Valtio makes proxy-state simple for React and Vanilla",
44
"private": true,
55
"type": "commonjs",
6-
"version": "1.13.2",
6+
"version": "2.0.0-beta.5",
7+
"publishConfig": {
8+
"tag": "next"
9+
},
710
"main": "./index.js",
811
"types": "./index.d.ts",
912
"typesVersions": {
10-
"<4.5": {
13+
">=4.5": {
14+
"esm/*": [
15+
"esm/*"
16+
],
17+
"*": [
18+
"*"
19+
]
20+
},
21+
"*": {
1122
"esm/*": [
12-
"ts3.4/*"
23+
"ts_version_4.5_and_above_is_required.d.ts"
1324
],
1425
"*": [
15-
"ts3.4/*"
26+
"ts_version_4.5_and_above_is_required.d.ts"
1627
]
1728
}
1829
},
@@ -23,10 +34,6 @@
2334
"types": "./esm/index.d.mts",
2435
"default": "./esm/index.mjs"
2536
},
26-
"module": {
27-
"types": "./esm/index.d.ts",
28-
"default": "./esm/index.js"
29-
},
3037
"default": {
3138
"types": "./index.d.ts",
3239
"default": "./index.js"
@@ -37,10 +44,6 @@
3744
"types": "./esm/*.d.mts",
3845
"default": "./esm/*.mjs"
3946
},
40-
"module": {
41-
"types": "./esm/*.d.ts",
42-
"default": "./esm/*.js"
43-
},
4447
"default": {
4548
"types": "./*.d.ts",
4649
"default": "./*.js"
@@ -61,9 +64,7 @@
6164
"build:vanilla_utils": "rollup -c --config-vanilla_utils",
6265
"build:react": "rollup -c --config-react",
6366
"build:react_utils": "rollup -c --config-react_utils",
64-
"build:macro": "rollup -c --config-macro",
65-
"build:macro_vite": "rollup -c --config-macro_vite",
66-
"postbuild": "pnpm patch-d-ts && pnpm copy && pnpm patch-macro-vite && pnpm patch-ts3.4 && pnpm patch-esm-ts",
67+
"postbuild": "pnpm patch-d-ts && pnpm copy && pnpm patch-old-ts && pnpm patch-esm-ts",
6768
"prettier": "prettier '*.{js,json,md}' '{src,tests,docs}/**/*.{ts,tsx,md,mdx}' --write",
6869
"eslint": "eslint --no-eslintrc --c .eslintrc.json --fix '*.{js,json,ts}' '{src,tests}/**/*.{ts,tsx}'",
6970
"test": "pnpm run '/^test:.*/'",
@@ -72,10 +73,9 @@
7273
"test:lint": "eslint --no-eslintrc --c .eslintrc.json '*.{js,json,ts}' '{src,tests}/**/*.{ts,tsx}'",
7374
"test:spec": "vitest",
7475
"patch-d-ts": "node -e \"var {entries}=require('./rollup.config.js');require('shelljs').find('dist/**/*.d.ts').forEach(f=>{entries.forEach(({find,replacement})=>require('shelljs').sed('-i',new RegExp(' from \\''+find.source.slice(0,-1)+'\\';$'),' from \\''+replacement+'\\';',f));require('shelljs').sed('-i',/ from '(\\.[^']+)\\.ts';$/,' from \\'\\$1\\';',f)})\"",
75-
"copy": "shx cp -r dist/src/* dist/esm && shx cp -r dist/src/* dist && shx rm -rf dist/{src,tests} && downlevel-dts dist dist/ts3.4 && shx cp package.json readme.md LICENSE dist && json -I -f dist/package.json -e \"this.private=false; this.devDependencies=undefined; this.optionalDependencies=undefined; this.scripts=undefined; this.prettier=undefined;\"",
76-
"patch-macro-vite": "shx cp dist/esm/macro/vite.d.ts dist/macro/ && shx cp dist/ts3.4/esm/macro/vite.d.ts dist/ts3.4/macro/",
77-
"patch-ts3.4": "node -e \"require('shelljs').find('dist/ts3.4/**/*.d.ts').forEach(f=>{require('fs').appendFileSync(f,'declare type Awaited<T> = T extends Promise<infer V> ? V : T;');require('shelljs').sed('-i',/^declare type Snapshot<T> =/,'declare type Snapshot<T> = T extends SnapshotIgnore ? T : T extends Promise<unknown> ? Awaited<T> : T extends object ? { readonly [K in keyof T]: Snapshot2<T[K]> } : T; declare type Snapshot2<T> = T extends SnapshotIgnore ? T : T extends Promise<unknown> ? Awaited<T> : T extends object ? { readonly [K in keyof T]: T[K] } : T;;declare type _Snapshot<T> =',f)})\"",
78-
"patch-esm-ts": "node -e \"require('shelljs').find('dist/esm/**/*.d.ts').forEach(f=>{var f2=f.replace(/\\.ts$/,'.mts');require('fs').copyFileSync(f,f2);require('shelljs').sed('-i',/ from '(\\.[^']+)';$/,' from \\'\\$1.mjs\\';',f2);require('shelljs').sed('-i',/^declare module '(\\.[^']+)'/,'declare module \\'\\$1.mjs\\'',f2)})\""
76+
"copy": "shx cp -r dist/src/* dist/esm && shx cp -r dist/src/* dist && shx rm -rf dist/{src,tests} && shx cp package.json readme.md LICENSE dist && json -I -f dist/package.json -e \"this.private=false; this.devDependencies=undefined; this.optionalDependencies=undefined; this.scripts=undefined; this.prettier=undefined;\"",
77+
"patch-old-ts": "shx touch dist/ts_version_4.5_and_above_is_required.d.ts",
78+
"patch-esm-ts": "node -e \"require('shelljs').find('dist/esm/**/*.d.ts').forEach(f=>{var f2=f.replace(/\\.ts$/,'.mts');require('fs').renameSync(f,f2);require('shelljs').sed('-i',/ from '(\\.[^']+)';$/,' from \\'\\$1.mjs\\';',f2);require('shelljs').sed('-i',/^declare module '(\\.[^']+)'/,'declare module \\'\\$1.mjs\\'',f2)})\""
7979
},
8080
"engines": {
8181
"node": ">=12.20.0"
@@ -106,42 +106,22 @@
106106
"homepage": "https://github.com/pmndrs/valtio",
107107
"packageManager": "[email protected]",
108108
"dependencies": {
109-
"derive-valtio": "0.1.0",
110-
"proxy-compare": "2.6.0",
111-
"use-sync-external-store": "1.2.2"
109+
"proxy-compare": "^3.0.0"
112110
},
113111
"devDependencies": {
114-
"@babel/core": "^7.24.5",
115-
"@babel/helper-module-imports": "^7.24.3",
116-
"@babel/plugin-transform-react-jsx": "^7.23.4",
117-
"@babel/plugin-transform-typescript": "^7.24.5",
118-
"@babel/preset-env": "^7.24.5",
119-
"@babel/types": "^7.24.5",
120112
"@redux-devtools/extension": "^3.3.0",
121113
"@rollup/plugin-alias": "^5.1.0",
122-
"@rollup/plugin-babel": "^6.0.4",
123114
"@rollup/plugin-node-resolve": "^15.2.3",
124115
"@rollup/plugin-replace": "^5.0.5",
125-
"@rollup/plugin-terser": "^0.4.4",
126116
"@rollup/plugin-typescript": "^11.1.6",
127117
"@testing-library/react": "^15.0.6",
128-
"@typed-macro/core": "1.0.0-alpha",
129-
"@typed-macro/runtime": "1.0.0-alpha",
130-
"@types/babel-plugin-macros": "^3.1.3",
131-
"@types/babel-plugin-tester": "^9.0.10",
132-
"@types/babel__traverse": "^7.20.5",
133118
"@types/jsdom": "^21.1.6",
134-
"@types/react": "18.2.56",
119+
"@types/react": "^18.3.1",
135120
"@types/react-dom": "^18.3.0",
136-
"@types/use-sync-external-store": "^0.0.6",
137121
"@typescript-eslint/eslint-plugin": "^7.8.0",
138122
"@typescript-eslint/parser": "^7.8.0",
139123
"@vitest/coverage-v8": "^1.6.0",
140124
"@vitest/ui": "^1.6.0",
141-
"aslemammad-vite-plugin-macro": "^1.0.0",
142-
"babel-plugin-macros": "^3.1.0",
143-
"babel-plugin-tester": "10.1.0",
144-
"downlevel-dts": "^0.11.0",
145125
"esbuild": "^0.20.2",
146126
"eslint": "8.57.0",
147127
"eslint-config-prettier": "^9.1.0",
@@ -157,8 +137,8 @@
157137
"postinstall-postinstall": "^2.1.0",
158138
"prettier": "^3.2.5",
159139
"proxy-memoize": "^3.0.0",
160-
"react": "^18.3.1",
161-
"react-dom": "^18.3.1",
140+
"react": "19.0.0-beta-1beb73de0f-20240503",
141+
"react-dom": "19.0.0-beta-1beb73de0f-20240503",
162142
"redux": "^5.0.1",
163143
"rollup": "^4.17.2",
164144
"rollup-plugin-esbuild": "^6.1.1",
@@ -174,8 +154,8 @@
174154
"@types/react": "18.2.56"
175155
},
176156
"peerDependencies": {
177-
"@types/react": ">=16.8",
178-
"react": ">=16.8"
157+
"@types/react": ">=18.0.0",
158+
"react": ">=18.0.0"
179159
},
180160
"peerDependenciesMeta": {
181161
"@types/react": {

0 commit comments

Comments
 (0)