@tanstack/db
Version:
A reactive client store for building super fast apps on sync
1 lines • 6.2 kB
Source Map (JSON)
{"version":3,"file":"index-registry.cjs","sources":["../../../src/indexes/index-registry.ts"],"sourcesContent":["/**\n * Index Dev Mode - Helps developers identify when indexes would improve performance\n *\n * Dev mode suggestions are ON by default in non-production builds.\n */\n\n// Dev mode detection settings - ON by default in non-production\nlet devModeConfig: IndexDevModeConfig = {\n enabled: true,\n collectionSizeThreshold: 1000,\n slowQueryThresholdMs: 10,\n onSuggestion: null,\n}\n\nexport interface IndexDevModeConfig {\n /** Enable dev mode index suggestions */\n enabled: boolean\n /** Suggest indexes when collection has more than this many items */\n collectionSizeThreshold: number\n /** Suggest indexes when queries take longer than this (ms) */\n slowQueryThresholdMs: number\n /** Custom handler for index suggestions */\n onSuggestion: ((suggestion: IndexSuggestion) => void) | null\n}\n\nexport interface IndexSuggestion {\n type: `collection-size` | `slow-query` | `frequent-field`\n collectionId: string\n fieldPath: Array<string>\n message: string\n collectionSize?: number\n queryTimeMs?: number\n queryCount?: number\n}\n\n// Track query patterns for dev mode\nconst queryPatterns = new Map<\n string,\n {\n fieldPath: Array<string>\n queryCount: number\n totalTimeMs: number\n avgTimeMs: number\n }\n>()\n\n/**\n * Configure dev mode for index suggestions\n */\nexport function configureIndexDevMode(\n config: Partial<IndexDevModeConfig>,\n): void {\n devModeConfig = { ...devModeConfig, ...config }\n}\n\n/**\n * Get current dev mode configuration\n */\nexport function getIndexDevModeConfig(): IndexDevModeConfig {\n return devModeConfig\n}\n\n/**\n * Check if dev mode is enabled\n */\nexport function isDevModeEnabled(): boolean {\n return devModeConfig.enabled && process.env.NODE_ENV !== `production`\n}\n\n/**\n * Emit an index suggestion (dev mode only)\n */\nexport function emitIndexSuggestion(suggestion: IndexSuggestion): void {\n if (!isDevModeEnabled()) return\n\n if (devModeConfig.onSuggestion) {\n try {\n devModeConfig.onSuggestion(suggestion)\n } catch {\n // Don't let a buggy callback crash query execution\n }\n } else {\n // Default: log to console with helpful formatting\n console.warn(\n `[TanStack DB] Index suggestion for \"${suggestion.collectionId}\":\\n` +\n ` ${suggestion.message}\\n` +\n ` Field: ${suggestion.fieldPath.join(`.`)}\\n` +\n ` Add index: collection.createIndex((row) => row.${suggestion.fieldPath.join(`.`)})`,\n )\n }\n}\n\n/**\n * Track a query for dev mode analysis\n */\nexport function trackQuery(\n collectionId: string,\n fieldPath: Array<string>,\n executionTimeMs: number,\n): void {\n if (!isDevModeEnabled()) return\n\n const key = `${collectionId}:${fieldPath.join(`.`)}`\n const existing = queryPatterns.get(key)\n\n if (existing) {\n existing.queryCount++\n existing.totalTimeMs += executionTimeMs\n existing.avgTimeMs = existing.totalTimeMs / existing.queryCount\n } else {\n queryPatterns.set(key, {\n fieldPath,\n queryCount: 1,\n totalTimeMs: executionTimeMs,\n avgTimeMs: executionTimeMs,\n })\n }\n\n // Check if we should suggest an index\n const pattern = queryPatterns.get(key)!\n if (pattern.avgTimeMs > devModeConfig.slowQueryThresholdMs) {\n emitIndexSuggestion({\n type: `slow-query`,\n collectionId,\n fieldPath,\n message: `Queries on \"${fieldPath.join(`.`)}\" are slow (avg ${pattern.avgTimeMs.toFixed(1)}ms). Consider adding an index.`,\n queryTimeMs: pattern.avgTimeMs,\n queryCount: pattern.queryCount,\n })\n }\n}\n\n/**\n * Check collection size and suggest index if needed (dev mode)\n */\nexport function checkCollectionSizeForIndex(\n collectionId: string,\n collectionSize: number,\n fieldPath: Array<string>,\n): void {\n if (!isDevModeEnabled()) return\n\n if (collectionSize > devModeConfig.collectionSizeThreshold) {\n emitIndexSuggestion({\n type: `collection-size`,\n collectionId,\n fieldPath,\n message: `Collection has ${collectionSize} items. Queries on \"${fieldPath.join(`.`)}\" may benefit from an index.`,\n collectionSize,\n })\n }\n}\n\n/**\n * Clear query pattern tracking (useful for tests)\n */\nexport function clearQueryPatterns(): void {\n queryPatterns.clear()\n}\n\n/**\n * Get query patterns (useful for debugging/testing)\n */\nexport function getQueryPatterns(): Map<\n string,\n {\n fieldPath: Array<string>\n queryCount: number\n totalTimeMs: number\n avgTimeMs: number\n }\n> {\n return new Map(queryPatterns)\n}\n"],"names":[],"mappings":";;AAOA,IAAI,gBAAoC;AAAA,EACtC,SAAS;AAAA,EACT,yBAAyB;AAAA,EACzB,sBAAsB;AAAA,EACtB,cAAc;AAChB;AAwBA,MAAM,oCAAoB,IAAA;AAanB,SAAS,sBACd,QACM;AACN,kBAAgB,EAAE,GAAG,eAAe,GAAG,OAAA;AACzC;AAKO,SAAS,wBAA4C;AAC1D,SAAO;AACT;AAKO,SAAS,mBAA4B;AAC1C,SAAO,cAAc,WAAW,QAAQ,IAAI,aAAa;AAC3D;AAKO,SAAS,oBAAoB,YAAmC;AACrE,MAAI,CAAC,mBAAoB;AAEzB,MAAI,cAAc,cAAc;AAC9B,QAAI;AACF,oBAAc,aAAa,UAAU;AAAA,IACvC,QAAQ;AAAA,IAER;AAAA,EACF,OAAO;AAEL,YAAQ;AAAA,MACN,uCAAuC,WAAW,YAAY;AAAA,IACvD,WAAW,OAAO;AAAA,WACX,WAAW,UAAU,KAAK,GAAG,CAAC;AAAA,mDACU,WAAW,UAAU,KAAK,GAAG,CAAC;AAAA,IAAA;AAAA,EAExF;AACF;AAKO,SAAS,WACd,cACA,WACA,iBACM;AACN,MAAI,CAAC,mBAAoB;AAEzB,QAAM,MAAM,GAAG,YAAY,IAAI,UAAU,KAAK,GAAG,CAAC;AAClD,QAAM,WAAW,cAAc,IAAI,GAAG;AAEtC,MAAI,UAAU;AACZ,aAAS;AACT,aAAS,eAAe;AACxB,aAAS,YAAY,SAAS,cAAc,SAAS;AAAA,EACvD,OAAO;AACL,kBAAc,IAAI,KAAK;AAAA,MACrB;AAAA,MACA,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,WAAW;AAAA,IAAA,CACZ;AAAA,EACH;AAGA,QAAM,UAAU,cAAc,IAAI,GAAG;AACrC,MAAI,QAAQ,YAAY,cAAc,sBAAsB;AAC1D,wBAAoB;AAAA,MAClB,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,SAAS,eAAe,UAAU,KAAK,GAAG,CAAC,mBAAmB,QAAQ,UAAU,QAAQ,CAAC,CAAC;AAAA,MAC1F,aAAa,QAAQ;AAAA,MACrB,YAAY,QAAQ;AAAA,IAAA,CACrB;AAAA,EACH;AACF;AAKO,SAAS,4BACd,cACA,gBACA,WACM;AACN,MAAI,CAAC,mBAAoB;AAEzB,MAAI,iBAAiB,cAAc,yBAAyB;AAC1D,wBAAoB;AAAA,MAClB,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,SAAS,kBAAkB,cAAc,uBAAuB,UAAU,KAAK,GAAG,CAAC;AAAA,MACnF;AAAA,IAAA,CACD;AAAA,EACH;AACF;AAKO,SAAS,qBAA2B;AACzC,gBAAc,MAAA;AAChB;AAKO,SAAS,mBAQd;AACA,SAAO,IAAI,IAAI,aAAa;AAC9B;;;;;;;;;"}