Skip to content

Commit 6f52df2

Browse files
committed
Merge branch 'main' into fix/compiler-friendly-provider
2 parents 152e447 + ef36aa1 commit 6f52df2

File tree

8 files changed

+73
-106
lines changed

8 files changed

+73
-106
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
types: [opened, synchronize]
88

99
jobs:
10-
test_matrix:
10+
test_multiple_builds:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
fail-fast: false

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

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,7 @@ on:
77
types: [opened, synchronize]
88

99
jobs:
10-
test:
11-
runs-on: ubuntu-latest
12-
steps:
13-
- uses: actions/checkout@v4
14-
- uses: pnpm/action-setup@v4
15-
- uses: actions/setup-node@v4
16-
with:
17-
node-version: 'lts/*'
18-
cache: 'pnpm'
19-
- run: pnpm install
20-
- run: pnpm run build # we don't have any other workflows to test build
21-
- run: pnpm run test:spec
22-
23-
test_matrix:
10+
test_multiple_versions:
2411
runs-on: ubuntu-latest
2512
strategy:
2613
fail-fast: false

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
types: [opened, synchronize]
88

99
jobs:
10-
test_matrix:
10+
test_old_typescript:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
fail-fast: false

.github/workflows/lint-and-type.yml renamed to .github/workflows/test.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Lint and Type
1+
name: Test
22

33
on:
44
push:
@@ -7,7 +7,7 @@ on:
77
types: [opened, synchronize]
88

99
jobs:
10-
lint:
10+
test:
1111
runs-on: ubuntu-latest
1212
steps:
1313
- uses: actions/checkout@v4
@@ -20,3 +20,5 @@ jobs:
2020
- run: pnpm run test:format
2121
- run: pnpm run test:types
2222
- run: pnpm run test:lint
23+
- run: pnpm run test:spec
24+
- run: pnpm run build # we don't have any other workflows to test build

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
visit [jotai.org](https://jotai.org) or `npm i jotai`
99

10-
[![Build Status](https://img.shields.io/github/actions/workflow/status/pmndrs/jotai/lint-and-type.yml?branch=main&style=flat&colorA=000000&colorB=000000)](https://github.com/pmndrs/jotai/actions?query=workflow%3ALint)
10+
[![Build Status](https://img.shields.io/github/actions/workflow/status/pmndrs/jotai/test.yml?branch=main&style=flat&colorA=000000&colorB=000000)](https://github.com/pmndrs/jotai/actions?query=workflow%3ALint)
1111
[![Build Size](https://img.shields.io/bundlephobia/minzip/jotai?label=bundle%20size&style=flat&colorA=000000&colorB=000000)](https://bundlephobia.com/result?p=jotai)
1212
[![Version](https://img.shields.io/npm/v/jotai?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/jotai)
1313
[![Downloads](https://img.shields.io/npm/dt/jotai.svg?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/jotai)

docs/third-party/history.mdx

Lines changed: 58 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,92 @@
11
---
22
title: History
3-
description: A Jōtai utility package for advanced state history management
4-
nav: 5.02
5-
keywords: history,undo,redo,jotai
3+
description: A Jōtai utility package for state history
4+
nav: 4.04
5+
keywords: history, undo, redo, track changes
66
---
77

8-
[jotai-history](https://github.com/jotaijs/jotai-history) is a utility package for advanced state history management.
8+
[jotai-history](https://github.com/jotaijs/jotai-history) is a utility package for tracking state history in Jotai.
99

10-
## install
10+
## Installation
1111

1212
```
1313
npm install jotai-history
1414
```
1515

16-
## withHistory
16+
## `withHistory`
1717

18-
### Signature
19-
20-
```ts
21-
declare function withHistory<T>(targetAtom: Atom<T>, limit: number): Atom<T[]>
22-
```
18+
```js
19+
import { withHistory } from 'jotai-history'
2320

24-
This function creates an atom that keeps a history of states for a given `targetAtom`. The `limit` parameter determines the maximum number of history states to keep.
25-
This is useful for tracking the changes over time.
21+
const targetAtom = atom(0)
22+
const limit = 2
23+
const historyAtom = withHistory(targetAtom, limit)
2624

27-
The history atom tracks changes to the `targetAtom` and maintains a list of previous states up to the specified `limit`. When the `targetAtom` changes, its new state is added to the history.
25+
function Component() {
26+
const [current, previous] = useAtomValue(historyAtom)
27+
...
28+
}
29+
```
2830

29-
### Usage
31+
### Description
3032

31-
```jsx
32-
import { atom, useAtomValue, useSetAtom } from 'jotai'
33-
import { withHistory } from 'jotai-history'
33+
`withHistory` creates an atom that tracks the history of states for a given `targetAtom`. The most recent `limit` states are retained.
3434

35-
const countAtom = atom(0)
36-
const countWithPrevious = withHistory(countAtom, 2)
35+
### Action Symbols
3736

38-
function CountComponent() {
39-
const [count, previousCount] = useAtomValue(countWithPrevious)
40-
const setCount = useSetAtom(countAtom)
37+
- **RESET**
38+
Clears the entire history, removing all previous states (including the undo/redo stack).
4139

42-
return (
43-
<>
44-
<p>Count: {count}</p>
45-
<p>Previous Count: {previousCount}</p>
46-
<button onClick={() => setCount((c) => c + 1)}>Increment</button>
47-
</>
48-
)
49-
}
50-
```
40+
```js
41+
import { RESET } from 'jotai-history'
5142

52-
## withUndo
43+
...
5344

54-
### Signature
45+
function Component() {
46+
const setHistoryAtom = useSetAtom(historyAtom)
47+
...
48+
setHistoryAtom(RESET)
49+
}
50+
```
5551

56-
```ts
57-
type Undoable = {
58-
undo: () => void
59-
redo: () => void
60-
canUndo: boolean
61-
canRedo: boolean
62-
}
63-
declare function withUndo<T>(
64-
targetAtom: WritableAtom<T, [T], any>,
65-
limit: number,
66-
): Atom<Undoable>
67-
```
52+
- **UNDO** and **REDO**
53+
Moves the `targetAtom` backward or forward in its history.
6854

69-
`withHistory` provides undo and redo capabilities for an atom. It keeps track of the value history of `targetAtom` and provides methods to move back and forth through that history.
55+
```js
56+
import { REDO, UNDO } from 'jotai-history'
7057

71-
The returned object includes:
58+
...
7259

73-
- `undo`: A function to revert to the previous state.
74-
- `redo`: A function to advance to the next state.
75-
- `canUndo`: A boolean indicating if it's possible to undo.
76-
- `canRedo`: A boolean indicating if it's possible to redo.
60+
function Component() {
61+
const setHistoryAtom = useSetAtom(historyAtom)
62+
...
63+
setHistoryAtom(UNDO)
64+
setHistoryAtom(REDO)
65+
}
66+
```
7767

78-
### Usage
68+
### Indicators
7969

80-
```jsx
81-
import { atom, useAtom, useAtomValue } from 'jotai'
82-
import { withUndo } from 'jotai-history'
70+
- **canUndo** and **canRedo**
71+
Booleans indicating whether undo or redo actions are currently possible. These can be used to disable buttons or conditionally trigger actions.
8372

84-
const counterAtom = atom(0)
85-
const undoCounterAtom = withUndo(counterAtom, 5)
73+
```jsx
74+
...
8675

87-
function CounterComponent() {
88-
const { undo, redo, canUndo, canRedo } = useAtomValue(undoCounterAtom)
89-
const [value, setValue] = useAtom(counterAtom)
76+
function Component() {
77+
const history = useAtomValue(historyAtom)
9078

91-
return (
92-
<>
93-
<p>Count: {value}</p>
94-
<button onClick={() => setValue((c) => c + 1)}>Increment</button>
95-
<button onClick={undo} disabled={!canUndo}>
96-
Undo
97-
</button>
98-
<button onClick={redo} disabled={!canRedo}>
99-
Redo
100-
</button>
101-
</>
102-
)
103-
}
104-
```
79+
return (
80+
<>
81+
<button disabled={!history.canUndo}>Undo</button>
82+
<button disabled={!history.canRedo}>Redo</button>
83+
</>
84+
)
85+
}
86+
```
10587

10688
<CodeSandbox id="g6qj3q" />
10789

10890
## Memory Management
10991

110-
⚠️ Since `withHistory` and `withUndo` keeps a history of states, it's important to manage memory by setting a reasonable `limit`. Excessive history can lead to memory bloat, especially in applications with frequent state updates.
92+
> Because `withHistory` maintains a list of previous states, be mindful of memory usage by setting a reasonable `limit`. Applications that update state frequently can grow significantly in memory usage.

eslint.config.mjs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@ export default tseslint.config(
1717
tseslint.configs.recommended,
1818
react.configs.flat.recommended,
1919
react.configs.flat['jsx-runtime'],
20+
reactHooks.configs['recommended-latest'],
21+
reactCompiler.configs.recommended,
2022
{
21-
plugins: {
22-
'react-compiler': reactCompiler,
23-
'react-hooks': reactHooks,
24-
},
2523
settings: {
2624
react: {
2725
version: 'detect',
@@ -74,8 +72,6 @@ export default tseslint.config(
7472
'warn',
7573
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
7674
],
77-
'react-compiler/react-compiler': 'warn',
78-
...reactHooks.configs.recommended.rules,
7975
},
8076
},
8177
{

src/vanilla/internals.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Internal functions (subject to ch>ange without notice)
1+
// Internal functions (subject to change without notice)
22
// In case you rely on them, be sure to pin the version
33

44
import type { Atom, WritableAtom } from './atom.ts'
@@ -374,7 +374,7 @@ type BuildingBlocks = readonly [
374374
mountCallbacks: Callbacks,
375375
unmountCallbacks: Callbacks,
376376
storeHooks: StoreHooks,
377-
// atom intercepters
377+
// atom interceptors
378378
atomRead: AtomRead,
379379
atomWrite: AtomWrite,
380380
atomOnInit: AtomOnInit,
@@ -405,7 +405,7 @@ const buildStore = (
405405
mountCallbacks: Callbacks = new Set(),
406406
unmountCallbacks: Callbacks = new Set(),
407407
storeHooks: StoreHooks = {},
408-
// atom intercepters
408+
// atom interceptors
409409
atomRead: AtomRead = (atom, ...params) => atom.read(...params),
410410
atomWrite: AtomWrite = (atom, ...params) => atom.write(...params),
411411
atomOnInit: AtomOnInit = (atom, store) => atom.unstable_onInit?.(store),
@@ -480,7 +480,7 @@ const buildStore = (
480480
const recomputeInvalidatedAtoms =
481481
buildingBlockFunctions[2] ||
482482
(() => {
483-
// Step 1: traverse the dependency graph to build the topsorted atom list
483+
// Step 1: traverse the dependency graph to build the topologically sorted atom list
484484
// We don't bother to check for cycles, which simplifies the algorithm.
485485
// This is a topological sort via depth-first search, slightly modified from
486486
// what's described here for simplicity and performance reasons:
@@ -853,7 +853,7 @@ const buildStore = (
853853
mountCallbacks,
854854
unmountCallbacks,
855855
storeHooks,
856-
// atom intercepters
856+
// atom interceptors
857857
atomRead,
858858
atomWrite,
859859
atomOnInit,

0 commit comments

Comments
 (0)