synapse-storage
Version:
Набор инструментов для управления состоянием и апи-запросами
58 lines (56 loc) • 2.06 kB
JavaScript
/**
* Creates a dummy Proxy state object for path extraction.
*/ function createDummyState() {
const handler = {
get: (target, prop)=>{
target[prop] = target[prop] || new Proxy({}, handler);
return target[prop];
}
};
return new Proxy({}, handler);
}
/**
* Extracts the property path from a selector function using Proxy.
*
* **Limitations:**
* - Does not support conditional logic (if/ternary): Proxy records ALL accessed paths
* and returns the longest, which leads to subscription on the wrong path.
* - Does not support destructuring or array methods (map, filter, etc.)
* - For such cases use string-based subscription: `storage.subscribe('user.permissions', callback)`
*/ function extractPath(selector, dummyState, cache) {
if (cache?.has(selector)) {
return cache.get(selector);
}
const accessedPaths = [];
const createProxyHandler = (path = '')=>({
get: (_target, prop)=>{
if (typeof prop === 'symbol') {
return Reflect.get(_target, prop);
}
const currentPath = path ? `${path}.${prop}` : prop;
accessedPaths.push(currentPath);
return new Proxy({}, createProxyHandler(currentPath));
},
has: ()=>true,
ownKeys: ()=>[],
getOwnPropertyDescriptor: ()=>({
configurable: true,
enumerable: true
}),
apply: ()=>{
return new Proxy(()=>{}, createProxyHandler(path));
}
});
try {
selector(new Proxy(dummyState, createProxyHandler()));
} catch {
// Ignore errors from accessing non-existent properties
}
if (accessedPaths.length === 0) return '';
accessedPaths.sort((a, b)=>b.length - a.length);
const result = accessedPaths[0];
cache?.set(selector, result);
return result;
}
export { createDummyState, extractPath };
//# sourceMappingURL=path-selector.util.js.map