Skip to content

Commit

Permalink
Merge branch 'main' into fix-snap-cache-invalid
Browse files Browse the repository at this point in the history
  • Loading branch information
Juyeong-Byeon committed Jun 10, 2023
2 parents 37d7e4d + d1da1b2 commit 5e7403c
Show file tree
Hide file tree
Showing 34 changed files with 1,337 additions and 1,995 deletions.
2 changes: 1 addition & 1 deletion .codesandbox/ci.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"simple-snowpack-react-o1gmx",
"react-parcel-onewf"
],
"node": "14"
"node": "18"
}
6 changes: 4 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"prettier",
"react-hooks",
"import",
"jest"
"vitest"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
Expand All @@ -31,6 +31,8 @@
}
},
"rules": {
"import/namespace": "off",
"import/named": "off",
"eqeqeq": "error",
"no-var": "error",
"prefer-const": "error",
Expand All @@ -48,7 +50,7 @@
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-explicit-any": "off",
"jest/consistent-test-it": [
"vitest/consistent-test-it": [
"error",
{ "fn": "it", "withinDescribe": "it" }
],
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint-and-type.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14'
node-version: '18'
cache: yarn
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- run: yarn install --frozen-lockfile --check-files
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/test-multiple-builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14'
node-version: '18'
cache: yarn
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- run: yarn install --frozen-lockfile --check-files
Expand Down Expand Up @@ -52,7 +52,6 @@ jobs:
if: ${{ matrix.build == 'umd' }}
run: |
sed -i~ "s/<rootDir>\/src\(.*\)\.ts/<rootDir>\/dist\/umd\1.${NODE_ENV}.js/" package.json
sed -i~ 's/"test:ci":.*,$/"test:ci": "jest",/' package.json
env:
NODE_ENV: ${{ matrix.env }}
- name: Patch for SystemJS
Expand Down
9 changes: 4 additions & 5 deletions .github/workflows/test-multiple-versions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14'
node-version: '18'
cache: yarn
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- run: yarn install --frozen-lockfile --check-files
Expand All @@ -33,13 +33,13 @@ jobs:
- 18.0.0
- 18.1.0
- 18.2.0
- 18.3.0-next-b14f8da15-20230403
- 0.0.0-experimental-b14f8da15-20230403
- 18.3.0-canary-aef7ce554-20230503
- 0.0.0-experimental-aef7ce554-20230503
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14'
node-version: '18'
cache: yarn
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- run: yarn install --frozen-lockfile --check-files
Expand All @@ -53,7 +53,6 @@ jobs:
sed -i~ '1s/^/import React from "react";/' tests/*.tsx
sed -i~ 's/"jsx": "react-jsx"/"jsx": "react"/' tsconfig.json
sed -i~ 's/import\.meta\.env[?]\.MODE/"DEVELOPMENT".toLowerCase()/' src/*.ts src/*/*.ts src/*/*/*.ts
sed -i~ 's/"test:ci":.*,$/"test:ci": "jest",/' package.json
- name: Test ${{ matrix.react }}
run: |
yarn add -D react@${{ matrix.react }} react-dom@${{ matrix.react }}
Expand Down
20 changes: 15 additions & 5 deletions .github/workflows/test-old-typescript.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14'
node-version: '18'
cache: yarn
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- run: yarn install --frozen-lockfile --check-files
Expand All @@ -52,11 +52,21 @@ jobs:
sed -i~ '1s/^/import React from "react";/' tests/*.tsx
sed -i~ 's/"jsx": "react-jsx"/"jsx": "react"/' tsconfig.json
sed -i~ 's/"noUncheckedIndexedAccess": true,//' tsconfig.json
yarn json -I -f package.json -e "this.resolutions={}; this.resolutions['@jest/globals']='25.5.2'; 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';"
yarn add -D @jest/globals@25.5.2 pretty-format@25.5.0 @types/prettier@2.4.2 @types/yargs@17.0.13 @types/node@18.11.18 @types/babel__traverse@7.18.2
yarn 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';"
yarn add -D pretty-format@25.5.0 @types/prettier@2.4.2 @types/yargs@17.0.13 @types/node@18.11.18 @types/babel__traverse@7.18.2
rm -r tests/macro-vite.*
- name: Test ${{ matrix.typescript }}
- name: Install old TypeScript
run: |
yarn add -D typescript@${{ matrix.typescript }}
rm -r node_modules/@types/jsdom node_modules/parse5 node_modules/@types/babel__core/node_modules
rm node_modules/parse5/dist/*.d.ts
- name: Patch testing setup for older TS
if: ${{ matrix.typescript == '4.0.5' || startsWith(matrix.typescript, '3.') }}
run: |
yarn add -D @testing-library/user-event@12.1.7 @testing-library/react@11.0.4
rm node_modules/vitest/dist/*.d.ts
rm node_modules/parse5/dist/*.d.ts
echo "declare module 'vitest'" >> ./src/types.d.ts
- name: Test ${{ matrix.typescript }}
run: |
rm -r node_modules/@types/babel__core/node_modules
yarn tsc --noEmit
67 changes: 67 additions & 0 deletions docs/guides/computed-properties.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,73 @@ When you call `state.doubled` on the `state` proxy, it is not cached, and will b

However, when you make a snapshot, calls to `snap.doubled` are effectively cached, because the value of an object getter is copied during the snapshot process.

⚠️ Note: In the current implementation a computed property should only reference _sibling_ properties, otherwise you'll encounter weird bugs. For example:

```js
const user = proxy({
name: 'John',
// OK - can reference sibling props via the proxy object
get greetingEn() {
return 'Hello ' + user.name
},
// OK - or via `this`
get greetingFr() {
return 'Bonjour ' + this.name
},
})
```

```js
const state = proxy({
// could be nested
user: {
name: 'John',
// OK - can reference sibling props via the proxy object
get greetingEn() {
return 'Hello ' + state.user.name
},
// OK - or via `this`
get greetingFr() {
return 'Bonjour ' + this.name
},
},
})
```

```js
const state = proxy({
user: {
name: 'John',
},
greetings: {
// WRONG - can reference sibling props only. Use `derive` instead
get greetingEn() {
return 'Hello ' + state.user.name
},
// WRONG - `this` points to `state.greetings`. Use `derive` instead
get greetingFr() {
return 'Bonjour ' + this.user.name
},
},
})
```

```js
const user = proxy({
name: 'John',
})
const greetings = proxy({
// WRONG - can reference sibling props only. Use `derive` instead
get greetingEn() {
return 'Hello ' + user.name
},
// WRONG - `this` points to `greetings`. Use `derive` instead
get greetingFr() {
return 'Bonjour ' + this.name
},
})
```

## Object getter and setter

Setters are also supported:
Expand Down
80 changes: 80 additions & 0 deletions docs/how-tos/some-gotchas.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,83 @@ subscribe(state.subscribeData, async () => {
state.results = await load(state.someData)
})
```

## Issue with array proxy

The following use case can occur unexpected results on `arr` subscription:

```javascript
const byId = {}
arr.forEach((item) => {
byId[item.id] = item
})
arr.splice(0, arr.length)
arr.push(newValue())
someUpdateFunc(byId)
Object.keys(byId).forEach((key) => arr.push(byId[key]))
```

[Issues](https://github.com/pmndrs/valtio/issues/712) may arise when handling the array proxy reference in the subsequent steps:

a. Subscribe array proxy

b. Use the proxy as snapshot

c. Assign temp variable for updating

d. Remove proxy from the array

e. Update temp

f. Push temp in the original array

**Example issue case:**

```javascript
const a = proxy([
{
nested: {
nested: {
test: 'apple',
},
},
},
])

const sa = snapshot(a) // b.

// a.
subscribe(a, () => {
const updated = snapshot(a)
console.log('this is updated proxy. test is Banana', a)
console.log('however, for the snapshot of a, test is still apple', updated)
})

function handle() {
const temp = a[0] // c.
a.splice(0, 1) // d.
temp.nested.nested.test = 'Banana' // e.
a.push(temp) // f.
console.log(Object.is(temp, a[0])) // this will be true
}
```

**To work around this, swap d and e:**

```javascript
// ...

function handle() {
const temp = a[0]
temp.nested.nested.test = 'Banana' // Update first remove from array
a.splice(0, 1)
a.push(temp)
}
// ...
```

If the workaround is not applied and you are using react with [devtools()](https://valtio.pmnd.rs/docs/api/utils/devtools), the redux devtools will notify a value update, but the snapshot will remain the same within the devtools' subscription.

As a result, the devtools will not display any state change.

Additionally, this issue involved not only updating devtools, but also triggering `re-render`.
2 changes: 1 addition & 1 deletion docs/introduction/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import logo from './logo.svg'

### Proxy state made simple.

The Valtio api is minimal, flexible, unopinionated and a touch magical. Valtio's proxy turns the object you pass it into a self-aware proxy, allowing fine-grained subscription and creativity in making state updates. In React, Valtio shines at render optimization. It is compatible with Suspense and React 18. Valtio is also a viable option in vanilla javascript applications.
The Valtio API is minimal, flexible, unopinionated and a touch magical. Valtio's proxy turns the object you pass it into a self-aware proxy, allowing fine-grained subscription and creativity in making state updates. In React, Valtio shines at render optimization. It is compatible with Suspense and React 18. Valtio is also a viable option in vanilla javascript applications.

#### Installation

Expand Down
Loading

0 comments on commit 5e7403c

Please sign in to comment.