{"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":"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"}