@lensmcp/valtio-instrumentation 1.16.31 → 1.17.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/lib/snapshot.d.ts +2 -0
- package/lib/snapshot.d.ts.map +1 -1
- package/lib/snapshot.js +30 -1
- package/package.json +2 -2
package/lib/snapshot.d.ts
CHANGED
|
@@ -14,4 +14,6 @@ export declare function useTrackedSnapshot<T extends object>(target: T, opts: Us
|
|
|
14
14
|
* `proxy()`; falls back to a single root subscription when nothing is read.
|
|
15
15
|
*/
|
|
16
16
|
export declare function useSnapshot<T extends object>(target: T): T;
|
|
17
|
+
/** Join a visited-property path, truncated to {@link SUB_PATH_DEPTH} segments (0 ⇒ no truncation). */
|
|
18
|
+
export declare function truncatePath(parts: readonly (string | symbol)[]): string;
|
|
17
19
|
//# sourceMappingURL=snapshot.d.ts.map
|
package/lib/snapshot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/lib/snapshot.ts"],"names":[],"mappings":"AAoCA,MAAM,WAAW,kBAAkB;IACjC;0DACsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;2DACuD;IACvD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,EACjD,MAAM,EAAE,CAAC,EACT,IAAI,EAAE,kBAAkB,GACvB,CAAC,CAcH;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAgF1D"}
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/lib/snapshot.ts"],"names":[],"mappings":"AAoCA,MAAM,WAAW,kBAAkB;IACjC;0DACsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;2DACuD;IACvD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,EACjD,MAAM,EAAE,CAAC,EACT,IAAI,EAAE,kBAAkB,GACvB,CAAC,CAcH;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAgF1D;AA2BD,sGAAsG;AACtG,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,MAAM,CAGxE"}
|
package/lib/snapshot.js
CHANGED
|
@@ -79,7 +79,7 @@ export function useSnapshot(target) {
|
|
|
79
79
|
// Runs after every commit — `affected` now reflects this render's reads.
|
|
80
80
|
useEffect(() => {
|
|
81
81
|
const paths = affected
|
|
82
|
-
? affectedToPathList(currSnapshot, affected, true).map((parts) => parts
|
|
82
|
+
? affectedToPathList(currSnapshot, affected, true).map((parts) => truncatePath(parts))
|
|
83
83
|
: [];
|
|
84
84
|
const next = new Set(paths.length ? paths : ['']);
|
|
85
85
|
reconcileSubscriptions(subscribedRef.current, next, storeId, componentInstanceId);
|
|
@@ -98,6 +98,35 @@ export function useSnapshot(target) {
|
|
|
98
98
|
? createProxy(currSnapshot, affected, proxyCache, targetCache)
|
|
99
99
|
: currSnapshot;
|
|
100
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Depth a tracked read path is reported at. `affectedToPathList` returns EVERY property visited, so a
|
|
103
|
+
* component that reads one large nested object through `useSnapshot` yields thousands of paths — and one
|
|
104
|
+
* event was published per path, per reconcile.
|
|
105
|
+
*
|
|
106
|
+
* Worked failure (foodguard, 2026-07-28): a run-timeline phase toggle re-rendered a list reading
|
|
107
|
+
* `runs[i].input` (a deep run payload). React rendered only **22** times, yet the bus took **26,216**
|
|
108
|
+
* `subscription-added/removed` events for a single store in 10s (peak 10,486/s, ~1,200 per render), and
|
|
109
|
+
* valtio events were **68%** of the whole event log — the mechanism behind the 60-84 MB `events.jsonl`
|
|
110
|
+
* files and an earlier OOM flood. It read as an app render storm and was not: the storm was the
|
|
111
|
+
* instrumentation.
|
|
112
|
+
*
|
|
113
|
+
* Truncating to the first N segments fixes it at the source instead of capping the emission: the `Set`
|
|
114
|
+
* then DEDUPES thousands of deep paths down to a handful, so the reducer's `storeId::path → subscribers`
|
|
115
|
+
* view stays complete and correct — just aggregated at a granularity a human can use
|
|
116
|
+
* (`entries.["runs","all"].data` rather than `…data.3.input.steps.7.config.foo`, which no one needs a
|
|
117
|
+
* subscriber list for). It also makes the set STABLE across renders, so churn stops generating
|
|
118
|
+
* remove+add pairs. Override with `LENSMCP_VALTIO_PATH_DEPTH`; `0` restores full untruncated paths.
|
|
119
|
+
*/
|
|
120
|
+
const SUB_PATH_DEPTH = (() => {
|
|
121
|
+
const raw = typeof process !== 'undefined' ? process.env?.['LENSMCP_VALTIO_PATH_DEPTH'] : undefined;
|
|
122
|
+
const n = Number(raw);
|
|
123
|
+
return Number.isFinite(n) && n >= 0 && n <= 20 ? Math.floor(n) : 3;
|
|
124
|
+
})();
|
|
125
|
+
/** Join a visited-property path, truncated to {@link SUB_PATH_DEPTH} segments (0 ⇒ no truncation). */
|
|
126
|
+
export function truncatePath(parts) {
|
|
127
|
+
const segs = parts.map(String);
|
|
128
|
+
return (SUB_PATH_DEPTH > 0 ? segs.slice(0, SUB_PATH_DEPTH) : segs).join('.');
|
|
129
|
+
}
|
|
101
130
|
/** Add/remove subscriptions so the registry matches `next` exactly. */
|
|
102
131
|
function reconcileSubscriptions(prev, next, storeId, componentInstanceId) {
|
|
103
132
|
for (const path of next) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lensmcp/valtio-instrumentation",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@lensmcp/react-instrumentation": "1.
|
|
17
|
+
"@lensmcp/react-instrumentation": "1.17.0",
|
|
18
18
|
"proxy-compare": "^3.0.0",
|
|
19
19
|
"tslib": "^2.3.0"
|
|
20
20
|
},
|