@rozenite/tanstack-query-plugin 1.0.0-alpha.1 → 1.0.0-alpha.10
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 +2 -2
- package/dist/assets/CXEL7IU7-BTFA0aeQ.js +1172 -0
- package/dist/assets/tanstack-query-DWTo8DT_.js +48 -0
- package/dist/react-native.cjs +1 -1
- package/dist/react-native.d.ts +1 -5
- package/dist/react-native.js +3 -150
- package/dist/rozenite.config.d.ts +7 -0
- package/dist/rozenite.json +1 -1
- package/dist/src/react-native/useHandleDevToolsMessages.d.ts +3 -0
- package/dist/src/react-native/useHandleInitialData.d.ts +3 -0
- package/dist/src/react-native/useSyncTanStackCache.d.ts +3 -0
- package/dist/src/react-native/useTanStackQueryDevTools.d.ts +2 -0
- package/dist/src/shared/dehydrate.d.ts +6 -0
- package/dist/src/shared/hydrate.d.ts +10 -0
- package/dist/src/shared/messaging.d.ts +34 -0
- package/dist/src/shared/types.d.ts +25 -0
- package/dist/src/shared/useSyncOnlineStatus.d.ts +2 -0
- package/dist/src/ui/tanstack-query.d.ts +1 -0
- package/dist/src/ui/useHandleSyncMessages.d.ts +2 -0
- package/dist/src/ui/useSyncDevToolsEvents.d.ts +2 -0
- package/dist/src/ui/useSyncInitialData.d.ts +2 -0
- package/dist/tanstack-query.html +1 -1
- package/dist/useTanstackQueryDevTools.cjs +1 -0
- package/dist/useTanstackQueryDevTools.js +312 -0
- package/package.json +14 -9
- package/project.json +12 -0
- package/react-native.ts +2 -2
- package/src/react-native/useHandleDevToolsMessages.ts +2 -3
- package/src/react-native/useHandleInitialData.ts +2 -3
- package/src/react-native/useSyncTanStackCache.ts +223 -10
- package/src/react-native/{useTanStackQueryDevTools.ts → useTanstackQueryDevTools.ts} +5 -4
- package/src/shared/dehydrate.ts +8 -6
- package/src/shared/hydrate.ts +218 -74
- package/src/shared/messaging.ts +36 -1
- package/src/shared/types.ts +5 -0
- package/src/shared/useSyncOnlineStatus.ts +2 -3
- package/src/ui/tanstack-query.tsx +2 -2
- package/src/ui/useHandleSyncMessages.ts +45 -3
- package/tsconfig.json +13 -6
- package/tsconfig.tsbuildinfo +1 -0
- package/dist/assets/tanstack-query-4kxOTB8B.js +0 -48
package/package.json
CHANGED
|
@@ -1,27 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rozenite/tanstack-query-plugin",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.10",
|
|
4
4
|
"description": "TanStack Query for Rozenite.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/react-native.cjs",
|
|
7
7
|
"module": "./dist/react-native.js",
|
|
8
8
|
"types": "./dist/react-native.d.ts",
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"
|
|
10
|
+
"fast-deep-equal": "^3.1.3",
|
|
11
|
+
"@rozenite/plugin-bridge": "1.0.0-alpha.10"
|
|
11
12
|
},
|
|
12
13
|
"devDependencies": {
|
|
14
|
+
"@tanstack/react-query": "^5.0.0",
|
|
13
15
|
"@tanstack/react-query-devtools": "^5.0.0",
|
|
16
|
+
"@types/react": "~18.3.12",
|
|
17
|
+
"react": "18.3.1",
|
|
18
|
+
"react-dom": "18.3.0",
|
|
19
|
+
"react-native": "0.76.0",
|
|
20
|
+
"react-native-web": "0.21.0",
|
|
14
21
|
"typescript": "^5.7.3",
|
|
15
22
|
"vite": "^6.0.0",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"rozenite": "1.0.0-alpha.0",
|
|
19
|
-
"@rozenite/vite-plugin": "1.0.0-alpha.1"
|
|
23
|
+
"rozenite": "1.0.0-alpha.10",
|
|
24
|
+
"@rozenite/vite-plugin": "1.0.0-alpha.10"
|
|
20
25
|
},
|
|
21
26
|
"peerDependencies": {
|
|
22
|
-
"react": "
|
|
23
|
-
"react
|
|
24
|
-
"
|
|
27
|
+
"@tanstack/react-query": "^5.0.0",
|
|
28
|
+
"react": "*",
|
|
29
|
+
"react-native": "*"
|
|
25
30
|
},
|
|
26
31
|
"license": "MIT",
|
|
27
32
|
"scripts": {
|
package/project.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
3
|
+
"name": "@rozenite/tanstack-query-plugin",
|
|
4
|
+
"targets": {
|
|
5
|
+
"build": {
|
|
6
|
+
"cache": true,
|
|
7
|
+
"dependsOn": ["^build"],
|
|
8
|
+
"inputs": ["{projectRoot}/src/**/*"],
|
|
9
|
+
"outputs": ["{projectRoot}/dist"]
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
package/react-native.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
1
|
export let useTanStackQueryDevTools: typeof import('./src/react-native/useTanStackQueryDevTools').useTanStackQueryDevTools;
|
|
3
2
|
|
|
4
3
|
if (process.env.NODE_ENV !== 'production') {
|
|
5
|
-
useTanStackQueryDevTools =
|
|
4
|
+
useTanStackQueryDevTools =
|
|
5
|
+
require('./src/react-native/useTanStackQueryDevTools').useTanStackQueryDevTools;
|
|
6
6
|
} else {
|
|
7
7
|
useTanStackQueryDevTools = () => ({ isConnected: false });
|
|
8
8
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
3
3
|
import { TanStackQueryPluginClient } from '../shared/messaging';
|
|
4
4
|
|
|
5
5
|
export const useHandleDevToolsMessages = (
|
|
6
|
+
queryClient: QueryClient,
|
|
6
7
|
client: TanStackQueryPluginClient | null
|
|
7
8
|
) => {
|
|
8
|
-
const queryClient = useQueryClient();
|
|
9
|
-
|
|
10
9
|
useEffect(() => {
|
|
11
10
|
if (!client) {
|
|
12
11
|
return;
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
import { TanStackQueryPluginClient } from '../shared/messaging';
|
|
3
|
-
import {
|
|
3
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
4
4
|
import { dehydrateQueryClient } from '../shared/dehydrate';
|
|
5
5
|
|
|
6
6
|
export const useHandleInitialData = (
|
|
7
|
+
queryClient: QueryClient,
|
|
7
8
|
client: TanStackQueryPluginClient | null
|
|
8
9
|
) => {
|
|
9
|
-
const queryClient = useQueryClient();
|
|
10
|
-
|
|
11
10
|
useEffect(() => {
|
|
12
11
|
if (!client) {
|
|
13
12
|
return;
|
|
@@ -1,23 +1,236 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
QueryClient,
|
|
3
|
+
QueryCacheNotifyEvent,
|
|
4
|
+
MutationCacheNotifyEvent,
|
|
5
|
+
} from '@tanstack/react-query';
|
|
6
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
7
|
+
import equal from 'fast-deep-equal';
|
|
3
8
|
import { TanStackQueryPluginClient } from '../shared/messaging';
|
|
4
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
dehydrateQuery,
|
|
11
|
+
dehydrateMutation,
|
|
12
|
+
dehydrateObservers,
|
|
13
|
+
} from '../shared/dehydrate';
|
|
14
|
+
import { SerializableObserver, PartialQueryState } from '../shared/types';
|
|
5
15
|
|
|
6
16
|
export const useSyncTanStackCache = (
|
|
17
|
+
queryClient: QueryClient,
|
|
7
18
|
client: TanStackQueryPluginClient | null
|
|
8
19
|
) => {
|
|
9
|
-
const
|
|
20
|
+
const previousObserversRef = useRef<Map<string, SerializableObserver[]>>(
|
|
21
|
+
new Map()
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const handler = useMemo(() => {
|
|
25
|
+
return (event: QueryCacheNotifyEvent | MutationCacheNotifyEvent): void => {
|
|
26
|
+
if (!client) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (event.type === 'observerResultsUpdated') {
|
|
31
|
+
// We don't need to sync this type of events.
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if ('query' in event) {
|
|
36
|
+
const { query, type } = event;
|
|
37
|
+
|
|
38
|
+
if (type === 'added' || type === 'removed') {
|
|
39
|
+
if (type === 'removed') {
|
|
40
|
+
// We don't need to store observers for removed queries.
|
|
41
|
+
previousObserversRef.current.delete(query.queryHash);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const dehydratedQuery = dehydrateQuery(query);
|
|
45
|
+
client.send('sync-query-event', { type, data: dehydratedQuery });
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (type === 'updated' && 'action' in event) {
|
|
50
|
+
const action = event.action;
|
|
51
|
+
|
|
52
|
+
switch (action.type) {
|
|
53
|
+
case 'fetch': {
|
|
54
|
+
// Only need loading state and fetch metadata
|
|
55
|
+
const fetchData: PartialQueryState = {
|
|
56
|
+
queryHash: query.queryHash,
|
|
57
|
+
state: {
|
|
58
|
+
status: query.state.status,
|
|
59
|
+
fetchStatus: query.state.fetchStatus,
|
|
60
|
+
fetchMeta: query.state.fetchMeta,
|
|
61
|
+
dataUpdatedAt: query.state.dataUpdatedAt,
|
|
62
|
+
errorUpdatedAt: query.state.errorUpdatedAt,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
client.send('sync-query-event', {
|
|
66
|
+
type: 'updated',
|
|
67
|
+
action: 'fetch',
|
|
68
|
+
data: fetchData,
|
|
69
|
+
});
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
case 'success': {
|
|
74
|
+
// Only need new data and success state
|
|
75
|
+
const successData: PartialQueryState = {
|
|
76
|
+
queryHash: query.queryHash,
|
|
77
|
+
state: {
|
|
78
|
+
status: query.state.status,
|
|
79
|
+
data: query.state.data,
|
|
80
|
+
dataUpdatedAt: query.state.dataUpdatedAt,
|
|
81
|
+
error: query.state.error,
|
|
82
|
+
errorUpdatedAt: query.state.errorUpdatedAt,
|
|
83
|
+
fetchStatus: query.state.fetchStatus,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
client.send('sync-query-event', {
|
|
87
|
+
type: 'updated',
|
|
88
|
+
action: 'success',
|
|
89
|
+
data: successData,
|
|
90
|
+
});
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
case 'error': {
|
|
95
|
+
// Only need error information
|
|
96
|
+
const errorData: PartialQueryState = {
|
|
97
|
+
queryHash: query.queryHash,
|
|
98
|
+
state: {
|
|
99
|
+
status: query.state.status,
|
|
100
|
+
error: query.state.error,
|
|
101
|
+
errorUpdatedAt: query.state.errorUpdatedAt,
|
|
102
|
+
fetchStatus: query.state.fetchStatus,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
client.send('sync-query-event', {
|
|
106
|
+
type: 'updated',
|
|
107
|
+
action: 'error',
|
|
108
|
+
data: errorData,
|
|
109
|
+
});
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
case 'setState': {
|
|
114
|
+
// Only need the specific state changes
|
|
115
|
+
const setStateData: PartialQueryState = {
|
|
116
|
+
queryHash: query.queryHash,
|
|
117
|
+
state: action.state, // Only the changed state parts
|
|
118
|
+
};
|
|
119
|
+
client.send('sync-query-event', {
|
|
120
|
+
type: 'updated',
|
|
121
|
+
action: 'setState',
|
|
122
|
+
data: setStateData,
|
|
123
|
+
});
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
case 'invalidate': {
|
|
128
|
+
// Only need invalidation flag
|
|
129
|
+
const invalidateData: PartialQueryState = {
|
|
130
|
+
queryHash: query.queryHash,
|
|
131
|
+
state: {
|
|
132
|
+
isInvalidated: query.state.isInvalidated,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
client.send('sync-query-event', {
|
|
136
|
+
type: 'updated',
|
|
137
|
+
action: 'invalidate',
|
|
138
|
+
data: invalidateData,
|
|
139
|
+
});
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
case 'pause': {
|
|
144
|
+
// Need to sync the paused fetch status
|
|
145
|
+
const pauseData: PartialQueryState = {
|
|
146
|
+
queryHash: query.queryHash,
|
|
147
|
+
state: {
|
|
148
|
+
fetchStatus: query.state.fetchStatus,
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
client.send('sync-query-event', {
|
|
152
|
+
type: 'updated',
|
|
153
|
+
action: 'pause',
|
|
154
|
+
data: pauseData,
|
|
155
|
+
});
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
case 'continue': {
|
|
160
|
+
// Need to sync the resumed fetch status
|
|
161
|
+
const continueData: PartialQueryState = {
|
|
162
|
+
queryHash: query.queryHash,
|
|
163
|
+
state: {
|
|
164
|
+
fetchStatus: query.state.fetchStatus,
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
client.send('sync-query-event', {
|
|
168
|
+
type: 'updated',
|
|
169
|
+
action: 'continue',
|
|
170
|
+
data: continueData,
|
|
171
|
+
});
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
default: {
|
|
176
|
+
// Fallback to full data for unknown actions
|
|
177
|
+
const dehydratedQuery = dehydrateQuery(query);
|
|
178
|
+
client.send('sync-query-event', { type, data: dehydratedQuery });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (
|
|
185
|
+
type === 'observerAdded' ||
|
|
186
|
+
type === 'observerRemoved' ||
|
|
187
|
+
type === 'observerOptionsUpdated'
|
|
188
|
+
) {
|
|
189
|
+
const dehydratedObservers = dehydrateObservers(query);
|
|
190
|
+
const previousObservers = previousObserversRef.current.get(
|
|
191
|
+
query.queryHash
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
// For observerOptionsUpdated, only send if the observers actually changed
|
|
195
|
+
if (type === 'observerOptionsUpdated' && previousObservers) {
|
|
196
|
+
if (equal(previousObservers, dehydratedObservers)) {
|
|
197
|
+
// No meaningful change, skip sending
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
previousObserversRef.current.set(
|
|
203
|
+
query.queryHash,
|
|
204
|
+
dehydratedObservers
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
client.send('sync-query-event', {
|
|
208
|
+
type,
|
|
209
|
+
data: {
|
|
210
|
+
queryHash: query.queryHash,
|
|
211
|
+
observers: dehydratedObservers,
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const { mutation, type } = event;
|
|
219
|
+
if (mutation) {
|
|
220
|
+
const dehydratedMutation = dehydrateMutation(mutation);
|
|
221
|
+
client.send('sync-mutation-event', {
|
|
222
|
+
type,
|
|
223
|
+
data: dehydratedMutation,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
}, [client]);
|
|
10
228
|
|
|
11
229
|
useEffect(() => {
|
|
12
230
|
if (!client) {
|
|
13
231
|
return;
|
|
14
232
|
}
|
|
15
233
|
|
|
16
|
-
const handler = (): void => {
|
|
17
|
-
const dehydratedState = dehydrateQueryClient(queryClient);
|
|
18
|
-
client.send('sync-data', { data: dehydratedState });
|
|
19
|
-
};
|
|
20
|
-
|
|
21
234
|
const mutationCacheSubscription = queryClient
|
|
22
235
|
.getMutationCache()
|
|
23
236
|
.subscribe(handler);
|
|
@@ -29,5 +242,5 @@ export const useSyncTanStackCache = (
|
|
|
29
242
|
mutationCacheSubscription();
|
|
30
243
|
queryCacheSubscription();
|
|
31
244
|
};
|
|
32
|
-
}, [client, queryClient]);
|
|
245
|
+
}, [client, queryClient, handler]);
|
|
33
246
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
1
2
|
import { useRozeniteDevToolsClient } from '@rozenite/plugin-bridge';
|
|
2
3
|
import { TanStackQueryPluginEventMap } from '../shared/messaging';
|
|
3
4
|
import { useSyncOnlineStatus } from '../shared/useSyncOnlineStatus';
|
|
@@ -5,16 +6,16 @@ import { useHandleDevToolsMessages } from './useHandleDevToolsMessages';
|
|
|
5
6
|
import { useSyncTanStackCache } from './useSyncTanStackCache';
|
|
6
7
|
import { useHandleInitialData } from './useHandleInitialData';
|
|
7
8
|
|
|
8
|
-
export const useTanStackQueryDevTools = () => {
|
|
9
|
+
export const useTanStackQueryDevTools = (queryClient: QueryClient) => {
|
|
9
10
|
const client = useRozeniteDevToolsClient<TanStackQueryPluginEventMap>({
|
|
10
11
|
pluginId: '@rozenite/tanstack-query-plugin',
|
|
11
12
|
});
|
|
12
13
|
|
|
13
14
|
useSyncOnlineStatus(client);
|
|
14
15
|
|
|
15
|
-
useHandleDevToolsMessages(client);
|
|
16
|
+
useHandleDevToolsMessages(queryClient, client);
|
|
16
17
|
|
|
17
|
-
useSyncTanStackCache(client);
|
|
18
|
+
useSyncTanStackCache(queryClient, client);
|
|
18
19
|
|
|
19
|
-
useHandleInitialData(client);
|
|
20
|
+
useHandleInitialData(queryClient, client);
|
|
20
21
|
};
|
package/src/shared/dehydrate.ts
CHANGED
|
@@ -6,13 +6,15 @@ import type {
|
|
|
6
6
|
SerializableQueryClient,
|
|
7
7
|
} from './types';
|
|
8
8
|
|
|
9
|
+
export const dehydrateObservers = (query: Query): SerializableObserver[] => {
|
|
10
|
+
return query.observers.map((observer) => ({
|
|
11
|
+
queryHash: query.queryHash,
|
|
12
|
+
options: observer.options,
|
|
13
|
+
}));
|
|
14
|
+
};
|
|
15
|
+
|
|
9
16
|
export const dehydrateQuery = (query: Query): SerializableQuery => {
|
|
10
|
-
const dehydratedObservers: SerializableObserver[] = query
|
|
11
|
-
(observer) => ({
|
|
12
|
-
queryHash: query.queryHash,
|
|
13
|
-
options: observer.options,
|
|
14
|
-
})
|
|
15
|
-
);
|
|
17
|
+
const dehydratedObservers: SerializableObserver[] = dehydrateObservers(query);
|
|
16
18
|
|
|
17
19
|
return {
|
|
18
20
|
state: query.state,
|