UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

1 lines • 7.48 kB
{"version":3,"file":"public-key-reduction.cjs","sources":["../../../../src/query/live/public-key-reduction.ts"],"sourcesContent":["import { map, reduce, serializeValue } from '@tanstack/db-ivm'\nimport { deepEquals } from '../../utils.js'\nimport { getParentContextIdentity } from '../equality-value-identity.js'\nimport { INCLUDES_ROUTING } from '../compiler/route-metadata.js'\nimport { codedMessage, devBuild } from '../../error-message.js'\nimport type { ValueIdentity } from '../equality-value-identity.js'\nimport type { CompilationResult } from '../compiler/index.js'\nimport type { ResultStream } from '../../types.js'\n\n// Public-key reduction. A joined query with a custom key needs only this\n// part of materialization, so it ships in core without the include\n// materializer.\n\nexport type ResultTuple = [\n value: Record<PropertyKey, any>,\n order: string | undefined,\n correlationKey?: unknown,\n parentContext?: Record<string, any> | null,\n routing?: IncludesRouting,\n publicKey?: unknown,\n]\n\nexport type IncludesRouting = Record<string, IncludeRoute>\n\nexport type IncludeRoute = {\n active: boolean\n correlationKey: unknown\n parentContext: Record<string, any> | null\n}\n\nexport type CanonicalResult = {\n publicKey: unknown\n tuple: ResultTuple\n}\n\nexport type RelationScope = `root` | `child`\n\nexport function exposeRouting(pipeline: ResultStream): ResultStream {\n return pipeline.pipe(\n map(([key, rawTuple]) => {\n const tuple = rawTuple as ResultTuple\n return [\n key,\n [\n tuple[0],\n tuple[1],\n tuple[2],\n tuple[3],\n tuple[0][INCLUDES_ROUTING],\n tuple[4],\n ],\n ]\n }),\n ) as unknown as ResultStream\n}\n\nexport function canonicalizeByPublicKey(\n pipeline: ResultStream,\n getKey: ((row: any) => unknown) | undefined,\n scope: RelationScope,\n valueIdentity: ValueIdentity,\n): ResultStream {\n return pipeline.pipe(\n map(([internalKey, rawTuple]) => {\n const tuple = rawTuple as ResultTuple\n const publicKey = getKey ? getKey(tuple[0]) : (tuple[5] ?? internalKey)\n const relationKey =\n scope === `root`\n ? serializeValue([`root`, publicKey])\n : serializeValue([\n routeKey(tuple[2], tuple[3], valueIdentity),\n publicKey,\n ])\n return [relationKey, { publicKey, tuple }] as [string, CanonicalResult]\n }),\n reduce((values: Array<[CanonicalResult, number]>) => {\n const totalMultiplicity = values.reduce(\n (total, [, multiplicity]) => total + multiplicity,\n 0,\n )\n if (totalMultiplicity === 0) return []\n if (totalMultiplicity < 0) {\n throw new Error(\n devBuild() && process.env.NODE_ENV !== `production`\n ? `Canonical query row has negative multiplicity`\n : codedMessage(154),\n )\n }\n\n const visible = values.find(([, multiplicity]) => multiplicity > 0)?.[0]\n if (!visible) {\n throw new Error(\n devBuild() && process.env.NODE_ENV !== `production`\n ? `Canonical query row has no positive contributor`\n : codedMessage(155),\n )\n }\n\n for (const [candidate, multiplicity] of values) {\n if (multiplicity <= 0) continue\n assertCongruentContributors(visible, candidate)\n }\n\n return [[visible, 1]]\n }),\n map(([relationKey, { publicKey, tuple }]) => [\n scope === `root` ? publicKey : relationKey,\n tuple,\n ]),\n ) as ResultStream\n}\n\nfunction assertCongruentContributors(\n left: CanonicalResult,\n right: CanonicalResult,\n): void {\n const [leftValue, leftOrder, leftCorrelation, leftContext, leftRouting] =\n left.tuple\n const [rightValue, rightOrder, rightCorrelation, rightContext, rightRouting] =\n right.tuple\n\n if (\n leftOrder !== rightOrder ||\n !deepEquals(leftValue, rightValue) ||\n !deepEquals(leftCorrelation, rightCorrelation) ||\n !deepEquals(leftContext, rightContext) ||\n !deepEquals(leftRouting, rightRouting)\n ) {\n throw new Error(\n devBuild() && process.env.NODE_ENV !== `production`\n ? `Query contributors for public key ${serializeValue(left.publicKey)} are not congruent`\n : codedMessage(156, { publicKey: left.publicKey }),\n )\n }\n}\n\nexport function routeKey(\n correlationKey: unknown,\n parentContext: Record<string, any> | null | undefined,\n valueIdentity: ValueIdentity,\n): string {\n return serializeValue([\n valueIdentity.equality(correlationKey ?? null),\n getParentContextIdentity(parentContext ?? null),\n ])\n}\n\n/** Reduces a query without includes to one canonical row per public key. */\nexport function reducePublicKeys(\n compilation: CompilationResult,\n getKey: (row: any) => unknown,\n): { pipeline: ResultStream; facades: undefined } {\n return {\n pipeline: canonicalizeByPublicKey(\n exposeRouting(compilation.pipeline),\n getKey,\n `root`,\n compilation.valueIdentity,\n ),\n facades: undefined,\n }\n}\n"],"names":["map","INCLUDES_ROUTING","serializeValue","reduce","devBuild","codedMessage","deepEquals","getParentContextIdentity"],"mappings":";;;;;;;AAqCO,SAAS,cAAc,UAAsC;AAClE,SAAO,SAAS;AAAA,IACdA,MAAAA,IAAI,CAAC,CAAC,KAAK,QAAQ,MAAM;AACvB,YAAM,QAAQ;AACd,aAAO;AAAA,QACL;AAAA,QACA;AAAA,UACE,MAAM,CAAC;AAAA,UACP,MAAM,CAAC;AAAA,UACP,MAAM,CAAC;AAAA,UACP,MAAM,CAAC;AAAA,UACP,MAAM,CAAC,EAAEC,8BAAgB;AAAA,UACzB,MAAM,CAAC;AAAA,QAAA;AAAA,MACT;AAAA,IAEJ,CAAC;AAAA,EAAA;AAEL;AAEO,SAAS,wBACd,UACA,QACA,OACA,eACc;AACd,SAAO,SAAS;AAAA,IACdD,MAAAA,IAAI,CAAC,CAAC,aAAa,QAAQ,MAAM;AAC/B,YAAM,QAAQ;AACd,YAAM,YAAY,SAAS,OAAO,MAAM,CAAC,CAAC,IAAK,MAAM,CAAC,KAAK;AAC3D,YAAM,cACJ,UAAU,SACNE,MAAAA,eAAe,CAAC,QAAQ,SAAS,CAAC,IAClCA,MAAAA,eAAe;AAAA,QACb,SAAS,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,aAAa;AAAA,QAC1C;AAAA,MAAA,CACD;AACP,aAAO,CAAC,aAAa,EAAE,WAAW,OAAO;AAAA,IAC3C,CAAC;AAAA,IACDC,MAAAA,OAAO,CAAC,WAA6C;AACnD,YAAM,oBAAoB,OAAO;AAAA,QAC/B,CAAC,OAAO,CAAA,EAAG,YAAY,MAAM,QAAQ;AAAA,QACrC;AAAA,MAAA;AAEF,UAAI,sBAAsB,EAAG,QAAO,CAAA;AACpC,UAAI,oBAAoB,GAAG;AACzB,cAAM,IAAI;AAAA,UACRC,sBAAA,KAAc,QAAQ,IAAI,aAAa,eACnC,kDACAC,aAAAA,aAAa,GAAG;AAAA,QAAA;AAAA,MAExB;AAEA,YAAM,UAAU,OAAO,KAAK,CAAC,CAAA,EAAG,YAAY,MAAM,eAAe,CAAC,IAAI,CAAC;AACvE,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI;AAAA,UACRD,sBAAA,KAAc,QAAQ,IAAI,aAAa,eACnC,oDACAC,aAAAA,aAAa,GAAG;AAAA,QAAA;AAAA,MAExB;AAEA,iBAAW,CAAC,WAAW,YAAY,KAAK,QAAQ;AAC9C,YAAI,gBAAgB,EAAG;AACvB,oCAA4B,SAAS,SAAS;AAAA,MAChD;AAEA,aAAO,CAAC,CAAC,SAAS,CAAC,CAAC;AAAA,IACtB,CAAC;AAAA,IACDL,MAAAA,IAAI,CAAC,CAAC,aAAa,EAAE,WAAW,MAAA,CAAO,MAAM;AAAA,MAC3C,UAAU,SAAS,YAAY;AAAA,MAC/B;AAAA,IAAA,CACD;AAAA,EAAA;AAEL;AAEA,SAAS,4BACP,MACA,OACM;AACN,QAAM,CAAC,WAAW,WAAW,iBAAiB,aAAa,WAAW,IACpE,KAAK;AACP,QAAM,CAAC,YAAY,YAAY,kBAAkB,cAAc,YAAY,IACzE,MAAM;AAER,MACE,cAAc,cACd,CAACM,MAAAA,WAAW,WAAW,UAAU,KACjC,CAACA,MAAAA,WAAW,iBAAiB,gBAAgB,KAC7C,CAACA,MAAAA,WAAW,aAAa,YAAY,KACrC,CAACA,iBAAW,aAAa,YAAY,GACrC;AACA,UAAM,IAAI;AAAA,MACRF,2BAAc,QAAQ,IAAI,aAAa,eACnC,qCAAqCF,MAAAA,eAAe,KAAK,SAAS,CAAC,uBACnEG,aAAAA,aAAa,KAAK,EAAE,WAAW,KAAK,WAAW;AAAA,IAAA;AAAA,EAEvD;AACF;AAEO,SAAS,SACd,gBACA,eACA,eACQ;AACR,SAAOH,qBAAe;AAAA,IACpB,cAAc,SAAS,kBAAkB,IAAI;AAAA,IAC7CK,sBAAAA,yBAAyB,iBAAiB,IAAI;AAAA,EAAA,CAC/C;AACH;AAGO,SAAS,iBACd,aACA,QACgD;AAChD,SAAO;AAAA,IACL,UAAU;AAAA,MACR,cAAc,YAAY,QAAQ;AAAA,MAClC;AAAA,MACA;AAAA,MACA,YAAY;AAAA,IAAA;AAAA,IAEd,SAAS;AAAA,EAAA;AAEb;;;;;"}