@tanstack/db
Version:
A reactive client store for building super fast apps on sync
1 lines • 8.11 kB
Source Map (JSON)
{"version":3,"file":"lazy-targets.cjs","sources":["../../../../src/query/compiler/lazy-targets.ts"],"sourcesContent":["import { PropRef, followRef } from '../ir.js'\nimport type {\n BasicExpression,\n CollectionRef,\n From,\n QueryIR,\n QueryRef,\n} from '../ir.js'\nimport type { Collection } from '../../collection/index.js'\n\nexport type LazyLoadTarget = {\n alias: string\n collection: Collection\n path: Array<string>\n}\n\nexport function getLazyLoadTargets(\n rawQuery: QueryIR,\n lazyFrom: From,\n lazyAlias: string,\n lazySourceExpr: BasicExpression,\n lazySource: Collection | undefined,\n aliasRemapping: Record<string, string>,\n): Array<LazyLoadTarget> {\n if (lazyFrom.type === `unionFrom`) {\n return getTargetsFromExpression(rawQuery, lazySourceExpr)\n }\n\n if (lazyFrom.type === `queryRef` && containsUnionFrom(lazyFrom.query.from)) {\n const targets = getTargetsFromQueryRef(\n lazyFrom.query,\n lazyAlias,\n lazySourceExpr,\n )\n return dedupeLazyLoadTargets(targets)\n }\n\n if (!lazySource) {\n return []\n }\n\n const lazySourceRef = toPropRef(lazySourceExpr)\n if (!lazySourceRef) {\n return []\n }\n\n const followRefResult = followRef(rawQuery, lazySourceRef, lazySource)\n if (!followRefResult) {\n return []\n }\n\n return [\n {\n alias: aliasRemapping[lazyAlias] || lazyAlias,\n collection: followRefResult.collection,\n path: followRefResult.path,\n },\n ]\n}\n\nexport function containsUnionFrom(from: From): boolean {\n if (from.type === `unionFrom`) {\n return true\n }\n if (from.type === `queryRef`) {\n return containsUnionFrom(from.query.from)\n }\n if (from.type === `unionAll`) {\n return from.queries.some((query) => containsUnionFrom(query.from))\n }\n return false\n}\n\nfunction getTargetsFromQueryRef(\n query: QueryIR,\n outerAlias: string,\n expr: unknown,\n): Array<LazyLoadTarget> {\n if (!expr || typeof expr !== `object` || !(`type` in expr)) {\n return []\n }\n\n const expression = expr as BasicExpression\n if (expression.type === `func` && expression.name === `coalesce`) {\n return dedupeLazyLoadTargets(\n expression.args.flatMap((arg) =>\n getTargetsFromQueryRef(query, outerAlias, arg),\n ),\n )\n }\n\n const ref = toPropRef(expression)\n if (!ref || ref.path[0] !== outerAlias) {\n return []\n }\n\n return getTargetsFromPropRef(query, new PropRef(ref.path.slice(1)))\n}\n\nfunction getTargetsFromExpression(\n query: QueryIR,\n expr: unknown,\n): Array<LazyLoadTarget> {\n if (!expr || typeof expr !== `object` || !(`type` in expr)) {\n return []\n }\n\n const expression = expr as BasicExpression\n if (expression.type === `ref`) {\n return getTargetsFromPropRef(query, expression)\n }\n\n if (expression.type === `func` && expression.name === `coalesce`) {\n return dedupeLazyLoadTargets(\n expression.args.flatMap((arg) => getTargetsFromExpression(query, arg)),\n )\n }\n\n return []\n}\n\nfunction getTargetsFromPropRef(\n query: QueryIR,\n ref: PropRef,\n): Array<LazyLoadTarget> {\n if (ref.path.length === 0) {\n return []\n }\n\n if (ref.path.length === 1) {\n const field = ref.path[0]!\n const selectedField = query.select?.[field]\n if (selectedField) {\n return getTargetsFromExpression(query, selectedField)\n }\n return []\n }\n\n const [alias, ...path] = ref.path\n const source = getSourceFromAlias(query, alias!)\n if (!source) {\n return []\n }\n\n if (source.type === `collectionRef`) {\n return [{ alias: source.alias, collection: source.collection, path }]\n }\n\n if (source.query.limit || source.query.offset) {\n return []\n }\n\n return getTargetsFromQueryRef(source.query, source.alias, ref)\n}\n\nfunction getSourceFromAlias(\n query: QueryIR,\n alias: string,\n): CollectionRef | QueryRef | undefined {\n if (query.join) {\n for (const join of query.join) {\n if (join.from.alias === alias) {\n return join.from\n }\n }\n }\n\n const from = query.from\n const sources =\n from.type === `unionFrom`\n ? from.sources\n : from.type === `unionAll`\n ? []\n : [from]\n return sources.find((source) => source.alias === alias)\n}\n\nfunction dedupeLazyLoadTargets(\n targets: Array<LazyLoadTarget>,\n): Array<LazyLoadTarget> {\n const seen = new Set<string>()\n const deduped: Array<LazyLoadTarget> = []\n for (const target of targets) {\n const key = `${target.alias}:${target.path.join(`.`)}`\n if (!seen.has(key)) {\n seen.add(key)\n deduped.push(target)\n }\n }\n return deduped\n}\n\nfunction toPropRef(expr: unknown): PropRef | undefined {\n if (expr instanceof PropRef) {\n return expr\n }\n if (\n expr &&\n typeof expr === `object` &&\n `type` in expr &&\n (expr as { type?: string }).type === `ref` &&\n Array.isArray((expr as { path?: unknown }).path)\n ) {\n return new PropRef((expr as unknown as { path: Array<string> }).path)\n }\n return undefined\n}\n"],"names":["followRef","PropRef"],"mappings":"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"}