@tanstack/electric-db-collection
Version:
ElectricSQL collection for TanStack DB
1 lines • 5.27 kB
Source Map (JSON)
{"version":3,"file":"tag-index.cjs","sources":["../../src/tag-index.ts"],"sourcesContent":["// Import Row and Message types for the isEventMessage function\nimport type { Message, Row } from '@electric-sql/client'\n\nexport type RowId = string | number\nexport type MoveTag = string\nexport type ParsedMoveTag = Array<string>\nexport type Position = number\nexport type Value = string\nexport type MoveOutPattern = {\n pos: Position\n value: Value\n}\n\nconst TAG_WILDCARD = `_`\n\n/**\n * Event message type for move-out events\n */\nexport interface EventMessage {\n headers: {\n event: `move-out`\n patterns: Array<MoveOutPattern>\n }\n}\n\n/**\n * Tag index structure: array indexed by position, maps value to set of row IDs.\n * For example:\n * ```example\n * const tag1 = [a, b, c]\n * const tag2 = [a, b, d]\n * const tag3 = [a, d, e]\n *\n * // Index is:\n * [\n * new Map([a -> <rows with a on index 0>])\n * new Map([b -> <rows with b on index 1>, d -> <rows with d on index 1>])\n * new Map([c -> <rows with c on index 2>, d -> <rows with d on index 2>, e -> <rows with e on index 2>])\n * ]\n * ```\n */\nexport type TagIndex = Array<Map<Value, Set<RowId>>>\n\n/**\n * Abstraction to get the value at a specific position in a tag\n */\nexport function getValue(tag: ParsedMoveTag, position: Position): Value {\n if (position >= tag.length) {\n throw new Error(`Position out of bounds`)\n }\n return tag[position]!\n}\n\n/**\n * Abstraction to extract position and value from a pattern.\n */\nfunction getPositionalValue(pattern: MoveOutPattern): {\n pos: number\n value: string\n} {\n return pattern\n}\n\n/**\n * Abstraction to get the length of a tag\n */\nexport function getTagLength(tag: ParsedMoveTag): number {\n return tag.length\n}\n\n/**\n * Check if a tag matches a pattern.\n * A tag matches if the value at the pattern's position equals the pattern's value,\n * or if the value at that position is \"_\" (wildcard).\n */\nexport function tagMatchesPattern(\n tag: ParsedMoveTag,\n pattern: MoveOutPattern,\n): boolean {\n const { pos, value } = getPositionalValue(pattern)\n const tagValue = getValue(tag, pos)\n return tagValue === value || tagValue === TAG_WILDCARD\n}\n\n/**\n * Add a tag to the index for efficient pattern matching\n */\nexport function addTagToIndex(\n tag: ParsedMoveTag,\n rowId: RowId,\n index: TagIndex,\n tagLength: number,\n): void {\n for (let i = 0; i < tagLength; i++) {\n const value = getValue(tag, i)\n\n // Only index non-wildcard values\n if (value !== TAG_WILDCARD) {\n const positionIndex = index[i]!\n if (!positionIndex.has(value)) {\n positionIndex.set(value, new Set())\n }\n\n const tags = positionIndex.get(value)!\n tags.add(rowId)\n }\n }\n}\n\n/**\n * Remove a tag from the index\n */\nexport function removeTagFromIndex(\n tag: ParsedMoveTag,\n rowId: RowId,\n index: TagIndex,\n tagLength: number,\n): void {\n for (let i = 0; i < tagLength; i++) {\n const value = getValue(tag, i)\n\n // Only remove non-wildcard values\n if (value !== TAG_WILDCARD) {\n const positionIndex = index[i]\n if (positionIndex) {\n const rowSet = positionIndex.get(value)\n if (rowSet) {\n rowSet.delete(rowId)\n\n // Clean up empty sets\n if (rowSet.size === 0) {\n positionIndex.delete(value)\n }\n }\n }\n }\n }\n}\n\n/**\n * Find all rows that match a given pattern\n */\nexport function findRowsMatchingPattern(\n pattern: MoveOutPattern,\n index: TagIndex,\n): Set<RowId> {\n const { pos, value } = getPositionalValue(pattern)\n const positionIndex = index[pos]\n const rowSet = positionIndex?.get(value)\n return rowSet ?? new Set()\n}\n\n/**\n * Check if a message is an event message with move-out event\n */\nexport function isMoveOutMessage<T extends Row<unknown>>(\n message: Message<T>,\n): message is Message<T> & EventMessage {\n return message.headers.event === `move-out`\n}\n"],"names":[],"mappings":";;AAaA,MAAM,eAAe;AAiCd,SAAS,SAAS,KAAoB,UAA2B;AACtE,MAAI,YAAY,IAAI,QAAQ;AAC1B,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AACA,SAAO,IAAI,QAAQ;AACrB;AAKA,SAAS,mBAAmB,SAG1B;AACA,SAAO;AACT;AAKO,SAAS,aAAa,KAA4B;AACvD,SAAO,IAAI;AACb;AAOO,SAAS,kBACd,KACA,SACS;AACT,QAAM,EAAE,KAAK,UAAU,mBAAmB,OAAO;AACjD,QAAM,WAAW,SAAS,KAAK,GAAG;AAClC,SAAO,aAAa,SAAS,aAAa;AAC5C;AAKO,SAAS,cACd,KACA,OACA,OACA,WACM;AACN,WAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,UAAM,QAAQ,SAAS,KAAK,CAAC;AAG7B,QAAI,UAAU,cAAc;AAC1B,YAAM,gBAAgB,MAAM,CAAC;AAC7B,UAAI,CAAC,cAAc,IAAI,KAAK,GAAG;AAC7B,sBAAc,IAAI,OAAO,oBAAI,IAAA,CAAK;AAAA,MACpC;AAEA,YAAM,OAAO,cAAc,IAAI,KAAK;AACpC,WAAK,IAAI,KAAK;AAAA,IAChB;AAAA,EACF;AACF;AAKO,SAAS,mBACd,KACA,OACA,OACA,WACM;AACN,WAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,UAAM,QAAQ,SAAS,KAAK,CAAC;AAG7B,QAAI,UAAU,cAAc;AAC1B,YAAM,gBAAgB,MAAM,CAAC;AAC7B,UAAI,eAAe;AACjB,cAAM,SAAS,cAAc,IAAI,KAAK;AACtC,YAAI,QAAQ;AACV,iBAAO,OAAO,KAAK;AAGnB,cAAI,OAAO,SAAS,GAAG;AACrB,0BAAc,OAAO,KAAK;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,wBACd,SACA,OACY;AACZ,QAAM,EAAE,KAAK,UAAU,mBAAmB,OAAO;AACjD,QAAM,gBAAgB,MAAM,GAAG;AAC/B,QAAM,SAAS,eAAe,IAAI,KAAK;AACvC,SAAO,8BAAc,IAAA;AACvB;AAKO,SAAS,iBACd,SACsC;AACtC,SAAO,QAAQ,QAAQ,UAAU;AACnC;;;;;;;;"}