@tanstack/vue-table
Version:
Headless UI for building powerful tables & datagrids for Vue.
74 lines (73 loc) • 1.9 kB
JavaScript
//#region src/merge-proxy.ts
function trueFn() {
return true;
}
const $PROXY = Symbol("merge-proxy");
const $SOURCES = Symbol("merge-proxy-sources");
const propTraps = {
get(_, property, receiver) {
if (property === $PROXY) return receiver;
if (property === $SOURCES) return _.sources;
return _.get(property);
},
has(_, property) {
return _.has(property);
},
set: trueFn,
deleteProperty: trueFn,
getOwnPropertyDescriptor(_, property) {
return {
configurable: true,
enumerable: true,
get() {
return _.get(property);
},
set: trueFn,
deleteProperty: trueFn
};
},
ownKeys(_) {
return _.keys();
}
};
function resolveSource(s) {
return s && typeof s === "object" && "value" in s ? s.value : s;
}
function mergeProxy(...sources) {
const flattenedSources = sources.flatMap((source) => {
if (typeof source === "object" && source !== null && $SOURCES in source && Array.isArray(source[$SOURCES])) return source[$SOURCES];
return [source];
});
return new Proxy({
sources: flattenedSources,
get(property) {
for (let i = flattenedSources.length - 1; i >= 0; i--) {
const v = resolveSource(flattenedSources[i])[property];
if (v !== void 0) return v;
}
},
has(property) {
for (let i = flattenedSources.length - 1; i >= 0; i--) if (property in resolveSource(flattenedSources[i])) return true;
return false;
},
keys() {
const keys = [];
for (const source of flattenedSources) keys.push(...Object.keys(resolveSource(source)));
return [...Array.from(new Set(keys))];
}
}, propTraps);
}
function flatMerge(...sources) {
const result = {};
for (let source of sources) {
source = resolveSource(source);
if (!source) continue;
for (const key of Reflect.ownKeys(source)) {
const value = source[key];
if (value !== void 0) result[key] = value;
}
}
return result;
}
//#endregion
export { flatMerge, mergeProxy };