react-smart-query 1.0.0 β 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +169 -73
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,130 +1,226 @@
|
|
|
1
|
-
# π§
|
|
1
|
+
# π§ react-smart-query
|
|
2
2
|
|
|
3
|
-
**
|
|
4
|
-
|
|
5
|
-
React Smart Query is more than just a cache; it's a high-performance normalization engine designed to handle complex, paginated lists with predictable, O(log n) mutations β even when offline.
|
|
3
|
+
**Offline-first normalized data layer for React Native & Web**
|
|
6
4
|
|
|
7
5
|
[](https://www.npmjs.com/package/react-smart-query)
|
|
8
6
|
[](https://opensource.org/licenses/MIT)
|
|
9
7
|
|
|
10
8
|
---
|
|
11
9
|
|
|
12
|
-
##
|
|
10
|
+
## β‘ Quick Example
|
|
11
|
+
|
|
12
|
+
Get started in seconds. It looks just like the tools you already know, but with superpowers.
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
import { useSmartQuery } from 'react-smart-query';
|
|
16
|
+
|
|
17
|
+
const { data, isLoading } = useSmartQuery({
|
|
18
|
+
queryKey: ["expenses"],
|
|
19
|
+
queryFn: fetchExpenses
|
|
20
|
+
});
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## π¨ The Problem
|
|
26
|
+
|
|
27
|
+
TanStack Query (React Query) handles data fetching brilliantly. But as your app grows, real-world constraints start to show. Complex apps often struggle with:
|
|
28
|
+
|
|
29
|
+
- **Pagination + Mutation Bugs**: Updating a single item buried inside page 3 of an infinite list requires complex, error-prone manual cache traversals.
|
|
30
|
+
- **Offline Sync**: Surviving patchy networks and syncing user actions when they come back online.
|
|
31
|
+
- **Unnecessary Re-renders**: UI components rendering more often than they need to.
|
|
32
|
+
- **Large List Updates**: Finding and updating items in massive arrays without freezing the UI.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## π‘ The Solution
|
|
13
37
|
|
|
14
|
-
|
|
15
|
-
1. **Data Duplication:** The same resource existing in multiple pages of a query response cache, leading to out-of-sync UI components.
|
|
16
|
-
2. **Inconsistent Ordering:** Newly added optimistic items appearing at the top/bottom rather than their correct sorted semantic position, causing visual "jumps" on next load.
|
|
17
|
-
3. **Complex Manual Cache Logic:** Forcing developers to write intricate, error-prone traversal logic just to update a single nested item deep inside a page array.
|
|
38
|
+
`react-smart-query` intercepts your API responses and stores them intelligently.
|
|
18
39
|
|
|
19
|
-
**
|
|
40
|
+
- **Adds offline-first support** right out of the box.
|
|
41
|
+
- **Uses normalized storage** (a flat dictionary) behind the scenes for lighting-fast updates.
|
|
42
|
+
- **Fixes pagination + mutation issues** automatically. No more manual cache traversal!
|
|
43
|
+
- **Works on top of React Query**. It enhances your existing setup without replacing it.
|
|
20
44
|
|
|
21
|
-
|
|
45
|
+
---
|
|
22
46
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
- **Offline-
|
|
26
|
-
- **
|
|
27
|
-
- **
|
|
47
|
+
## β¨ Key Features
|
|
48
|
+
|
|
49
|
+
- πΆ **Offline-first caching** (MMKV for mobile, IndexedDB for web)
|
|
50
|
+
- π **Normalized data structure** (`{ byId, allIds }` map) for `O(1)` updates
|
|
51
|
+
- π§ **Smart diff updates** (minimal, surgically precise re-renders)
|
|
52
|
+
- π **Infinite query with normalized pagination** (no more page-splicing bugs)
|
|
53
|
+
- π **Global mutation system** (add/update/remove from anywhere, without hooks)
|
|
54
|
+
- π± **Cross-platform support**
|
|
55
|
+
- π‘οΈ **Memory protection** (maxItems to elegantly trim huge lists)
|
|
56
|
+
|
|
57
|
+
---
|
|
28
58
|
|
|
29
|
-
|
|
59
|
+
## βοΈ Why Not Just TanStack Query?
|
|
30
60
|
|
|
31
|
-
React Smart Query
|
|
61
|
+
React Smart Query takes the heavy lifting out of state mutability. It delegates the networking to TanStack Query and completely upgrades the storage.
|
|
32
62
|
|
|
33
|
-
| Feature | TanStack Query |
|
|
34
|
-
| :--- |
|
|
35
|
-
| **
|
|
36
|
-
| **
|
|
37
|
-
| **
|
|
38
|
-
| **
|
|
39
|
-
| **Offline Mutations** | Difficult (Requires manual hydration/plugins) | Built-in Persistent Queue & Auto-Sync |
|
|
40
|
-
| **Memory Management** | Time-based garbage collection | Time-based + Soft trimming of large lists |
|
|
63
|
+
| Feature | TanStack Query | react-smart-query |
|
|
64
|
+
| :--- | :---: | :---: |
|
|
65
|
+
| **Offline queue** | β | β
|
|
|
66
|
+
| **Normalized cache** | β | β
|
|
|
67
|
+
| **Pagination + mutation fix** | β | β
|
|
|
68
|
+
| **Global mutations** | β | β
|
|
|
41
69
|
|
|
42
70
|
---
|
|
43
71
|
|
|
44
72
|
## π¦ Installation
|
|
45
73
|
|
|
74
|
+
Install the library alongside its peer dependencies:
|
|
75
|
+
|
|
46
76
|
```bash
|
|
47
77
|
npm install react-smart-query @tanstack/react-query react-native-mmkv
|
|
48
78
|
```
|
|
49
79
|
|
|
50
80
|
---
|
|
51
81
|
|
|
52
|
-
##
|
|
82
|
+
## π¦ Quick Start
|
|
83
|
+
|
|
84
|
+
### 1. Setup
|
|
53
85
|
|
|
54
|
-
|
|
86
|
+
Just wrap your app like you normally would. Your data layer is instantly primed.
|
|
55
87
|
|
|
56
88
|
```tsx
|
|
57
|
-
import {
|
|
89
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
58
90
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
91
|
+
const queryClient = new QueryClient();
|
|
92
|
+
|
|
93
|
+
export default function App() {
|
|
94
|
+
return (
|
|
95
|
+
<QueryClientProvider client={queryClient}>
|
|
96
|
+
<YourApp />
|
|
97
|
+
</QueryClientProvider>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
64
100
|
```
|
|
65
101
|
|
|
66
|
-
### 2.
|
|
102
|
+
### 2. Standard Query
|
|
67
103
|
|
|
68
104
|
```tsx
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
});
|
|
105
|
+
import { useSmartQuery } from 'react-smart-query';
|
|
106
|
+
|
|
107
|
+
function UserProfile({ userId }) {
|
|
108
|
+
const { data } = useSmartQuery({
|
|
109
|
+
queryKey: ['users', userId],
|
|
110
|
+
queryFn: () => api.getUser(userId),
|
|
111
|
+
select: (res) => res.user,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
return <Text>{data?.name}</Text>;
|
|
115
|
+
}
|
|
116
|
+
```
|
|
77
117
|
|
|
78
|
-
|
|
79
|
-
|
|
118
|
+
### 3. Infinite Query
|
|
119
|
+
|
|
120
|
+
This is where the magic happens. Mutating paged data is now effortless.
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
import { useInfiniteSmartQuery } from 'react-smart-query';
|
|
124
|
+
|
|
125
|
+
function Feed() {
|
|
126
|
+
const { data, addItem } = useInfiniteSmartQuery({
|
|
127
|
+
queryKey: ['feed'],
|
|
128
|
+
queryFn: ({ pageParam }) => api.getFeed({ cursor: pageParam }),
|
|
129
|
+
getNextCursor: (res) => res.nextCursor,
|
|
130
|
+
select: (res) => res.items,
|
|
131
|
+
getItemId: (item) => item.id,
|
|
132
|
+
sortComparator: (a, b) => b.createdAt - a.createdAt,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Adding an item automatically sorts it into the exact right place!
|
|
136
|
+
const onNewPost = (post) => addItem(post);
|
|
137
|
+
|
|
138
|
+
return <FlatList data={data} renderItem={...} />;
|
|
139
|
+
}
|
|
80
140
|
```
|
|
81
141
|
|
|
82
142
|
---
|
|
83
143
|
|
|
144
|
+
## πΌ Example Use Case
|
|
145
|
+
|
|
146
|
+
**Scenario: An Expense Tracking App**
|
|
147
|
+
|
|
148
|
+
Imagine a user is traveling through the subway and logs an expense.
|
|
149
|
+
1. `react-smart-query` immediately intercepts this.
|
|
150
|
+
2. It pushes the action to an **Offline Queue**.
|
|
151
|
+
3. It performs a **Global Mutation**, inserting the new expense into the normalized store.
|
|
152
|
+
4. Your Infinite List jumps to lifeβit finds the expense, uses your `sortComparator` via binary search to place it at exactly the top of the list, and triggers a surgically precise re-render.
|
|
153
|
+
5. When the user exits the subway, the queue detects the network and syncs the expense to your server.
|
|
154
|
+
|
|
155
|
+
**Perfect for:** Expense Apps, Chat Apps, Social Feeds, and Dashboards.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## π οΈ API Overview
|
|
160
|
+
|
|
161
|
+
- **`useSmartQuery`**: Drop-in enhancement for viewing and caching standard API calls.
|
|
162
|
+
- **`useInfiniteSmartQuery`**: The flagship hook. Takes paginated API chunks, flattens them, sorts them globally, and gives you `addItem`, `updateItem`, and `removeItem` helpers.
|
|
163
|
+
- **`getSmartQueryActions`**: A global API to mutate data from outside of React components (e.g., from a push notification background handler).
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
84
167
|
## ποΈ Architecture
|
|
85
168
|
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
169
|
+
```text
|
|
170
|
+
UI (React Components)
|
|
171
|
+
β
|
|
172
|
+
Smart Query Hooks
|
|
173
|
+
β
|
|
174
|
+
TanStack Query (Networking)
|
|
175
|
+
β
|
|
176
|
+
Normalized Cache + Offline Queue
|
|
177
|
+
β
|
|
178
|
+
Storage (MMKV / IndexedDB)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## π΅οΈ Debug Tools
|
|
184
|
+
|
|
185
|
+
For power users, `react-smart-query` comes with built-in development inspection tools to see exactly how your data is normalizing.
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
import "react-smart-query/debug";
|
|
189
|
+
import { smartQueryDebug } from "react-smart-query";
|
|
190
|
+
|
|
191
|
+
// Prints the exact current state of the global { byId, allIds } maps to your console!
|
|
192
|
+
await smartQueryDebug.snapshot();
|
|
96
193
|
```
|
|
97
194
|
|
|
98
195
|
---
|
|
99
196
|
|
|
100
|
-
##
|
|
197
|
+
## π€ When to Use / Not Use
|
|
101
198
|
|
|
102
|
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
199
|
+
β
**Use if:**
|
|
200
|
+
- You are building offline-first apps.
|
|
201
|
+
- You have large, paginated lists.
|
|
202
|
+
- You have high-frequency data updates (websocket chats, real-time feeds).
|
|
203
|
+
|
|
204
|
+
β **Avoid if:**
|
|
205
|
+
- You are building a very small app without offline needs.
|
|
206
|
+
- Your data is purely static and never mutates locally.
|
|
106
207
|
|
|
107
208
|
---
|
|
108
209
|
|
|
109
|
-
##
|
|
210
|
+
## πΊοΈ Roadmap
|
|
110
211
|
|
|
111
|
-
|
|
112
|
-
-
|
|
113
|
-
-
|
|
114
|
-
- You want to eliminate "flicker" when items change positions.
|
|
212
|
+
- [ ] DevTools UI (Visual Inspector)
|
|
213
|
+
- [ ] Built-in WebSocket sync adapter
|
|
214
|
+
- [ ] Lightweight Plugin System
|
|
115
215
|
|
|
116
|
-
|
|
117
|
-
- Your data is small and non-relational.
|
|
118
|
-
- You don't need offline persistence or sorted lists.
|
|
216
|
+
---
|
|
119
217
|
|
|
120
|
-
##
|
|
218
|
+
## π€ Contributing
|
|
121
219
|
|
|
122
|
-
|
|
123
|
-
- [API Reference](./docs/API_REFERENCE.md)
|
|
124
|
-
- [Guidelines & Best Practices](./docs/GUIDELINES.md)
|
|
125
|
-
- [Testing & Debugging](./docs/TESTING.md)
|
|
220
|
+
We welcome contributions! Whether you're fixing a bug, adding a feature, or improving documentation, check out our repository and open a Pull Request.
|
|
126
221
|
|
|
127
222
|
---
|
|
128
223
|
|
|
129
224
|
## π License
|
|
225
|
+
|
|
130
226
|
MIT Β© 2024 React Smart Query Team
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-smart-query",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Offline-first, normalized, cache-versioned data layer for React Native and Expo. Built on TanStack Query with MMKV (native) and IndexedDB (web).",
|
|
5
5
|
"author": "Subham Ghosh <subham49ghosh@gmail.com>",
|
|
6
6
|
"license": "MIT",
|