@tanstack/db
Version:
A reactive client store for building super fast apps on sync
187 lines (186 loc) • 5.51 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const ir = require("../ir.cjs");
function getLazyLoadTargets(rawQuery, lazyFrom, lazyAlias, lazySourceExpr, lazySource, aliasRemapping) {
if (lazyFrom.type === `unionFrom`) {
return getTargetsFromExpression(rawQuery, lazySourceExpr);
}
if (lazyFrom.type === `queryRef` && containsUnionFrom(lazyFrom.query.from)) {
const targets = getTargetsFromQueryRef(
lazyFrom.query,
lazyAlias,
lazySourceExpr
);
return dedupeLazyLoadTargets(targets);
}
if (!lazySource) {
return [];
}
const lazySourceRef = toPropRef(lazySourceExpr);
if (!lazySourceRef) {
return [];
}
const followRefResult = ir.followRef(rawQuery, lazySourceRef, lazySource);
if (!followRefResult) {
return [];
}
const alias = followRefResult.alias || aliasRemapping[lazyAlias] || lazyAlias;
const source = resolveLazySource(rawQuery, lazyFrom, {
alias,
collection: followRefResult.collection
});
if (!source) {
return [];
}
return [
{
sourceId: source.sourceId,
alias,
collection: followRefResult.collection,
path: followRefResult.path
}
];
}
function containsUnionFrom(from) {
if (from.type === `unionFrom`) {
return true;
}
if (from.type === `queryRef`) {
return containsUnionFrom(from.query.from);
}
if (from.type === `unionAll`) {
return from.queries.some((query) => containsUnionFrom(query.from));
}
return false;
}
function getTargetsFromQueryRef(query, outerAlias, expr) {
if (!expr || typeof expr !== `object` || !(`type` in expr)) {
return [];
}
const expression = expr;
if (expression.type === `func` && expression.name === `coalesce`) {
return dedupeLazyLoadTargets(
expression.args.flatMap(
(arg) => getTargetsFromQueryRef(query, outerAlias, arg)
)
);
}
const ref = toPropRef(expression);
if (!ref || ref.path[0] !== outerAlias) {
return [];
}
return getTargetsFromPropRef(query, new ir.PropRef(ref.path.slice(1)));
}
function getTargetsFromExpression(query, expr) {
if (!expr || typeof expr !== `object` || !(`type` in expr)) {
return [];
}
const expression = expr;
if (expression.type === `ref`) {
return getTargetsFromPropRef(query, expression);
}
if (expression.type === `func` && expression.name === `coalesce`) {
return dedupeLazyLoadTargets(
expression.args.flatMap((arg) => getTargetsFromExpression(query, arg))
);
}
return [];
}
function getTargetsFromPropRef(query, ref) {
if (ref.path.length === 0) {
return [];
}
if (ref.path.length === 1) {
const field = ref.path[0];
const selectedField = query.select?.[field];
if (selectedField) {
return getTargetsFromExpression(query, selectedField);
}
return [];
}
const [alias, ...path] = ref.path;
const source = getSourceFromAlias(query, alias);
if (!source) {
return [];
}
if (source.type === `collectionRef`) {
return [
{
sourceId: source.sourceId,
alias: source.alias,
collection: source.collection,
path
}
];
}
if (source.query.limit || source.query.offset) {
return [];
}
return getTargetsFromQueryRef(source.query, source.alias, ref);
}
function getSourceFromAlias(query, alias) {
if (query.join) {
for (const join of query.join) {
if (join.from.alias === alias) {
return join.from;
}
}
}
const from = query.from;
const sources = from.type === `unionFrom` ? from.sources : from.type === `unionAll` ? [] : [from];
return sources.find((source) => source.alias === alias);
}
function resolveLazySource(query, lazyFrom, target) {
const source = findCollectionSource(query, target.alias, target.collection);
if (source) return source;
if (lazyFrom.type === `collectionRef` && lazyFrom.collection === target.collection && lazyFrom.alias === target.alias) {
return lazyFrom;
}
return void 0;
}
function findCollectionSource(query, alias, collection) {
const sources = [
...query.from.type === `unionFrom` ? query.from.sources : query.from.type === `unionAll` ? [] : [query.from],
...query.join?.map((join) => join.from) ?? []
];
for (const source of sources) {
if (source.type === `collectionRef` && source.alias === alias && source.collection === collection) {
return source;
}
if (source.type === `queryRef`) {
const nested = findCollectionSource(source.query, alias, collection);
if (nested) return nested;
}
}
if (query.from.type === `unionAll`) {
for (const branch of query.from.queries) {
const nested = findCollectionSource(branch, alias, collection);
if (nested) return nested;
}
}
return void 0;
}
function dedupeLazyLoadTargets(targets) {
const seen = /* @__PURE__ */ new Set();
const deduped = [];
for (const target of targets) {
const key = `${target.sourceId}:${target.path.join(`.`)}`;
if (!seen.has(key)) {
seen.add(key);
deduped.push(target);
}
}
return deduped;
}
function toPropRef(expr) {
if (expr instanceof ir.PropRef) {
return expr;
}
if (expr && typeof expr === `object` && `type` in expr && expr.type === `ref` && Array.isArray(expr.path)) {
return new ir.PropRef(expr.path);
}
return void 0;
}
exports.containsUnionFrom = containsUnionFrom;
exports.getLazyLoadTargets = getLazyLoadTargets;
//# sourceMappingURL=lazy-targets.cjs.map