UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

1 lines • 11.7 kB
{"version":3,"file":"route-metadata.cjs","sources":["../../../../src/query/compiler/route-metadata.ts"],"sourcesContent":["import { 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`)\nexport const CALLBACK_INPUT = Symbol(`tanstack_db_callback_input`)\nexport const CALLBACK_SELECTED = Symbol(`tanstack_db_callback_selected`)\nconst ROUTE_METADATA = Symbol(`tanstack_db_route_metadata`)\nexport const INCLUDES_PUBLIC_KEY = Symbol(`includesPublicKey`)\nexport const INCLUDES_ROUTING = Symbol(`includesRouting`)\nconst INTERNAL_ROUTE_KEYS = new Set<PropertyKey>([\n ROUTE_METADATA,\n INCLUDES_PUBLIC_KEY,\n CALLBACK_INPUT,\n CALLBACK_SELECTED,\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 dirty?: true\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 stripRouteMetadata<T extends object>(value: T): T {\n const result = { ...value } as T & Record<PropertyKey, unknown>\n delete result[ROUTE_METADATA]\n return result\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 callbackValue?: unknown,\n): NamespacedRow {\n const scalar = getRoutedScalarMetadata(row)\n const route = scalar ?? getRouteMetadata(row)\n const namespaced = {\n ...getParentContextValue(route?.parentContext),\n [alias]: scalar\n ? scalar.value\n : route\n ? stripRouteMetadata(row as Record<PropertyKey, unknown>)\n : row,\n } as NamespacedRow\n if (route)\n attachRouteMetadata(namespaced, route.correlationKey, route.parentContext)\n if (scalar)\n Object.assign(namespaced, { [INCLUDES_PUBLIC_KEY]: scalar.publicKey })\n if (callbackValue !== undefined && callbackValue !== row)\n Object.assign(namespaced, { [CALLBACK_INPUT]: { [alias]: callbackValue } })\n return namespaced\n}\n\n/** A namespace keeps authored values beside its callback source overrides.\n * A one-element tuple denotes a flat union view: absent fields must disappear,\n * whereas named overrides replace only their own source aliases.\n */\nexport function getCallbackInput<T extends object>(row: T): T {\n const view = (row as Record<PropertyKey, unknown>)[CALLBACK_INPUT]\n if (Array.isArray(view)) {\n const result = { ...view[0] }\n if (`$selected` in row) result.$selected = row.$selected\n return result as T\n }\n return view && typeof view === `object` ? { ...row, ...view } : row\n}\n\n/** Copy public containers while removing private route state at every depth. */\nexport function stripInternalRouteMetadata(value: unknown): unknown {\n return transformPublicContainers(value, (leaf) => leaf, INTERNAL_ROUTE_KEYS)\n}\n\n/** Remove every compiler-owned key before invoking user code. */\nexport function stripInternalCallbackMetadata(value: unknown): unknown {\n return transformPublicContainers(\n value,\n (leaf) => leaf,\n INTERNAL_CALLBACK_KEYS,\n )\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.dirty) return\n container.dirty = true\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 const copy = (container: PublicContainer): object => {\n if (!container.dirty) return container.value\n if (container.copy) return container.copy\n const result = Array.isArray(container.value)\n ? []\n : Object.create(Object.getPrototypeOf(container.value))\n container.copy = result\n for (const key of Reflect.ownKeys(container.properties)) {\n const descriptor = container.properties[key]!\n if (descriptor.child) descriptor.value = copy(descriptor.child)\n }\n return Object.defineProperties(result, container.properties)\n }\n return copy(root)\n}\n\nexport function isPublicContainer(value: unknown): value is object {\n return Array.isArray(value) || isPlainObject(value)\n}\n"],"names":["isPlainObject","getParentContextValue"],"mappings":"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"}