@buoy-gg/zustand 7.0.32 → 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 +83 -141
- package/lib/commonjs/zustand/components/ZustandStateChangeItem.js +8 -61
- package/lib/commonjs/zustand/components/ZustandStateInfoView.js +2 -46
- package/lib/commonjs/zustand/components/ZustandStoreBrowser.js +29 -54
- 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 +85 -143
- package/lib/module/zustand/components/ZustandStateChangeItem.js +10 -63
- package/lib/module/zustand/components/ZustandStateInfoView.js +1 -45
- package/lib/module/zustand/components/ZustandStoreBrowser.js +31 -56
- 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/components/ZustandStoreBrowser.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
|
@@ -5,53 +5,41 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.useZustandStateChanges = useZustandStateChanges;
|
|
7
7
|
var _react = require("react");
|
|
8
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
8
9
|
var _zustandStateStore = require("../utils/zustandStateStore");
|
|
9
10
|
/**
|
|
10
11
|
* Hook for consuming Zustand state changes from the store
|
|
11
12
|
*
|
|
12
|
-
*
|
|
13
|
+
* The subscribe / filter / pause / clear plumbing is shared `useChangeLog`;
|
|
14
|
+
* this file owns the zustand-specific filter, stats and store registry.
|
|
13
15
|
*/
|
|
14
16
|
|
|
17
|
+
function filterChanges(changes, filter) {
|
|
18
|
+
let filtered = changes;
|
|
19
|
+
if (filter.searchText) {
|
|
20
|
+
const search = filter.searchText.toLowerCase();
|
|
21
|
+
filtered = filtered.filter(c => c.storeName.toLowerCase().includes(search) || c.partialPreview.toLowerCase().includes(search) || c.changedKeys.some(k => k.toLowerCase().includes(search)));
|
|
22
|
+
}
|
|
23
|
+
if (filter.storeNames && filter.storeNames.length > 0) {
|
|
24
|
+
filtered = filtered.filter(c => filter.storeNames.includes(c.storeName));
|
|
25
|
+
}
|
|
26
|
+
if (filter.onlyWithChanges) {
|
|
27
|
+
filtered = filtered.filter(c => c.hasStateChange);
|
|
28
|
+
}
|
|
29
|
+
return filtered;
|
|
30
|
+
}
|
|
31
|
+
const readStores = () => _zustandStateStore.zustandStateStore.getStores();
|
|
32
|
+
const subscribeToStores = listener => _zustandStateStore.zustandStateStore.subscribeToStores(listener);
|
|
15
33
|
function useZustandStateChanges() {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
// Subscribe to state changes
|
|
22
|
-
(0, _react.useEffect)(() => {
|
|
23
|
-
const unsubChanges = _zustandStateStore.zustandStateStore.subscribe(newChanges => {
|
|
24
|
-
setStateChanges(newChanges);
|
|
25
|
-
});
|
|
26
|
-
const unsubStores = _zustandStateStore.zustandStateStore.subscribeToStores(newStores => {
|
|
27
|
-
setStores(newStores);
|
|
28
|
-
});
|
|
29
|
-
return () => {
|
|
30
|
-
unsubChanges();
|
|
31
|
-
unsubStores();
|
|
32
|
-
};
|
|
33
|
-
}, []);
|
|
34
|
-
|
|
35
|
-
// Filter state changes — derive directly from state to avoid stale reads
|
|
36
|
-
const filteredChanges = (0, _react.useMemo)(() => {
|
|
37
|
-
let filtered = stateChanges;
|
|
38
|
-
if (filter.searchText) {
|
|
39
|
-
const search = filter.searchText.toLowerCase();
|
|
40
|
-
filtered = filtered.filter(c => c.storeName.toLowerCase().includes(search) || c.partialPreview.toLowerCase().includes(search) || c.changedKeys.some(k => k.toLowerCase().includes(search)));
|
|
41
|
-
}
|
|
42
|
-
if (filter.storeNames && filter.storeNames.length > 0) {
|
|
43
|
-
filtered = filtered.filter(c => filter.storeNames.includes(c.storeName));
|
|
44
|
-
}
|
|
45
|
-
if (filter.onlyWithChanges) {
|
|
46
|
-
filtered = filtered.filter(c => c.hasStateChange);
|
|
47
|
-
}
|
|
48
|
-
return filtered;
|
|
49
|
-
}, [stateChanges, filter]);
|
|
34
|
+
const log = (0, _sharedUi.useChangeLog)(_zustandStateStore.zustandStateStore, {
|
|
35
|
+
filterItems: filterChanges
|
|
36
|
+
});
|
|
37
|
+
const stores = (0, _sharedUi.useSubscribedValue)(readStores, subscribeToStores);
|
|
50
38
|
|
|
51
39
|
// Get stats — derive directly from state
|
|
52
40
|
const stats = (0, _react.useMemo)(() => {
|
|
53
|
-
const total =
|
|
54
|
-
const withChanges =
|
|
41
|
+
const total = log.items.length;
|
|
42
|
+
const withChanges = log.items.filter(c => c.hasStateChange).length;
|
|
55
43
|
return {
|
|
56
44
|
totalChanges: total,
|
|
57
45
|
changesWithStateChange: withChanges,
|
|
@@ -59,33 +47,25 @@ function useZustandStateChanges() {
|
|
|
59
47
|
storeCount: stores.length,
|
|
60
48
|
averageDuration: 0
|
|
61
49
|
};
|
|
62
|
-
}, [
|
|
50
|
+
}, [log.items, stores]);
|
|
63
51
|
|
|
64
52
|
// Get unique store names
|
|
65
53
|
const storeNames = (0, _react.useMemo)(() => {
|
|
66
54
|
return _zustandStateStore.zustandStateStore.getUniqueStoreNames();
|
|
67
55
|
}, [stores]);
|
|
68
|
-
const clearChanges = (0, _react.useCallback)(() => {
|
|
69
|
-
_zustandStateStore.zustandStateStore.clearStateChanges();
|
|
70
|
-
}, []);
|
|
71
|
-
const toggleCapture = (0, _react.useCallback)(() => {
|
|
72
|
-
const newEnabled = !isEnabled;
|
|
73
|
-
_zustandStateStore.zustandStateStore.setEnabled(newEnabled);
|
|
74
|
-
setIsEnabled(newEnabled);
|
|
75
|
-
}, [isEnabled]);
|
|
76
56
|
const getChangeById = (0, _react.useCallback)(id => {
|
|
77
57
|
return _zustandStateStore.zustandStateStore.getStateChangeById(id);
|
|
78
58
|
}, []);
|
|
79
59
|
return {
|
|
80
|
-
stateChanges,
|
|
81
|
-
filteredChanges,
|
|
82
|
-
filter,
|
|
83
|
-
setFilter,
|
|
60
|
+
stateChanges: log.items,
|
|
61
|
+
filteredChanges: log.filteredItems,
|
|
62
|
+
filter: log.filter,
|
|
63
|
+
setFilter: log.setFilter,
|
|
84
64
|
stats,
|
|
85
65
|
stores,
|
|
86
|
-
clearChanges,
|
|
87
|
-
isEnabled,
|
|
88
|
-
toggleCapture,
|
|
66
|
+
clearChanges: log.clear,
|
|
67
|
+
isEnabled: log.isEnabled,
|
|
68
|
+
toggleCapture: log.toggleCapture,
|
|
89
69
|
storeNames,
|
|
90
70
|
getChangeById
|
|
91
71
|
};
|
|
@@ -11,18 +11,10 @@ var _sharedUi = require("@buoy-gg/shared-ui");
|
|
|
11
11
|
* Same hazard as redux: up to 200 changes × 2 full trees on every snapshot
|
|
12
12
|
* freeze/OOM-killed large apps. Dashboards fetch trees via `getChangeDetail`.
|
|
13
13
|
*/
|
|
14
|
-
const STATE_ON_DEVICE = exports.STATE_ON_DEVICE =
|
|
15
|
-
__buoyStateOnDevice: true,
|
|
16
|
-
note: "State trees stay on the device — fetched on demand via getChangeDetail / getStoreState."
|
|
17
|
-
});
|
|
14
|
+
const STATE_ON_DEVICE = exports.STATE_ON_DEVICE = (0, _sharedUi.onDeviceMarker)("State", "State trees stay on the device — fetched on demand via getChangeDetail / getStoreState.");
|
|
18
15
|
|
|
19
16
|
/** Wire-form sentinel for an oversized `partial` (replace can carry a whole tree). */
|
|
20
|
-
const PAYLOAD_ON_DEVICE = exports.PAYLOAD_ON_DEVICE =
|
|
21
|
-
__buoyPayloadOnDevice: true,
|
|
22
|
-
note: "Partial stays on the device — fetched on demand via getChangeDetail."
|
|
23
|
-
});
|
|
24
|
-
const MAX_CHANGE_DETAIL_BYTES = 8 * 1024 * 1024;
|
|
25
|
-
const MAX_WIRE_PAYLOAD_BYTES = 16 * 1024;
|
|
17
|
+
const PAYLOAD_ON_DEVICE = exports.PAYLOAD_ON_DEVICE = (0, _sharedUi.onDeviceMarker)("Payload", "Partial stays on the device — fetched on demand via getChangeDetail.");
|
|
26
18
|
/** Top-level keys of an object state, for the compact (no-values) view. */
|
|
27
19
|
function topLevelKeys(state) {
|
|
28
20
|
return state && typeof state === "object" && !Array.isArray(state) ? Object.keys(state) : undefined;
|
|
@@ -33,31 +25,17 @@ function topLevelKeys(state) {
|
|
|
33
25
|
* change, so keying on identity is correct and self-invalidating — without it
|
|
34
26
|
* every `partial` in the list is re-measured on all ~5 snapshots per second.
|
|
35
27
|
*/
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
nextState: STATE_ON_DEVICE,
|
|
44
|
-
partial: toWirePartial(change.partial)
|
|
45
|
-
};
|
|
46
|
-
changeCache.set(change, wire);
|
|
47
|
-
return wire;
|
|
48
|
-
}
|
|
49
|
-
function toWirePartial(value) {
|
|
50
|
-
if (value === undefined) return value;
|
|
51
|
-
return (0, _sharedUi.isOverWireBudget)(value, MAX_WIRE_PAYLOAD_BYTES) ? PAYLOAD_ON_DEVICE : value;
|
|
52
|
-
}
|
|
53
|
-
function toWireState(value) {
|
|
54
|
-
return (0, _sharedUi.isOverWireBudget)(value, MAX_WIRE_PAYLOAD_BYTES) ? STATE_ON_DEVICE : value;
|
|
55
|
-
}
|
|
28
|
+
const toWireChange = (0, _sharedUi.memoByIdentity)(change => ({
|
|
29
|
+
...change,
|
|
30
|
+
prevState: STATE_ON_DEVICE,
|
|
31
|
+
nextState: STATE_ON_DEVICE,
|
|
32
|
+
partial: (0, _sharedUi.toWire)(change.partial, PAYLOAD_ON_DEVICE)
|
|
33
|
+
}));
|
|
34
|
+
const toWireState = value => (0, _sharedUi.toWire)(value, STATE_ON_DEVICE);
|
|
56
35
|
|
|
57
36
|
/**
|
|
58
37
|
* Sync adapter for the zustand tool, consumed by @buoy-gg/external-sync's
|
|
59
|
-
* `useExternalSync
|
|
60
|
-
* this package doesn't need a dependency on it).
|
|
38
|
+
* `useExternalSync`.
|
|
61
39
|
*
|
|
62
40
|
* State changes are captured by the middleware (watchStores/buoyDevTools),
|
|
63
41
|
* independent of whether a dashboard is watching — subscribing here only
|
|
@@ -72,7 +50,7 @@ function toWireState(value) {
|
|
|
72
50
|
*
|
|
73
51
|
* The `setState` action powers remote time-travel/reset from the dashboard.
|
|
74
52
|
*/
|
|
75
|
-
const zustandSyncAdapter = exports.zustandSyncAdapter = {
|
|
53
|
+
const zustandSyncAdapter = exports.zustandSyncAdapter = (0, _sharedUi.createSyncAdapter)({
|
|
76
54
|
version: 2,
|
|
77
55
|
getSnapshot: () => ({
|
|
78
56
|
changes: _zustandStateStore.zustandStateStore.getStateChanges().map(toWireChange),
|
|
@@ -81,14 +59,7 @@ const zustandSyncAdapter = exports.zustandSyncAdapter = {
|
|
|
81
59
|
currentState: toWireState(store.currentState)
|
|
82
60
|
}))
|
|
83
61
|
}),
|
|
84
|
-
subscribe: onChange =>
|
|
85
|
-
const unsubscribeChanges = _zustandStateStore.zustandStateStore.subscribe(onChange);
|
|
86
|
-
const unsubscribeStores = _zustandStateStore.zustandStateStore.subscribeToStores(onChange);
|
|
87
|
-
return () => {
|
|
88
|
-
unsubscribeChanges();
|
|
89
|
-
unsubscribeStores();
|
|
90
|
-
};
|
|
91
|
-
},
|
|
62
|
+
subscribe: [onChange => _zustandStateStore.zustandStateStore.subscribe(onChange), onChange => _zustandStateStore.zustandStateStore.subscribeToStores(onChange)],
|
|
92
63
|
actions: {
|
|
93
64
|
clearEvents: () => {
|
|
94
65
|
_zustandStateStore.zustandStateStore.clearStateChanges();
|
|
@@ -98,32 +69,11 @@ const zustandSyncAdapter = exports.zustandSyncAdapter = {
|
|
|
98
69
|
* The per-snapshot stream stays tree-free; this is the explicit,
|
|
99
70
|
* size-guarded channel for the detail pane.
|
|
100
71
|
*/
|
|
101
|
-
getChangeDetail:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
found: false,
|
|
107
|
-
reason: "missing id"
|
|
108
|
-
};
|
|
109
|
-
const change = _zustandStateStore.zustandStateStore.getStateChangeById(id);
|
|
110
|
-
if (!change) return {
|
|
111
|
-
found: false,
|
|
112
|
-
reason: "unknown id"
|
|
113
|
-
};
|
|
114
|
-
const cappedNote = {
|
|
115
|
-
__buoyTruncated: true,
|
|
116
|
-
note: `Exceeds the ${MAX_CHANGE_DETAIL_BYTES / (1024 * 1024)}MB detail limit — inspect it on-device.`
|
|
117
|
-
};
|
|
118
|
-
const cap = value => (0, _sharedUi.isOverWireBudget)(value, MAX_CHANGE_DETAIL_BYTES) ? cappedNote : value;
|
|
119
|
-
return {
|
|
120
|
-
found: true,
|
|
121
|
-
id,
|
|
122
|
-
prevState: cap(change.prevState),
|
|
123
|
-
nextState: cap(change.nextState),
|
|
124
|
-
partial: cap(change.partial)
|
|
125
|
-
};
|
|
126
|
-
},
|
|
72
|
+
getChangeDetail: (0, _sharedUi.detailByIdAction)(id => _zustandStateStore.zustandStateStore.getStateChangeById(id), (change, cap) => ({
|
|
73
|
+
prevState: cap(change.prevState),
|
|
74
|
+
nextState: cap(change.nextState),
|
|
75
|
+
partial: cap(change.partial)
|
|
76
|
+
})),
|
|
127
77
|
/**
|
|
128
78
|
* On-demand current state for one store. Wire-form snapshots replace
|
|
129
79
|
* oversized / unserializable `currentState` with STATE_ON_DEVICE.
|
|
@@ -131,7 +81,7 @@ const zustandSyncAdapter = exports.zustandSyncAdapter = {
|
|
|
131
81
|
getStoreState: params => {
|
|
132
82
|
const {
|
|
133
83
|
storeName
|
|
134
|
-
} = params
|
|
84
|
+
} = (0, _sharedUi.readParams)(params);
|
|
135
85
|
if (!storeName) return {
|
|
136
86
|
found: false,
|
|
137
87
|
reason: "missing storeName"
|
|
@@ -147,11 +97,7 @@ const zustandSyncAdapter = exports.zustandSyncAdapter = {
|
|
|
147
97
|
} catch {
|
|
148
98
|
currentState = undefined;
|
|
149
99
|
}
|
|
150
|
-
|
|
151
|
-
__buoyTruncated: true,
|
|
152
|
-
note: `Exceeds the ${MAX_CHANGE_DETAIL_BYTES / (1024 * 1024)}MB detail limit — inspect it on-device.`
|
|
153
|
-
};
|
|
154
|
-
if (!(0, _sharedUi.isOverWireBudget)(currentState, MAX_CHANGE_DETAIL_BYTES)) {
|
|
100
|
+
if (!(0, _sharedUi.isOverWireBudget)(currentState, _sharedUi.WIRE_DETAIL_LIMIT_BYTES)) {
|
|
155
101
|
return {
|
|
156
102
|
found: true,
|
|
157
103
|
storeName,
|
|
@@ -161,7 +107,7 @@ const zustandSyncAdapter = exports.zustandSyncAdapter = {
|
|
|
161
107
|
return {
|
|
162
108
|
found: true,
|
|
163
109
|
storeName,
|
|
164
|
-
currentState: (0, _sharedUi.isJsonSerializable)(currentState) ?
|
|
110
|
+
currentState: (0, _sharedUi.isJsonSerializable)(currentState) ? (0, _sharedUi.truncatedNote)(_sharedUi.WIRE_DETAIL_LIMIT_BYTES) : STATE_ON_DEVICE
|
|
165
111
|
};
|
|
166
112
|
},
|
|
167
113
|
/**
|
|
@@ -174,7 +120,7 @@ const zustandSyncAdapter = exports.zustandSyncAdapter = {
|
|
|
174
120
|
const {
|
|
175
121
|
includeValues = false,
|
|
176
122
|
limit
|
|
177
|
-
} = params
|
|
123
|
+
} = (0, _sharedUi.readParams)(params);
|
|
178
124
|
const all = _zustandStateStore.zustandStateStore.getStoreSnapshots();
|
|
179
125
|
const capped = typeof limit === "number" && limit > 0 ? all.slice(0, limit) : all;
|
|
180
126
|
const stores = capped.map(s => ({
|
|
@@ -201,7 +147,7 @@ const zustandSyncAdapter = exports.zustandSyncAdapter = {
|
|
|
201
147
|
storeName,
|
|
202
148
|
state,
|
|
203
149
|
replace
|
|
204
|
-
} = params
|
|
150
|
+
} = (0, _sharedUi.readParams)(params);
|
|
205
151
|
if (!storeName) return {
|
|
206
152
|
ok: false,
|
|
207
153
|
error: "Missing storeName."
|
|
@@ -240,7 +186,7 @@ const zustandSyncAdapter = exports.zustandSyncAdapter = {
|
|
|
240
186
|
rehydrate: async params => {
|
|
241
187
|
const {
|
|
242
188
|
storeName
|
|
243
|
-
} = params
|
|
189
|
+
} = (0, _sharedUi.readParams)(params);
|
|
244
190
|
if (!storeName) return {
|
|
245
191
|
ok: false,
|
|
246
192
|
error: "Missing storeName."
|
|
@@ -270,4 +216,4 @@ const zustandSyncAdapter = exports.zustandSyncAdapter = {
|
|
|
270
216
|
};
|
|
271
217
|
}
|
|
272
218
|
}
|
|
273
|
-
};
|
|
219
|
+
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
4
|
-
var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
|
|
5
4
|
var _zustandStateStore = require("./zustandStateStore");
|
|
6
5
|
var _editableState = require("./editableState");
|
|
7
6
|
/**
|
|
@@ -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 = (0, _sharedUi.createRestoreScope)(options);
|
|
96
|
+
const result = (0, _sharedUi.emptyRestoreResult)();
|
|
106
97
|
if (!snapshot?.stores) {
|
|
107
|
-
return
|
|
108
|
-
ok: false,
|
|
109
|
-
applied: 0,
|
|
110
|
-
skipped: [],
|
|
111
|
-
warnings: ["empty zustand snapshot"]
|
|
112
|
-
};
|
|
98
|
+
return (0, _sharedUi.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.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 (0, _sharedUi.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 ((0, _dataViewer.boundedDeepEqual)(oldState, newState)) {
|
|
215
|
-
items.push({
|
|
216
|
-
key: name,
|
|
217
|
-
label: name,
|
|
218
|
-
verdict: "unchanged"
|
|
219
|
-
});
|
|
220
|
-
} else if ((0, _dataViewer.jsonLikelyLargerThan)(oldState, ITEM_RENDER_BYTE_LIMIT) || (0, _dataViewer.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((0, _sharedUi.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)`);
|