@ecency/sdk 1.5.7 → 1.5.8
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 +201 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,12 +2,212 @@
|
|
|
2
2
|
|
|
3
3
|
Framework-agnostic data layer for Hive apps with first-class React Query support.
|
|
4
4
|
|
|
5
|
-
## What
|
|
5
|
+
## What's Inside
|
|
6
6
|
|
|
7
7
|
- Query and mutation option builders powered by [@tanstack/react-query](https://tanstack.com/query)
|
|
8
8
|
- Modular APIs: accounts, posts, communities, market, wallet, notifications, analytics, integrations, core, auth, bridge, games, hive-engine, operations, points, private-api, promotions, proposals, resource-credits, search, spk, witnesses
|
|
9
9
|
- Central configuration via `CONFIG` / `ConfigManager` (RPC client, QueryClient)
|
|
10
10
|
|
|
11
|
+
## Why React Query?
|
|
12
|
+
|
|
13
|
+
The Ecency SDK is built on **React Query** (TanStack Query) to provide a production-ready data synchronization layer out of the box. React Query transforms how Hive applications handle server state, eliminating common pitfalls and dramatically improving user experience.
|
|
14
|
+
|
|
15
|
+
### Key Benefits
|
|
16
|
+
|
|
17
|
+
#### 1. **Automatic Caching & Deduplication**
|
|
18
|
+
Multiple components can request the same data without redundant network calls. React Query automatically:
|
|
19
|
+
- Caches responses by query key
|
|
20
|
+
- Deduplicates concurrent requests
|
|
21
|
+
- Shares cached data across components instantly
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
// Both components use the same query - only 1 API call is made
|
|
25
|
+
// Component A
|
|
26
|
+
useQuery(getAccountFullQueryOptions("ecency"));
|
|
27
|
+
|
|
28
|
+
// Component B (rendered simultaneously)
|
|
29
|
+
useQuery(getAccountFullQueryOptions("ecency")); // ← Uses cached data
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
#### 2. **Background Synchronization**
|
|
33
|
+
Data automatically stays fresh without manual refetching. React Query:
|
|
34
|
+
- Refetches stale data on window focus
|
|
35
|
+
- Updates data on network reconnection
|
|
36
|
+
- Supports configurable background polling
|
|
37
|
+
- Prevents showing outdated information
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
// Data refetches automatically when user returns to tab
|
|
41
|
+
const { data } = useQuery({
|
|
42
|
+
...getPostsRankedQueryOptions("trending", "", "", 20),
|
|
43
|
+
staleTime: 60000, // Consider fresh for 60s
|
|
44
|
+
refetchInterval: 120000 // Poll every 2 minutes
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### 3. **Optimistic Updates**
|
|
49
|
+
Instant UI feedback before blockchain confirmation:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
const { mutateAsync } = useAccountUpdate(username, auth);
|
|
53
|
+
|
|
54
|
+
await mutateAsync(
|
|
55
|
+
{ metadata: newProfile },
|
|
56
|
+
{
|
|
57
|
+
// Update UI immediately
|
|
58
|
+
onMutate: (variables) => {
|
|
59
|
+
queryClient.setQueryData(
|
|
60
|
+
getAccountFullQueryOptions(username).queryKey,
|
|
61
|
+
(old) => ({ ...old, ...variables.metadata })
|
|
62
|
+
);
|
|
63
|
+
},
|
|
64
|
+
// Rollback on error
|
|
65
|
+
onError: (err, variables, context) => {
|
|
66
|
+
queryClient.setQueryData(
|
|
67
|
+
getAccountFullQueryOptions(username).queryKey,
|
|
68
|
+
context.previousData
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### 4. **SSR & Prefetching**
|
|
76
|
+
First-class server-side rendering support:
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
// Next.js App Router example
|
|
80
|
+
export async function generateMetadata({ params }) {
|
|
81
|
+
const queryClient = new QueryClient();
|
|
82
|
+
|
|
83
|
+
// Prefetch on server
|
|
84
|
+
await queryClient.prefetchQuery(
|
|
85
|
+
getAccountFullQueryOptions(params.username)
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
// Data is hydrated on client instantly
|
|
89
|
+
return { title: /* ... */ };
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### 5. **Loading & Error States**
|
|
94
|
+
Built-in state management eliminates boilerplate:
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
const { data, isLoading, error, isRefetching } = useQuery(
|
|
98
|
+
getAccountFullQueryOptions("ecency")
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
if (isLoading) return <Spinner />;
|
|
102
|
+
if (error) return <ErrorMessage error={error} />;
|
|
103
|
+
|
|
104
|
+
return <Profile data={data} isRefreshing={isRefetching} />;
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### 6. **Dependent Queries**
|
|
108
|
+
Chain queries with automatic dependency tracking:
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
// Step 1: Fetch account
|
|
112
|
+
const { data: account } = useQuery(getAccountFullQueryOptions(username));
|
|
113
|
+
|
|
114
|
+
// Step 2: Fetch wallet only after account loads
|
|
115
|
+
const { data: wallet } = useQuery({
|
|
116
|
+
...getAccountWalletAssetInfoQueryOptions(username, "HIVE"),
|
|
117
|
+
enabled: !!account // Wait for account
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### 7. **Pagination & Infinite Scroll**
|
|
122
|
+
Built-in pagination utilities:
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
const {
|
|
126
|
+
data,
|
|
127
|
+
fetchNextPage,
|
|
128
|
+
hasNextPage,
|
|
129
|
+
isFetchingNextPage
|
|
130
|
+
} = useInfiniteQuery(
|
|
131
|
+
getPostsRankedInfiniteQueryOptions("trending", "hive-engine")
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// Automatically manages page state and cursor tracking
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Why This Matters for Hive Apps
|
|
138
|
+
|
|
139
|
+
Hive applications face unique challenges:
|
|
140
|
+
- **High API latency**: Blockchain RPC calls can be slow (100-500ms)
|
|
141
|
+
- **Rate limits**: Excessive requests can hit node rate limits
|
|
142
|
+
- **Stale data**: Blockchain data changes frequently (new posts, votes, transfers)
|
|
143
|
+
- **Complex state**: Managing loading states, errors, and cache invalidation manually is error-prone
|
|
144
|
+
|
|
145
|
+
The Ecency SDK with React Query solves all of these:
|
|
146
|
+
|
|
147
|
+
✅ **Reduced API calls** by 70-90% through intelligent caching
|
|
148
|
+
✅ **Instant UI updates** with optimistic mutations
|
|
149
|
+
✅ **Zero manual cache management** - React Query handles invalidation
|
|
150
|
+
✅ **Better UX** with background updates and retry logic
|
|
151
|
+
✅ **Faster perceived performance** with prefetching and SSR
|
|
152
|
+
✅ **Less code** - no custom loading/error/caching logic needed
|
|
153
|
+
|
|
154
|
+
### How Other Apps Can Benefit
|
|
155
|
+
|
|
156
|
+
Any Hive application can leverage this SDK to:
|
|
157
|
+
|
|
158
|
+
1. **Drop custom data fetching code** - Use pre-built query options for all common Hive operations
|
|
159
|
+
2. **Share cache across features** - One query for account data serves entire app
|
|
160
|
+
3. **Add real-time features** easily with `refetchInterval` and optimistic updates
|
|
161
|
+
4. **Improve SEO** with SSR-ready queries that prefetch on server
|
|
162
|
+
5. **Reduce bundle size** - Share the SDK's type-safe queries instead of custom fetch logic
|
|
163
|
+
|
|
164
|
+
**Example: Building a Hive blog reader**
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
import { useQuery, useInfiniteQuery } from "@tanstack/react-query";
|
|
168
|
+
import {
|
|
169
|
+
getAccountFullQueryOptions,
|
|
170
|
+
getPostQueryOptions,
|
|
171
|
+
getPostsRankedInfiniteQueryOptions
|
|
172
|
+
} from "@ecency/sdk";
|
|
173
|
+
|
|
174
|
+
// Profile page - automatic caching
|
|
175
|
+
function ProfilePage({ username }) {
|
|
176
|
+
const { data: account, isLoading } = useQuery(
|
|
177
|
+
getAccountFullQueryOptions(username)
|
|
178
|
+
);
|
|
179
|
+
// ✅ Cached automatically, shared across components
|
|
180
|
+
// ✅ Refetches on window focus
|
|
181
|
+
// ✅ Handles loading/error states
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Feed page - infinite scroll
|
|
185
|
+
function FeedPage() {
|
|
186
|
+
const { data, fetchNextPage, hasNextPage } = useInfiniteQuery(
|
|
187
|
+
getPostsRankedInfiniteQueryOptions("trending")
|
|
188
|
+
);
|
|
189
|
+
// ✅ Automatic pagination
|
|
190
|
+
// ✅ Background updates
|
|
191
|
+
// ✅ Deduplicates concurrent requests
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Post page - dependent queries
|
|
195
|
+
function PostPage({ author, permlink }) {
|
|
196
|
+
const { data: post } = useQuery(
|
|
197
|
+
getPostQueryOptions(author, permlink)
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
const { data: authorAccount } = useQuery({
|
|
201
|
+
...getAccountFullQueryOptions(post?.author),
|
|
202
|
+
enabled: !!post // Wait for post to load
|
|
203
|
+
});
|
|
204
|
+
// ✅ Efficient dependent loading
|
|
205
|
+
// ✅ Shares cache with ProfilePage above
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Zero manual cache management. Zero custom fetch logic. Production-ready data layer.**
|
|
210
|
+
|
|
11
211
|
## Installation
|
|
12
212
|
|
|
13
213
|
```sh
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ecency/sdk",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.8",
|
|
5
5
|
"description": "Ecency SDK",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@types/node": "^22.13.8",
|
|
64
|
+
"@vitest/coverage-v8": "^2.0.0",
|
|
64
65
|
"bip39": "^3.1.0",
|
|
65
66
|
"eslint": "^9.21.0",
|
|
66
67
|
"lru-cache": "^11.0.2",
|