@tanstack/db
Version:
A reactive client store for building super fast apps on sync
1 lines • 13.3 kB
Source Map (JSON)
{"version":3,"file":"route-metadata.cjs","sources":["../../../../src/query/compiler/route-metadata.ts"],"sourcesContent":["import { VIRTUAL_PROP_NAMES } from '../../virtual-props.js'\nimport { isPlainObject } from '../../utils/type-guards.js'\nimport { getParentContextValue } from '../equality-value-identity.js'\nimport type { NamespacedRow } from '../../types.js'\n\nconst ROUTED_SCALAR_VALUE = Symbol(`tanstack_db_routed_scalar_value`)\nconst ROUTE_METADATA = Symbol(`tanstack_db_route_metadata`)\nexport const INCLUDES_PUBLIC_KEY = Symbol(`includesPublicKey`)\nexport const SOURCE_METADATA = Symbol(`sourceMetadata`)\nconst SOURCE_ROUTING = Symbol(`sourceRouting`)\nexport const ROW_METADATA = Symbol(`rowMetadata`)\nexport type RowMetadata = Partial<\n Record<(typeof VIRTUAL_PROP_NAMES)[number], unknown>\n>\n\nexport const INCLUDES_ROUTING = Symbol(`includesRouting`)\nconst INTERNAL_ROUTE_KEYS = new Set<PropertyKey>([\n ROUTE_METADATA,\n INCLUDES_PUBLIC_KEY,\n SOURCE_METADATA,\n ROW_METADATA,\n SOURCE_ROUTING,\n])\nconst INTERNAL_CALLBACK_KEYS = new Set<PropertyKey>([\n ...INTERNAL_ROUTE_KEYS,\n INCLUDES_ROUTING,\n])\n\ntype RoutedResult = {\n [ROUTED_SCALAR_VALUE]: unknown\n [ROUTE_METADATA]: RouteMetadata\n [INCLUDES_PUBLIC_KEY]: unknown\n}\n\ntype PublicContainer = {\n value: object\n properties: Record<\n PropertyKey,\n PropertyDescriptor & { child?: PublicContainer }\n >\n parents: Array<PublicContainer>\n copy?: object\n}\n\nexport type RouteMetadata = {\n correlationKey: unknown\n parentContext: unknown\n}\n\nexport type RoutedScalarMetadata = {\n value: unknown\n correlationKey: unknown\n parentContext: unknown\n publicKey: unknown\n}\n\nexport function attachRouteMetadata<T extends object>(\n value: T,\n correlationKey: unknown,\n parentContext: unknown,\n): T {\n return Object.assign(value, {\n [ROUTE_METADATA]: { correlationKey, parentContext } satisfies RouteMetadata,\n })\n}\n\nexport function getRouteMetadata(value: unknown): RouteMetadata | undefined {\n if (\n value == null ||\n typeof value !== `object` ||\n !(ROUTE_METADATA in value)\n ) {\n return undefined\n }\n return (value as { [ROUTE_METADATA]: RouteMetadata })[ROUTE_METADATA]\n}\n\nexport function getNamespacedRouteMetadata(\n row: unknown,\n source: string,\n): RouteMetadata | undefined {\n return (\n getRouteMetadata(row) ??\n (row != null && typeof row === `object`\n ? getRouteMetadata((row as Record<string, unknown>)[source])\n : undefined)\n )\n}\n\nexport function attachRouteMetadataToResult(\n value: unknown,\n correlationKey: unknown,\n parentContext: unknown,\n publicKey: unknown,\n): unknown {\n if (\n correlationKey === undefined &&\n parentContext === undefined &&\n publicKey === undefined\n ) {\n return value\n }\n\n return Object.assign(\n isPlainObject(value) ? { ...value } : { [ROUTED_SCALAR_VALUE]: value },\n {\n [ROUTE_METADATA]: { correlationKey, parentContext },\n [INCLUDES_PUBLIC_KEY]: publicKey,\n },\n )\n}\n\nexport function getRoutedScalarMetadata(\n value: unknown,\n): RoutedScalarMetadata | undefined {\n if (\n value == null ||\n typeof value !== `object` ||\n !(ROUTED_SCALAR_VALUE in value)\n ) {\n return undefined\n }\n\n const routed = value as RoutedResult\n return {\n value: routed[ROUTED_SCALAR_VALUE],\n ...routed[ROUTE_METADATA],\n publicKey: routed[INCLUDES_PUBLIC_KEY],\n }\n}\n\n/** Give FROM and JOIN rows the same route and callback namespace. */\nexport function wrapInputRow(\n alias: string,\n row: unknown,\n metadata?: RowMetadata | null,\n hasInternalState = true,\n): NamespacedRow {\n if (!hasInternalState) return { [alias]: row } as NamespacedRow\n const scalar = getRoutedScalarMetadata(row)\n const route = scalar ?? getRouteMetadata(row)\n const namespaced = {\n ...getParentContextValue(route?.parentContext),\n [alias]: scalar ? scalar.value : stripInternalCallbackMetadata(row),\n } as NamespacedRow\n if (route)\n attachRouteMetadata(namespaced, route.correlationKey, route.parentContext)\n if (route)\n Object.assign(namespaced, {\n [INCLUDES_PUBLIC_KEY]:\n scalar?.publicKey ??\n (row as Record<PropertyKey, unknown>)[INCLUDES_PUBLIC_KEY],\n })\n if (metadata !== undefined)\n Object.assign(namespaced, { [SOURCE_METADATA]: { [alias]: metadata } })\n if (row !== null && typeof row === `object` && INCLUDES_ROUTING in row)\n Object.assign(namespaced, {\n [SOURCE_ROUTING]: {\n [alias]: (row as Record<PropertyKey, unknown>)[INCLUDES_ROUTING],\n },\n })\n return namespaced\n}\n\n/** Attribution and include routing belong to the namespace, never source data. */\nexport function getSourceMetadata(\n row: Record<PropertyKey, unknown>,\n alias: string,\n): RowMetadata | null {\n const metadata = row[SOURCE_METADATA] as\n Record<string, RowMetadata | null> | undefined\n if (metadata && Object.hasOwn(metadata, alias)) return metadata[alias]!\n const source = row[alias]\n if (source == null || typeof source !== `object`) return null\n const result: RowMetadata = {}\n for (const name of VIRTUAL_PROP_NAMES)\n if (name in source) result[name] = (source as Record<string, unknown>)[name]\n return result\n}\n\nexport function getSourceRouting(\n row: Record<PropertyKey, unknown>,\n alias: string,\n): unknown {\n return (row[SOURCE_ROUTING] as Record<string, unknown> | undefined)?.[alias]\n}\n\nexport function mergeSourceContext(\n target: Record<PropertyKey, unknown>,\n left: Record<PropertyKey, unknown> | undefined,\n right: Record<PropertyKey, unknown> | undefined,\n): void {\n for (const field of [SOURCE_METADATA, SOURCE_ROUTING])\n if (left?.[field] || right?.[field])\n target[field] = {\n ...(left?.[field] as object | undefined),\n ...(right?.[field] as object | undefined),\n }\n}\n\n/** Restore namespace state after resolving its public include paths. */\nexport function restoreInternalRouteMetadata(\n target: Record<PropertyKey, unknown>,\n source: object,\n): void {\n for (const key of INTERNAL_ROUTE_KEYS)\n if (Object.hasOwn(source, key))\n target[key] = (source as Record<PropertyKey, unknown>)[key]\n}\n\n/** Remove private route state from a known result root. */\nexport function stripInternalRouteMetadata(value: unknown): unknown {\n return stripInternalMetadata(value, INTERNAL_ROUTE_KEYS)\n}\n\n/** Remove compiler-owned keys before invoking user code, at the known scope. */\nexport function stripInternalCallbackMetadata(value: unknown): unknown {\n return stripInternalMetadata(value, INTERNAL_CALLBACK_KEYS)\n}\n\nfunction stripInternalMetadata(\n value: unknown,\n keys: ReadonlySet<PropertyKey>,\n): unknown {\n if (!isPublicContainer(value)) return value\n for (const key of keys)\n if (Object.hasOwn(value, key)) {\n const properties: Record<PropertyKey, PropertyDescriptor> =\n Object.getOwnPropertyDescriptors(value)\n for (const omitted of keys) delete properties[omitted]\n return Object.defineProperties(\n createPublicContainerShell(value),\n properties,\n )\n }\n return value\n}\n\n/** Copy only paths changed by a leaf transform or an omitted private key. */\nexport function transformPublicContainers(\n value: unknown,\n transformLeaf: (value: unknown) => unknown,\n omittedKeys: ReadonlySet<PropertyKey>,\n): unknown {\n const rootReplacement = transformLeaf(value)\n if (!Object.is(rootReplacement, value)) return rootReplacement\n if (!isPublicContainer(value)) return value\n\n const containers = new Map<object, PublicContainer>()\n const queue: Array<PublicContainer> = []\n const markDirty = (container: PublicContainer) => {\n if (container.copy) return\n container.copy = createPublicContainerShell(container.value)\n queue.push(container)\n }\n const visit = (current: object): PublicContainer => {\n const existing = containers.get(current)\n if (existing) return existing\n const container: PublicContainer = {\n value: current,\n properties: Object.getOwnPropertyDescriptors(current),\n parents: [],\n }\n containers.set(current, container)\n for (const key of Reflect.ownKeys(container.properties)) {\n if (omittedKeys.has(key)) {\n delete container.properties[key]\n markDirty(container)\n continue\n }\n const descriptor = container.properties[key]!\n if (!descriptor.enumerable || !(`value` in descriptor)) continue\n const child = descriptor.value\n descriptor.value = transformLeaf(child)\n if (!Object.is(descriptor.value, child)) markDirty(container)\n else if (isPublicContainer(child)) {\n descriptor.child = visit(child)\n descriptor.child.parents.push(container)\n }\n }\n return container\n }\n const root = visit(value)\n for (const container of queue) {\n for (const parent of container.parents) markDirty(parent)\n }\n // Every dirty container has a shell before linking children, so shared\n // references and cycles point to the same copy without a second recursion.\n for (const container of queue) {\n for (const key of Reflect.ownKeys(container.properties)) {\n const descriptor = container.properties[key]!\n if (descriptor.child)\n descriptor.value = descriptor.child.copy ?? descriptor.child.value\n }\n Object.defineProperties(container.copy!, container.properties)\n }\n return root.copy ?? value\n}\n\n/** Allocate a descriptor-copy target without losing array prototypes. */\nexport function createPublicContainerShell(value: object): object {\n const prototype = Object.getPrototypeOf(value)\n return Array.isArray(value)\n ? Object.setPrototypeOf([], prototype)\n : Object.create(prototype)\n}\n\nexport function isPublicContainer(value: unknown): value is object {\n return Array.isArray(value) || isPlainObject(value)\n}\n"],"names":["isPlainObject","getParentContextValue","VIRTUAL_PROP_NAMES"],"mappings":";;;;;AAKA,MAAM,6CAA6B,iCAAiC;AACpE,MAAM,wCAAwB,4BAA4B;AACnD,MAAM,6CAA6B,mBAAmB;AACtD,MAAM,yCAAyB,gBAAgB;AACtD,MAAM,wCAAwB,eAAe;AACtC,MAAM,sCAAsB,aAAa;AAKzC,MAAM,0CAA0B,iBAAiB;AACxD,MAAM,0CAA0B,IAAiB;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,MAAM,6CAA6B,IAAiB;AAAA,EAClD,GAAG;AAAA,EACH;AACF,CAAC;AA8BM,SAAS,oBACd,OACA,gBACA,eACG;AACH,SAAO,OAAO,OAAO,OAAO;AAAA,IAC1B,CAAC,cAAc,GAAG,EAAE,gBAAgB,cAAA;AAAA,EAAc,CACnD;AACH;AAEO,SAAS,iBAAiB,OAA2C;AAC1E,MACE,SAAS,QACT,OAAO,UAAU,YACjB,EAAE,kBAAkB,QACpB;AACA,WAAO;AAAA,EACT;AACA,SAAQ,MAA8C,cAAc;AACtE;AAEO,SAAS,2BACd,KACA,QAC2B;AAC3B,SACE,iBAAiB,GAAG,MACnB,OAAO,QAAQ,OAAO,QAAQ,WAC3B,iBAAkB,IAAgC,MAAM,CAAC,IACzD;AAER;AAEO,SAAS,4BACd,OACA,gBACA,eACA,WACS;AACT,MACE,mBAAmB,UACnB,kBAAkB,UAClB,cAAc,QACd;AACA,WAAO;AAAA,EACT;AAEA,SAAO,OAAO;AAAA,IACZA,WAAAA,cAAc,KAAK,IAAI,EAAE,GAAG,MAAA,IAAU,EAAE,CAAC,mBAAmB,GAAG,MAAA;AAAA,IAC/D;AAAA,MACE,CAAC,cAAc,GAAG,EAAE,gBAAgB,cAAA;AAAA,MACpC,CAAC,mBAAmB,GAAG;AAAA,IAAA;AAAA,EACzB;AAEJ;AAEO,SAAS,wBACd,OACkC;AAClC,MACE,SAAS,QACT,OAAO,UAAU,YACjB,EAAE,uBAAuB,QACzB;AACA,WAAO;AAAA,EACT;AAEA,QAAM,SAAS;AACf,SAAO;AAAA,IACL,OAAO,OAAO,mBAAmB;AAAA,IACjC,GAAG,OAAO,cAAc;AAAA,IACxB,WAAW,OAAO,mBAAmB;AAAA,EAAA;AAEzC;AAGO,SAAS,aACd,OACA,KACA,UACA,mBAAmB,MACJ;AACf,MAAI,CAAC,iBAAkB,QAAO,EAAE,CAAC,KAAK,GAAG,IAAA;AACzC,QAAM,SAAS,wBAAwB,GAAG;AAC1C,QAAM,QAAQ,UAAU,iBAAiB,GAAG;AAC5C,QAAM,aAAa;AAAA,IACjB,GAAGC,sBAAAA,sBAAsB,OAAO,aAAa;AAAA,IAC7C,CAAC,KAAK,GAAG,SAAS,OAAO,QAAQ,8BAA8B,GAAG;AAAA,EAAA;AAEpE,MAAI;AACF,wBAAoB,YAAY,MAAM,gBAAgB,MAAM,aAAa;AAC3E,MAAI;AACF,WAAO,OAAO,YAAY;AAAA,MACxB,CAAC,mBAAmB,GAClB,QAAQ,aACP,IAAqC,mBAAmB;AAAA,IAAA,CAC5D;AACH,MAAI,aAAa;AACf,WAAO,OAAO,YAAY,EAAE,CAAC,eAAe,GAAG,EAAE,CAAC,KAAK,GAAG,SAAA,GAAY;AACxE,MAAI,QAAQ,QAAQ,OAAO,QAAQ,YAAY,oBAAoB;AACjE,WAAO,OAAO,YAAY;AAAA,MACxB,CAAC,cAAc,GAAG;AAAA,QAChB,CAAC,KAAK,GAAI,IAAqC,gBAAgB;AAAA,MAAA;AAAA,IACjE,CACD;AACH,SAAO;AACT;AAGO,SAAS,kBACd,KACA,OACoB;AACpB,QAAM,WAAW,IAAI,eAAe;AAEpC,MAAI,YAAY,OAAO,OAAO,UAAU,KAAK,EAAG,QAAO,SAAS,KAAK;AACrE,QAAM,SAAS,IAAI,KAAK;AACxB,MAAI,UAAU,QAAQ,OAAO,WAAW,SAAU,QAAO;AACzD,QAAM,SAAsB,CAAA;AAC5B,aAAW,QAAQC,aAAAA;AACjB,QAAI,QAAQ,OAAQ,QAAO,IAAI,IAAK,OAAmC,IAAI;AAC7E,SAAO;AACT;AAEO,SAAS,iBACd,KACA,OACS;AACT,SAAQ,IAAI,cAAc,IAA4C,KAAK;AAC7E;AAEO,SAAS,mBACd,QACA,MACA,OACM;AACN,aAAW,SAAS,CAAC,iBAAiB,cAAc;AAClD,QAAI,OAAO,KAAK,KAAK,QAAQ,KAAK;AAChC,aAAO,KAAK,IAAI;AAAA,QACd,GAAI,OAAO,KAAK;AAAA,QAChB,GAAI,QAAQ,KAAK;AAAA,MAAA;AAEzB;AAGO,SAAS,6BACd,QACA,QACM;AACN,aAAW,OAAO;AAChB,QAAI,OAAO,OAAO,QAAQ,GAAG;AAC3B,aAAO,GAAG,IAAK,OAAwC,GAAG;AAChE;AAGO,SAAS,2BAA2B,OAAyB;AAClE,SAAO,sBAAsB,OAAO,mBAAmB;AACzD;AAGO,SAAS,8BAA8B,OAAyB;AACrE,SAAO,sBAAsB,OAAO,sBAAsB;AAC5D;AAEA,SAAS,sBACP,OACA,MACS;AACT,MAAI,CAAC,kBAAkB,KAAK,EAAG,QAAO;AACtC,aAAW,OAAO;AAChB,QAAI,OAAO,OAAO,OAAO,GAAG,GAAG;AAC7B,YAAM,aACJ,OAAO,0BAA0B,KAAK;AACxC,iBAAW,WAAW,KAAM,QAAO,WAAW,OAAO;AACrD,aAAO,OAAO;AAAA,QACZ,2BAA2B,KAAK;AAAA,QAChC;AAAA,MAAA;AAAA,IAEJ;AACF,SAAO;AACT;AAgEO,SAAS,2BAA2B,OAAuB;AAChE,QAAM,YAAY,OAAO,eAAe,KAAK;AAC7C,SAAO,MAAM,QAAQ,KAAK,IACtB,OAAO,eAAe,CAAA,GAAI,SAAS,IACnC,OAAO,OAAO,SAAS;AAC7B;AAEO,SAAS,kBAAkB,OAAiC;AACjE,SAAO,MAAM,QAAQ,KAAK,KAAKF,WAAAA,cAAc,KAAK;AACpD;;;;;;;;;;;;;;;;;;;"}