@lightdash/query-sdk 1.11.0 → 1.13.0

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.
package/dist/features.js CHANGED
@@ -59,6 +59,12 @@ export const SDK_FEATURES = [
59
59
  label: 'Dashboard visualization context',
60
60
  description: 'Receive query context when app visualizations are embedded in dashboards.',
61
61
  },
62
+ {
63
+ key: 'viz-config-options',
64
+ label: 'Visualization config options',
65
+ description: "Let viewers adjust the visualization from the Lightdash config panel — toggles, dropdowns, numbers, text and colours — and take series colours from the chart's palette, without regenerating the app.",
66
+ wiring: 'Declare configOptions (and colorPalette, if the viz colours series) in the viz schema, then read options[name] and colorPalette from useVizContext().',
67
+ },
62
68
  ];
63
69
  export const SDK_FEATURE_KEYS = SDK_FEATURES.map((f) => f.key);
64
70
  export const SDK_MANIFEST_MESSAGE_TYPE = 'lightdash:sdk:manifest';
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "1.11.0";
1
+ export declare const SDK_VERSION = "1.13.0";
@@ -1,2 +1,2 @@
1
1
  // Generated by scripts/generateSdkVersion.mjs (prebuild) — do not edit.
2
- export const SDK_VERSION = '1.11.0';
2
+ export const SDK_VERSION = '1.13.0';
package/dist/index.d.ts CHANGED
@@ -13,6 +13,6 @@ export type { InspectAvailableMessage, InspectSelectedMessage, } from './inspect
13
13
  export { exportToSheets } from './exportToSheets';
14
14
  export type { ExportToSheetsOptions, ExportToSheetsResult, } from './exportToSheets';
15
15
  export { VizContextProvider, useVizContext, getFormatted, getRaw, } from './vizContext';
16
- export type { VizContext, VizContextCell, VizContextRow, DataAppVizContextMessage, VizContextRequestMessage, } from './vizContext';
16
+ export type { VizContext, VizContextCell, VizContextOptionValue, VizContextRow, DataAppVizContextMessage, VizContextRequestMessage, } from './vizContext';
17
17
  export { useUrlState } from './urlState';
18
18
  export type { SdkUrlStateChangeMessage, UrlStateMap } from './urlState';
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ export { createPostMessageTransport } from './postMessageTransport';
16
16
  export { SDK_FEATURES, SDK_FEATURE_KEYS, SDK_MANIFEST_MESSAGE_TYPE, } from './features';
17
17
  // Google Sheets export (data apps)
18
18
  export { exportToSheets } from './exportToSheets';
19
- // Data app viz render context (host-pushed rows + field mapping)
19
+ // Data app viz render context (host-pushed rows + field mapping + config options)
20
20
  export { VizContextProvider, useVizContext, getFormatted, getRaw, } from './vizContext';
21
21
  // Shareable URL state (seeded from and written back to the host page URL)
22
22
  export { useUrlState } from './urlState';
@@ -23,15 +23,28 @@ export type VizContextCell = {
23
23
  };
24
24
  /** A result row keyed by query field id. */
25
25
  export type VizContextRow = Record<string, VizContextCell | undefined>;
26
+ /**
27
+ * A config option value. Its shape follows the option's declared type:
28
+ * `boolean` → boolean, `number` → number, `select`/`text`/`color` → string.
29
+ * Series colours are not an option — they arrive on `colorPalette`.
30
+ */
31
+ export type VizContextOptionValue = boolean | number | string;
26
32
  /**
27
33
  * Pushed by the host into the iframe. `fieldMapping` maps each field name the
28
34
  * renderer declared to the query field id it resolves to; `rows` are the
29
- * host-fetched result rows keyed by field id.
35
+ * host-fetched result rows keyed by field id; `options` holds the current
36
+ * value of each config option the renderer declared; `colorPalette` is the
37
+ * Lightdash palette resolved for this chart, pushed whether or not the
38
+ * renderer declared one.
30
39
  */
31
40
  export type DataAppVizContextMessage = {
32
41
  type: 'lightdash:sdk:data-app-viz-context';
33
42
  fieldMapping: Record<string, string>;
34
43
  rows: VizContextRow[];
44
+ /** Absent when the installed host predates config-option delivery. */
45
+ options?: Record<string, VizContextOptionValue>;
46
+ /** Absent when the installed host predates palette delivery. */
47
+ colorPalette?: string[];
35
48
  };
36
49
  /** Posted by the iframe on mount so the host pushes the current context. */
37
50
  export type VizContextRequestMessage = {
@@ -46,13 +59,32 @@ export type VizContext = {
46
59
  fieldMapping: Record<string, string>;
47
60
  /** Host-fetched result rows, keyed by query field id. */
48
61
  rows: VizContextRow[];
62
+ /** Config option name → current value (the user's choice, else the declared default). */
63
+ options: Record<string, VizContextOptionValue>;
64
+ /**
65
+ * Ordered series colours resolved from the Lightdash palette the viewer
66
+ * picked. Colour multi-series charts with
67
+ * `colorPalette[i % colorPalette.length]`. Empty only when the host
68
+ * resolved no palette; keep a fallback array in your own code for that.
69
+ */
70
+ colorPalette: string[];
49
71
  /** False until the first context arrives — render a placeholder while false. */
50
72
  ready: boolean;
51
73
  };
52
- type VizContextState = {
74
+ type VizContextValue = {
53
75
  fieldMapping: Record<string, string>;
54
76
  rows: VizContextRow[];
55
- } | null;
77
+ options: Record<string, VizContextOptionValue>;
78
+ colorPalette: string[];
79
+ };
80
+ type VizContextState = VizContextValue | null;
81
+ /**
82
+ * Normalises an inbound host message into provider state. The payload crosses a
83
+ * postMessage boundary so every key is treated as untrusted; `options` and
84
+ * `colorPalette` are also absent from hosts predating them, and fall back to
85
+ * `{}` / `[]`.
86
+ */
87
+ export declare function toVizContextState(message: DataAppVizContextMessage): VizContextValue;
56
88
  declare const NO_PROVIDER: unique symbol;
57
89
  /**
58
90
  * Owns the single listener + handshake for a data app viz. Mount it in the
@@ -67,7 +99,8 @@ export declare function VizContextProvider({ children }: {
67
99
  * one is mounted (the scaffold default); otherwise self-subscribes so the hook
68
100
  * still works standalone. Re-renders whenever the host pushes (on load, on
69
101
  * mapping change, on query change). Resolve a declared field to its bound cell
70
- * with `fieldMapping[name]` then `getFormatted`/`getRaw`.
102
+ * with `fieldMapping[name]` then `getFormatted`/`getRaw`; read a declared
103
+ * config option with `options[name]`, and colour series from `colorPalette`.
71
104
  */
72
105
  export declare function useVizContext(): VizContext;
73
106
  export {};
@@ -28,6 +28,33 @@ export const getRaw = (row, fieldId) => {
28
28
  return null;
29
29
  return row[fieldId]?.value?.raw ?? null;
30
30
  };
31
+ const isVizContextOptionValue = (value) => typeof value === 'string' ||
32
+ typeof value === 'boolean' ||
33
+ (typeof value === 'number' && Number.isFinite(value));
34
+ const normalizeOptions = (options) => {
35
+ if (typeof options !== 'object' ||
36
+ options === null ||
37
+ Array.isArray(options)) {
38
+ return {};
39
+ }
40
+ return Object.fromEntries(Object.entries(options).filter((entry) => isVizContextOptionValue(entry[1])));
41
+ };
42
+ /**
43
+ * Normalises an inbound host message into provider state. The payload crosses a
44
+ * postMessage boundary so every key is treated as untrusted; `options` and
45
+ * `colorPalette` are also absent from hosts predating them, and fall back to
46
+ * `{}` / `[]`.
47
+ */
48
+ export function toVizContextState(message) {
49
+ return {
50
+ fieldMapping: message.fieldMapping ?? {},
51
+ rows: Array.isArray(message.rows) ? message.rows : [],
52
+ options: normalizeOptions(message.options),
53
+ colorPalette: Array.isArray(message.colorPalette)
54
+ ? message.colorPalette.filter((color) => typeof color === 'string')
55
+ : [],
56
+ };
57
+ }
31
58
  // Distinguishes "no provider mounted" from "provider present, no context yet".
32
59
  const NO_PROVIDER = Symbol('viz-context/no-provider');
33
60
  const VizContextContext = createContext(NO_PROVIDER);
@@ -45,10 +72,7 @@ function useVizContextSubscription(enabled) {
45
72
  const data = event.data;
46
73
  if (!data || data.type !== DATA_APP_VIZ_CONTEXT_MESSAGE)
47
74
  return;
48
- setContext({
49
- fieldMapping: data.fieldMapping ?? {},
50
- rows: Array.isArray(data.rows) ? data.rows : [],
51
- });
75
+ setContext(toVizContextState(data));
52
76
  };
53
77
  window.addEventListener('message', handleMessage);
54
78
  // Ask the host to push the current context. Sent from a mount effect —
@@ -77,7 +101,8 @@ export function VizContextProvider({ children }) {
77
101
  * one is mounted (the scaffold default); otherwise self-subscribes so the hook
78
102
  * still works standalone. Re-renders whenever the host pushes (on load, on
79
103
  * mapping change, on query change). Resolve a declared field to its bound cell
80
- * with `fieldMapping[name]` then `getFormatted`/`getRaw`.
104
+ * with `fieldMapping[name]` then `getFormatted`/`getRaw`; read a declared
105
+ * config option with `options[name]`, and colour series from `colorPalette`.
81
106
  */
82
107
  export function useVizContext() {
83
108
  const fromProvider = useContext(VizContextContext);
@@ -91,6 +116,8 @@ export function useVizContext() {
91
116
  return {
92
117
  fieldMapping: context?.fieldMapping ?? {},
93
118
  rows: context?.rows ?? [],
119
+ options: context?.options ?? {},
120
+ colorPalette: context?.colorPalette ?? [],
94
121
  ready: context !== null,
95
122
  };
96
123
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/query-sdk",
3
- "version": "1.11.0",
3
+ "version": "1.13.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "SDK for building custom data apps against the Lightdash semantic layer",
@@ -35,7 +35,7 @@
35
35
  "typescript": "npm:@typescript/typescript6@6.0.1",
36
36
  "typescript-7": "npm:typescript@7.0.1-rc",
37
37
  "vitest": "4.1.6",
38
- "@lightdash/common": "1.11.0"
38
+ "@lightdash/common": "1.13.0"
39
39
  },
40
40
  "scripts": {
41
41
  "prebuild": "node ./scripts/generateSdkVersion.mjs",