@lensmcp/valtio-instrumentation 1.18.4 → 1.18.6
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/index.js +1 -10
- package/lib/proxy.js +1 -94
- package/lib/snapshot.js +1 -165
- package/lib/store-registry.js +1 -58
- package/lib/types.js +1 -1
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -1,10 +1 @@
|
|
|
1
|
-
|
|
2
|
-
// Vite plugin can alias `valtio → @lensmcp/valtio-instrumentation` in dev
|
|
3
|
-
// with no caller changes. `proxy` + `useSnapshot` are the instrumented
|
|
4
|
-
// versions; the rest pass through from the real valtio (imported via the
|
|
5
|
-
// `valtio/vanilla` subpath so this module never aliases itself).
|
|
6
|
-
export { ref, snapshot, subscribe, getVersion, unstable_enableOp, unstable_getInternalStates, unstable_replaceInternalFunction, } from 'valtio/vanilla';
|
|
7
|
-
export { proxy } from './lib/proxy.js';
|
|
8
|
-
export { useSnapshot, useTrackedSnapshot } from './lib/snapshot.js';
|
|
9
|
-
// LensMCP-specific extras (not part of the valtio surface).
|
|
10
|
-
export { registerStore, tagProxy, storeIdOf, addSubscription, removeSubscription, subscribersFor, subscribersForPathAndParents, resetRegistry, } from './lib/store-registry.js';
|
|
1
|
+
"use strict";export{ref,snapshot,subscribe,getVersion,unstable_enableOp,unstable_getInternalStates,unstable_replaceInternalFunction}from"valtio/vanilla";export{proxy}from"./lib/proxy.js";export{useSnapshot,useTrackedSnapshot}from"./lib/snapshot.js";export{registerStore,tagProxy,storeIdOf,addSubscription,removeSubscription,subscribersFor,subscribersForPathAndParents,resetRegistry}from"./lib/store-registry.js";
|
package/lib/proxy.js
CHANGED
|
@@ -1,94 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* `proxy(initial, opts)` — wraps the actual Valtio proxy and emits
|
|
3
|
-
* `store-created` + per-mutation `state-update` events.
|
|
4
|
-
*
|
|
5
|
-
* Valtio is a peer dependency; we import it statically so bundlers
|
|
6
|
-
* resolve it the same way as user code.
|
|
7
|
-
*/
|
|
8
|
-
// Import the REAL valtio via the `valtio/vanilla` subpath — never bare
|
|
9
|
-
// `valtio` — so the dev-time `valtio → @lensmcp/valtio-instrumentation`
|
|
10
|
-
// alias (Phase 8) doesn't make this module import itself.
|
|
11
|
-
// `unstable_enableOp` turns on path-aware ops; without it `subscribe()`
|
|
12
|
-
// callbacks receive empty op arrays.
|
|
13
|
-
import { proxy as valtioProxy, subscribe as valtioSubscribe, unstable_enableOp, } from 'valtio/vanilla';
|
|
14
|
-
import { publish, depsHash } from '@lensmcp/react-instrumentation';
|
|
15
|
-
import { registerStore, subscribersForPathAndParents, tagProxy, } from './store-registry.js';
|
|
16
|
-
let opsEnabled = false;
|
|
17
|
-
function ensureOpsEnabled() {
|
|
18
|
-
if (opsEnabled)
|
|
19
|
-
return;
|
|
20
|
-
try {
|
|
21
|
-
unstable_enableOp(true);
|
|
22
|
-
opsEnabled = true;
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
/* older valtio without the flag — fall through, paths just won't populate */
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
let storeCounter = 0;
|
|
29
|
-
/**
|
|
30
|
-
* Create a tracked Valtio proxy.
|
|
31
|
-
*/
|
|
32
|
-
export function proxy(initial, opts = {}) {
|
|
33
|
-
ensureOpsEnabled();
|
|
34
|
-
const storeId = opts.storeId ?? `valtio:store:${++storeCounter}`;
|
|
35
|
-
registerStore(storeId, opts.source);
|
|
36
|
-
const proxied = valtioProxy(initial);
|
|
37
|
-
// Remember which store this proxy is, so the drop-in `useSnapshot(store)`
|
|
38
|
-
// can recover the id with no extra args.
|
|
39
|
-
tagProxy(proxied, storeId);
|
|
40
|
-
publish({
|
|
41
|
-
source: 'valtio',
|
|
42
|
-
category: 'state',
|
|
43
|
-
severity: 'info',
|
|
44
|
-
title: `store-created ${storeId}`,
|
|
45
|
-
fingerprint: `valtio-store:${storeId}`,
|
|
46
|
-
raw: {
|
|
47
|
-
kind: 'store-created',
|
|
48
|
-
store: {
|
|
49
|
-
storeId,
|
|
50
|
-
source: opts.source,
|
|
51
|
-
initialPreview: opts.emitInitialPreview === false ? undefined : safePreview(initial),
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
});
|
|
55
|
-
// Subscribe at the root to all changes; Valtio's ops carry the path
|
|
56
|
-
// tuple so we can emit one `state-update` per touched leaf.
|
|
57
|
-
valtioSubscribe(proxied, (ops) => {
|
|
58
|
-
for (const op of ops) {
|
|
59
|
-
const [, pathParts, value, prevValue] = op;
|
|
60
|
-
const path = (pathParts ?? []).map(String).join('.');
|
|
61
|
-
if (!path)
|
|
62
|
-
continue;
|
|
63
|
-
const changedKeys = (pathParts ?? []).map(String);
|
|
64
|
-
publish({
|
|
65
|
-
source: 'valtio',
|
|
66
|
-
category: 'state',
|
|
67
|
-
severity: 'info',
|
|
68
|
-
title: `state-update ${storeId}.${path}`,
|
|
69
|
-
fingerprint: `valtio-update:${storeId}:${path}`,
|
|
70
|
-
raw: {
|
|
71
|
-
kind: 'state-update',
|
|
72
|
-
update: {
|
|
73
|
-
storeId,
|
|
74
|
-
path,
|
|
75
|
-
changedKeys,
|
|
76
|
-
beforeHash: depsHash([prevValue]),
|
|
77
|
-
afterHash: depsHash([value]),
|
|
78
|
-
preview: safePreview(value),
|
|
79
|
-
subscribers: subscribersForPathAndParents(storeId, path),
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
}, true);
|
|
85
|
-
return proxied;
|
|
86
|
-
}
|
|
87
|
-
function safePreview(v) {
|
|
88
|
-
try {
|
|
89
|
-
return JSON.parse(JSON.stringify(v));
|
|
90
|
-
}
|
|
91
|
-
catch {
|
|
92
|
-
return undefined;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
1
|
+
"use strict";var m=Object.defineProperty;var a=(t,r)=>m(t,"name",{value:r,configurable:!0});var h=Object.defineProperty,i=a((t,r)=>h(t,"name",{value:r,configurable:!0}),"s");import{proxy as P,subscribe as $,unstable_enableOp as w}from"valtio/vanilla";import{publish as p,depsHash as f}from"@lensmcp/react-instrumentation";import{registerStore as x,subscribersForPathAndParents as S,tagProxy as O}from"./store-registry.js";let d=!1;function l(){if(!d)try{w(!0),d=!0}catch{}}a(l,"x"),i(l,"ensureOpsEnabled");let I=0;export function proxy(t,r={}){l();const e=r.storeId??`valtio:store:${++I}`;x(e,r.source);const o=P(t);return O(o,e),p({source:"valtio",category:"state",severity:"info",title:`store-created ${e}`,fingerprint:`valtio-store:${e}`,raw:{kind:"store-created",store:{storeId:e,source:r.source,initialPreview:r.emitInitialPreview===!1?void 0:n(t)}}}),$(o,v=>{for(const b of v){const[,c,u,y]=b,s=(c??[]).map(String).join(".");if(!s)continue;const g=(c??[]).map(String);p({source:"valtio",category:"state",severity:"info",title:`state-update ${e}.${s}`,fingerprint:`valtio-update:${e}:${s}`,raw:{kind:"state-update",update:{storeId:e,path:s,changedKeys:g,beforeHash:f([y]),afterHash:f([u]),preview:n(u),subscribers:S(e,s)}}})}},!0),o}a(proxy,"proxy"),i(proxy,"proxy");function n(t){try{return JSON.parse(JSON.stringify(t))}catch{return}}a(n,"f"),i(n,"safePreview");
|
package/lib/snapshot.js
CHANGED
|
@@ -1,165 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* `useSnapshot` — the drop-in replacement for valtio's `useSnapshot`, with
|
|
3
|
-
* **per-path subscription inference**.
|
|
4
|
-
*
|
|
5
|
-
* valtio's own re-render optimisation is a `proxy-compare` "affected"
|
|
6
|
-
* WeakMap recording which snapshot paths a component reads. We inline
|
|
7
|
-
* valtio v2's `useSnapshot` here so we *own* that `affected` map, then read
|
|
8
|
-
* it back with `affectedToPathList` after commit to learn exactly which
|
|
9
|
-
* (`storeId`, `path`) pairs the component depends on — and register one
|
|
10
|
-
* subscription per path instead of a single store-root subscription.
|
|
11
|
-
*
|
|
12
|
-
* `useTrackedSnapshot(target, { storeId, path })` stays available for
|
|
13
|
-
* callers that want to declare a path explicitly.
|
|
14
|
-
*/
|
|
15
|
-
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useSyncExternalStore, } from 'react';
|
|
16
|
-
// Real valtio via the `valtio/vanilla` subpath (never bare `valtio`), so the
|
|
17
|
-
// dev-time alias doesn't make this module import itself.
|
|
18
|
-
import { snapshot as valtioSnapshot, subscribe as valtioSubscribe, } from 'valtio/vanilla';
|
|
19
|
-
import { useSnapshot as valtioUseSnapshot } from 'valtio/react';
|
|
20
|
-
import { affectedToPathList, createProxy, isChanged } from 'proxy-compare';
|
|
21
|
-
import { useLensmcpContext, publish } from '@lensmcp/react-instrumentation';
|
|
22
|
-
import { addSubscription, removeSubscription, storeIdOf } from './store-registry.js';
|
|
23
|
-
// Shared across components for proxy reuse, exactly as valtio does.
|
|
24
|
-
const targetCache = new WeakMap();
|
|
25
|
-
export function useTrackedSnapshot(target, opts) {
|
|
26
|
-
const ctx = useLensmcpContext();
|
|
27
|
-
const path = opts.path ?? '';
|
|
28
|
-
const componentInstanceId = ctx.componentInstanceId ?? `react:component:anonymous`;
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
emitSubscription('added', opts.storeId, path, componentInstanceId);
|
|
31
|
-
return () => {
|
|
32
|
-
emitSubscription('removed', opts.storeId, path, componentInstanceId);
|
|
33
|
-
};
|
|
34
|
-
}, [opts.storeId, path, componentInstanceId]);
|
|
35
|
-
return valtioUseSnapshot(target);
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Drop-in `useSnapshot(store)` matching valtio's signature exactly. Infers
|
|
39
|
-
* the read paths from `proxy-compare`'s affected map and registers one
|
|
40
|
-
* subscription per path. Recovers the storeId tagged by the instrumented
|
|
41
|
-
* `proxy()`; falls back to a single root subscription when nothing is read.
|
|
42
|
-
*/
|
|
43
|
-
export function useSnapshot(target) {
|
|
44
|
-
const storeId = storeIdOf(target) ?? 'valtio:store:anonymous';
|
|
45
|
-
const ctx = useLensmcpContext();
|
|
46
|
-
const componentInstanceId = ctx.componentInstanceId ?? 'react:component:anonymous';
|
|
47
|
-
// ---- valtio v2's useSnapshot, inlined so we own `affected` ----
|
|
48
|
-
const affected = useMemo(() => target && new WeakMap(), [target]);
|
|
49
|
-
const lastSnapshot = useRef(undefined);
|
|
50
|
-
let inRender = true;
|
|
51
|
-
const currSnapshot = useSyncExternalStore(useCallback((callback) => {
|
|
52
|
-
const unsub = valtioSubscribe(target, callback, false);
|
|
53
|
-
callback();
|
|
54
|
-
return unsub;
|
|
55
|
-
}, [target]), () => {
|
|
56
|
-
const next = valtioSnapshot(target);
|
|
57
|
-
try {
|
|
58
|
-
if (!inRender &&
|
|
59
|
-
lastSnapshot.current &&
|
|
60
|
-
affected &&
|
|
61
|
-
!isChanged(lastSnapshot.current, next, affected, new WeakMap())) {
|
|
62
|
-
return lastSnapshot.current;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
/* fall through to the fresh snapshot */
|
|
67
|
-
}
|
|
68
|
-
return next;
|
|
69
|
-
}, () => valtioSnapshot(target));
|
|
70
|
-
inRender = false;
|
|
71
|
-
useLayoutEffect(() => {
|
|
72
|
-
lastSnapshot.current = currSnapshot;
|
|
73
|
-
});
|
|
74
|
-
const proxyCache = useMemo(() => new WeakMap(), []);
|
|
75
|
-
// ---- LensMCP: reconcile per-path subscriptions to the read set ----
|
|
76
|
-
const subscribedRef = useRef(undefined);
|
|
77
|
-
if (!subscribedRef.current)
|
|
78
|
-
subscribedRef.current = new Set();
|
|
79
|
-
// Runs after every commit — `affected` now reflects this render's reads.
|
|
80
|
-
useEffect(() => {
|
|
81
|
-
const paths = affected
|
|
82
|
-
? affectedToPathList(currSnapshot, affected, true).map((parts) => truncatePath(parts))
|
|
83
|
-
: [];
|
|
84
|
-
const next = new Set(paths.length ? paths : ['']);
|
|
85
|
-
reconcileSubscriptions(subscribedRef.current, next, storeId, componentInstanceId);
|
|
86
|
-
});
|
|
87
|
-
// Drop all subscriptions on unmount.
|
|
88
|
-
useEffect(() => {
|
|
89
|
-
const subscribed = subscribedRef.current;
|
|
90
|
-
return () => {
|
|
91
|
-
for (const path of [...subscribed]) {
|
|
92
|
-
emitSubscription('removed', storeId, path, componentInstanceId);
|
|
93
|
-
}
|
|
94
|
-
subscribed.clear();
|
|
95
|
-
};
|
|
96
|
-
}, [storeId, componentInstanceId]);
|
|
97
|
-
return affected
|
|
98
|
-
? createProxy(currSnapshot, affected, proxyCache, targetCache)
|
|
99
|
-
: currSnapshot;
|
|
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
|
-
}
|
|
130
|
-
/** Add/remove subscriptions so the registry matches `next` exactly. */
|
|
131
|
-
function reconcileSubscriptions(prev, next, storeId, componentInstanceId) {
|
|
132
|
-
for (const path of next) {
|
|
133
|
-
if (!prev.has(path)) {
|
|
134
|
-
emitSubscription('added', storeId, path, componentInstanceId);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
for (const path of [...prev]) {
|
|
138
|
-
if (!next.has(path)) {
|
|
139
|
-
emitSubscription('removed', storeId, path, componentInstanceId);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
prev.clear();
|
|
143
|
-
for (const path of next)
|
|
144
|
-
prev.add(path);
|
|
145
|
-
}
|
|
146
|
-
function emitSubscription(kind, storeId, path, componentInstanceId) {
|
|
147
|
-
if (kind === 'added') {
|
|
148
|
-
addSubscription({ storeId, path, componentInstanceId });
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
removeSubscription({ storeId, path, componentInstanceId });
|
|
152
|
-
}
|
|
153
|
-
const verb = kind === 'added' ? 'sub' : 'unsub';
|
|
154
|
-
publish({
|
|
155
|
-
source: 'valtio',
|
|
156
|
-
category: 'state',
|
|
157
|
-
severity: 'debug',
|
|
158
|
-
title: `subscription-${kind} ${storeId}.${path}`,
|
|
159
|
-
fingerprint: `valtio-${verb}:${storeId}:${path}:${componentInstanceId}`,
|
|
160
|
-
raw: {
|
|
161
|
-
kind: `subscription-${kind}`,
|
|
162
|
-
subscription: { storeId, path, componentInstanceId },
|
|
163
|
-
},
|
|
164
|
-
});
|
|
165
|
-
}
|
|
1
|
+
"use strict";var P=Object.defineProperty;var a=(n,e)=>P(n,"name",{value:e,configurable:!0});var $=Object.defineProperty,i=a((n,e)=>$(n,"name",{value:e,configurable:!0}),"c");import{useCallback as w,useEffect as m,useLayoutEffect as M,useMemo as h,useRef as b,useSyncExternalStore as g}from"react";import{snapshot as l,subscribe as T}from"valtio/vanilla";import{useSnapshot as x}from"valtio/react";import{affectedToPathList as E,createProxy as L,isChanged as C}from"proxy-compare";import{useLensmcpContext as I,publish as W}from"@lensmcp/react-instrumentation";import{addSubscription as N,removeSubscription as _,storeIdOf as A}from"./store-registry.js";const H=new WeakMap;export function useTrackedSnapshot(n,e){const s=I(),t=e.path??"",o=s.componentInstanceId??"react:component:anonymous";return m(()=>(c("added",e.storeId,t,o),()=>{c("removed",e.storeId,t,o)}),[e.storeId,t,o]),x(n)}a(useTrackedSnapshot,"useTrackedSnapshot"),i(useTrackedSnapshot,"useTrackedSnapshot");export function useSnapshot(n){const e=A(n)??"valtio:store:anonymous",s=I().componentInstanceId??"react:component:anonymous",t=h(()=>n&&new WeakMap,[n]),o=b(void 0);let f=!0;const p=g(w(r=>{const u=T(n,r,!1);return r(),u},[n]),()=>{const r=l(n);try{if(!f&&o.current&&t&&!C(o.current,r,t,new WeakMap))return o.current}catch{}return r},()=>l(n));f=!1,M(()=>{o.current=p});const y=h(()=>new WeakMap,[]),d=b(void 0);return d.current||(d.current=new Set),m(()=>{const r=t?E(p,t,!0).map(k=>truncatePath(k)):[],u=new Set(r.length?r:[""]);S(d.current,u,e,s)}),m(()=>{const r=d.current;return()=>{for(const u of[...r])c("removed",e,u,s);r.clear()}},[e,s]),t?L(p,t,y,H):p}a(useSnapshot,"useSnapshot"),i(useSnapshot,"useSnapshot");const v=(()=>{const n=typeof process<"u"?process.env?.LENSMCP_VALTIO_PATH_DEPTH:void 0,e=Number(n);return Number.isFinite(e)&&e>=0&&e<=20?Math.floor(e):3})();export function truncatePath(n){const e=n.map(String);return(v>0?e.slice(0,v):e).join(".")}a(truncatePath,"truncatePath"),i(truncatePath,"truncatePath");function S(n,e,s,t){for(const o of e)n.has(o)||c("added",s,o,t);for(const o of[...n])e.has(o)||c("removed",s,o,t);n.clear();for(const o of e)n.add(o)}a(S,"R"),i(S,"reconcileSubscriptions");function c(n,e,s,t){n==="added"?N({storeId:e,path:s,componentInstanceId:t}):_({storeId:e,path:s,componentInstanceId:t});const o=n==="added"?"sub":"unsub";W({source:"valtio",category:"state",severity:"debug",title:`subscription-${n} ${e}.${s}`,fingerprint:`valtio-${o}:${e}:${s}:${t}`,raw:{kind:`subscription-${n}`,subscription:{storeId:e,path:s,componentInstanceId:t}}})}a(c,"a"),i(c,"emitSubscription");
|
package/lib/store-registry.js
CHANGED
|
@@ -1,58 +1 @@
|
|
|
1
|
-
const
|
|
2
|
-
const stores = new Map();
|
|
3
|
-
// proxy object → its storeId, so the drop-in `useSnapshot(store)` can
|
|
4
|
-
// recover the store id without the caller passing it.
|
|
5
|
-
const proxyStoreIds = new WeakMap();
|
|
6
|
-
export function registerStore(storeId, source) {
|
|
7
|
-
stores.set(storeId, { storeId, source });
|
|
8
|
-
}
|
|
9
|
-
export function tagProxy(proxyObject, storeId) {
|
|
10
|
-
proxyStoreIds.set(proxyObject, storeId);
|
|
11
|
-
}
|
|
12
|
-
export function storeIdOf(proxyObject) {
|
|
13
|
-
return proxyStoreIds.get(proxyObject);
|
|
14
|
-
}
|
|
15
|
-
export function isStoreRegistered(storeId) {
|
|
16
|
-
return stores.has(storeId);
|
|
17
|
-
}
|
|
18
|
-
export function addSubscription(entry) {
|
|
19
|
-
const key = `${entry.storeId}::${entry.path}`;
|
|
20
|
-
let set = subs.get(key);
|
|
21
|
-
if (!set) {
|
|
22
|
-
set = new Set();
|
|
23
|
-
subs.set(key, set);
|
|
24
|
-
}
|
|
25
|
-
set.add(entry.componentInstanceId);
|
|
26
|
-
}
|
|
27
|
-
export function removeSubscription(entry) {
|
|
28
|
-
const key = `${entry.storeId}::${entry.path}`;
|
|
29
|
-
const set = subs.get(key);
|
|
30
|
-
if (set) {
|
|
31
|
-
set.delete(entry.componentInstanceId);
|
|
32
|
-
if (set.size === 0)
|
|
33
|
-
subs.delete(key);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export function subscribersFor(storeId, path) {
|
|
37
|
-
return [...(subs.get(`${storeId}::${path}`) ?? [])];
|
|
38
|
-
}
|
|
39
|
-
/** Walk every prefix of `path` and union the subscribers. Used when a
|
|
40
|
-
* state-update lands on a nested path but parent-path snapshot users
|
|
41
|
-
* also need to be notified. */
|
|
42
|
-
export function subscribersForPathAndParents(storeId, path) {
|
|
43
|
-
const out = new Set();
|
|
44
|
-
const parts = path.split('.');
|
|
45
|
-
for (let i = parts.length; i > 0; i--) {
|
|
46
|
-
const candidate = parts.slice(0, i).join('.');
|
|
47
|
-
for (const id of subscribersFor(storeId, candidate))
|
|
48
|
-
out.add(id);
|
|
49
|
-
}
|
|
50
|
-
// root subscribers
|
|
51
|
-
for (const id of subscribersFor(storeId, ''))
|
|
52
|
-
out.add(id);
|
|
53
|
-
return [...out];
|
|
54
|
-
}
|
|
55
|
-
export function resetRegistry() {
|
|
56
|
-
subs.clear();
|
|
57
|
-
stores.clear();
|
|
58
|
-
}
|
|
1
|
+
"use strict";var f=Object.defineProperty;var o=(e,t)=>f(e,"name",{value:t,configurable:!0});var b=Object.defineProperty,n=o((e,t)=>b(e,"name",{value:t,configurable:!0}),"n");const s=new Map,c=new Map,u=new WeakMap;export function registerStore(e,t){c.set(e,{storeId:e,source:t})}o(registerStore,"registerStore"),n(registerStore,"registerStore");export function tagProxy(e,t){u.set(e,t)}o(tagProxy,"tagProxy"),n(tagProxy,"tagProxy");export function storeIdOf(e){return u.get(e)}o(storeIdOf,"storeIdOf"),n(storeIdOf,"storeIdOf");export function isStoreRegistered(e){return c.has(e)}o(isStoreRegistered,"isStoreRegistered"),n(isStoreRegistered,"isStoreRegistered");export function addSubscription(e){const t=`${e.storeId}::${e.path}`;let r=s.get(t);r||(r=new Set,s.set(t,r)),r.add(e.componentInstanceId)}o(addSubscription,"addSubscription"),n(addSubscription,"addSubscription");export function removeSubscription(e){const t=`${e.storeId}::${e.path}`,r=s.get(t);r&&(r.delete(e.componentInstanceId),r.size===0&&s.delete(t))}o(removeSubscription,"removeSubscription"),n(removeSubscription,"removeSubscription");export function subscribersFor(e,t){return[...s.get(`${e}::${t}`)??[]]}o(subscribersFor,"subscribersFor"),n(subscribersFor,"subscribersFor");export function subscribersForPathAndParents(e,t){const r=new Set,a=t.split(".");for(let i=a.length;i>0;i--){const d=a.slice(0,i).join(".");for(const p of subscribersFor(e,d))r.add(p)}for(const i of subscribersFor(e,""))r.add(i);return[...r]}o(subscribersForPathAndParents,"subscribersForPathAndParents"),n(subscribersForPathAndParents,"subscribersForPathAndParents");export function resetRegistry(){s.clear(),c.clear()}o(resetRegistry,"resetRegistry"),n(resetRegistry,"resetRegistry");
|
package/lib/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
"use strict";export{};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lensmcp/valtio-instrumentation",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.6",
|
|
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.18.
|
|
17
|
+
"@lensmcp/react-instrumentation": "1.18.6",
|
|
18
18
|
"proxy-compare": "^3.0.0",
|
|
19
19
|
"tslib": "^2.3.0"
|
|
20
20
|
},
|