qortex-core 0.1.0 → 0.1.2
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 +277 -0
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
# 🎯 qortex-core
|
|
2
|
+
|
|
3
|
+
> **Framework-agnostic query cache. Set and read data from anywhere! 🧠**
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/js/qortex-core)
|
|
6
|
+
[](https://bundlephobia.com/package/qortex-core)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
|
|
9
|
+
## ✨ What makes this special?
|
|
10
|
+
|
|
11
|
+
**qortex-core** lets you **set and read data from anywhere** - not just within a specific framework! Perfect for:
|
|
12
|
+
|
|
13
|
+
- 🔐 **App core data** - Authentication, user profiles accessible from anywhere
|
|
14
|
+
- 🎯 **Cross-framework** - Share data between React, Vue, vanilla JS, Node.js
|
|
15
|
+
- 🔄 **Background services** - WebSocket updates, timers, external events
|
|
16
|
+
- ⚡ **Real-time apps** - Push changes from anywhere, see them everywhere instantly
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pnpm add qortex-core
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { queryManager } from "qortex-core";
|
|
24
|
+
|
|
25
|
+
// Set global defaults for all queries
|
|
26
|
+
queryManager.setDefaultConfig({
|
|
27
|
+
staleTime: 5 * 60 * 1000, // 5 minutes default
|
|
28
|
+
throttleTime: 100, // 100ms throttle
|
|
29
|
+
usePreviousDataOnError: true
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Register a fetcher
|
|
33
|
+
queryManager.registerFetcher(["todos"], {
|
|
34
|
+
fetcher: async () => {
|
|
35
|
+
const response = await fetch("/api/todos");
|
|
36
|
+
return response.json();
|
|
37
|
+
},
|
|
38
|
+
placeholderData: [] // Uses global staleTime: 5 minutes
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Fetch data
|
|
42
|
+
const todos = await queryManager.fetchQuery(["todos"]);
|
|
43
|
+
console.log("Todos loaded:", todos);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## 🔐 Perfect for Authentication
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
// Auth service - update from anywhere
|
|
50
|
+
class AuthService {
|
|
51
|
+
async login(email: string, password: string) {
|
|
52
|
+
const { user, token } = await fetch("/api/auth/login", {
|
|
53
|
+
method: "POST",
|
|
54
|
+
body: JSON.stringify({ email, password })
|
|
55
|
+
}).then(r => r.json());
|
|
56
|
+
|
|
57
|
+
// 🎯 Update auth state - accessible everywhere!
|
|
58
|
+
queryManager.setQueryData(["auth", "user"], user);
|
|
59
|
+
queryManager.setQueryData(["auth", "isAuthenticated"], true);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
logout() {
|
|
63
|
+
// 🎯 Clear auth state from anywhere
|
|
64
|
+
queryManager.setQueryData(["auth", "user"], null);
|
|
65
|
+
queryManager.setQueryData(["auth", "isAuthenticated"], false);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Access from any environment
|
|
70
|
+
// React
|
|
71
|
+
function useAuth() {
|
|
72
|
+
const user = queryManager.getQueryData(["auth", "user"]);
|
|
73
|
+
const isAuthenticated = queryManager.getQueryData(["auth", "isAuthenticated"]);
|
|
74
|
+
return { user, isAuthenticated };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// React with hooks (qortex-react package)
|
|
78
|
+
import { useQuery, useQueryData } from "qortex-react";
|
|
79
|
+
|
|
80
|
+
function AuthComponent() {
|
|
81
|
+
const { data: user, isLoading } = useQuery(["auth", "user"]);
|
|
82
|
+
const isAuthenticated = useQueryData(["auth", "isAuthenticated"]);
|
|
83
|
+
|
|
84
|
+
if (isLoading) return <div>Loading...</div>;
|
|
85
|
+
return <div>Welcome {user?.name}</div>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Vue
|
|
89
|
+
function useAuth() {
|
|
90
|
+
const user = ref(queryManager.getQueryData(["auth", "user"]));
|
|
91
|
+
const isAuthenticated = ref(queryManager.getQueryData(["auth", "isAuthenticated"]));
|
|
92
|
+
|
|
93
|
+
queryManager.subscribeQuery(["auth", "user"], (state) => {
|
|
94
|
+
user.value = state.data;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return { user, isAuthenticated };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Vanilla JS
|
|
101
|
+
function checkAuth() {
|
|
102
|
+
const user = queryManager.getQueryData(["auth", "user"]);
|
|
103
|
+
const isAuthenticated = queryManager.getQueryData(["auth", "isAuthenticated"]);
|
|
104
|
+
return { user, isAuthenticated };
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## 🎨 API Reference
|
|
109
|
+
|
|
110
|
+
### `queryManager.registerFetcher(key, options)`
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
queryManager.registerFetcher(key, {
|
|
114
|
+
fetcher: async () => Promise<T>,
|
|
115
|
+
staleTime?: number, // Default: 0
|
|
116
|
+
placeholderData?: T,
|
|
117
|
+
enabled?: boolean // Default: true
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### `queryManager.fetchQuery(key, options?)`
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
const data = await queryManager.fetchQuery(key, {
|
|
125
|
+
fetcher?: Fetcher<T>,
|
|
126
|
+
staleTime?: number
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### `queryManager.setQueryData(key, data)`
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
// Direct update
|
|
134
|
+
queryManager.setQueryData(["todos"], newTodos);
|
|
135
|
+
|
|
136
|
+
// Functional update
|
|
137
|
+
queryManager.setQueryData(["todos"], (oldData) => [
|
|
138
|
+
...(oldData || []),
|
|
139
|
+
newTodo
|
|
140
|
+
]);
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### `queryManager.getQueryData(key)`
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
const user = queryManager.getQueryData(["auth", "user"]);
|
|
147
|
+
const isAuthenticated = queryManager.getQueryData(["auth", "isAuthenticated"]);
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### React Hooks (qortex-react package)
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
import { useQuery, useQueryData } from "qortex-react";
|
|
154
|
+
|
|
155
|
+
// Full query state with loading, error, refetch
|
|
156
|
+
const { data, isLoading, error, refetch } = useQuery(["todos"]);
|
|
157
|
+
|
|
158
|
+
// Just the data - simpler API
|
|
159
|
+
const todos = useQueryData(["todos"]);
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### `queryManager.subscribeQuery(key, callback)`
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
const unsubscribe = queryManager.subscribeQuery(["todos"], (state) => {
|
|
166
|
+
console.log("State changed:", state);
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### `queryManager.setDefaultConfig(config)`
|
|
171
|
+
|
|
172
|
+
Set global default configuration for all queries.
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
queryManager.setDefaultConfig({
|
|
176
|
+
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
177
|
+
refetchOnSubscribe: "stale",
|
|
178
|
+
throttleTime: 100, // 100ms throttle
|
|
179
|
+
usePreviousDataOnError: true,
|
|
180
|
+
equalityFn: shallowEqual
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Available options:**
|
|
185
|
+
- `enabled?: boolean` - Whether queries are enabled by default
|
|
186
|
+
- `refetchOnSubscribe?: "stale" | "always" | false` - Default refetch behavior
|
|
187
|
+
- `staleTime?: number` - Default time before data is considered stale
|
|
188
|
+
- `usePreviousDataOnError?: boolean` - Keep previous data on error
|
|
189
|
+
- `usePlaceholderOnError?: boolean` - Use placeholder data on error
|
|
190
|
+
- `equalityFn?: EqualityFn<any>` - Default equality function
|
|
191
|
+
- `throttleTime?: number` - Default throttle time for duplicate request prevention
|
|
192
|
+
|
|
193
|
+
## 🎯 More Examples
|
|
194
|
+
|
|
195
|
+
### WebSocket Updates
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
// Update data from WebSocket
|
|
199
|
+
const ws = new WebSocket("ws://localhost:8080");
|
|
200
|
+
ws.onmessage = (event) => {
|
|
201
|
+
const data = JSON.parse(event.data);
|
|
202
|
+
queryManager.setQueryData(["live-stats"], data);
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// Access from any environment
|
|
206
|
+
const stats = queryManager.getQueryData(["live-stats"]);
|
|
207
|
+
console.log("Users online:", stats?.users);
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Cross-Framework Data Sharing
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
// React component updates data
|
|
214
|
+
function ReactComponent() {
|
|
215
|
+
const updateTheme = () => {
|
|
216
|
+
queryManager.setQueryData(["user", "preferences"], { theme: "dark" });
|
|
217
|
+
};
|
|
218
|
+
return <button onClick={updateTheme}>Update Theme</button>;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Vue component automatically reflects changes
|
|
222
|
+
function VueComponent() {
|
|
223
|
+
const preferences = ref(queryManager.getQueryData(["user", "preferences"]));
|
|
224
|
+
|
|
225
|
+
queryManager.subscribeQuery(["user", "preferences"], (state) => {
|
|
226
|
+
preferences.value = state.data;
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
return { preferences };
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Vanilla JS also gets updates
|
|
233
|
+
function vanillaJSFunction() {
|
|
234
|
+
const preferences = queryManager.getQueryData(["user", "preferences"]);
|
|
235
|
+
console.log("Current theme:", preferences?.theme);
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## 🎭 TypeScript Support
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
interface User {
|
|
243
|
+
id: string;
|
|
244
|
+
name: string;
|
|
245
|
+
email: string;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Type-safe usage
|
|
249
|
+
queryManager.registerFetcher<User[]>(["users"], {
|
|
250
|
+
fetcher: async (): Promise<User[]> => {
|
|
251
|
+
const response = await fetch("/api/users");
|
|
252
|
+
return response.json();
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const users = await queryManager.fetchQuery<User[]>(["users"]);
|
|
257
|
+
// users is typed as User[] | undefined
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## 📄 License
|
|
261
|
+
|
|
262
|
+
MIT License - feel free to use this in your projects! 🎉
|
|
263
|
+
|
|
264
|
+
## 🎯 Support
|
|
265
|
+
|
|
266
|
+
Need help? Have questions?
|
|
267
|
+
|
|
268
|
+
- 📧 **Email**: [darshannaik.com](https://darshannaik.com)
|
|
269
|
+
- 🐛 **Issues**: [GitHub Issues](https://github.com/Darshan-Naik/qortex/issues)
|
|
270
|
+
- 🌟 **Repository**: [https://github.com/Darshan-Naik/qortex](https://github.com/Darshan-Naik/qortex)
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
<div align="center">
|
|
275
|
+
<p>Made with ❤️ by <a href="https://darshannaik.com">Darshan</a></p>
|
|
276
|
+
<p>⭐ Star this repo if you found it helpful!</p>
|
|
277
|
+
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qortex-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Framework-agnostic query cache & fetch registry (MFE friendly).",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.mjs",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
],
|
|
24
24
|
"repository": {
|
|
25
25
|
"type": "git",
|
|
26
|
-
"url": "https://github.com/Darshan-Naik/qortex.git"
|
|
26
|
+
"url": "git+https://github.com/Darshan-Naik/qortex.git"
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://github.com/Darshan-Naik/qortex#readme",
|
|
29
29
|
"bugs": {
|