drizzle-cube 0.1.65 → 0.1.67

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 (35) hide show
  1. package/dist/adapters/{compiler-tWqDBXA3.js → compiler-BEgt1OH1.js} +9 -5
  2. package/dist/adapters/{compiler-CGImvJqY.cjs → compiler-DP0leK4b.cjs} +1 -1
  3. package/dist/adapters/express/index.cjs +1 -1
  4. package/dist/adapters/express/index.js +1 -1
  5. package/dist/adapters/fastify/index.cjs +1 -1
  6. package/dist/adapters/fastify/index.js +1 -1
  7. package/dist/adapters/hono/index.cjs +1 -1
  8. package/dist/adapters/hono/index.js +1 -1
  9. package/dist/adapters/nextjs/index.cjs +1 -1
  10. package/dist/adapters/nextjs/index.js +1 -1
  11. package/dist/client/charts.js +3 -3
  12. package/dist/client/chunks/{charts-P7xq59Tl.js → charts-jwgcWeFt.js} +331 -311
  13. package/dist/client/chunks/charts-jwgcWeFt.js.map +1 -0
  14. package/dist/client/chunks/{components-BzN5ydzE.js → components-Bbd9Us6e.js} +4057 -4052
  15. package/dist/client/chunks/components-Bbd9Us6e.js.map +1 -0
  16. package/dist/client/chunks/{providers-DONuYrGH.js → providers-D7zRgZrO.js} +37 -37
  17. package/dist/client/chunks/providers-D7zRgZrO.js.map +1 -0
  18. package/dist/client/client/CubeClient.d.ts +1 -0
  19. package/dist/client/components/AnalyticsDashboard.d.ts +1 -1
  20. package/dist/client/components/DashboardGrid.d.ts +3 -1
  21. package/dist/client/components/LoadingIndicator.d.ts +16 -0
  22. package/dist/client/components.js +6 -6
  23. package/dist/client/hooks.js +2 -2
  24. package/dist/client/index.d.ts +2 -0
  25. package/dist/client/index.js +31 -30
  26. package/dist/client/providers.js +1 -1
  27. package/dist/client/styles.css +1 -1
  28. package/dist/client/types.d.ts +4 -0
  29. package/dist/client-bundle-stats.html +1 -1
  30. package/dist/server/index.cjs +1 -1
  31. package/dist/server/index.js +5 -1
  32. package/package.json +5 -1
  33. package/dist/client/chunks/charts-P7xq59Tl.js.map +0 -1
  34. package/dist/client/chunks/components-BzN5ydzE.js.map +0 -1
  35. package/dist/client/chunks/providers-DONuYrGH.js.map +0 -1
@@ -3,11 +3,12 @@ import { useState as w, useCallback as m, useEffect as j, useContext as T, creat
3
3
  class D {
4
4
  apiUrl;
5
5
  headers;
6
+ credentials;
6
7
  constructor(t, r = {}) {
7
8
  this.apiUrl = r.apiUrl || "/cubejs-api/v1", this.headers = {
8
9
  "Content-Type": "application/json",
9
10
  ...r.headers
10
- }, t && (this.headers.Authorization = t);
11
+ }, this.credentials = r.credentials ?? "include", t && (this.headers.Authorization = t);
11
12
  }
12
13
  async load(t) {
13
14
  const r = JSON.stringify(t), e = encodeURIComponent(r), a = `${this.apiUrl}/load?query=${e}`, s = await fetch(a, {
@@ -18,8 +19,7 @@ class D {
18
19
  Object.entries(this.headers).filter(([c]) => c !== "Content-Type")
19
20
  )
20
21
  },
21
- credentials: "include"
22
- // Include cookies for session auth
22
+ credentials: this.credentials
23
23
  });
24
24
  if (!s.ok) {
25
25
  let c = `Cube query failed: ${s.status}`;
@@ -35,14 +35,14 @@ class D {
35
35
  }
36
36
  throw new Error(c);
37
37
  }
38
- const o = await s.json();
39
- return new C(o);
38
+ const n = await s.json();
39
+ return new C(n);
40
40
  }
41
41
  async meta() {
42
42
  const t = `${this.apiUrl}/meta`, r = await fetch(t, {
43
43
  method: "GET",
44
44
  headers: this.headers,
45
- credentials: "include"
45
+ credentials: this.credentials
46
46
  });
47
47
  if (!r.ok)
48
48
  throw new Error(`Failed to fetch meta: ${r.status}`);
@@ -57,7 +57,7 @@ class D {
57
57
  Object.entries(this.headers).filter(([s]) => s !== "Content-Type")
58
58
  )
59
59
  },
60
- credentials: "include"
60
+ credentials: this.credentials
61
61
  });
62
62
  if (!a.ok)
63
63
  throw new Error(`SQL generation failed: ${a.status}`);
@@ -67,7 +67,7 @@ class D {
67
67
  const r = `${this.apiUrl}/dry-run`, e = await fetch(r, {
68
68
  method: "POST",
69
69
  headers: this.headers,
70
- credentials: "include",
70
+ credentials: this.credentials,
71
71
  body: JSON.stringify({ query: t })
72
72
  });
73
73
  if (!e.ok) {
@@ -75,8 +75,8 @@ class D {
75
75
  try {
76
76
  const s = await e.text();
77
77
  try {
78
- const o = JSON.parse(s);
79
- o.error ? a = o.error : a += ` ${s}`;
78
+ const n = JSON.parse(s);
79
+ n.error ? a = n.error : a += ` ${s}`;
80
80
  } catch {
81
81
  a += ` ${s}`;
82
82
  }
@@ -94,18 +94,18 @@ class D {
94
94
  const r = `${this.apiUrl}/batch`, e = await fetch(r, {
95
95
  method: "POST",
96
96
  headers: this.headers,
97
- credentials: "include",
97
+ credentials: this.credentials,
98
98
  body: JSON.stringify({ queries: t })
99
99
  });
100
100
  if (!e.ok) {
101
101
  let s = `Batch query failed: ${e.status}`;
102
102
  try {
103
- const o = await e.text();
103
+ const n = await e.text();
104
104
  try {
105
- const c = JSON.parse(o);
106
- c.error ? s = c.error : s += ` ${o}`;
105
+ const c = JSON.parse(n);
106
+ c.error ? s = c.error : s += ` ${n}`;
107
107
  } catch {
108
- s += ` ${o}`;
108
+ s += ` ${n}`;
109
109
  }
110
110
  } catch {
111
111
  }
@@ -135,14 +135,14 @@ class C {
135
135
  return this.loadResponse.results && this.loadResponse.results[0] ? this.loadResponse.results[0].annotation || {} : this.loadResponse.annotation || {};
136
136
  }
137
137
  }
138
- function L(n, t = {}) {
139
- return new D(n, t);
138
+ function L(o, t = {}) {
139
+ return new D(o, t);
140
140
  }
141
141
  const P = 900 * 1e3;
142
142
  let h = null;
143
- function k(n) {
143
+ function k(o) {
144
144
  const t = {};
145
- return n.cubes.forEach((r) => {
145
+ return o.cubes.forEach((r) => {
146
146
  r.measures.forEach((e) => {
147
147
  t[e.name] = e.title || e.shortTitle || e.name;
148
148
  }), r.dimensions.forEach((e) => {
@@ -155,15 +155,15 @@ function k(n) {
155
155
  function v() {
156
156
  return h ? Date.now() - h.timestamp < P : !1;
157
157
  }
158
- function F(n) {
159
- const [t, r] = w(null), [e, a] = w({}), [s, o] = w(!0), [c, u] = w(null), l = m(async () => {
158
+ function F(o) {
159
+ const [t, r] = w(null), [e, a] = w({}), [s, n] = w(!0), [c, u] = w(null), l = m(async () => {
160
160
  if (v() && h) {
161
- r(h.data), a(h.labelMap), o(!1), u(null);
161
+ r(h.data), a(h.labelMap), n(!1), u(null);
162
162
  return;
163
163
  }
164
164
  try {
165
- o(!0), u(null);
166
- const i = await n.meta(), p = k(i);
165
+ n(!0), u(null);
166
+ const i = await o.meta(), p = k(i);
167
167
  h = {
168
168
  data: i,
169
169
  labelMap: p,
@@ -173,9 +173,9 @@ function F(n) {
173
173
  const p = i instanceof Error ? i.message : "Failed to fetch metadata";
174
174
  u(p), console.error("Failed to fetch cube metadata:", i);
175
175
  } finally {
176
- o(!1);
176
+ n(!1);
177
177
  }
178
- }, [n]);
178
+ }, [o]);
179
179
  j(() => {
180
180
  l();
181
181
  }, [l]);
@@ -228,8 +228,8 @@ class J {
228
228
  try {
229
229
  const r = t.map((a) => a.query), e = await this.batchExecutor(r);
230
230
  t.forEach((a, s) => {
231
- const o = e[s];
232
- o && "error" in o && o.error ? a.reject(new Error(o.error)) : a.resolve(o);
231
+ const n = e[s];
232
+ n && "error" in n && n.error ? a.reject(new Error(n.error)) : a.resolve(n);
233
233
  });
234
234
  } catch (r) {
235
235
  t.forEach((e) => {
@@ -252,7 +252,7 @@ class J {
252
252
  }
253
253
  const g = U(null);
254
254
  function G({
255
- cubeApi: n,
255
+ cubeApi: o,
256
256
  apiOptions: t,
257
257
  token: r,
258
258
  options: e = {},
@@ -260,19 +260,19 @@ function G({
260
260
  // Default to AI enabled for backward compatibility
261
261
  enableBatching: s = !0,
262
262
  // Default to batching enabled
263
- batchDelayMs: o = 100,
263
+ batchDelayMs: n = 100,
264
264
  // Default 100ms batch window
265
265
  children: c
266
266
  }) {
267
267
  const [u, l] = w(null), d = u || {
268
268
  apiOptions: t || { apiUrl: "/cubejs-api/v1" },
269
269
  token: r
270
- }, f = E(() => n && !t && !r ? n : L(d.token, d.apiOptions), [n, t, r, d.apiOptions, d.token]), i = E(() => {
270
+ }, f = E(() => o && !t && !r ? o : L(d.token, d.apiOptions), [o, t, r, d.apiOptions, d.token]), i = E(() => {
271
271
  if (!s)
272
272
  return null;
273
273
  const y = (b) => f.batchLoad(b);
274
- return new J(y, o);
275
- }, [s, f, o]), { meta: p, labelMap: M, loading: S, error: x, getFieldLabel: $, refetch: q } = F(f), O = {
274
+ return new J(y, n);
275
+ }, [s, f, n]), { meta: p, labelMap: M, loading: S, error: x, getFieldLabel: $, refetch: q } = F(f), O = {
276
276
  cubeApi: f,
277
277
  options: e,
278
278
  meta: p,
@@ -294,10 +294,10 @@ function G({
294
294
  return /* @__PURE__ */ R(g.Provider, { value: O, children: c });
295
295
  }
296
296
  function Q() {
297
- const n = T(g);
298
- if (!n)
297
+ const o = T(g);
298
+ if (!o)
299
299
  throw new Error("useCubeContext must be used within a CubeProvider");
300
- return n;
300
+ return o;
301
301
  }
302
302
  export {
303
303
  G as C,
@@ -305,4 +305,4 @@ export {
305
305
  L as c,
306
306
  Q as u
307
307
  };
308
- //# sourceMappingURL=providers-DONuYrGH.js.map
308
+ //# sourceMappingURL=providers-D7zRgZrO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers-D7zRgZrO.js","sources":["../../../src/client/client/CubeClient.ts","../../../src/client/hooks/useCubeMeta.ts","../../../src/client/client/BatchCoordinator.ts","../../../src/client/providers/CubeProvider.tsx"],"sourcesContent":["/**\n * Minimal Cube client implementation\n * Replaces @cubejs-client/core with lighter implementation\n */\n\nimport type { CubeQuery, CubeApiOptions, CubeResultSet } from '../types'\n\nexport class CubeClient {\n private apiUrl: string\n private headers: Record<string, string>\n private credentials: 'include' | 'omit' | 'same-origin'\n\n constructor(token?: string, options: CubeApiOptions = {}) {\n this.apiUrl = options.apiUrl || '/cubejs-api/v1'\n this.headers = {\n 'Content-Type': 'application/json',\n ...options.headers\n }\n this.credentials = options.credentials ?? 'include'\n\n if (token) {\n this.headers['Authorization'] = token\n }\n }\n\n async load(query: CubeQuery): Promise<CubeResultSet> {\n // Use GET with query parameter for standard Cube.js compatibility\n const queryString = JSON.stringify(query)\n const queryParam = encodeURIComponent(queryString)\n const url = `${this.apiUrl}/load?query=${queryParam}`\n\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n // Remove Content-Type for GET request\n ...Object.fromEntries(\n Object.entries(this.headers).filter(([key]) => key !== 'Content-Type')\n )\n },\n credentials: this.credentials\n })\n\n if (!response.ok) {\n let errorMessage = `Cube query failed: ${response.status}`\n try {\n const errorText = await response.text()\n // Try to parse as JSON first to get structured error\n try {\n const errorData = JSON.parse(errorText)\n if (errorData.error) {\n errorMessage = errorData.error\n } else {\n errorMessage += ` ${errorText}`\n }\n } catch {\n // If not JSON, use the raw text\n errorMessage += ` ${errorText}`\n }\n } catch {\n // If we can't read the response, just use the status\n }\n throw new Error(errorMessage)\n }\n\n const result = await response.json()\n return new ResultSet(result)\n }\n\n async meta(): Promise<any> {\n const url = `${this.apiUrl}/meta`\n \n const response = await fetch(url, {\n method: 'GET',\n headers: this.headers,\n credentials: this.credentials\n })\n\n if (!response.ok) {\n throw new Error(`Failed to fetch meta: ${response.status}`)\n }\n\n return response.json()\n }\n\n async sql(query: CubeQuery): Promise<any> {\n // Use GET with query parameter for standard Cube.js compatibility\n const queryParam = encodeURIComponent(JSON.stringify(query))\n const url = `${this.apiUrl}/sql?query=${queryParam}`\n \n const response = await fetch(url, {\n method: 'GET',\n headers: {\n // Remove Content-Type for GET request\n ...Object.fromEntries(\n Object.entries(this.headers).filter(([key]) => key !== 'Content-Type')\n )\n },\n credentials: this.credentials\n })\n\n if (!response.ok) {\n throw new Error(`SQL generation failed: ${response.status}`)\n }\n\n return response.json()\n }\n\n async dryRun(query: CubeQuery): Promise<any> {\n const url = `${this.apiUrl}/dry-run`\n\n const response = await fetch(url, {\n method: 'POST',\n headers: this.headers,\n credentials: this.credentials,\n body: JSON.stringify({ query })\n })\n\n if (!response.ok) {\n let errorMessage = `Dry run failed: ${response.status}`\n try {\n const errorText = await response.text()\n try {\n const errorData = JSON.parse(errorText)\n if (errorData.error) {\n errorMessage = errorData.error\n } else {\n errorMessage += ` ${errorText}`\n }\n } catch {\n errorMessage += ` ${errorText}`\n }\n } catch {\n // If we can't read the response, just use the status\n }\n throw new Error(errorMessage)\n }\n\n return response.json()\n }\n\n /**\n * Execute multiple queries in a single batch request\n * Used by BatchCoordinator to optimize network requests\n */\n async batchLoad(queries: CubeQuery[]): Promise<CubeResultSet[]> {\n const url = `${this.apiUrl}/batch`\n\n const response = await fetch(url, {\n method: 'POST',\n headers: this.headers,\n credentials: this.credentials,\n body: JSON.stringify({ queries })\n })\n\n if (!response.ok) {\n let errorMessage = `Batch query failed: ${response.status}`\n try {\n const errorText = await response.text()\n try {\n const errorData = JSON.parse(errorText)\n if (errorData.error) {\n errorMessage = errorData.error\n } else {\n errorMessage += ` ${errorText}`\n }\n } catch {\n errorMessage += ` ${errorText}`\n }\n } catch {\n // If we can't read the response, just use the status\n }\n throw new Error(errorMessage)\n }\n\n const batchResponse = await response.json()\n\n // batchResponse.results is an array of individual query results\n // Each result may have succeeded or failed\n return batchResponse.results.map((result: any) => {\n // If this individual query failed, create a ResultSet with error info\n if (!result.success && result.error) {\n // Create a result set that will throw when accessed\n return {\n ...new ResultSet({ data: [], annotation: {} }),\n error: result.error\n }\n }\n\n // Create ResultSet from successful result\n return new ResultSet(result)\n })\n }\n}\n\n/**\n * Simple ResultSet implementation\n */\nclass ResultSet implements CubeResultSet {\n public loadResponse: any\n\n constructor(loadResponse: any) {\n this.loadResponse = loadResponse\n }\n\n rawData(): any[] {\n // Handle new nested structure: loadResponse.results[0].data\n // Keep backward compatibility with old structure: loadResponse.data\n if (this.loadResponse.results && this.loadResponse.results[0]) {\n return this.loadResponse.results[0].data || []\n }\n return this.loadResponse.data || []\n }\n\n tablePivot(): any[] {\n // For pie charts and tables, return the raw data\n return this.rawData()\n }\n\n series(): any[] {\n // Simple series implementation\n return this.rawData()\n }\n\n annotation(): any {\n // Handle new nested structure: loadResponse.results[0].annotation\n // Keep backward compatibility with old structure: loadResponse.annotation\n if (this.loadResponse.results && this.loadResponse.results[0]) {\n return this.loadResponse.results[0].annotation || {}\n }\n return this.loadResponse.annotation || {}\n }\n}\n\n/**\n * Factory function to create a cube client\n */\nexport function createCubeClient(token?: string, options: CubeApiOptions = {}): CubeClient {\n return new CubeClient(token, options)\n}\n\n// Legacy compatibility export\nexport function cube(token?: string, options: CubeApiOptions = {}): CubeClient {\n return createCubeClient(token, options)\n}","import { useState, useEffect, useCallback } from 'react'\nimport type { CubeClient } from '../client/CubeClient'\n\nexport interface CubeMetaField {\n name: string\n title: string\n shortTitle: string\n type: string\n}\n\nexport interface CubeMetaRelationship {\n targetCube: string\n relationship: 'belongsTo' | 'hasOne' | 'hasMany'\n joinFields: Array<{\n sourceField: string\n targetField: string\n }>\n}\n\nexport interface CubeMetaCube {\n name: string\n title: string\n description?: string\n measures: CubeMetaField[]\n dimensions: CubeMetaField[]\n segments: CubeMetaField[]\n relationships?: CubeMetaRelationship[]\n}\n\nexport interface CubeMeta {\n cubes: CubeMetaCube[]\n}\n\nexport type FieldLabelMap = Record<string, string>\n\ninterface CachedMeta {\n data: CubeMeta\n labelMap: FieldLabelMap\n timestamp: number\n}\n\ninterface UseCubeMetaResult {\n meta: CubeMeta | null\n labelMap: FieldLabelMap\n loading: boolean\n error: string | null\n refetch: () => void\n getFieldLabel: (fieldName: string) => string\n}\n\n// Cache duration: 15 minutes\nconst CACHE_DURATION = 15 * 60 * 1000\n\n// In-memory cache\nlet cachedMeta: CachedMeta | null = null\n\nfunction buildLabelMap(meta: CubeMeta): FieldLabelMap {\n const labelMap: FieldLabelMap = {}\n \n meta.cubes.forEach(cube => {\n // Add measures\n cube.measures.forEach(measure => {\n labelMap[measure.name] = measure.title || measure.shortTitle || measure.name\n })\n \n // Add dimensions\n cube.dimensions.forEach(dimension => {\n labelMap[dimension.name] = dimension.title || dimension.shortTitle || dimension.name\n })\n \n // Add segments\n cube.segments.forEach(segment => {\n labelMap[segment.name] = segment.title || segment.shortTitle || segment.name\n })\n })\n \n return labelMap\n}\n\nfunction isCacheValid(): boolean {\n if (!cachedMeta) return false\n const now = Date.now()\n return (now - cachedMeta.timestamp) < CACHE_DURATION\n}\n\n// Export cache clearing function for tests\nexport function clearMetaCache() {\n cachedMeta = null\n}\n\nexport function useCubeMeta(cubeApi: CubeClient): UseCubeMetaResult {\n const [meta, setMeta] = useState<CubeMeta | null>(null)\n const [labelMap, setLabelMap] = useState<FieldLabelMap>({})\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n const fetchMeta = useCallback(async () => {\n // Check cache first\n if (isCacheValid() && cachedMeta) {\n setMeta(cachedMeta.data)\n setLabelMap(cachedMeta.labelMap)\n setLoading(false)\n setError(null)\n return\n }\n\n try {\n setLoading(true)\n setError(null)\n \n const metaData: CubeMeta = await cubeApi.meta()\n const newLabelMap = buildLabelMap(metaData)\n \n // Cache the result\n cachedMeta = {\n data: metaData,\n labelMap: newLabelMap,\n timestamp: Date.now()\n }\n \n setMeta(metaData)\n setLabelMap(newLabelMap)\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to fetch metadata'\n setError(errorMessage)\n console.error('Failed to fetch cube metadata:', err)\n } finally {\n setLoading(false)\n }\n }, [cubeApi])\n\n useEffect(() => {\n fetchMeta()\n }, [fetchMeta])\n\n const getFieldLabel = useCallback((fieldName: string): string => {\n return labelMap[fieldName] || fieldName\n }, [labelMap])\n\n const refetch = useCallback(() => {\n // Clear cache and refetch\n cachedMeta = null\n fetchMeta()\n }, [fetchMeta])\n\n return {\n meta,\n labelMap,\n loading,\n error,\n refetch,\n getFieldLabel\n }\n}","import type { CubeQuery, CubeResultSet } from '../types'\n\n/**\n * Represents a queued query with its resolver/rejector\n */\ninterface QueuedQuery {\n query: CubeQuery\n resolve: (result: CubeResultSet) => void\n reject: (error: Error) => void\n}\n\n/**\n * BatchCoordinator collects queries triggered in the same render cycle\n * and sends them as a single batch request to minimize network overhead.\n *\n * Uses a configurable delay (default 100ms) to batch queries from lazy-loaded\n * portlets that become visible during the same scroll action.\n */\nexport class BatchCoordinator {\n private queue: QueuedQuery[] = []\n private flushScheduled = false\n private batchExecutor: (queries: CubeQuery[]) => Promise<CubeResultSet[]>\n private delayMs: number\n\n constructor(batchExecutor: (queries: CubeQuery[]) => Promise<CubeResultSet[]>, delayMs: number = 100) {\n this.batchExecutor = batchExecutor\n this.delayMs = delayMs\n }\n\n /**\n * Register a query to be batched. Returns a promise that resolves\n * when the batch is executed and this specific query's result is available.\n */\n public register(query: CubeQuery): Promise<CubeResultSet> {\n return new Promise<CubeResultSet>((resolve, reject) => {\n // Add query to queue\n this.queue.push({ query, resolve, reject })\n\n // Schedule flush if not already scheduled\n if (!this.flushScheduled) {\n this.scheduleFlush()\n }\n })\n }\n\n /**\n * Schedule a flush after a short delay to collect multiple queries.\n * The delay allows queries from lazy-loaded portlets that become visible\n * during the same scroll action to be batched together.\n */\n private scheduleFlush(): void {\n this.flushScheduled = true\n\n setTimeout(() => {\n this.flush()\n }, this.delayMs)\n }\n\n /**\n * Execute all queued queries as a batch and resolve individual promises\n */\n private async flush(): Promise<void> {\n // Reset state\n this.flushScheduled = false\n\n // Take current queue and clear it\n const currentQueue = this.queue.slice()\n this.queue = []\n\n if (currentQueue.length === 0) {\n return\n }\n\n try {\n // Extract queries\n const queries = currentQueue.map(item => item.query)\n\n // Execute batch\n const results = await this.batchExecutor(queries)\n\n // Resolve individual promises with their corresponding results\n currentQueue.forEach((item, index) => {\n const result = results[index]\n\n // Check if this specific query had an error\n if (result && 'error' in result && result.error) {\n item.reject(new Error(result.error as string))\n } else {\n item.resolve(result)\n }\n })\n } catch (error) {\n // If entire batch fails, reject all queries\n currentQueue.forEach(item => {\n item.reject(error instanceof Error ? error : new Error(String(error)))\n })\n }\n }\n\n /**\n * Get current queue size (useful for debugging)\n */\n public getQueueSize(): number {\n return this.queue.length\n }\n\n /**\n * Clear the queue (useful for testing/cleanup)\n */\n public clear(): void {\n this.queue = []\n this.flushScheduled = false\n }\n}\n","/**\n * Lightweight CubeProvider implementation\n * Replaces @cubejs-client/react provider\n */\n\nimport React, { createContext, useContext, useMemo, useState } from 'react'\nimport { createCubeClient, type CubeClient } from '../client/CubeClient'\nimport type { CubeQueryOptions, CubeApiOptions, FeaturesConfig } from '../types'\nimport { useCubeMeta, type CubeMeta, type FieldLabelMap } from '../hooks/useCubeMeta'\nimport { BatchCoordinator } from '../client/BatchCoordinator'\n\ninterface CubeContextValue {\n cubeApi: CubeClient\n options?: CubeQueryOptions\n meta: CubeMeta | null\n labelMap: FieldLabelMap\n metaLoading: boolean\n metaError: string | null\n getFieldLabel: (fieldName: string) => string\n refetchMeta: () => void\n updateApiConfig: (apiOptions: CubeApiOptions, token?: string) => void\n features: FeaturesConfig\n batchCoordinator: BatchCoordinator | null\n enableBatching: boolean\n}\n\nconst CubeContext = createContext<CubeContextValue | null>(null)\n\ninterface CubeProviderProps {\n cubeApi?: CubeClient\n apiOptions?: CubeApiOptions\n token?: string\n options?: CubeQueryOptions\n features?: FeaturesConfig\n enableBatching?: boolean\n batchDelayMs?: number // Delay in ms to collect queries before batching (default: 100)\n children: React.ReactNode\n}\n\nexport function CubeProvider({\n cubeApi: initialCubeApi,\n apiOptions: initialApiOptions,\n token: initialToken,\n options = {},\n features = { enableAI: true, aiEndpoint: '/api/ai/generate' }, // Default to AI enabled for backward compatibility\n enableBatching = true, // Default to batching enabled\n batchDelayMs = 100, // Default 100ms batch window\n children\n}: CubeProviderProps) {\n // State for dynamic API configuration (only for updates via updateApiConfig)\n const [dynamicConfig, setDynamicConfig] = useState<{ apiOptions: CubeApiOptions; token?: string } | null>(null)\n\n // Determine current config: dynamic config takes precedence over props\n const currentConfig = dynamicConfig || {\n apiOptions: initialApiOptions || { apiUrl: '/cubejs-api/v1' },\n token: initialToken\n }\n\n // Create or use the provided CubeClient, recreating when config changes\n const cubeApi = useMemo(() => {\n if (initialCubeApi && !initialApiOptions && !initialToken) {\n // Use provided client if no initial config specified\n return initialCubeApi\n }\n\n // Create client with current config\n return createCubeClient(currentConfig.token, currentConfig.apiOptions)\n }, [initialCubeApi, initialApiOptions, initialToken, currentConfig.apiOptions, currentConfig.token])\n\n // Create BatchCoordinator if batching is enabled\n const batchCoordinator = useMemo(() => {\n if (!enableBatching) {\n return null\n }\n\n // Create batch executor function that uses cubeApi.batchLoad\n const batchExecutor = (queries: any[]) => cubeApi.batchLoad(queries)\n\n return new BatchCoordinator(batchExecutor, batchDelayMs)\n }, [enableBatching, cubeApi, batchDelayMs])\n\n const { meta, labelMap, loading: metaLoading, error: metaError, getFieldLabel, refetch: refetchMeta } = useCubeMeta(cubeApi)\n \n const updateApiConfig = (newApiOptions: CubeApiOptions, newToken?: string) => {\n setDynamicConfig({\n apiOptions: newApiOptions,\n token: newToken\n })\n }\n \n const contextValue = {\n cubeApi,\n options,\n meta,\n labelMap,\n metaLoading,\n metaError,\n getFieldLabel,\n refetchMeta,\n updateApiConfig,\n features,\n batchCoordinator,\n enableBatching\n }\n \n return (\n <CubeContext.Provider value={contextValue}>\n {children}\n </CubeContext.Provider>\n )\n}\n\nexport function useCubeContext() {\n const context = useContext(CubeContext)\n \n if (!context) {\n throw new Error('useCubeContext must be used within a CubeProvider')\n }\n return context\n}"],"names":["CubeClient","token","options","query","queryString","queryParam","url","response","key","errorMessage","errorText","errorData","result","ResultSet","queries","loadResponse","createCubeClient","CACHE_DURATION","cachedMeta","buildLabelMap","meta","labelMap","cube","measure","dimension","segment","isCacheValid","useCubeMeta","cubeApi","setMeta","useState","setLabelMap","loading","setLoading","error","setError","fetchMeta","useCallback","metaData","newLabelMap","err","useEffect","getFieldLabel","fieldName","refetch","BatchCoordinator","batchExecutor","delayMs","resolve","reject","currentQueue","item","results","index","CubeContext","createContext","CubeProvider","initialCubeApi","initialApiOptions","initialToken","features","enableBatching","batchDelayMs","children","dynamicConfig","setDynamicConfig","currentConfig","useMemo","batchCoordinator","metaLoading","metaError","refetchMeta","contextValue","newApiOptions","newToken","useCubeContext","context","useContext"],"mappings":";;AAOO,MAAMA,EAAW;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAYC,GAAgBC,IAA0B,IAAI;AACxD,SAAK,SAASA,EAAQ,UAAU,kBAChC,KAAK,UAAU;AAAA,MACb,gBAAgB;AAAA,MAChB,GAAGA,EAAQ;AAAA,IAAA,GAEb,KAAK,cAAcA,EAAQ,eAAe,WAEtCD,MACF,KAAK,QAAQ,gBAAmBA;AAAA,EAEpC;AAAA,EAEA,MAAM,KAAKE,GAA0C;AAEnD,UAAMC,IAAc,KAAK,UAAUD,CAAK,GAClCE,IAAa,mBAAmBD,CAAW,GAC3CE,IAAM,GAAG,KAAK,MAAM,eAAeD,CAAU,IAE7CE,IAAW,MAAM,MAAMD,GAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS;AAAA;AAAA,QAEP,GAAG,OAAO;AAAA,UACR,OAAO,QAAQ,KAAK,OAAO,EAAE,OAAO,CAAC,CAACE,CAAG,MAAMA,MAAQ,cAAc;AAAA,QAAA;AAAA,MACvE;AAAA,MAEF,aAAa,KAAK;AAAA,IAAA,CACnB;AAED,QAAI,CAACD,EAAS,IAAI;AAChB,UAAIE,IAAe,sBAAsBF,EAAS,MAAM;AACxD,UAAI;AACF,cAAMG,IAAY,MAAMH,EAAS,KAAA;AAEjC,YAAI;AACF,gBAAMI,IAAY,KAAK,MAAMD,CAAS;AACtC,UAAIC,EAAU,QACZF,IAAeE,EAAU,QAEzBF,KAAgB,IAAIC,CAAS;AAAA,QAEjC,QAAQ;AAEN,UAAAD,KAAgB,IAAIC,CAAS;AAAA,QAC/B;AAAA,MACF,QAAQ;AAAA,MAER;AACA,YAAM,IAAI,MAAMD,CAAY;AAAA,IAC9B;AAEA,UAAMG,IAAS,MAAML,EAAS,KAAA;AAC9B,WAAO,IAAIM,EAAUD,CAAM;AAAA,EAC7B;AAAA,EAEA,MAAM,OAAqB;AACzB,UAAMN,IAAM,GAAG,KAAK,MAAM,SAEpBC,IAAW,MAAM,MAAMD,GAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS,KAAK;AAAA,MACd,aAAa,KAAK;AAAA,IAAA,CACnB;AAED,QAAI,CAACC,EAAS;AACZ,YAAM,IAAI,MAAM,yBAAyBA,EAAS,MAAM,EAAE;AAG5D,WAAOA,EAAS,KAAA;AAAA,EAClB;AAAA,EAEA,MAAM,IAAIJ,GAAgC;AAExC,UAAME,IAAa,mBAAmB,KAAK,UAAUF,CAAK,CAAC,GACrDG,IAAM,GAAG,KAAK,MAAM,cAAcD,CAAU,IAE5CE,IAAW,MAAM,MAAMD,GAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS;AAAA;AAAA,QAEP,GAAG,OAAO;AAAA,UACR,OAAO,QAAQ,KAAK,OAAO,EAAE,OAAO,CAAC,CAACE,CAAG,MAAMA,MAAQ,cAAc;AAAA,QAAA;AAAA,MACvE;AAAA,MAEF,aAAa,KAAK;AAAA,IAAA,CACnB;AAED,QAAI,CAACD,EAAS;AACZ,YAAM,IAAI,MAAM,0BAA0BA,EAAS,MAAM,EAAE;AAG7D,WAAOA,EAAS,KAAA;AAAA,EAClB;AAAA,EAEA,MAAM,OAAOJ,GAAgC;AAC3C,UAAMG,IAAM,GAAG,KAAK,MAAM,YAEpBC,IAAW,MAAM,MAAMD,GAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS,KAAK;AAAA,MACd,aAAa,KAAK;AAAA,MAClB,MAAM,KAAK,UAAU,EAAE,OAAAH,GAAO;AAAA,IAAA,CAC/B;AAED,QAAI,CAACI,EAAS,IAAI;AAChB,UAAIE,IAAe,mBAAmBF,EAAS,MAAM;AACrD,UAAI;AACF,cAAMG,IAAY,MAAMH,EAAS,KAAA;AACjC,YAAI;AACF,gBAAMI,IAAY,KAAK,MAAMD,CAAS;AACtC,UAAIC,EAAU,QACZF,IAAeE,EAAU,QAEzBF,KAAgB,IAAIC,CAAS;AAAA,QAEjC,QAAQ;AACN,UAAAD,KAAgB,IAAIC,CAAS;AAAA,QAC/B;AAAA,MACF,QAAQ;AAAA,MAER;AACA,YAAM,IAAI,MAAMD,CAAY;AAAA,IAC9B;AAEA,WAAOF,EAAS,KAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAUO,GAAgD;AAC9D,UAAMR,IAAM,GAAG,KAAK,MAAM,UAEpBC,IAAW,MAAM,MAAMD,GAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS,KAAK;AAAA,MACd,aAAa,KAAK;AAAA,MAClB,MAAM,KAAK,UAAU,EAAE,SAAAQ,GAAS;AAAA,IAAA,CACjC;AAED,QAAI,CAACP,EAAS,IAAI;AAChB,UAAIE,IAAe,uBAAuBF,EAAS,MAAM;AACzD,UAAI;AACF,cAAMG,IAAY,MAAMH,EAAS,KAAA;AACjC,YAAI;AACF,gBAAMI,IAAY,KAAK,MAAMD,CAAS;AACtC,UAAIC,EAAU,QACZF,IAAeE,EAAU,QAEzBF,KAAgB,IAAIC,CAAS;AAAA,QAEjC,QAAQ;AACN,UAAAD,KAAgB,IAAIC,CAAS;AAAA,QAC/B;AAAA,MACF,QAAQ;AAAA,MAER;AACA,YAAM,IAAI,MAAMD,CAAY;AAAA,IAC9B;AAMA,YAJsB,MAAMF,EAAS,KAAA,GAIhB,QAAQ,IAAI,CAACK,MAE5B,CAACA,EAAO,WAAWA,EAAO,QAErB;AAAA,MACL,GAAG,IAAIC,EAAU,EAAE,MAAM,CAAA,GAAI,YAAY,CAAA,GAAI;AAAA,MAC7C,OAAOD,EAAO;AAAA,IAAA,IAKX,IAAIC,EAAUD,CAAM,CAC5B;AAAA,EACH;AACF;AAKA,MAAMC,EAAmC;AAAA,EAChC;AAAA,EAEP,YAAYE,GAAmB;AAC7B,SAAK,eAAeA;AAAA,EACtB;AAAA,EAEA,UAAiB;AAGf,WAAI,KAAK,aAAa,WAAW,KAAK,aAAa,QAAQ,CAAC,IACnD,KAAK,aAAa,QAAQ,CAAC,EAAE,QAAQ,CAAA,IAEvC,KAAK,aAAa,QAAQ,CAAA;AAAA,EACnC;AAAA,EAEA,aAAoB;AAElB,WAAO,KAAK,QAAA;AAAA,EACd;AAAA,EAEA,SAAgB;AAEd,WAAO,KAAK,QAAA;AAAA,EACd;AAAA,EAEA,aAAkB;AAGhB,WAAI,KAAK,aAAa,WAAW,KAAK,aAAa,QAAQ,CAAC,IACnD,KAAK,aAAa,QAAQ,CAAC,EAAE,cAAc,CAAA,IAE7C,KAAK,aAAa,cAAc,CAAA;AAAA,EACzC;AACF;AAKO,SAASC,EAAiBf,GAAgBC,IAA0B,IAAgB;AACzF,SAAO,IAAIF,EAAWC,GAAOC,CAAO;AACtC;AC3LA,MAAMe,IAAiB,MAAU;AAGjC,IAAIC,IAAgC;AAEpC,SAASC,EAAcC,GAA+B;AACpD,QAAMC,IAA0B,CAAA;AAEhC,SAAAD,EAAK,MAAM,QAAQ,CAAAE,MAAQ;AAEzB,IAAAA,EAAK,SAAS,QAAQ,CAAAC,MAAW;AAC/B,MAAAF,EAASE,EAAQ,IAAI,IAAIA,EAAQ,SAASA,EAAQ,cAAcA,EAAQ;AAAA,IAC1E,CAAC,GAGDD,EAAK,WAAW,QAAQ,CAAAE,MAAa;AACnC,MAAAH,EAASG,EAAU,IAAI,IAAIA,EAAU,SAASA,EAAU,cAAcA,EAAU;AAAA,IAClF,CAAC,GAGDF,EAAK,SAAS,QAAQ,CAAAG,MAAW;AAC/B,MAAAJ,EAASI,EAAQ,IAAI,IAAIA,EAAQ,SAASA,EAAQ,cAAcA,EAAQ;AAAA,IAC1E,CAAC;AAAA,EACH,CAAC,GAEMJ;AACT;AAEA,SAASK,IAAwB;AAC/B,SAAKR,IACO,KAAK,IAAA,IACHA,EAAW,YAAaD,IAFd;AAG1B;AAOO,SAASU,EAAYC,GAAwC;AAClE,QAAM,CAACR,GAAMS,CAAO,IAAIC,EAA0B,IAAI,GAChD,CAACT,GAAUU,CAAW,IAAID,EAAwB,CAAA,CAAE,GACpD,CAACE,GAASC,CAAU,IAAIH,EAAS,EAAI,GACrC,CAACI,GAAOC,CAAQ,IAAIL,EAAwB,IAAI,GAEhDM,IAAYC,EAAY,YAAY;AAExC,QAAIX,EAAA,KAAkBR,GAAY;AAChC,MAAAW,EAAQX,EAAW,IAAI,GACvBa,EAAYb,EAAW,QAAQ,GAC/Be,EAAW,EAAK,GAChBE,EAAS,IAAI;AACb;AAAA,IACF;AAEA,QAAI;AACF,MAAAF,EAAW,EAAI,GACfE,EAAS,IAAI;AAEb,YAAMG,IAAqB,MAAMV,EAAQ,KAAA,GACnCW,IAAcpB,EAAcmB,CAAQ;AAG1C,MAAApB,IAAa;AAAA,QACX,MAAMoB;AAAA,QACN,UAAUC;AAAA,QACV,WAAW,KAAK,IAAA;AAAA,MAAI,GAGtBV,EAAQS,CAAQ,GAChBP,EAAYQ,CAAW;AAAA,IACzB,SAASC,GAAK;AACZ,YAAM/B,IAAe+B,aAAe,QAAQA,EAAI,UAAU;AAC1D,MAAAL,EAAS1B,CAAY,GACrB,QAAQ,MAAM,kCAAkC+B,CAAG;AAAA,IACrD,UAAA;AACE,MAAAP,EAAW,EAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAACL,CAAO,CAAC;AAEZ,EAAAa,EAAU,MAAM;AACd,IAAAL,EAAA;AAAA,EACF,GAAG,CAACA,CAAS,CAAC;AAEd,QAAMM,IAAgBL,EAAY,CAACM,MAC1BtB,EAASsB,CAAS,KAAKA,GAC7B,CAACtB,CAAQ,CAAC,GAEPuB,IAAUP,EAAY,MAAM;AAEhC,IAAAnB,IAAa,MACbkB,EAAA;AAAA,EACF,GAAG,CAACA,CAAS,CAAC;AAEd,SAAO;AAAA,IACL,MAAAhB;AAAA,IACA,UAAAC;AAAA,IACA,SAAAW;AAAA,IACA,OAAAE;AAAA,IACA,SAAAU;AAAA,IACA,eAAAF;AAAA,EAAA;AAEJ;ACvIO,MAAMG,EAAiB;AAAA,EACpB,QAAuB,CAAA;AAAA,EACvB,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EAER,YAAYC,GAAmEC,IAAkB,KAAK;AACpG,SAAK,gBAAgBD,GACrB,KAAK,UAAUC;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,SAAS5C,GAA0C;AACxD,WAAO,IAAI,QAAuB,CAAC6C,GAASC,MAAW;AAErD,WAAK,MAAM,KAAK,EAAE,OAAA9C,GAAO,SAAA6C,GAAS,QAAAC,GAAQ,GAGrC,KAAK,kBACR,KAAK,cAAA;AAAA,IAET,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,gBAAsB;AAC5B,SAAK,iBAAiB,IAEtB,WAAW,MAAM;AACf,WAAK,MAAA;AAAA,IACP,GAAG,KAAK,OAAO;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,QAAuB;AAEnC,SAAK,iBAAiB;AAGtB,UAAMC,IAAe,KAAK,MAAM,MAAA;AAGhC,QAFA,KAAK,QAAQ,CAAA,GAETA,EAAa,WAAW;AAI5B,UAAI;AAEF,cAAMpC,IAAUoC,EAAa,IAAI,CAAAC,MAAQA,EAAK,KAAK,GAG7CC,IAAU,MAAM,KAAK,cAActC,CAAO;AAGhD,QAAAoC,EAAa,QAAQ,CAACC,GAAME,MAAU;AACpC,gBAAMzC,IAASwC,EAAQC,CAAK;AAG5B,UAAIzC,KAAU,WAAWA,KAAUA,EAAO,QACxCuC,EAAK,OAAO,IAAI,MAAMvC,EAAO,KAAe,CAAC,IAE7CuC,EAAK,QAAQvC,CAAM;AAAA,QAEvB,CAAC;AAAA,MACH,SAASsB,GAAO;AAEd,QAAAgB,EAAa,QAAQ,CAAAC,MAAQ;AAC3B,UAAAA,EAAK,OAAOjB,aAAiB,QAAQA,IAAQ,IAAI,MAAM,OAAOA,CAAK,CAAC,CAAC;AAAA,QACvE,CAAC;AAAA,MACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,eAAuB;AAC5B,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKO,QAAc;AACnB,SAAK,QAAQ,CAAA,GACb,KAAK,iBAAiB;AAAA,EACxB;AACF;ACvFA,MAAMoB,IAAcC,EAAuC,IAAI;AAaxD,SAASC,EAAa;AAAA,EAC3B,SAASC;AAAA,EACT,YAAYC;AAAA,EACZ,OAAOC;AAAA,EACP,SAAAzD,IAAU,CAAA;AAAA,EACV,UAAA0D,IAAW,EAAE,UAAU,IAAM,YAAY,mBAAA;AAAA;AAAA,EACzC,gBAAAC,IAAiB;AAAA;AAAA,EACjB,cAAAC,IAAe;AAAA;AAAA,EACf,UAAAC;AACF,GAAsB;AAEpB,QAAM,CAACC,GAAeC,CAAgB,IAAInC,EAAgE,IAAI,GAGxGoC,IAAgBF,KAAiB;AAAA,IACrC,YAAYN,KAAqB,EAAE,QAAQ,iBAAA;AAAA,IAC3C,OAAOC;AAAA,EAAA,GAIH/B,IAAUuC,EAAQ,MAClBV,KAAkB,CAACC,KAAqB,CAACC,IAEpCF,IAIFzC,EAAiBkD,EAAc,OAAOA,EAAc,UAAU,GACpE,CAACT,GAAgBC,GAAmBC,GAAcO,EAAc,YAAYA,EAAc,KAAK,CAAC,GAG7FE,IAAmBD,EAAQ,MAAM;AACrC,QAAI,CAACN;AACH,aAAO;AAIT,UAAMf,IAAgB,CAAChC,MAAmBc,EAAQ,UAAUd,CAAO;AAEnE,WAAO,IAAI+B,EAAiBC,GAAegB,CAAY;AAAA,EACzD,GAAG,CAACD,GAAgBjC,GAASkC,CAAY,CAAC,GAEpC,EAAE,MAAA1C,GAAM,UAAAC,GAAU,SAASgD,GAAa,OAAOC,GAAW,eAAA5B,GAAe,SAAS6B,MAAgB5C,EAAYC,CAAO,GASrH4C,IAAe;AAAA,IACnB,SAAA5C;AAAA,IACA,SAAA1B;AAAA,IACA,MAAAkB;AAAA,IACA,UAAAC;AAAA,IACA,aAAAgD;AAAA,IACA,WAAAC;AAAA,IACA,eAAA5B;AAAA,IACA,aAAA6B;AAAA,IACA,iBAhBsB,CAACE,GAA+BC,MAAsB;AAC5E,MAAAT,EAAiB;AAAA,QACf,YAAYQ;AAAA,QACZ,OAAOC;AAAA,MAAA,CACR;AAAA,IACH;AAAA,IAYE,UAAAd;AAAA,IACA,kBAAAQ;AAAA,IACA,gBAAAP;AAAA,EAAA;AAGF,2BACGP,EAAY,UAAZ,EAAqB,OAAOkB,GAC1B,UAAAT,GACH;AAEJ;AAEO,SAASY,IAAiB;AAC/B,QAAMC,IAAUC,EAAWvB,CAAW;AAEtC,MAAI,CAACsB;AACH,UAAM,IAAI,MAAM,mDAAmD;AAErE,SAAOA;AACT;"}
@@ -2,6 +2,7 @@ import { CubeQuery, CubeApiOptions, CubeResultSet } from '../types';
2
2
  export declare class CubeClient {
3
3
  private apiUrl;
4
4
  private headers;
5
+ private credentials;
5
6
  constructor(token?: string, options?: CubeApiOptions);
6
7
  load(query: CubeQuery): Promise<CubeResultSet>;
7
8
  meta(): Promise<any>;
@@ -1,2 +1,2 @@
1
1
  import { AnalyticsDashboardProps } from '../types';
2
- export default function AnalyticsDashboard({ config, editable, dashboardFilters: propDashboardFilters, onConfigChange, onSave, onDirtyStateChange }: AnalyticsDashboardProps): import("react/jsx-runtime").JSX.Element;
2
+ export default function AnalyticsDashboard({ config, editable, dashboardFilters: propDashboardFilters, loadingComponent, onConfigChange, onSave, onDirtyStateChange }: AnalyticsDashboardProps): import("react/jsx-runtime").JSX.Element;
@@ -1,9 +1,11 @@
1
+ import { ReactNode } from 'react';
1
2
  import { ColorPalette } from '../utils/colorPalettes';
2
3
  import { DashboardConfig, DashboardFilter, CubeMeta } from '../types';
3
4
  interface DashboardGridProps {
4
5
  config: DashboardConfig;
5
6
  editable?: boolean;
6
7
  dashboardFilters?: DashboardFilter[];
8
+ loadingComponent?: ReactNode;
7
9
  onConfigChange?: (config: DashboardConfig) => void;
8
10
  onPortletRefresh?: (portletId: string) => void;
9
11
  onSave?: (config: DashboardConfig) => Promise<void> | void;
@@ -11,5 +13,5 @@ interface DashboardGridProps {
11
13
  schema?: CubeMeta | null;
12
14
  onDashboardFiltersChange?: (filters: DashboardFilter[]) => void;
13
15
  }
14
- export default function DashboardGrid({ config, editable, dashboardFilters, onConfigChange, onPortletRefresh, onSave, colorPalette, schema, onDashboardFiltersChange }: DashboardGridProps): import("react/jsx-runtime").JSX.Element;
16
+ export default function DashboardGrid({ config, editable, dashboardFilters, loadingComponent, onConfigChange, onPortletRefresh, onSave, colorPalette, schema, onDashboardFiltersChange }: DashboardGridProps): import("react/jsx-runtime").JSX.Element;
15
17
  export {};
@@ -0,0 +1,16 @@
1
+ /**
2
+ * LoadingIndicator Component
3
+ *
4
+ * A centralized, theme-aware loading spinner that uses CSS variables
5
+ * for consistent styling across all drizzle-cube components.
6
+ *
7
+ * Can be overridden at the Dashboard or Portlet level by passing a
8
+ * custom loadingComponent prop.
9
+ */
10
+ export interface LoadingIndicatorProps {
11
+ /** Size variant: 'sm' (24px), 'md' (32px), 'lg' (48px) */
12
+ size?: 'sm' | 'md' | 'lg';
13
+ /** Additional CSS classes */
14
+ className?: string;
15
+ }
16
+ export default function LoadingIndicator({ size, className }: LoadingIndicatorProps): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,5 @@
1
- import { a as t, A as s, c as o, D as r, M as d, P as l, b as i, Q as n } from "./chunks/components-BzN5ydzE.js";
2
- import { c as P, G as b, E as c, z as u, y as D, F as h } from "./chunks/charts-P7xq59Tl.js";
1
+ import { a as t, A as s, c as o, D as r, M as d, P as l, b as i, Q as n } from "./chunks/components-Bbd9Us6e.js";
2
+ import { c as b, H as c, F as u, E as y, z as D, G as h } from "./chunks/charts-jwgcWeFt.js";
3
3
  export {
4
4
  t as AnalyticsDashboard,
5
5
  s as AnalyticsPortlet,
@@ -9,10 +9,10 @@ export {
9
9
  l as PortletContainer,
10
10
  i as PortletEditModal,
11
11
  n as QueryBuilder,
12
- P as createDashboardLayout,
13
- b as createSamplePortlet,
14
- c as findNextPosition,
15
- u as generatePortletId,
12
+ b as createDashboardLayout,
13
+ c as createSamplePortlet,
14
+ u as findNextPosition,
15
+ y as generatePortletId,
16
16
  D as generateResponsiveLayouts,
17
17
  h as validateCubeQuery
18
18
  };
@@ -1,6 +1,6 @@
1
1
  import { useState as b, useRef as w, useEffect as y, useCallback as C, useMemo as m } from "react";
2
- import { u as L } from "./chunks/providers-DONuYrGH.js";
3
- import { a as F } from "./chunks/providers-DONuYrGH.js";
2
+ import { u as L } from "./chunks/providers-D7zRgZrO.js";
3
+ import { a as F } from "./chunks/providers-D7zRgZrO.js";
4
4
  function W(e, r = {}) {
5
5
  const { cubeApi: s, batchCoordinator: u, enableBatching: a } = L(), [l, d] = b({
6
6
  resultSet: null,
@@ -1,5 +1,7 @@
1
1
  export { default as AnalyticsPortlet } from './components/AnalyticsPortlet';
2
2
  export { default as AnalyticsDashboard } from './components/AnalyticsDashboard';
3
+ export { default as LoadingIndicator } from './components/LoadingIndicator';
4
+ export type { LoadingIndicatorProps } from './components/LoadingIndicator';
3
5
  export { RechartsBarChart, RechartsLineChart, RechartsAreaChart, RechartsPieChart, RechartsScatterChart, RechartsRadarChart, RechartsRadialBarChart, RechartsTreeMapChart, DataTable } from './components/charts';
4
6
  export { default as DashboardGrid } from './components/DashboardGrid';
5
7
  export { default as PortletContainer } from './components/PortletContainer';
@@ -1,40 +1,41 @@
1
- import { a as r, A as s, c as t, D as h, M as o, P as C, b as c, Q as i, S as l, T as d, d as u, e as T, g as b, i as m, r as n, f as R, s as D, u as P, w as f } from "./chunks/components-BzN5ydzE.js";
2
- import { C as M, c as S, u as y } from "./chunks/providers-DONuYrGH.js";
3
- import { useCubeQuery as x } from "./hooks.js";
4
- import { D as g, A as B, B as L, L as Q, P as v, R as w, a as V, S as k, T as G, c as H, f as _ } from "./chunks/charts-P7xq59Tl.js";
1
+ import { a as r, A as s, c as t, D as o, M as h, P as i, b as c, Q as C, S as d, T as l, d as n, e as b, g as u, i as T, r as m, f as R, s as D, u as P, w as f } from "./chunks/components-Bbd9Us6e.js";
2
+ import { D as M, L as S, A as y, B as E, a as g, P as x, R as A, b as B, S as L, T as Q, c as v, f as w } from "./chunks/charts-jwgcWeFt.js";
3
+ import { C as k, c as G, u as H } from "./chunks/providers-D7zRgZrO.js";
4
+ import { useCubeQuery as _ } from "./hooks.js";
5
5
  export {
6
6
  r as AnalyticsDashboard,
7
7
  s as AnalyticsPortlet,
8
- M as CubeProvider,
8
+ k as CubeProvider,
9
9
  t as DashboardEditModal,
10
- h as DashboardGrid,
11
- g as DataTable,
12
- o as Modal,
13
- C as PortletContainer,
10
+ o as DashboardGrid,
11
+ M as DataTable,
12
+ S as LoadingIndicator,
13
+ h as Modal,
14
+ i as PortletContainer,
14
15
  c as PortletEditModal,
15
- i as QueryBuilder,
16
- B as RechartsAreaChart,
17
- L as RechartsBarChart,
18
- Q as RechartsLineChart,
19
- v as RechartsPieChart,
20
- w as RechartsRadarChart,
21
- V as RechartsRadialBarChart,
22
- k as RechartsScatterChart,
23
- G as RechartsTreeMapChart,
24
- l as ScrollContainerProvider,
25
- d as THEME_PRESETS,
26
- u as applyTheme,
27
- S as createCubeClient,
28
- H as createDashboardLayout,
29
- _ as formatChartData,
30
- T as getTheme,
31
- b as getThemeVariable,
32
- m as isDarkMode,
33
- n as resetTheme,
16
+ C as QueryBuilder,
17
+ y as RechartsAreaChart,
18
+ E as RechartsBarChart,
19
+ g as RechartsLineChart,
20
+ x as RechartsPieChart,
21
+ A as RechartsRadarChart,
22
+ B as RechartsRadialBarChart,
23
+ L as RechartsScatterChart,
24
+ Q as RechartsTreeMapChart,
25
+ d as ScrollContainerProvider,
26
+ l as THEME_PRESETS,
27
+ n as applyTheme,
28
+ G as createCubeClient,
29
+ v as createDashboardLayout,
30
+ w as formatChartData,
31
+ b as getTheme,
32
+ u as getThemeVariable,
33
+ T as isDarkMode,
34
+ m as resetTheme,
34
35
  R as setTheme,
35
36
  D as setThemeVariable,
36
- y as useCubeContext,
37
- x as useCubeQuery,
37
+ H as useCubeContext,
38
+ _ as useCubeQuery,
38
39
  P as useScrollContainer,
39
40
  f as watchThemeChanges
40
41
  };
@@ -1,4 +1,4 @@
1
- import { C as r, c as t, u } from "./chunks/providers-DONuYrGH.js";
1
+ import { C as r, c as t, u } from "./chunks/providers-D7zRgZrO.js";
2
2
  export {
3
3
  r as CubeProvider,
4
4
  t as createCubeClient,