You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+51-44Lines changed: 51 additions & 44 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,6 +16,7 @@
16
16
Most optimistic-update libraries snapshot your entire state tree for every in-flight operation. Optimistron doesn't. It tracks lightweight **transitions** (stage, amend, commit, fail) alongside your reducer state and replays them at read-time through `selectOptimistic` — right where `reselect` memoization already lives.
17
17
18
18
Good fit for:
19
+
19
20
-**Offline-first** — transitions queue up while disconnected, conflicts resolve on reconnect
| Branch tip |**Committed state** — only `COMMIT` advances it|
35
+
| Staged commits |**Transitions** — pending changes on top of committed state |
36
+
|`git rebase`|**`selectOptimistic`** — replays transitions at read-time|
36
37
| Merge conflict |**Sanitization** — detects no-ops and conflicts after every mutation |
37
38
38
39
`STAGE`, `AMEND`, `FAIL`, `STASH` never touch reducer state — they only modify the transitions list. The optimistic view updates because `selectOptimistic` re-derives on the next read.
39
40
40
-
No `isLoading` / `error` / `isOptimistic` flags. A pending transition *is* loading. A failed one *is* the error. One source of truth.
41
+
No `isLoading` / `error` / `isOptimistic` flags. A pending transition _is_ loading. A failed one _is_ the error. One source of truth.
41
42
42
43
---
43
44
@@ -53,7 +54,7 @@ No `isLoading` / `error` / `isOptimistic` flags. A pending transition *is* loadi
dispatch(createTodo.commit(todo.id)); // server confirmed — becomes committed state
105
103
dispatch(createTodo.fail(todo.id, error)); // server rejected — flagged as failed
106
104
```
107
105
@@ -120,8 +118,8 @@ dispatch(createTodo.fail(todo.id, error)); // server rejected — flagged as fai
120
118
Entities need a **monotonically increasing version** — `revision`, `updatedAt`, a sequence number. This is how sanitization tells "newer" from "stale":
121
119
122
120
```typescript
123
-
compare: (a) => (b) =>0|1|-1// version ordering (curried)
124
-
eq: (a) => (b) =>boolean// content equality at same version (curried)
121
+
compare: (a) => (b) =>0|1|-1;// version ordering (curried)
122
+
eq: (a) => (b) =>boolean;// content equality at same version (curried)
125
123
```
126
124
127
125
Without versioning, conflict detection degrades to content equality only.
@@ -176,27 +174,36 @@ You can implement the `StateHandler` interface for any shape — the built-ins a
176
174
The 4th argument to `optimistron()` supports three modes:
177
175
178
176
**Auto-wired** — zero boilerplate, handler routes payloads:
0 commit comments