@buoy-gg/zustand 7.0.33 → 7.0.34
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/lib/commonjs/zustand/components/ZustandDetailViewToggle.js +13 -107
- package/lib/commonjs/zustand/components/ZustandEventFilterView.js +24 -288
- package/lib/commonjs/zustand/components/ZustandModal.js +20 -85
- package/lib/commonjs/zustand/components/ZustandStateChangeItem.js +8 -61
- package/lib/commonjs/zustand/components/ZustandStateInfoView.js +2 -46
- package/lib/commonjs/zustand/hooks/useZustandStateChanges.js +33 -53
- package/lib/commonjs/zustand/sync/zustandSyncAdapter.js +24 -78
- package/lib/commonjs/zustand/utils/snapshotProvider.js +17 -60
- package/lib/commonjs/zustand/utils/zustandStateStore.js +37 -223
- package/lib/module/zustand/components/ZustandDetailViewToggle.js +15 -109
- package/lib/module/zustand/components/ZustandEventFilterView.js +28 -292
- package/lib/module/zustand/components/ZustandModal.js +22 -87
- package/lib/module/zustand/components/ZustandStateChangeItem.js +10 -63
- package/lib/module/zustand/components/ZustandStateInfoView.js +1 -45
- package/lib/module/zustand/hooks/useZustandStateChanges.js +34 -54
- package/lib/module/zustand/sync/zustandSyncAdapter.js +25 -79
- package/lib/module/zustand/utils/snapshotProvider.js +18 -61
- package/lib/module/zustand/utils/zustandStateStore.js +37 -223
- package/lib/typescript/zustand/components/ZustandDetailViewToggle.d.ts +2 -1
- package/lib/typescript/zustand/components/ZustandDetailViewToggle.d.ts.map +1 -1
- package/lib/typescript/zustand/components/ZustandEventFilterView.d.ts +6 -0
- package/lib/typescript/zustand/components/ZustandEventFilterView.d.ts.map +1 -1
- package/lib/typescript/zustand/components/ZustandModal.d.ts.map +1 -1
- package/lib/typescript/zustand/components/ZustandStateChangeItem.d.ts.map +1 -1
- package/lib/typescript/zustand/components/ZustandStateInfoView.d.ts.map +1 -1
- package/lib/typescript/zustand/hooks/useZustandStateChanges.d.ts +2 -1
- package/lib/typescript/zustand/hooks/useZustandStateChanges.d.ts.map +1 -1
- package/lib/typescript/zustand/sync/zustandSyncAdapter.d.ts +103 -117
- package/lib/typescript/zustand/sync/zustandSyncAdapter.d.ts.map +1 -1
- package/lib/typescript/zustand/utils/zustandStateStore.d.ts +6 -26
- package/lib/typescript/zustand/utils/zustandStateStore.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -3,51 +3,39 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Hook for consuming Zustand state changes from the store
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* The subscribe / filter / pause / clear plumbing is shared `useChangeLog`;
|
|
7
|
+
* this file owns the zustand-specific filter, stats and store registry.
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
|
-
import {
|
|
10
|
+
import { useCallback, useMemo } from "react";
|
|
11
|
+
import { useChangeLog, useSubscribedValue } from "@buoy-gg/shared-ui";
|
|
10
12
|
import { zustandStateStore } from "../utils/zustandStateStore";
|
|
13
|
+
function filterChanges(changes, filter) {
|
|
14
|
+
let filtered = changes;
|
|
15
|
+
if (filter.searchText) {
|
|
16
|
+
const search = filter.searchText.toLowerCase();
|
|
17
|
+
filtered = filtered.filter(c => c.storeName.toLowerCase().includes(search) || c.partialPreview.toLowerCase().includes(search) || c.changedKeys.some(k => k.toLowerCase().includes(search)));
|
|
18
|
+
}
|
|
19
|
+
if (filter.storeNames && filter.storeNames.length > 0) {
|
|
20
|
+
filtered = filtered.filter(c => filter.storeNames.includes(c.storeName));
|
|
21
|
+
}
|
|
22
|
+
if (filter.onlyWithChanges) {
|
|
23
|
+
filtered = filtered.filter(c => c.hasStateChange);
|
|
24
|
+
}
|
|
25
|
+
return filtered;
|
|
26
|
+
}
|
|
27
|
+
const readStores = () => zustandStateStore.getStores();
|
|
28
|
+
const subscribeToStores = listener => zustandStateStore.subscribeToStores(listener);
|
|
11
29
|
export function useZustandStateChanges() {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
// Subscribe to state changes
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
const unsubChanges = zustandStateStore.subscribe(newChanges => {
|
|
20
|
-
setStateChanges(newChanges);
|
|
21
|
-
});
|
|
22
|
-
const unsubStores = zustandStateStore.subscribeToStores(newStores => {
|
|
23
|
-
setStores(newStores);
|
|
24
|
-
});
|
|
25
|
-
return () => {
|
|
26
|
-
unsubChanges();
|
|
27
|
-
unsubStores();
|
|
28
|
-
};
|
|
29
|
-
}, []);
|
|
30
|
-
|
|
31
|
-
// Filter state changes — derive directly from state to avoid stale reads
|
|
32
|
-
const filteredChanges = useMemo(() => {
|
|
33
|
-
let filtered = stateChanges;
|
|
34
|
-
if (filter.searchText) {
|
|
35
|
-
const search = filter.searchText.toLowerCase();
|
|
36
|
-
filtered = filtered.filter(c => c.storeName.toLowerCase().includes(search) || c.partialPreview.toLowerCase().includes(search) || c.changedKeys.some(k => k.toLowerCase().includes(search)));
|
|
37
|
-
}
|
|
38
|
-
if (filter.storeNames && filter.storeNames.length > 0) {
|
|
39
|
-
filtered = filtered.filter(c => filter.storeNames.includes(c.storeName));
|
|
40
|
-
}
|
|
41
|
-
if (filter.onlyWithChanges) {
|
|
42
|
-
filtered = filtered.filter(c => c.hasStateChange);
|
|
43
|
-
}
|
|
44
|
-
return filtered;
|
|
45
|
-
}, [stateChanges, filter]);
|
|
30
|
+
const log = useChangeLog(zustandStateStore, {
|
|
31
|
+
filterItems: filterChanges
|
|
32
|
+
});
|
|
33
|
+
const stores = useSubscribedValue(readStores, subscribeToStores);
|
|
46
34
|
|
|
47
35
|
// Get stats — derive directly from state
|
|
48
36
|
const stats = useMemo(() => {
|
|
49
|
-
const total =
|
|
50
|
-
const withChanges =
|
|
37
|
+
const total = log.items.length;
|
|
38
|
+
const withChanges = log.items.filter(c => c.hasStateChange).length;
|
|
51
39
|
return {
|
|
52
40
|
totalChanges: total,
|
|
53
41
|
changesWithStateChange: withChanges,
|
|
@@ -55,33 +43,25 @@ export function useZustandStateChanges() {
|
|
|
55
43
|
storeCount: stores.length,
|
|
56
44
|
averageDuration: 0
|
|
57
45
|
};
|
|
58
|
-
}, [
|
|
46
|
+
}, [log.items, stores]);
|
|
59
47
|
|
|
60
48
|
// Get unique store names
|
|
61
49
|
const storeNames = useMemo(() => {
|
|
62
50
|
return zustandStateStore.getUniqueStoreNames();
|
|
63
51
|
}, [stores]);
|
|
64
|
-
const clearChanges = useCallback(() => {
|
|
65
|
-
zustandStateStore.clearStateChanges();
|
|
66
|
-
}, []);
|
|
67
|
-
const toggleCapture = useCallback(() => {
|
|
68
|
-
const newEnabled = !isEnabled;
|
|
69
|
-
zustandStateStore.setEnabled(newEnabled);
|
|
70
|
-
setIsEnabled(newEnabled);
|
|
71
|
-
}, [isEnabled]);
|
|
72
52
|
const getChangeById = useCallback(id => {
|
|
73
53
|
return zustandStateStore.getStateChangeById(id);
|
|
74
54
|
}, []);
|
|
75
55
|
return {
|
|
76
|
-
stateChanges,
|
|
77
|
-
filteredChanges,
|
|
78
|
-
filter,
|
|
79
|
-
setFilter,
|
|
56
|
+
stateChanges: log.items,
|
|
57
|
+
filteredChanges: log.filteredItems,
|
|
58
|
+
filter: log.filter,
|
|
59
|
+
setFilter: log.setFilter,
|
|
80
60
|
stats,
|
|
81
61
|
stores,
|
|
82
|
-
clearChanges,
|
|
83
|
-
isEnabled,
|
|
84
|
-
toggleCapture,
|
|
62
|
+
clearChanges: log.clear,
|
|
63
|
+
isEnabled: log.isEnabled,
|
|
64
|
+
toggleCapture: log.toggleCapture,
|
|
85
65
|
storeNames,
|
|
86
66
|
getChangeById
|
|
87
67
|
};
|
|
@@ -1,25 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { zustandStateStore } from "../utils/zustandStateStore";
|
|
4
|
-
import { isJsonSerializable, isOverWireBudget } from "@buoy-gg/shared-ui";
|
|
4
|
+
import { WIRE_DETAIL_LIMIT_BYTES, createSyncAdapter, detailByIdAction, isJsonSerializable, isOverWireBudget, memoByIdentity, onDeviceMarker, readParams, toWire, truncatedNote } from "@buoy-gg/shared-ui";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Sentinel used in WIRE-FORM snapshots in place of raw prevState/nextState.
|
|
8
8
|
* Same hazard as redux: up to 200 changes × 2 full trees on every snapshot
|
|
9
9
|
* freeze/OOM-killed large apps. Dashboards fetch trees via `getChangeDetail`.
|
|
10
10
|
*/
|
|
11
|
-
export const STATE_ON_DEVICE =
|
|
12
|
-
__buoyStateOnDevice: true,
|
|
13
|
-
note: "State trees stay on the device — fetched on demand via getChangeDetail / getStoreState."
|
|
14
|
-
});
|
|
11
|
+
export const STATE_ON_DEVICE = onDeviceMarker("State", "State trees stay on the device — fetched on demand via getChangeDetail / getStoreState.");
|
|
15
12
|
|
|
16
13
|
/** Wire-form sentinel for an oversized `partial` (replace can carry a whole tree). */
|
|
17
|
-
export const PAYLOAD_ON_DEVICE =
|
|
18
|
-
__buoyPayloadOnDevice: true,
|
|
19
|
-
note: "Partial stays on the device — fetched on demand via getChangeDetail."
|
|
20
|
-
});
|
|
21
|
-
const MAX_CHANGE_DETAIL_BYTES = 8 * 1024 * 1024;
|
|
22
|
-
const MAX_WIRE_PAYLOAD_BYTES = 16 * 1024;
|
|
14
|
+
export const PAYLOAD_ON_DEVICE = onDeviceMarker("Payload", "Partial stays on the device — fetched on demand via getChangeDetail.");
|
|
23
15
|
/** Top-level keys of an object state, for the compact (no-values) view. */
|
|
24
16
|
function topLevelKeys(state) {
|
|
25
17
|
return state && typeof state === "object" && !Array.isArray(state) ? Object.keys(state) : undefined;
|
|
@@ -30,31 +22,17 @@ function topLevelKeys(state) {
|
|
|
30
22
|
* change, so keying on identity is correct and self-invalidating — without it
|
|
31
23
|
* every `partial` in the list is re-measured on all ~5 snapshots per second.
|
|
32
24
|
*/
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
nextState: STATE_ON_DEVICE,
|
|
41
|
-
partial: toWirePartial(change.partial)
|
|
42
|
-
};
|
|
43
|
-
changeCache.set(change, wire);
|
|
44
|
-
return wire;
|
|
45
|
-
}
|
|
46
|
-
function toWirePartial(value) {
|
|
47
|
-
if (value === undefined) return value;
|
|
48
|
-
return isOverWireBudget(value, MAX_WIRE_PAYLOAD_BYTES) ? PAYLOAD_ON_DEVICE : value;
|
|
49
|
-
}
|
|
50
|
-
function toWireState(value) {
|
|
51
|
-
return isOverWireBudget(value, MAX_WIRE_PAYLOAD_BYTES) ? STATE_ON_DEVICE : value;
|
|
52
|
-
}
|
|
25
|
+
const toWireChange = memoByIdentity(change => ({
|
|
26
|
+
...change,
|
|
27
|
+
prevState: STATE_ON_DEVICE,
|
|
28
|
+
nextState: STATE_ON_DEVICE,
|
|
29
|
+
partial: toWire(change.partial, PAYLOAD_ON_DEVICE)
|
|
30
|
+
}));
|
|
31
|
+
const toWireState = value => toWire(value, STATE_ON_DEVICE);
|
|
53
32
|
|
|
54
33
|
/**
|
|
55
34
|
* Sync adapter for the zustand tool, consumed by @buoy-gg/external-sync's
|
|
56
|
-
* `useExternalSync
|
|
57
|
-
* this package doesn't need a dependency on it).
|
|
35
|
+
* `useExternalSync`.
|
|
58
36
|
*
|
|
59
37
|
* State changes are captured by the middleware (watchStores/buoyDevTools),
|
|
60
38
|
* independent of whether a dashboard is watching — subscribing here only
|
|
@@ -69,7 +47,7 @@ function toWireState(value) {
|
|
|
69
47
|
*
|
|
70
48
|
* The `setState` action powers remote time-travel/reset from the dashboard.
|
|
71
49
|
*/
|
|
72
|
-
export const zustandSyncAdapter = {
|
|
50
|
+
export const zustandSyncAdapter = createSyncAdapter({
|
|
73
51
|
version: 2,
|
|
74
52
|
getSnapshot: () => ({
|
|
75
53
|
changes: zustandStateStore.getStateChanges().map(toWireChange),
|
|
@@ -78,14 +56,7 @@ export const zustandSyncAdapter = {
|
|
|
78
56
|
currentState: toWireState(store.currentState)
|
|
79
57
|
}))
|
|
80
58
|
}),
|
|
81
|
-
subscribe: onChange =>
|
|
82
|
-
const unsubscribeChanges = zustandStateStore.subscribe(onChange);
|
|
83
|
-
const unsubscribeStores = zustandStateStore.subscribeToStores(onChange);
|
|
84
|
-
return () => {
|
|
85
|
-
unsubscribeChanges();
|
|
86
|
-
unsubscribeStores();
|
|
87
|
-
};
|
|
88
|
-
},
|
|
59
|
+
subscribe: [onChange => zustandStateStore.subscribe(onChange), onChange => zustandStateStore.subscribeToStores(onChange)],
|
|
89
60
|
actions: {
|
|
90
61
|
clearEvents: () => {
|
|
91
62
|
zustandStateStore.clearStateChanges();
|
|
@@ -95,32 +66,11 @@ export const zustandSyncAdapter = {
|
|
|
95
66
|
* The per-snapshot stream stays tree-free; this is the explicit,
|
|
96
67
|
* size-guarded channel for the detail pane.
|
|
97
68
|
*/
|
|
98
|
-
getChangeDetail:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
found: false,
|
|
104
|
-
reason: "missing id"
|
|
105
|
-
};
|
|
106
|
-
const change = zustandStateStore.getStateChangeById(id);
|
|
107
|
-
if (!change) return {
|
|
108
|
-
found: false,
|
|
109
|
-
reason: "unknown id"
|
|
110
|
-
};
|
|
111
|
-
const cappedNote = {
|
|
112
|
-
__buoyTruncated: true,
|
|
113
|
-
note: `Exceeds the ${MAX_CHANGE_DETAIL_BYTES / (1024 * 1024)}MB detail limit — inspect it on-device.`
|
|
114
|
-
};
|
|
115
|
-
const cap = value => isOverWireBudget(value, MAX_CHANGE_DETAIL_BYTES) ? cappedNote : value;
|
|
116
|
-
return {
|
|
117
|
-
found: true,
|
|
118
|
-
id,
|
|
119
|
-
prevState: cap(change.prevState),
|
|
120
|
-
nextState: cap(change.nextState),
|
|
121
|
-
partial: cap(change.partial)
|
|
122
|
-
};
|
|
123
|
-
},
|
|
69
|
+
getChangeDetail: detailByIdAction(id => zustandStateStore.getStateChangeById(id), (change, cap) => ({
|
|
70
|
+
prevState: cap(change.prevState),
|
|
71
|
+
nextState: cap(change.nextState),
|
|
72
|
+
partial: cap(change.partial)
|
|
73
|
+
})),
|
|
124
74
|
/**
|
|
125
75
|
* On-demand current state for one store. Wire-form snapshots replace
|
|
126
76
|
* oversized / unserializable `currentState` with STATE_ON_DEVICE.
|
|
@@ -128,7 +78,7 @@ export const zustandSyncAdapter = {
|
|
|
128
78
|
getStoreState: params => {
|
|
129
79
|
const {
|
|
130
80
|
storeName
|
|
131
|
-
} = params
|
|
81
|
+
} = readParams(params);
|
|
132
82
|
if (!storeName) return {
|
|
133
83
|
found: false,
|
|
134
84
|
reason: "missing storeName"
|
|
@@ -144,11 +94,7 @@ export const zustandSyncAdapter = {
|
|
|
144
94
|
} catch {
|
|
145
95
|
currentState = undefined;
|
|
146
96
|
}
|
|
147
|
-
|
|
148
|
-
__buoyTruncated: true,
|
|
149
|
-
note: `Exceeds the ${MAX_CHANGE_DETAIL_BYTES / (1024 * 1024)}MB detail limit — inspect it on-device.`
|
|
150
|
-
};
|
|
151
|
-
if (!isOverWireBudget(currentState, MAX_CHANGE_DETAIL_BYTES)) {
|
|
97
|
+
if (!isOverWireBudget(currentState, WIRE_DETAIL_LIMIT_BYTES)) {
|
|
152
98
|
return {
|
|
153
99
|
found: true,
|
|
154
100
|
storeName,
|
|
@@ -158,7 +104,7 @@ export const zustandSyncAdapter = {
|
|
|
158
104
|
return {
|
|
159
105
|
found: true,
|
|
160
106
|
storeName,
|
|
161
|
-
currentState: isJsonSerializable(currentState) ?
|
|
107
|
+
currentState: isJsonSerializable(currentState) ? truncatedNote(WIRE_DETAIL_LIMIT_BYTES) : STATE_ON_DEVICE
|
|
162
108
|
};
|
|
163
109
|
},
|
|
164
110
|
/**
|
|
@@ -171,7 +117,7 @@ export const zustandSyncAdapter = {
|
|
|
171
117
|
const {
|
|
172
118
|
includeValues = false,
|
|
173
119
|
limit
|
|
174
|
-
} = params
|
|
120
|
+
} = readParams(params);
|
|
175
121
|
const all = zustandStateStore.getStoreSnapshots();
|
|
176
122
|
const capped = typeof limit === "number" && limit > 0 ? all.slice(0, limit) : all;
|
|
177
123
|
const stores = capped.map(s => ({
|
|
@@ -198,7 +144,7 @@ export const zustandSyncAdapter = {
|
|
|
198
144
|
storeName,
|
|
199
145
|
state,
|
|
200
146
|
replace
|
|
201
|
-
} = params
|
|
147
|
+
} = readParams(params);
|
|
202
148
|
if (!storeName) return {
|
|
203
149
|
ok: false,
|
|
204
150
|
error: "Missing storeName."
|
|
@@ -237,7 +183,7 @@ export const zustandSyncAdapter = {
|
|
|
237
183
|
rehydrate: async params => {
|
|
238
184
|
const {
|
|
239
185
|
storeName
|
|
240
|
-
} = params
|
|
186
|
+
} = readParams(params);
|
|
241
187
|
if (!storeName) return {
|
|
242
188
|
ok: false,
|
|
243
189
|
error: "Missing storeName."
|
|
@@ -267,4 +213,4 @@ export const zustandSyncAdapter = {
|
|
|
267
213
|
};
|
|
268
214
|
}
|
|
269
215
|
}
|
|
270
|
-
};
|
|
216
|
+
});
|
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
* strips functions (recording where they were), and restore re-grafts the
|
|
14
14
|
* LIVE store's functions onto the snapshot before replacing.
|
|
15
15
|
*/
|
|
16
|
-
import { registerStateSnapshotProvider } from "@buoy-gg/shared-ui";
|
|
17
|
-
import { boundedDeepEqual, jsonLikelyLargerThan } from "@buoy-gg/shared-ui/dataViewer";
|
|
16
|
+
import { classifyPreviewItem, createRestoreScope, emptyRestoreResult, failedRestore, registerStateSnapshotProvider, unionKeys } from "@buoy-gg/shared-ui";
|
|
18
17
|
import { zustandStateStore } from "./zustandStateStore";
|
|
19
18
|
import { isPlainObjectLike, stripFunctions, STRIP_MAX_DEPTH } from "./editableState";
|
|
20
19
|
|
|
@@ -93,29 +92,13 @@ async function capture() {
|
|
|
93
92
|
}
|
|
94
93
|
async function restore(data, options) {
|
|
95
94
|
const snapshot = data;
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
const touch = key => !excludedSet.has(key) && (!includedSet || includedSet.has(key));
|
|
99
|
-
let excludedHits = 0;
|
|
100
|
-
const result = {
|
|
101
|
-
ok: true,
|
|
102
|
-
applied: 0,
|
|
103
|
-
skipped: [],
|
|
104
|
-
warnings: []
|
|
105
|
-
};
|
|
95
|
+
const scope = createRestoreScope(options);
|
|
96
|
+
const result = emptyRestoreResult();
|
|
106
97
|
if (!snapshot?.stores) {
|
|
107
|
-
return
|
|
108
|
-
ok: false,
|
|
109
|
-
applied: 0,
|
|
110
|
-
skipped: [],
|
|
111
|
-
warnings: ["empty zustand snapshot"]
|
|
112
|
-
};
|
|
98
|
+
return failedRestore("empty zustand snapshot");
|
|
113
99
|
}
|
|
114
100
|
for (const [name, envelope] of Object.entries(snapshot.stores)) {
|
|
115
|
-
if (!
|
|
116
|
-
excludedHits += 1;
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
101
|
+
if (!scope.allows(name)) continue;
|
|
119
102
|
const info = zustandStateStore.getStore(name);
|
|
120
103
|
if (!info) {
|
|
121
104
|
result.skipped.push({
|
|
@@ -142,12 +125,10 @@ async function restore(data, options) {
|
|
|
142
125
|
result.ok = false;
|
|
143
126
|
}
|
|
144
127
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
128
|
+
const excludedWarning = scope.excludedWarning("store(s)");
|
|
129
|
+
if (excludedWarning) result.warnings.push(excludedWarning);
|
|
148
130
|
return result;
|
|
149
131
|
}
|
|
150
|
-
const ITEM_RENDER_BYTE_LIMIT = 256 * 1024;
|
|
151
132
|
|
|
152
133
|
/**
|
|
153
134
|
* Per-store restore preview. Both sides are function-stripped through the
|
|
@@ -176,8 +157,7 @@ async function previewItems(target, base) {
|
|
|
176
157
|
const items = [];
|
|
177
158
|
const notes = [];
|
|
178
159
|
let preservedFns = 0;
|
|
179
|
-
const
|
|
180
|
-
for (const name of names) {
|
|
160
|
+
for (const name of unionKeys(baseStores, targetStores)) {
|
|
181
161
|
const inTarget = name in targetStores;
|
|
182
162
|
const inBase = name in baseStores;
|
|
183
163
|
if (!inTarget) {
|
|
@@ -200,39 +180,16 @@ async function previewItems(target, base) {
|
|
|
200
180
|
});
|
|
201
181
|
continue;
|
|
202
182
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
const newState = targetStores[name].state;
|
|
214
|
-
if (boundedDeepEqual(oldState, newState)) {
|
|
215
|
-
items.push({
|
|
216
|
-
key: name,
|
|
217
|
-
label: name,
|
|
218
|
-
verdict: "unchanged"
|
|
219
|
-
});
|
|
220
|
-
} else if (jsonLikelyLargerThan(oldState, ITEM_RENDER_BYTE_LIMIT) || jsonLikelyLargerThan(newState, ITEM_RENDER_BYTE_LIMIT)) {
|
|
221
|
-
items.push({
|
|
222
|
-
key: name,
|
|
223
|
-
label: name,
|
|
224
|
-
verdict: "too-large",
|
|
225
|
-
reason: "store too large to render a diff — restore still applies it"
|
|
226
|
-
});
|
|
227
|
-
} else {
|
|
228
|
-
items.push({
|
|
229
|
-
key: name,
|
|
230
|
-
label: name,
|
|
231
|
-
verdict: "changed",
|
|
232
|
-
oldValue: oldState,
|
|
233
|
-
newValue: newState
|
|
234
|
-
});
|
|
235
|
-
}
|
|
183
|
+
items.push(classifyPreviewItem({
|
|
184
|
+
key: name,
|
|
185
|
+
label: name,
|
|
186
|
+
oldValue: baseStores[name]?.state,
|
|
187
|
+
newValue: targetStores[name].state,
|
|
188
|
+
inOld: inBase,
|
|
189
|
+
inNew: true
|
|
190
|
+
}, {
|
|
191
|
+
tooLargeReason: "store too large to render a diff — restore still applies it"
|
|
192
|
+
}));
|
|
236
193
|
}
|
|
237
194
|
if (preservedFns > 0) {
|
|
238
195
|
notes.push(`${preservedFns} store action function${preservedFns === 1 ? "" : "s"} preserved on restore (not diffed)`);
|