@rozenite/tanstack-query-plugin 2.0.0 → 2.1.0
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/CHANGELOG.md +13 -0
- package/dist/devtools/assets/{CXEL7IU7-BtfXID7a.js → CXEL7IU7-BWccRGN3.js} +1 -1
- package/dist/devtools/assets/{tanstack-query-OfMbjvWS.js → tanstack-query-CbF_imft.js} +9 -9
- package/dist/devtools/tanstack-query.html +1 -1
- package/dist/react-native/chunks/useTanStackQueryDevTools.require.cjs +1 -1
- package/dist/react-native/chunks/useTanStackQueryDevTools.require.js +48 -94
- package/dist/rozenite.json +1 -1
- package/dist/sdk/index.js +17 -21
- package/package.json +28 -28
- package/src/react-native/agent/__tests__/tanstack-query-agent.test.ts +15 -38
- package/src/react-native/agent/tanstack-query-agent.ts +29 -96
- package/src/react-native/agent/useTanStackQueryAgentTools.ts +1 -4
- package/src/react-native/devtools-actions.ts +3 -10
- package/src/react-native/useHandleDevToolsMessages.ts +12 -16
- package/src/react-native/useHandleInitialData.ts +7 -0
- package/src/react-native/useSyncTanStackCache.ts +6 -21
- package/src/shared/agent-tools.ts +34 -66
- package/src/shared/dehydrate.ts +1 -3
- package/src/shared/hydrate.ts +11 -21
- package/src/shared/messaging.ts +8 -2
- package/src/shared/query-data-sync.test.ts +1 -5
- package/src/shared/query-data-sync.ts +8 -35
- package/src/shared/useSyncOnlineStatus.ts +4 -9
- package/src/ui/useHandleSyncMessages.ts +27 -35
- package/src/ui/useSyncDevToolsEvents.ts +4 -13
- package/src/ui/useSyncInitialData.test.tsx +76 -0
- package/src/ui/useSyncInitialData.ts +17 -4
- package/vite.config.ts +1 -4
package/src/shared/hydrate.ts
CHANGED
|
@@ -49,26 +49,24 @@ const hydrateObservers = (
|
|
|
49
49
|
|
|
50
50
|
hydratedOptions.queryFn = mockQueryFn;
|
|
51
51
|
|
|
52
|
-
const observer = new QueryObserver(
|
|
53
|
-
client,
|
|
54
|
-
hydratedOptions as QueryObserverOptions,
|
|
55
|
-
);
|
|
52
|
+
const observer = new QueryObserver(client, hydratedOptions as QueryObserverOptions);
|
|
56
53
|
query.addObserver(observer);
|
|
57
54
|
});
|
|
58
55
|
};
|
|
59
56
|
|
|
60
|
-
const hydrateMutation = (
|
|
61
|
-
client: QueryClient,
|
|
62
|
-
dehydratedMutation: SerializableMutation,
|
|
63
|
-
) => {
|
|
57
|
+
const hydrateMutation = (client: QueryClient, dehydratedMutation: SerializableMutation) => {
|
|
64
58
|
const mutationCache = client.getMutationCache();
|
|
65
59
|
const { options, state } = dehydratedMutation;
|
|
66
60
|
|
|
67
61
|
const existingMutation = mutationCache.find({
|
|
68
62
|
mutationKey: options.mutationKey,
|
|
69
63
|
});
|
|
70
|
-
const hydratedState: MutationState<unknown, Error, void, unknown> =
|
|
71
|
-
|
|
64
|
+
const hydratedState: MutationState<unknown, Error, void, unknown> = state as MutationState<
|
|
65
|
+
unknown,
|
|
66
|
+
Error,
|
|
67
|
+
void,
|
|
68
|
+
unknown
|
|
69
|
+
>;
|
|
72
70
|
const hydratedOptions: MutationOptions = options;
|
|
73
71
|
|
|
74
72
|
if (existingMutation) {
|
|
@@ -78,10 +76,7 @@ const hydrateMutation = (
|
|
|
78
76
|
mutationCache.build(client, hydratedOptions, hydratedState);
|
|
79
77
|
};
|
|
80
78
|
|
|
81
|
-
const hydrateQuery = (
|
|
82
|
-
client: QueryClient,
|
|
83
|
-
dehydratedQuery: SerializableQuery,
|
|
84
|
-
) => {
|
|
79
|
+
const hydrateQuery = (client: QueryClient, dehydratedQuery: SerializableQuery) => {
|
|
85
80
|
const queryCache = client.getQueryCache();
|
|
86
81
|
const { queryKey, state, queryHash, observers } = dehydratedQuery;
|
|
87
82
|
|
|
@@ -132,9 +127,7 @@ export const hydrateQueryClient = (
|
|
|
132
127
|
dehydratedState: SerializableQueryClient,
|
|
133
128
|
): void => {
|
|
134
129
|
// Hydrate mutations
|
|
135
|
-
dehydratedState.mutations.forEach((mutation) =>
|
|
136
|
-
hydrateMutation(client, mutation),
|
|
137
|
-
);
|
|
130
|
+
dehydratedState.mutations.forEach((mutation) => hydrateMutation(client, mutation));
|
|
138
131
|
|
|
139
132
|
// Hydrate queries
|
|
140
133
|
dehydratedState.queries.forEach((query) => hydrateQuery(client, query));
|
|
@@ -187,10 +180,7 @@ export const applyQueryEvent = (
|
|
|
187
180
|
};
|
|
188
181
|
|
|
189
182
|
// New function to handle action-based partial state updates
|
|
190
|
-
export const applyPartialQueryState = (
|
|
191
|
-
queryClient: QueryClient,
|
|
192
|
-
data: PartialQueryState,
|
|
193
|
-
): void => {
|
|
183
|
+
export const applyPartialQueryState = (queryClient: QueryClient, data: PartialQueryState): void => {
|
|
194
184
|
const queryCache = queryClient.getQueryCache();
|
|
195
185
|
const query = queryCache.get(data.queryHash);
|
|
196
186
|
|
package/src/shared/messaging.ts
CHANGED
|
@@ -19,6 +19,13 @@ export type TanStackQueryPluginEventMap = {
|
|
|
19
19
|
data?: unknown;
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Announced by the device once it is listening for panel messages. The panel
|
|
24
|
+
* is recreated on every app reload and asks for the cache immediately, which
|
|
25
|
+
* can land before the app's React tree has mounted the plugin; this lets the
|
|
26
|
+
* panel ask again instead of staying empty until the app is restarted.
|
|
27
|
+
*/
|
|
28
|
+
'device-ready': unknown;
|
|
22
29
|
'request-initial-data': unknown;
|
|
23
30
|
'sync-data': {
|
|
24
31
|
data: SerializableQueryClient;
|
|
@@ -53,5 +60,4 @@ export type TanStackQueryPluginEventMap = {
|
|
|
53
60
|
};
|
|
54
61
|
};
|
|
55
62
|
|
|
56
|
-
export type TanStackQueryPluginClient =
|
|
57
|
-
RozeniteDevToolsClient<TanStackQueryPluginEventMap>;
|
|
63
|
+
export type TanStackQueryPluginClient = RozeniteDevToolsClient<TanStackQueryPluginEventMap>;
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from 'vitest';
|
|
2
2
|
import { QueryClient } from '@tanstack/react-query';
|
|
3
|
-
import {
|
|
4
|
-
applyRemoteQueryState,
|
|
5
|
-
instrumentQuery,
|
|
6
|
-
instrumentQueryClient,
|
|
7
|
-
} from './query-data-sync';
|
|
3
|
+
import { applyRemoteQueryState, instrumentQuery, instrumentQueryClient } from './query-data-sync';
|
|
8
4
|
|
|
9
5
|
const createQueryClient = () =>
|
|
10
6
|
new QueryClient({
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Query,
|
|
3
|
-
QueryClient,
|
|
4
|
-
QueryKey,
|
|
5
|
-
QueryState,
|
|
6
|
-
} from '@tanstack/react-query';
|
|
1
|
+
import { Query, QueryClient, QueryKey, QueryState } from '@tanstack/react-query';
|
|
7
2
|
|
|
8
3
|
type QuerySetState = Query['setState'];
|
|
9
4
|
type QueryClientSetQueryData = QueryClient['setQueryData'];
|
|
@@ -16,27 +11,17 @@ type SyncQueryDataPayload = {
|
|
|
16
11
|
type QueryDataSyncHandler = (payload: SyncQueryDataPayload) => void;
|
|
17
12
|
|
|
18
13
|
const originalQuerySetStateMap = new WeakMap<Query, QuerySetState>();
|
|
19
|
-
const originalSetQueryDataMap = new WeakMap<
|
|
20
|
-
QueryClient,
|
|
21
|
-
QueryClientSetQueryData
|
|
22
|
-
>();
|
|
14
|
+
const originalSetQueryDataMap = new WeakMap<QueryClient, QueryClientSetQueryData>();
|
|
23
15
|
const instrumentedQueryClients = new WeakSet<QueryClient>();
|
|
24
16
|
const instrumentedQueries = new WeakSet<Query>();
|
|
25
|
-
const queryClientHandlers = new WeakMap<
|
|
26
|
-
QueryClient,
|
|
27
|
-
QueryDataSyncHandler | undefined
|
|
28
|
-
>();
|
|
17
|
+
const queryClientHandlers = new WeakMap<QueryClient, QueryDataSyncHandler | undefined>();
|
|
29
18
|
const queryHandlers = new WeakMap<Query, QueryDataSyncHandler | undefined>();
|
|
30
19
|
|
|
31
20
|
const getOriginalQuerySetState = (query: Query): QuerySetState => {
|
|
32
21
|
return originalQuerySetStateMap.get(query) ?? query.setState.bind(query);
|
|
33
22
|
};
|
|
34
23
|
|
|
35
|
-
const emitIfDataChanged = (
|
|
36
|
-
query: Query,
|
|
37
|
-
previousData: unknown,
|
|
38
|
-
handler?: QueryDataSyncHandler,
|
|
39
|
-
) => {
|
|
24
|
+
const emitIfDataChanged = (query: Query, previousData: unknown, handler?: QueryDataSyncHandler) => {
|
|
40
25
|
if (!handler || Object.is(previousData, query.state.data)) {
|
|
41
26
|
return;
|
|
42
27
|
}
|
|
@@ -47,10 +32,7 @@ const emitIfDataChanged = (
|
|
|
47
32
|
});
|
|
48
33
|
};
|
|
49
34
|
|
|
50
|
-
const isDataOnlyStateUpdate = (
|
|
51
|
-
previousState: QueryState,
|
|
52
|
-
nextState: Partial<QueryState>,
|
|
53
|
-
) => {
|
|
35
|
+
const isDataOnlyStateUpdate = (previousState: QueryState, nextState: Partial<QueryState>) => {
|
|
54
36
|
if (!('data' in nextState)) {
|
|
55
37
|
return false;
|
|
56
38
|
}
|
|
@@ -63,18 +45,12 @@ const isDataOnlyStateUpdate = (
|
|
|
63
45
|
return changedKeys.every((key) => key === 'data');
|
|
64
46
|
};
|
|
65
47
|
|
|
66
|
-
export const applyRemoteQueryState = (
|
|
67
|
-
query: Query,
|
|
68
|
-
state: Partial<QueryState>,
|
|
69
|
-
) => {
|
|
48
|
+
export const applyRemoteQueryState = (query: Query, state: Partial<QueryState>) => {
|
|
70
49
|
const originalSetState = getOriginalQuerySetState(query);
|
|
71
50
|
originalSetState(state);
|
|
72
51
|
};
|
|
73
52
|
|
|
74
|
-
export const instrumentQuery = (
|
|
75
|
-
query: Query,
|
|
76
|
-
handler?: QueryDataSyncHandler,
|
|
77
|
-
) => {
|
|
53
|
+
export const instrumentQuery = (query: Query, handler?: QueryDataSyncHandler) => {
|
|
78
54
|
queryHandlers.set(query, handler);
|
|
79
55
|
|
|
80
56
|
if (instrumentedQueries.has(query)) {
|
|
@@ -104,10 +80,7 @@ const resolveQueryHash = (queryClient: QueryClient, queryKey: QueryKey) => {
|
|
|
104
80
|
return queryClient.getQueryCache().find({ queryKey })?.queryHash;
|
|
105
81
|
};
|
|
106
82
|
|
|
107
|
-
export const instrumentQueryClient = (
|
|
108
|
-
queryClient: QueryClient,
|
|
109
|
-
handler?: QueryDataSyncHandler,
|
|
110
|
-
) => {
|
|
83
|
+
export const instrumentQueryClient = (queryClient: QueryClient, handler?: QueryDataSyncHandler) => {
|
|
111
84
|
queryClientHandlers.set(queryClient, handler);
|
|
112
85
|
|
|
113
86
|
if (instrumentedQueryClients.has(queryClient)) {
|
|
@@ -2,9 +2,7 @@ import { useEffect } from 'react';
|
|
|
2
2
|
import { onlineManager } from '@tanstack/react-query';
|
|
3
3
|
import { TanStackQueryPluginClient } from './messaging';
|
|
4
4
|
|
|
5
|
-
export const useSyncOnlineStatus = (
|
|
6
|
-
client: TanStackQueryPluginClient | null,
|
|
7
|
-
) => {
|
|
5
|
+
export const useSyncOnlineStatus = (client: TanStackQueryPluginClient | null) => {
|
|
8
6
|
useEffect(() => {
|
|
9
7
|
if (!client) {
|
|
10
8
|
return;
|
|
@@ -14,12 +12,9 @@ export const useSyncOnlineStatus = (
|
|
|
14
12
|
client.send('online-status-changed', { online });
|
|
15
13
|
});
|
|
16
14
|
|
|
17
|
-
const onlineMessageSubscription = client.onMessage(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
onlineManager.setOnline(online);
|
|
21
|
-
},
|
|
22
|
-
);
|
|
15
|
+
const onlineMessageSubscription = client.onMessage('online-status-changed', ({ online }) => {
|
|
16
|
+
onlineManager.setOnline(online);
|
|
17
|
+
});
|
|
23
18
|
|
|
24
19
|
return () => {
|
|
25
20
|
onlineManagerSubscription();
|
|
@@ -8,9 +8,7 @@ import {
|
|
|
8
8
|
applyQueryObserverEvent,
|
|
9
9
|
} from '../shared/hydrate';
|
|
10
10
|
|
|
11
|
-
export const useHandleSyncMessages = (
|
|
12
|
-
client: TanStackQueryPluginClient | null,
|
|
13
|
-
) => {
|
|
11
|
+
export const useHandleSyncMessages = (client: TanStackQueryPluginClient | null) => {
|
|
14
12
|
const queryClient = useQueryClient();
|
|
15
13
|
|
|
16
14
|
useEffect(() => {
|
|
@@ -18,39 +16,33 @@ export const useHandleSyncMessages = (
|
|
|
18
16
|
return;
|
|
19
17
|
}
|
|
20
18
|
|
|
21
|
-
const querySubscription = client.onMessage(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
);
|
|
19
|
+
const querySubscription = client.onMessage('sync-query-event', (message) => {
|
|
20
|
+
const { type, data } = message;
|
|
21
|
+
|
|
22
|
+
if (type === 'added' || type === 'removed') {
|
|
23
|
+
applyQueryEvent(queryClient, type, data);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (type === 'updated') {
|
|
28
|
+
const action = 'action' in message ? message.action : undefined;
|
|
29
|
+
applyQueryEvent(queryClient, type, data, action);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (
|
|
34
|
+
type === 'observerAdded' ||
|
|
35
|
+
type === 'observerRemoved' ||
|
|
36
|
+
type === 'observerOptionsUpdated'
|
|
37
|
+
) {
|
|
38
|
+
applyQueryObserverEvent(queryClient, data);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
47
42
|
|
|
48
|
-
const mutationSubscription = client.onMessage(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
applyMutationEvent(queryClient, type, data);
|
|
52
|
-
},
|
|
53
|
-
);
|
|
43
|
+
const mutationSubscription = client.onMessage('sync-mutation-event', ({ type, data }) => {
|
|
44
|
+
applyMutationEvent(queryClient, type, data);
|
|
45
|
+
});
|
|
54
46
|
|
|
55
47
|
// Keep the full sync for initial data requests
|
|
56
48
|
const fullSyncSubscription = client.onMessage('sync-data', ({ data }) => {
|
|
@@ -2,9 +2,7 @@ import { useQueryClient } from '@tanstack/react-query';
|
|
|
2
2
|
import { useEffect } from 'react';
|
|
3
3
|
import { TanStackQueryPluginClient } from '../shared/messaging';
|
|
4
4
|
|
|
5
|
-
export const useSyncDevToolsEvents = (
|
|
6
|
-
client: TanStackQueryPluginClient | null,
|
|
7
|
-
) => {
|
|
5
|
+
export const useSyncDevToolsEvents = (client: TanStackQueryPluginClient | null) => {
|
|
8
6
|
const queryClient = useQueryClient();
|
|
9
7
|
|
|
10
8
|
useEffect(() => {
|
|
@@ -17,14 +15,8 @@ export const useSyncDevToolsEvents = (
|
|
|
17
15
|
const { type, queryHash } = detail;
|
|
18
16
|
|
|
19
17
|
// Get the query from cache if we have a hash
|
|
20
|
-
const query = queryHash
|
|
21
|
-
|
|
22
|
-
: undefined;
|
|
23
|
-
if (
|
|
24
|
-
!query &&
|
|
25
|
-
type !== 'CLEAR_QUERY_CACHE' &&
|
|
26
|
-
type !== 'CLEAR_MUTATION_CACHE'
|
|
27
|
-
) {
|
|
18
|
+
const query = queryHash ? queryClient.getQueryCache().get(queryHash) : undefined;
|
|
19
|
+
if (!query && type !== 'CLEAR_QUERY_CACHE' && type !== 'CLEAR_MUTATION_CACHE') {
|
|
28
20
|
return;
|
|
29
21
|
}
|
|
30
22
|
|
|
@@ -49,7 +41,6 @@ export const useSyncDevToolsEvents = (
|
|
|
49
41
|
};
|
|
50
42
|
|
|
51
43
|
window.addEventListener('@tanstack/query-devtools-event', handleEvent);
|
|
52
|
-
return () =>
|
|
53
|
-
window.removeEventListener('@tanstack/query-devtools-event', handleEvent);
|
|
44
|
+
return () => window.removeEventListener('@tanstack/query-devtools-event', handleEvent);
|
|
54
45
|
}, [client]);
|
|
55
46
|
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
|
|
3
|
+
import { act, type ReactNode } from 'react';
|
|
4
|
+
import { createRoot } from 'react-dom/client';
|
|
5
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
+
import { TanStackQueryPluginClient } from '../shared/messaging';
|
|
8
|
+
import { useSyncInitialData } from './useSyncInitialData';
|
|
9
|
+
|
|
10
|
+
declare global {
|
|
11
|
+
var IS_REACT_ACT_ENVIRONMENT: boolean | undefined;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type Listener = (payload: unknown) => void;
|
|
15
|
+
|
|
16
|
+
const createClient = () => {
|
|
17
|
+
const listeners = new Map<string, Set<Listener>>();
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
send: vi.fn(),
|
|
21
|
+
onMessage: vi.fn((type: string, listener: Listener) => {
|
|
22
|
+
const typeListeners = listeners.get(type) ?? new Set<Listener>();
|
|
23
|
+
typeListeners.add(listener);
|
|
24
|
+
listeners.set(type, typeListeners);
|
|
25
|
+
return { remove: () => typeListeners.delete(listener) };
|
|
26
|
+
}),
|
|
27
|
+
close: vi.fn(),
|
|
28
|
+
emit: (type: string, payload: unknown) =>
|
|
29
|
+
listeners.get(type)?.forEach((listener) => listener(payload)),
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const requests = (client: ReturnType<typeof createClient>) =>
|
|
34
|
+
client.send.mock.calls.filter(([type]) => type === 'request-initial-data');
|
|
35
|
+
|
|
36
|
+
describe('useSyncInitialData', () => {
|
|
37
|
+
beforeEach(() => {
|
|
38
|
+
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
|
|
39
|
+
});
|
|
40
|
+
afterEach(() => {
|
|
41
|
+
document.body.innerHTML = '';
|
|
42
|
+
delete globalThis.IS_REACT_ACT_ENVIRONMENT;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// The panel is recreated on every app reload and asks for the cache before the
|
|
46
|
+
// app's React tree has mounted the plugin, so its first request is dropped.
|
|
47
|
+
it('asks for the cache again when the device announces itself', async () => {
|
|
48
|
+
const client = createClient();
|
|
49
|
+
const queryClient = new QueryClient();
|
|
50
|
+
queryClient.setQueryData(['stale-from-previous-context'], 'value');
|
|
51
|
+
|
|
52
|
+
const Harness = ({ children }: { children?: ReactNode }) => {
|
|
53
|
+
useSyncInitialData(client as unknown as TanStackQueryPluginClient);
|
|
54
|
+
return <>{children}</>;
|
|
55
|
+
};
|
|
56
|
+
const container = document.createElement('div');
|
|
57
|
+
document.body.append(container);
|
|
58
|
+
const root = createRoot(container);
|
|
59
|
+
await act(async () =>
|
|
60
|
+
root.render(
|
|
61
|
+
<QueryClientProvider client={queryClient}>
|
|
62
|
+
<Harness />
|
|
63
|
+
</QueryClientProvider>,
|
|
64
|
+
),
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
expect(requests(client)).toHaveLength(1);
|
|
68
|
+
|
|
69
|
+
await act(async () => client.emit('device-ready', {}));
|
|
70
|
+
|
|
71
|
+
expect(requests(client)).toHaveLength(2);
|
|
72
|
+
expect(queryClient.getQueryData(['stale-from-previous-context'])).toBeUndefined();
|
|
73
|
+
|
|
74
|
+
await act(async () => root.unmount());
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
2
3
|
import { TanStackQueryPluginClient } from '../shared/messaging';
|
|
3
4
|
|
|
4
|
-
export const useSyncInitialData = (
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
export const useSyncInitialData = (client: TanStackQueryPluginClient | null) => {
|
|
6
|
+
const queryClient = useQueryClient();
|
|
7
|
+
|
|
7
8
|
useEffect(() => {
|
|
8
9
|
if (!client) {
|
|
9
10
|
return;
|
|
10
11
|
}
|
|
11
12
|
|
|
13
|
+
// The device announces itself once it is listening. It reconnects on every
|
|
14
|
+
// app reload, so the cache has to be pulled again — what the panel holds
|
|
15
|
+
// belongs to the previous JS context.
|
|
16
|
+
const subscription = client.onMessage('device-ready', () => {
|
|
17
|
+
queryClient.clear();
|
|
18
|
+
client.send('request-initial-data', {});
|
|
19
|
+
});
|
|
20
|
+
|
|
12
21
|
client.send('request-initial-data', {});
|
|
13
|
-
|
|
22
|
+
|
|
23
|
+
return () => {
|
|
24
|
+
subscription.remove();
|
|
25
|
+
};
|
|
26
|
+
}, [client, queryClient]);
|
|
14
27
|
};
|
package/vite.config.ts
CHANGED
|
@@ -9,10 +9,7 @@ export default defineConfig({
|
|
|
9
9
|
test: {
|
|
10
10
|
passWithNoTests: true,
|
|
11
11
|
alias: {
|
|
12
|
-
'@rozenite/agent-shared': resolve(
|
|
13
|
-
__dirname,
|
|
14
|
-
'../agent-shared/src/index.ts',
|
|
15
|
-
),
|
|
12
|
+
'@rozenite/agent-shared': resolve(__dirname, '../agent-shared/src/index.ts'),
|
|
16
13
|
},
|
|
17
14
|
},
|
|
18
15
|
base: './',
|