drizzle-cube 0.2.24 → 0.2.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/adapters/compiler-C6JQHGrF.cjs +22 -0
  2. package/dist/adapters/{compiler-DkzdLcxq.js → compiler-Ddwn99Ja.js} +1419 -1287
  3. package/dist/adapters/express/index.cjs +1 -1
  4. package/dist/adapters/express/index.d.ts +6 -1
  5. package/dist/adapters/express/index.js +22 -20
  6. package/dist/adapters/fastify/index.cjs +1 -1
  7. package/dist/adapters/fastify/index.d.ts +6 -1
  8. package/dist/adapters/fastify/index.js +18 -16
  9. package/dist/adapters/hono/index.cjs +1 -1
  10. package/dist/adapters/hono/index.d.ts +6 -1
  11. package/dist/adapters/hono/index.js +87 -85
  12. package/dist/adapters/nextjs/index.cjs +1 -1
  13. package/dist/adapters/nextjs/index.d.ts +6 -1
  14. package/dist/adapters/nextjs/index.js +64 -63
  15. package/dist/adapters/utils.d.ts +18 -0
  16. package/dist/client/charts.js +2 -2
  17. package/dist/client/chunks/{charts-DboFPJFN.js → charts-BsXrHSCm.js} +32 -32
  18. package/dist/client/chunks/{charts-DboFPJFN.js.map → charts-BsXrHSCm.js.map} +1 -1
  19. package/dist/client/chunks/{charts--hFH-bsu.js → charts-BvLb1eub.js} +710 -703
  20. package/dist/client/chunks/charts-BvLb1eub.js.map +1 -0
  21. package/dist/client/chunks/components-BGWiuXqQ.js +15831 -0
  22. package/dist/client/chunks/components-BGWiuXqQ.js.map +1 -0
  23. package/dist/client/chunks/core-CX7kEAYO.js +6 -0
  24. package/dist/client/chunks/core-CX7kEAYO.js.map +1 -0
  25. package/dist/client/chunks/{index-yc7cf-yE.js → index-9x0R-Fme.js} +2 -2
  26. package/dist/client/chunks/{index-yc7cf-yE.js.map → index-9x0R-Fme.js.map} +1 -1
  27. package/dist/client/components/AnalysisBuilder/AnalysisQueryPanel.d.ts +3 -2
  28. package/dist/client/components/AnalysisBuilder/types.d.ts +63 -15
  29. package/dist/client/components/DashboardFilters/CompactFilterBar.d.ts +13 -0
  30. package/dist/client/components/DashboardFilters/CustomDateDropdown.d.ts +10 -0
  31. package/dist/client/components/DashboardFilters/DatePresetChips.d.ts +8 -0
  32. package/dist/client/components/DashboardFilters/FilterChip.d.ts +12 -0
  33. package/dist/client/components/DashboardFilters/FilterValuePopover.d.ts +11 -0
  34. package/dist/client/components/DashboardFilters/XTDDropdown.d.ts +10 -0
  35. package/dist/client/components/DashboardPortletCard.d.ts +12 -0
  36. package/dist/client/components/DebugModal.d.ts +7 -1
  37. package/dist/client/components/shared/utils.d.ts +34 -0
  38. package/dist/client/components.js +2 -2
  39. package/dist/client/hooks/useMultiCubeQuery.d.ts +36 -0
  40. package/dist/client/hooks.js +2 -2
  41. package/dist/client/icons.js +1 -1
  42. package/dist/client/index.d.ts +7 -1
  43. package/dist/client/index.js +70 -52
  44. package/dist/client/providers.js +1 -1
  45. package/dist/client/styles.css +1 -1
  46. package/dist/client/types.d.ts +32 -0
  47. package/dist/client/utils/multiQueryUtils.d.ts +86 -0
  48. package/dist/client/utils/multiQueryValidation.d.ts +69 -0
  49. package/dist/client/utils/shareUtils.d.ts +3 -3
  50. package/dist/client-bundle-stats.html +1 -1
  51. package/dist/server/index.cjs +17 -17
  52. package/dist/server/index.d.ts +326 -1
  53. package/dist/server/index.js +2429 -2148
  54. package/package.json +1 -1
  55. package/dist/adapters/compiler-BFqMax9M.cjs +0 -22
  56. package/dist/client/chunks/charts--hFH-bsu.js.map +0 -1
  57. package/dist/client/chunks/components-D7wTB56l.js +0 -14131
  58. package/dist/client/chunks/components-D7wTB56l.js.map +0 -1
  59. package/dist/client/chunks/core-PxWXpBbW.js +0 -6
  60. package/dist/client/chunks/core-PxWXpBbW.js.map +0 -1
@@ -36,6 +36,141 @@ export declare interface BaseQueryDefinition {
36
36
  where?: SQL;
37
37
  }
38
38
 
39
+ /**
40
+ * Cache configuration options
41
+ */
42
+ export declare interface CacheConfig {
43
+ /**
44
+ * Cache provider implementation
45
+ * Required if caching is enabled
46
+ */
47
+ provider: CacheProvider;
48
+ /**
49
+ * Default TTL in milliseconds
50
+ * @default 300000 (5 minutes)
51
+ */
52
+ defaultTtlMs?: number;
53
+ /**
54
+ * Prefix for all cache keys
55
+ * Useful for multi-environment setups (e.g., 'prod:', 'dev:')
56
+ * @default 'drizzle-cube:'
57
+ */
58
+ keyPrefix?: string;
59
+ /**
60
+ * Enable/disable caching globally
61
+ * Allows disabling without removing configuration
62
+ * @default true
63
+ */
64
+ enabled?: boolean;
65
+ /**
66
+ * Whether to include security context in cache key
67
+ * CRITICAL for multi-tenant applications - should almost always be true
68
+ * @default true
69
+ */
70
+ includeSecurityContext?: boolean;
71
+ /**
72
+ * Custom function to extract cacheable parts of security context
73
+ * Use when security context contains non-serializable values
74
+ * @default Uses JSON.stringify on entire security context
75
+ */
76
+ securityContextSerializer?: (ctx: SecurityContext) => string;
77
+ /**
78
+ * Callback for cache errors (get/set failures)
79
+ * Cache errors are non-fatal by default - queries still execute
80
+ */
81
+ onError?: (error: Error, operation: 'get' | 'set' | 'delete') => void;
82
+ /**
83
+ * Callback for cache events (hits, misses, sets)
84
+ * Useful for monitoring and debugging
85
+ */
86
+ onCacheEvent?: (event: CacheEvent) => void;
87
+ }
88
+
89
+ /**
90
+ * Metadata about a cached entry
91
+ * Used to provide cache information in query responses
92
+ */
93
+ export declare interface CacheEntryMetadata {
94
+ /** Unix timestamp (ms) when the entry was cached */
95
+ cachedAt: number;
96
+ /** Original TTL in milliseconds */
97
+ ttlMs: number;
98
+ /** Remaining TTL in milliseconds */
99
+ ttlRemainingMs: number;
100
+ }
101
+
102
+ /**
103
+ * Cache event for monitoring and debugging
104
+ */
105
+ export declare interface CacheEvent {
106
+ /** Type of cache event */
107
+ type: 'hit' | 'miss' | 'set' | 'error';
108
+ /** Cache key involved */
109
+ key: string;
110
+ /** Duration of the cache operation in milliseconds */
111
+ durationMs: number;
112
+ }
113
+
114
+ /**
115
+ * Return type for cache get operations
116
+ * Includes value and optional metadata for TTL tracking
117
+ */
118
+ export declare interface CacheGetResult<T> {
119
+ value: T;
120
+ metadata?: CacheEntryMetadata;
121
+ }
122
+
123
+ /**
124
+ * Configuration for cache key generation
125
+ */
126
+ declare interface CacheKeyConfig {
127
+ /** Prefix for all cache keys */
128
+ keyPrefix?: string;
129
+ /** Whether to include security context in cache key */
130
+ includeSecurityContext?: boolean;
131
+ /** Custom serializer for security context */
132
+ securityContextSerializer?: (ctx: SecurityContext) => string;
133
+ }
134
+
135
+ /**
136
+ * Cache provider interface that users implement for their preferred backend
137
+ * All methods use async/Promise to support network-based caches (Redis, etc.)
138
+ */
139
+ export declare interface CacheProvider {
140
+ /**
141
+ * Get a cached value by key
142
+ * @returns The cached value with metadata, or null/undefined if not found or expired
143
+ */
144
+ get<T = unknown>(key: string): Promise<CacheGetResult<T> | null | undefined>;
145
+ /**
146
+ * Set a value in the cache
147
+ * @param key - Cache key
148
+ * @param value - Value to cache (must be JSON-serializable)
149
+ * @param ttlMs - Time-to-live in milliseconds (optional, uses default if not provided)
150
+ */
151
+ set<T = unknown>(key: string, value: T, ttlMs?: number): Promise<void>;
152
+ /**
153
+ * Delete a specific key from the cache
154
+ * @returns true if key existed and was deleted, false otherwise
155
+ */
156
+ delete(key: string): Promise<boolean>;
157
+ /**
158
+ * Delete all keys matching a pattern (for cache invalidation)
159
+ * Pattern uses glob-style matching: 'prefix:*' matches all keys starting with 'prefix:'
160
+ * @returns Number of keys deleted
161
+ */
162
+ deletePattern(pattern: string): Promise<number>;
163
+ /**
164
+ * Check if a key exists in the cache
165
+ */
166
+ has(key: string): Promise<boolean>;
167
+ /**
168
+ * Optional: Called when the cache provider is no longer needed
169
+ * Use for cleanup (e.g., closing Redis connections)
170
+ */
171
+ close?(): Promise<void>;
172
+ }
173
+
39
174
  /**
40
175
  * Compiled cube with execution function
41
176
  */
@@ -515,6 +650,47 @@ export declare interface FilterCondition {
515
650
  */
516
651
  export declare type FilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'startsWith' | 'notStartsWith' | 'endsWith' | 'notEndsWith' | 'gt' | 'gte' | 'lt' | 'lte' | 'set' | 'notSet' | 'inDateRange' | 'beforeDate' | 'afterDate' | 'between' | 'notBetween' | 'in' | 'notIn' | 'like' | 'notLike' | 'ilike' | 'regex' | 'notRegex' | 'isEmpty' | 'isNotEmpty' | 'arrayContains' | 'arrayOverlaps' | 'arrayContained';
517
652
 
653
+ /**
654
+ * FNV-1a hash - fast, non-cryptographic hash function
655
+ * Returns hex string for cache key readability
656
+ *
657
+ * Properties:
658
+ * - O(n) time complexity
659
+ * - Low collision rate for similar strings
660
+ * - Deterministic across runs
661
+ *
662
+ * @param str - String to hash
663
+ * @returns 8-character hex string
664
+ */
665
+ export declare function fnv1aHash(str: string): string;
666
+
667
+ /**
668
+ * Generate a deterministic cache key from query and security context
669
+ *
670
+ * Key structure: {prefix}query:{queryHash}:ctx:{securityHash}
671
+ *
672
+ * Uses FNV-1a hash for:
673
+ * - Speed: ~3x faster than SHA-256
674
+ * - Simplicity: No dependencies required
675
+ * - Sufficient collision resistance for cache keys
676
+ *
677
+ * @param query - The semantic query to cache
678
+ * @param securityContext - Security context for tenant isolation
679
+ * @param config - Cache key configuration
680
+ * @returns Deterministic cache key string
681
+ */
682
+ export declare function generateCacheKey(query: SemanticQuery, securityContext: SecurityContext, config?: CacheKeyConfig): string;
683
+
684
+ /**
685
+ * Generate invalidation pattern for a cube
686
+ * Used when cube data changes and all related cache entries need clearing
687
+ *
688
+ * @param cubeName - Name of the cube to invalidate
689
+ * @param keyPrefix - Cache key prefix
690
+ * @returns Glob pattern for cache invalidation
691
+ */
692
+ export declare function getCubeInvalidationPattern(cubeName: string, keyPrefix?: string): string;
693
+
518
694
  /**
519
695
  * Derive SQL join type from semantic relationship
520
696
  */
@@ -735,6 +911,112 @@ export declare interface MeasureMetadata {
735
911
  */
736
912
  export declare type MeasureType = 'count' | 'countDistinct' | 'countDistinctApprox' | 'sum' | 'avg' | 'min' | 'max' | 'runningTotal' | 'number' | 'calculated' | 'stddev' | 'stddevSamp' | 'variance' | 'varianceSamp' | 'percentile' | 'median' | 'p95' | 'p99' | 'lag' | 'lead' | 'rank' | 'denseRank' | 'rowNumber' | 'ntile' | 'firstValue' | 'lastValue' | 'movingAvg' | 'movingSum';
737
913
 
914
+ /**
915
+ * Simple in-memory cache provider implementing the CacheProvider interface
916
+ *
917
+ * Features:
918
+ * - TTL support with automatic expiration on read
919
+ * - Optional automatic cleanup of expired entries
920
+ * - Optional max entries limit with LRU eviction
921
+ * - Full metadata support for TTL tracking
922
+ *
923
+ * Limitations:
924
+ * - Not shared across processes/instances
925
+ * - Data lost on process restart
926
+ * - Not suitable for distributed deployments
927
+ */
928
+ export declare class MemoryCacheProvider implements CacheProvider {
929
+ private cache;
930
+ private defaultTtlMs;
931
+ private maxEntries?;
932
+ private cleanupIntervalId?;
933
+ private accessOrder;
934
+ constructor(options?: MemoryCacheProviderOptions);
935
+ /**
936
+ * Get a cached value by key
937
+ * Returns null if not found or expired
938
+ * Automatically removes expired entries on access
939
+ */
940
+ get<T>(key: string): Promise<CacheGetResult<T> | null>;
941
+ /**
942
+ * Set a value in the cache
943
+ * Respects maxEntries limit with LRU eviction
944
+ */
945
+ set<T>(key: string, value: T, ttlMs?: number): Promise<void>;
946
+ /**
947
+ * Delete a specific key from the cache
948
+ * Returns true if key existed and was deleted
949
+ */
950
+ delete(key: string): Promise<boolean>;
951
+ /**
952
+ * Delete all keys matching a pattern
953
+ * Supports glob-style patterns with trailing '*'
954
+ * Returns number of keys deleted
955
+ */
956
+ deletePattern(pattern: string): Promise<number>;
957
+ /**
958
+ * Check if a key exists in the cache
959
+ * Returns false for expired entries
960
+ */
961
+ has(key: string): Promise<boolean>;
962
+ /**
963
+ * Stop automatic cleanup and clear the cache
964
+ * Call this when the cache provider is no longer needed
965
+ */
966
+ close(): Promise<void>;
967
+ /**
968
+ * Remove all expired entries from the cache
969
+ * Called automatically by cleanup interval
970
+ * Can also be called manually
971
+ *
972
+ * @returns Number of entries removed
973
+ */
974
+ cleanup(): number;
975
+ /**
976
+ * Get current cache size (number of entries)
977
+ * Note: May include expired entries that haven't been cleaned up yet
978
+ */
979
+ size(): number;
980
+ /**
981
+ * Clear all entries from the cache
982
+ */
983
+ clear(): void;
984
+ /**
985
+ * Get cache statistics
986
+ */
987
+ stats(): {
988
+ size: number;
989
+ maxEntries?: number;
990
+ defaultTtlMs: number;
991
+ };
992
+ private touchAccessOrder;
993
+ private removeFromAccessOrder;
994
+ private evictOldest;
995
+ }
996
+
997
+ /**
998
+ * Options for MemoryCacheProvider
999
+ */
1000
+ declare interface MemoryCacheProviderOptions {
1001
+ /**
1002
+ * Default TTL in milliseconds
1003
+ * @default 300000 (5 minutes)
1004
+ */
1005
+ defaultTtlMs?: number;
1006
+ /**
1007
+ * Maximum number of entries in the cache
1008
+ * When exceeded, oldest entries are evicted (LRU)
1009
+ * @default undefined (unlimited)
1010
+ */
1011
+ maxEntries?: number;
1012
+ /**
1013
+ * Interval in milliseconds to run automatic cleanup
1014
+ * Set to 0 to disable automatic cleanup
1015
+ * @default 60000 (1 minute)
1016
+ */
1017
+ cleanupIntervalMs?: number;
1018
+ }
1019
+
738
1020
  /**
739
1021
  * Multi-cube query context for cross-cube operations
740
1022
  */
@@ -760,6 +1042,15 @@ export declare class MySQLExecutor extends BaseDatabaseExecutor {
760
1042
  getEngineType(): 'mysql' | 'singlestore';
761
1043
  }
762
1044
 
1045
+ /**
1046
+ * Normalize query for consistent hashing
1047
+ * Sorts arrays and object keys to ensure same query = same hash
1048
+ *
1049
+ * @param query - The semantic query to normalize
1050
+ * @returns Normalized query with sorted arrays and keys
1051
+ */
1052
+ export declare function normalizeQuery(query: SemanticQuery): SemanticQuery;
1053
+
763
1054
  /**
764
1055
  * Period comparison metadata for compareDateRange queries
765
1056
  * Provides information about the periods being compared
@@ -1033,6 +1324,20 @@ export declare class QueryBuilder {
1033
1324
  buildLogicalFilter(filter: Filter, cubes: Map<string, Cube>, context: QueryContext): SQL | null;
1034
1325
  }
1035
1326
 
1327
+ /**
1328
+ * Cache metadata included in QueryResult when served from cache
1329
+ */
1330
+ export declare interface QueryCacheMetadata {
1331
+ /** Always true when this object is present */
1332
+ hit: true;
1333
+ /** ISO timestamp when the result was cached */
1334
+ cachedAt: string;
1335
+ /** Original TTL in milliseconds */
1336
+ ttlMs: number;
1337
+ /** Remaining TTL in milliseconds */
1338
+ ttlRemainingMs: number;
1339
+ }
1340
+
1036
1341
  /**
1037
1342
  * Query context passed to cube SQL functions
1038
1343
  * Provides access to database, schema, and security context
@@ -1064,7 +1369,8 @@ export declare class QueryExecutor {
1064
1369
  private cteBuilder;
1065
1370
  private databaseAdapter;
1066
1371
  private comparisonQueryBuilder;
1067
- constructor(dbExecutor: DatabaseExecutor);
1372
+ private cacheConfig?;
1373
+ constructor(dbExecutor: DatabaseExecutor, cacheConfig?: CacheConfig);
1068
1374
  /**
1069
1375
  * Unified query execution method that handles both single and multi-cube queries
1070
1376
  */
@@ -1073,6 +1379,11 @@ export declare class QueryExecutor {
1073
1379
  * Legacy interface for single cube queries
1074
1380
  */
1075
1381
  executeQuery(cube: Cube, query: SemanticQuery, securityContext: SecurityContext): Promise<QueryResult>;
1382
+ /**
1383
+ * Execute a comparison query with caching support
1384
+ * Wraps executeComparisonQuery with cache set logic
1385
+ */
1386
+ private executeComparisonQueryWithCache;
1076
1387
  /**
1077
1388
  * Execute a comparison query with multiple date periods
1078
1389
  * Expands compareDateRange into multiple sub-queries and merges results
@@ -1310,6 +1621,17 @@ export declare interface QueryResult {
1310
1621
  /** Period comparison metadata (present when compareDateRange is used) */
1311
1622
  periods?: PeriodComparisonMetadata;
1312
1623
  };
1624
+ /** Cache metadata (present when result served from cache) */
1625
+ cache?: {
1626
+ /** Always true when this object is present */
1627
+ hit: true;
1628
+ /** ISO timestamp when the result was cached */
1629
+ cachedAt: string;
1630
+ /** Original TTL in milliseconds */
1631
+ ttlMs: number;
1632
+ /** Remaining TTL in milliseconds */
1633
+ ttlRemainingMs: number;
1634
+ };
1313
1635
  }
1314
1636
 
1315
1637
  /**
@@ -1368,11 +1690,14 @@ export declare class SemanticLayerCompiler {
1368
1690
  private cubes;
1369
1691
  private dbExecutor?;
1370
1692
  private metadataCache?;
1693
+ private cacheConfig?;
1371
1694
  constructor(options?: {
1372
1695
  drizzle?: DatabaseExecutor['db'];
1373
1696
  schema?: any;
1374
1697
  databaseExecutor?: DatabaseExecutor;
1375
1698
  engineType?: 'postgres' | 'mysql' | 'sqlite' | 'singlestore';
1699
+ /** Cache configuration for query result caching */
1700
+ cache?: CacheConfig;
1376
1701
  });
1377
1702
  /**
1378
1703
  * Set or update the database executor