@carto/ps-react-ui 4.5.0 → 4.6.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.
Files changed (99) hide show
  1. package/dist/{download-config-DemuQ3Jm.js → download-config-C3I0jWIL.js} +2 -2
  2. package/dist/{download-config-DemuQ3Jm.js.map → download-config-C3I0jWIL.js.map} +1 -1
  3. package/dist/{row-D4VOhcNI.js → row-DZSP99LW.js} +2 -2
  4. package/dist/{row-D4VOhcNI.js.map → row-DZSP99LW.js.map} +1 -1
  5. package/dist/{series-Bola3CmD.js → series-DLNHDWs0.js} +3 -3
  6. package/dist/{series-Bola3CmD.js.map → series-DLNHDWs0.js.map} +1 -1
  7. package/dist/types/hooks/index.d.ts +0 -1
  8. package/dist/types/widgets/actions/brush-toggle/brush-toggle.d.ts +3 -0
  9. package/dist/types/widgets/actions/index.d.ts +4 -4
  10. package/dist/types/widgets/actions/lock-selection/types.d.ts +2 -0
  11. package/dist/types/widgets/actions/relative-data/relative-data.d.ts +7 -2
  12. package/dist/types/widgets/actions/relative-data/types.d.ts +2 -0
  13. package/dist/types/widgets/actions/zoom-toggle/zoom-toggle.d.ts +4 -0
  14. package/dist/types/widgets/category/index.d.ts +10 -2
  15. package/dist/types/widgets/category/style.d.ts +1 -0
  16. package/dist/types/widgets/no-data/no-data.d.ts +3 -2
  17. package/dist/types/widgets/no-data/types.d.ts +5 -1
  18. package/dist/types/widgets/stores/index.d.ts +1 -1
  19. package/dist/types/widgets/stores/types.d.ts +10 -10
  20. package/dist/types/widgets/stores/widget-store.d.ts +2 -3
  21. package/dist/types/widgets/table/index.d.ts +6 -2
  22. package/dist/{use-widget-ref-BFazQvJK.js → use-widget-ref-Ddr_SlJJ.js} +2 -2
  23. package/dist/{use-widget-ref-BFazQvJK.js.map → use-widget-ref-Ddr_SlJJ.js.map} +1 -1
  24. package/dist/{use-widget-selector-DqRmWQ1K.js → use-widget-selector-DFl2hW0R.js} +2 -2
  25. package/dist/{use-widget-selector-DqRmWQ1K.js.map → use-widget-selector-DFl2hW0R.js.map} +1 -1
  26. package/dist/{widget-store-CIrb9RKP.js → widget-store-Bw5zRUGg.js} +93 -95
  27. package/dist/widget-store-Bw5zRUGg.js.map +1 -0
  28. package/dist/widgets/actions.js +770 -755
  29. package/dist/widgets/actions.js.map +1 -1
  30. package/dist/widgets/bar.js +2 -2
  31. package/dist/widgets/category.js +187 -183
  32. package/dist/widgets/category.js.map +1 -1
  33. package/dist/widgets/echart.js +2 -2
  34. package/dist/widgets/error.js +37 -2
  35. package/dist/widgets/error.js.map +1 -1
  36. package/dist/widgets/formula.js +5 -5
  37. package/dist/widgets/histogram.js +1 -1
  38. package/dist/widgets/loader.js +1 -1
  39. package/dist/widgets/markdown.js +2 -2
  40. package/dist/widgets/no-data.js +58 -2
  41. package/dist/widgets/no-data.js.map +1 -1
  42. package/dist/widgets/note.js +121 -2
  43. package/dist/widgets/note.js.map +1 -1
  44. package/dist/widgets/pie.js +2 -2
  45. package/dist/widgets/range.js +3 -3
  46. package/dist/widgets/scatterplot.js +2 -2
  47. package/dist/widgets/skeleton-loader.js +1 -1
  48. package/dist/widgets/spread.js +5 -5
  49. package/dist/widgets/stores.js +2 -2
  50. package/dist/widgets/subheader.js +29 -29
  51. package/dist/widgets/subheader.js.map +1 -1
  52. package/dist/widgets/table.js +3 -3
  53. package/dist/widgets/timeseries.js +2 -2
  54. package/dist/widgets/utils.js +1 -1
  55. package/dist/widgets/wrapper.js +2 -2
  56. package/package.json +1 -5
  57. package/src/hooks/index.ts +0 -1
  58. package/src/widgets/actions/brush-toggle/brush-toggle.tsx +18 -22
  59. package/src/widgets/actions/change-column/change-column.test.tsx +1 -1
  60. package/src/widgets/actions/download/download.test.tsx +1 -1
  61. package/src/widgets/actions/index.ts +11 -2
  62. package/src/widgets/actions/lock-selection/lock-selection.test.tsx +14 -0
  63. package/src/widgets/actions/lock-selection/lock-selection.tsx +18 -11
  64. package/src/widgets/actions/lock-selection/types.ts +2 -0
  65. package/src/widgets/actions/relative-data/relative-data.test.tsx +211 -20
  66. package/src/widgets/actions/relative-data/relative-data.tsx +65 -34
  67. package/src/widgets/actions/relative-data/types.ts +2 -0
  68. package/src/widgets/actions/searcher/searcher.tsx +28 -30
  69. package/src/widgets/actions/stack-toggle/stack-toggle.tsx +11 -2
  70. package/src/widgets/actions/zoom-toggle/zoom-toggle.tsx +53 -45
  71. package/src/widgets/category/category-ui.tsx +7 -6
  72. package/src/widgets/category/index.ts +13 -14
  73. package/src/widgets/category/style.ts +1 -0
  74. package/src/widgets/no-data/no-data.test.tsx +90 -40
  75. package/src/widgets/no-data/no-data.tsx +7 -5
  76. package/src/widgets/no-data/types.ts +5 -1
  77. package/src/widgets/stores/index.ts +2 -0
  78. package/src/widgets/stores/types.ts +10 -18
  79. package/src/widgets/stores/widget-store.test.ts +132 -13
  80. package/src/widgets/stores/widget-store.ts +29 -35
  81. package/src/widgets/subheader/subheader.tsx +11 -3
  82. package/src/widgets/table/index.ts +6 -4
  83. package/dist/error-Cj8eUMrl.js +0 -40
  84. package/dist/error-Cj8eUMrl.js.map +0 -1
  85. package/dist/no-data-DkIt7Qt1.js +0 -61
  86. package/dist/no-data-DkIt7Qt1.js.map +0 -1
  87. package/dist/note-t51drNe0.js +0 -124
  88. package/dist/note-t51drNe0.js.map +0 -1
  89. package/dist/types/hooks/use-debounce.d.ts +0 -19
  90. package/dist/types/widgets/category/components/index.d.ts +0 -10
  91. package/dist/types/widgets/index.d.ts +0 -9
  92. package/dist/types/widgets/table/hooks/index.d.ts +0 -6
  93. package/dist/widget-store-CIrb9RKP.js.map +0 -1
  94. package/dist/widgets.js +0 -13
  95. package/dist/widgets.js.map +0 -1
  96. package/src/hooks/use-debounce.ts +0 -55
  97. package/src/widgets/category/components/index.ts +0 -14
  98. package/src/widgets/index.ts +0 -25
  99. package/src/widgets/table/hooks/index.ts +0 -7
@@ -1,98 +1,95 @@
1
- import { create as y } from "zustand";
2
- const b = /* @__PURE__ */ new Map(), w = /* @__PURE__ */ new Map(), u = y()((T, p) => ({
1
+ import { create as P } from "zustand";
2
+ const p = /* @__PURE__ */ new Map(), w = /* @__PURE__ */ new Map(), u = P()((T, b) => ({
3
3
  // State
4
4
  widgets: {},
5
5
  // Actions
6
6
  /** Merges partial state into the widget entry. Creates the widget if it doesn't exist. */
7
- setWidget: (e, o) => {
8
- T((s) => {
9
- const t = s.widgets[e] ?? {};
7
+ setWidget: (e, t) => {
8
+ T((o) => {
9
+ const s = o.widgets[e] ?? {};
10
10
  return {
11
11
  widgets: {
12
- ...s.widgets,
12
+ ...o.widgets,
13
13
  [e]: {
14
+ ...s,
14
15
  ...t,
15
- ...o,
16
16
  id: e
17
17
  }
18
18
  }
19
19
  };
20
20
  });
21
21
  },
22
- removeWidget: (e) => T((o) => {
23
- const s = {
24
- ...o.widgets
22
+ removeWidget: (e) => T((t) => {
23
+ const o = {
24
+ ...t.widgets
25
25
  };
26
- return delete s[e], {
27
- widgets: s
26
+ return delete o[e], {
27
+ widgets: o
28
28
  };
29
29
  }),
30
30
  clearWidgets: () => T({
31
31
  widgets: {}
32
32
  }),
33
- getWidget: (e) => p().widgets[e],
33
+ getWidget: (e) => b().widgets[e],
34
34
  /**
35
35
  * Registers a transformation tool for a widget's data or config pipeline.
36
36
  *
37
37
  * **No-op optimization:** When a tool with the same `id` already exists and its
38
38
  * structural properties (`order`, `enabled`, `type`, `disables`) are unchanged,
39
- * only `fn` and `config` are updated via direct mutation — no store update is
40
- * triggered. This allows action components to include all reactive dependencies
41
- * in their `useEffect` arrays without causing WidgetLoader pipeline cascades.
39
+ * only `fn` is updated via direct mutation — no store update is triggered. This
40
+ * allows action components to include all reactive dependencies in their
41
+ * `useEffect` arrays without causing WidgetLoader pipeline cascades.
42
42
  */
43
- registerTool: (e, o) => {
44
- const t = p().widgets[e]?.registeredTools?.find((n) => n.id === o.id);
45
- if (t?.order === o.order && t.enabled === o.enabled && t.type === o.type && t.disables === o.disables) {
46
- t.fn = o.fn, o.config && (t.config = o.config);
43
+ registerTool: (e, t) => {
44
+ const s = b().widgets[e]?.registeredTools?.find((n) => n.id === t.id);
45
+ if (s?.order === t.order && s.enabled === t.enabled && s.type === t.type && s.disables === t.disables) {
46
+ s.fn = t.fn;
47
47
  return;
48
48
  }
49
49
  T((n) => {
50
- const g = n.widgets[e] ?? {}, c = (g.registeredTools ?? []).filter((f) => f.id !== o.id);
50
+ const g = n.widgets[e] ?? {}, f = (g.registeredTools ?? []).filter((l) => l.id !== t.id);
51
51
  return {
52
52
  widgets: {
53
53
  ...n.widgets,
54
54
  [e]: {
55
55
  ...g,
56
56
  id: e,
57
- registeredTools: [...c, o]
57
+ registeredTools: [...f, t]
58
58
  }
59
59
  }
60
60
  };
61
61
  });
62
62
  },
63
- unregisterTool: (e, o) => T((s) => {
64
- const t = s.widgets[e];
65
- if (!t) return s;
66
- const g = (t.registeredTools ?? []).filter((d) => d.id !== o);
63
+ unregisterTool: (e, t) => T((o) => {
64
+ const s = o.widgets[e];
65
+ if (!s) return o;
66
+ const g = (s.registeredTools ?? []).filter((d) => d.id !== t);
67
67
  return {
68
68
  widgets: {
69
- ...s.widgets,
69
+ ...o.widgets,
70
70
  [e]: {
71
- ...t,
71
+ ...s,
72
72
  registeredTools: g
73
73
  }
74
74
  }
75
75
  };
76
76
  }),
77
- updateToolConfig: (e, o, s) => T((t) => {
78
- const n = t.widgets[e];
79
- if (!n) return t;
80
- const d = (n.registeredTools ?? []).map((c) => c.id === o ? {
81
- ...c,
82
- config: {
83
- ...c.config,
84
- ...s
85
- }
86
- } : c);
87
- return {
77
+ /**
78
+ * Triggers pipeline re-execution by creating a new `registeredTools` reference.
79
+ * This is a lightweight operation that only bumps the array reference without
80
+ * modifying any tool.
81
+ */
82
+ triggerToolPipeline: (e) => T((t) => {
83
+ const o = t.widgets[e];
84
+ return o ? {
88
85
  widgets: {
89
86
  ...t.widgets,
90
87
  [e]: {
91
- ...n,
92
- registeredTools: d
88
+ ...o,
89
+ registeredTools: [...o.registeredTools ?? []]
93
90
  }
94
91
  }
95
- };
92
+ } : t;
96
93
  }),
97
94
  /**
98
95
  * Updates a tool's enabled state.
@@ -100,21 +97,21 @@ const b = /* @__PURE__ */ new Map(), w = /* @__PURE__ */ new Map(), u = y()((T,
100
97
  * **No-op optimization:** Skips the store update if the tool already has the
101
98
  * requested enabled value.
102
99
  */
103
- setToolEnabled: (e, o, s) => {
104
- const t = p().widgets[e];
105
- t && t.registeredTools?.find((g) => g.id === o)?.enabled === s || T((n) => {
100
+ setToolEnabled: (e, t, o) => {
101
+ const s = b().widgets[e];
102
+ s && s.registeredTools?.find((g) => g.id === t)?.enabled === o || T((n) => {
106
103
  const g = n.widgets[e];
107
104
  if (!g) return n;
108
- const c = (g.registeredTools ?? []).map((f) => f.id === o ? {
109
- ...f,
110
- enabled: s
111
- } : f);
105
+ const f = (g.registeredTools ?? []).map((l) => l.id === t ? {
106
+ ...l,
107
+ enabled: o
108
+ } : l);
112
109
  return {
113
110
  widgets: {
114
111
  ...n.widgets,
115
112
  [e]: {
116
113
  ...g,
117
- registeredTools: c
114
+ registeredTools: f
118
115
  }
119
116
  }
120
117
  };
@@ -132,42 +129,43 @@ const b = /* @__PURE__ */ new Map(), w = /* @__PURE__ */ new Map(), u = y()((T,
132
129
  * **No-op optimization:** Skips the final `set()` if the transformed data is
133
130
  * referentially identical (`Object.is`) to what's already in the store.
134
131
  */
135
- executeToolPipeline: async (e, o) => {
136
- const s = p().widgets[e];
137
- if (!s) return;
138
- const t = (b.get(e) ?? 0) + 1;
139
- b.set(e, t);
140
- const n = s, g = /* @__PURE__ */ new Set();
132
+ executeToolPipeline: async (e, t) => {
133
+ const o = b().widgets[e];
134
+ if (!o) return;
135
+ const s = (p.get(e) ?? 0) + 1;
136
+ p.set(e, s);
137
+ const n = o, g = /* @__PURE__ */ new Set();
141
138
  for (const i of n.registeredTools ?? [])
142
- i.enabled && i.disables && i.disables.forEach((l) => g.add(l));
143
- const d = [...n.registeredTools ?? []].filter((i) => (i.type ?? "data") === "data" && i.enabled && !g.has(i.id)).sort((i, l) => i.order - l.order);
144
- let c = o;
139
+ i.enabled && i.disables && i.disables.forEach((c) => g.add(c));
140
+ const d = [...n.registeredTools ?? []].filter((i) => (i.type ?? "data") === "data" && i.enabled && !g.has(i.id)).sort((i, c) => i.order - c.order);
141
+ let f = t;
145
142
  for (const i of d) {
146
- if (b.get(e) !== t)
143
+ if (p.get(e) !== s)
147
144
  return;
148
145
  try {
149
- c = await i.fn(c, i.config);
150
- } catch (l) {
151
- console.error(`Tool ${i.id} failed for widget ${e}:`, l);
146
+ f = await i.fn(f);
147
+ } catch (c) {
148
+ console.error(`Tool ${i.id} failed for widget ${e}:`, c);
152
149
  }
153
150
  }
154
- const f = p().widgets[e];
155
- if (f && Object.is(f.data, c)) {
156
- b.get(e) === t && b.delete(e);
151
+ const l = b().widgets[e];
152
+ if (l && Object.is(l.data, f) && Object.is(l.sourceData, t)) {
153
+ p.get(e) === s && p.delete(e);
157
154
  return;
158
155
  }
159
156
  T((i) => {
160
- const l = i.widgets[e];
161
- return l ? {
157
+ const c = i.widgets[e];
158
+ return c ? {
162
159
  widgets: {
163
160
  ...i.widgets,
164
161
  [e]: {
165
- ...l,
166
- data: c
162
+ ...c,
163
+ sourceData: t,
164
+ data: f
167
165
  }
168
166
  }
169
167
  } : i;
170
- }), b.get(e) === t && b.delete(e);
168
+ }), p.get(e) === s && p.delete(e);
171
169
  },
172
170
  /**
173
171
  * Executes the config transformation pipeline for a widget.
@@ -181,33 +179,33 @@ const b = /* @__PURE__ */ new Map(), w = /* @__PURE__ */ new Map(), u = y()((T,
181
179
  * **No-op optimization:** Skips the final `set()` when the config object is unchanged
182
180
  * and all its properties already match what's in the store.
183
181
  */
184
- executeConfigPipeline: async (e, o) => {
185
- const s = p().widgets[e];
186
- if (!s) return;
187
- const t = (w.get(e) ?? 0) + 1;
188
- w.set(e, t);
182
+ executeConfigPipeline: async (e, t) => {
183
+ const o = b().widgets[e];
184
+ if (!o) return;
185
+ const s = (w.get(e) ?? 0) + 1;
186
+ w.set(e, s);
189
187
  const n = /* @__PURE__ */ new Set();
190
- for (const r of s.registeredTools ?? [])
188
+ for (const r of o.registeredTools ?? [])
191
189
  r.enabled && r.disables && r.disables.forEach((a) => n.add(a));
192
- const g = [...s.registeredTools ?? []].filter((r) => r.type === "config" && r.enabled && !n.has(r.id)).sort((r, a) => r.order - a.order);
193
- let d = o;
190
+ const g = [...o.registeredTools ?? []].filter((r) => r.type === "config" && r.enabled && !n.has(r.id)).sort((r, a) => r.order - a.order);
191
+ let d = t;
194
192
  for (const r of g) {
195
- if (w.get(e) !== t)
193
+ if (w.get(e) !== s)
196
194
  return;
197
195
  try {
198
- d = await r.fn(d, r.config);
196
+ d = await r.fn(d);
199
197
  } catch (a) {
200
198
  console.error(`Config tool ${r.id} failed for widget ${e}:`, a);
201
199
  }
202
200
  }
203
- const c = o, f = d, i = p().widgets[e], l = i?._lastConfig, W = {};
204
- for (const r of Object.keys(f)) {
205
- const a = !Object.is(f[r], c[r]), C = !l || !(r in l), m = !C && Object.is(i[r], l[r]);
206
- (a || C || m) && (W[r] = f[r]);
201
+ const f = t, l = d, i = b().widgets[e], c = i?._lastConfig, W = {};
202
+ for (const r of Object.keys(l)) {
203
+ const a = !Object.is(l[r], f[r]), S = !c || !(r in c), C = !S && Object.is(i[r], c[r]);
204
+ (a || S || C) && (W[r] = l[r]);
207
205
  }
208
- const S = Object.keys(W).some((r) => !Object.is(i?.[r], W[r])), h = !Object.is(d, l);
209
- if (!S && !h) {
210
- w.get(e) === t && w.delete(e);
206
+ const h = Object.keys(W).some((r) => !Object.is(i?.[r], W[r])), y = !Object.is(d, c);
207
+ if (!h && !y) {
208
+ w.get(e) === s && w.delete(e);
211
209
  return;
212
210
  }
213
211
  T((r) => {
@@ -222,9 +220,9 @@ const b = /* @__PURE__ */ new Map(), w = /* @__PURE__ */ new Map(), u = y()((T,
222
220
  }
223
221
  }
224
222
  } : r;
225
- }), w.get(e) === t && w.delete(e);
223
+ }), w.get(e) === s && w.delete(e);
226
224
  }
227
- })), P = {
225
+ })), x = {
228
226
  get setWidget() {
229
227
  return u.getState().setWidget;
230
228
  },
@@ -243,12 +241,12 @@ const b = /* @__PURE__ */ new Map(), w = /* @__PURE__ */ new Map(), u = y()((T,
243
241
  get unregisterTool() {
244
242
  return u.getState().unregisterTool;
245
243
  },
246
- get updateToolConfig() {
247
- return u.getState().updateToolConfig;
248
- },
249
244
  get setToolEnabled() {
250
245
  return u.getState().setToolEnabled;
251
246
  },
247
+ get triggerToolPipeline() {
248
+ return u.getState().triggerToolPipeline;
249
+ },
252
250
  get executeToolPipeline() {
253
251
  return u.getState().executeToolPipeline;
254
252
  },
@@ -258,6 +256,6 @@ const b = /* @__PURE__ */ new Map(), w = /* @__PURE__ */ new Map(), u = y()((T,
258
256
  };
259
257
  export {
260
258
  u,
261
- P as w
259
+ x as w
262
260
  };
263
- //# sourceMappingURL=widget-store-CIrb9RKP.js.map
261
+ //# sourceMappingURL=widget-store-Bw5zRUGg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-store-Bw5zRUGg.js","sources":["../src/widgets/stores/widget-store.ts"],"sourcesContent":["import { create } from 'zustand'\nimport type {\n WidgetState,\n WidgetStore,\n ToolRegistration,\n WidgetStoreActions,\n} from './types'\n\n// Track active pipeline executions for cancellation\nconst activePipelines = new Map<string, number>()\nconst activeConfigPipelines = new Map<string, number>()\n\n/**\n * Zustand store for managing widget state across the application.\n *\n * Provides centralized state management for all widget UI components, including\n * data/config transformation pipelines via registered tools.\n *\n * **Performance optimizations:**\n * - `registerTool` skips the store update when structural properties (order, enabled,\n * type, disables) haven't changed — only `fn` is updated via direct mutation,\n * avoiding a new `registeredTools` array reference and WidgetLoader pipeline cascades.\n * - `setToolEnabled` skips the store update when the enabled state is already the\n * requested value.\n * - `executeToolPipeline` / `executeConfigPipeline` skip the final `set()` when\n * the transformed data/config is referentially identical to what's already in the store.\n * - Both pipelines support cancellation — newer executions for the same widget\n * automatically cancel in-progress ones.\n *\n * @example Reading widget state (prefer useWidgetSelector for performance)\n * ```tsx\n * import { useWidgetSelector } from '@carto/ps-react-ui/widgets'\n *\n * function MyWidget({ id }: { id: string }) {\n * const { title, data } = useWidgetSelector(id, (w) => ({\n * title: w?.title,\n * data: w?.data,\n * }))\n * return <div>{title}: {JSON.stringify(data)}</div>\n * }\n * ```\n *\n * @example Writing widget state\n * ```tsx\n * import { widgetStoreActions } from '@carto/ps-react-ui/widgets'\n *\n * const { setWidget } = widgetStoreActions\n * setWidget('my-widget', { type: 'formula', isLoading: false, data: { value: 1000 } })\n * ```\n */\nexport const useWidgetStore = create<WidgetStore>()((set, get) => ({\n // State\n widgets: {},\n\n // Actions\n\n /** Merges partial state into the widget entry. Creates the widget if it doesn't exist. */\n setWidget: (id, widget) => {\n set((state) => {\n const prev = state.widgets[id] ?? ({} as WidgetStore['widgets'][string])\n return {\n widgets: {\n ...state.widgets,\n [id]: {\n ...prev,\n ...widget,\n id,\n },\n },\n }\n })\n },\n\n removeWidget: (id) =>\n set((state) => {\n const widgets = { ...state.widgets }\n\n delete widgets[id]\n\n return { widgets }\n }),\n\n clearWidgets: () =>\n set({\n widgets: {},\n }),\n\n getWidget: <T extends WidgetState>(id: string) => {\n return get().widgets[id] as T | undefined\n },\n\n /**\n * Registers a transformation tool for a widget's data or config pipeline.\n *\n * **No-op optimization:** When a tool with the same `id` already exists and its\n * structural properties (`order`, `enabled`, `type`, `disables`) are unchanged,\n * only `fn` is updated via direct mutation — no store update is triggered. This\n * allows action components to include all reactive dependencies in their\n * `useEffect` arrays without causing WidgetLoader pipeline cascades.\n */\n registerTool: (widgetId: string, tool: ToolRegistration) => {\n const current = get().widgets[widgetId]\n const existingTool = current?.registeredTools?.find(\n (t: ToolRegistration) => t.id === tool.id,\n )\n\n // No-op: structural properties unchanged — update fn via direct mutation.\n // Safe because fn is only consumed imperatively during pipeline execution.\n if (\n existingTool?.order === tool.order &&\n existingTool.enabled === tool.enabled &&\n existingTool.type === tool.type &&\n existingTool.disables === tool.disables\n ) {\n existingTool.fn = tool.fn\n return\n }\n\n set((state) => {\n const widget = state.widgets[widgetId] ?? ({} as WidgetState)\n const registeredTools = widget.registeredTools ?? []\n\n // Remove existing tool with same id if present\n const filteredTools = registeredTools.filter(\n (t: ToolRegistration) => t.id !== tool.id,\n )\n\n return {\n widgets: {\n ...state.widgets,\n [widgetId]: {\n ...widget,\n id: widgetId,\n registeredTools: [...filteredTools, tool],\n },\n },\n }\n })\n },\n\n unregisterTool: (widgetId: string, toolId: string) =>\n set((state) => {\n const current = state.widgets[widgetId]\n if (!current) return state\n\n const registeredTools = current.registeredTools ?? []\n const filteredTools = registeredTools.filter(\n (t: ToolRegistration) => t.id !== toolId,\n )\n\n return {\n widgets: {\n ...state.widgets,\n [widgetId]: {\n ...current,\n registeredTools: filteredTools,\n },\n },\n }\n }),\n\n /**\n * Triggers pipeline re-execution by creating a new `registeredTools` reference.\n * This is a lightweight operation that only bumps the array reference without\n * modifying any tool.\n */\n triggerToolPipeline: (widgetId: string) =>\n set((state) => {\n const widget = state.widgets[widgetId]\n if (!widget) return state\n\n return {\n widgets: {\n ...state.widgets,\n [widgetId]: {\n ...widget,\n registeredTools: [...(widget.registeredTools ?? [])],\n },\n },\n }\n }),\n\n /**\n * Updates a tool's enabled state.\n *\n * **No-op optimization:** Skips the store update if the tool already has the\n * requested enabled value.\n */\n setToolEnabled: (widgetId: string, toolId: string, enabled: boolean) => {\n const current = get().widgets[widgetId]\n if (current) {\n const tool = current.registeredTools?.find(\n (t: ToolRegistration) => t.id === toolId,\n )\n if (tool?.enabled === enabled) return\n }\n\n set((state) => {\n const widget = state.widgets[widgetId]\n if (!widget) return state\n\n const registeredTools = widget.registeredTools ?? []\n const updatedTools = registeredTools.map((tool: ToolRegistration) =>\n tool.id === toolId ? { ...tool, enabled } : tool,\n )\n\n return {\n widgets: {\n ...state.widgets,\n [widgetId]: {\n ...widget,\n registeredTools: updatedTools,\n },\n },\n }\n })\n },\n\n /**\n * Executes the data transformation pipeline for a widget.\n *\n * Filters to enabled data-type tools (respecting `disables`), sorts by `order`,\n * and chains their `fn` calls. Supports async tools.\n *\n * **Cancellation:** Newer executions for the same widget automatically cancel\n * in-progress ones via a version counter.\n *\n * **No-op optimization:** Skips the final `set()` if the transformed data is\n * referentially identical (`Object.is`) to what's already in the store.\n */\n executeToolPipeline: async (widgetId: string, sourceData: unknown) => {\n const widget = get().widgets[widgetId]\n if (!widget) return\n\n // Cancel any in-progress pipeline for this widget\n const currentExecution = (activePipelines.get(widgetId) ?? 0) + 1\n activePipelines.set(widgetId, currentExecution)\n\n const widgetWithTools = widget\n\n // Build set of tool IDs that should be disabled\n const disabledToolIds = new Set<string>()\n for (const tool of widgetWithTools.registeredTools ?? []) {\n if (tool.enabled && tool.disables) {\n tool.disables.forEach((id) => disabledToolIds.add(id))\n }\n }\n\n // Sort tools by order and filter enabled data-only tools, excluding disabled tools\n const sortedTools = [...(widgetWithTools.registeredTools ?? [])]\n .filter(\n (tool) =>\n (tool.type ?? 'data') === 'data' &&\n tool.enabled &&\n !disabledToolIds.has(tool.id),\n )\n .sort((a, b) => a.order - b.order)\n\n // Execute pipeline - handle both sync and async tools\n let transformedData = sourceData\n for (const tool of sortedTools) {\n // Check if this execution was cancelled\n if (activePipelines.get(widgetId) !== currentExecution) {\n return\n }\n\n try {\n // Call tool function (may return Promise or direct value)\n transformedData = await tool.fn(transformedData)\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(`Tool ${tool.id} failed for widget ${widgetId}:`, error)\n // Continue with current data to prevent one tool from breaking all\n }\n }\n\n // Skip store update if neither data nor sourceData changed\n const widgetAfter = get().widgets[widgetId]\n if (\n widgetAfter &&\n Object.is(widgetAfter.data, transformedData) &&\n Object.is(widgetAfter.sourceData, sourceData)\n ) {\n if (activePipelines.get(widgetId) === currentExecution) {\n activePipelines.delete(widgetId)\n }\n return\n }\n\n // Single store update with final transformed data\n set((state) => {\n const currentWidget = state.widgets[widgetId]\n if (!currentWidget) return state\n\n return {\n widgets: {\n ...state.widgets,\n [widgetId]: {\n ...currentWidget,\n sourceData,\n data: transformedData,\n },\n },\n }\n })\n\n // Clean up tracking\n if (activePipelines.get(widgetId) === currentExecution) {\n activePipelines.delete(widgetId)\n }\n },\n\n /**\n * Executes the config transformation pipeline for a widget.\n *\n * Filters to enabled config-type tools (respecting `disables`), sorts by `order`,\n * and chains their `fn` calls. The transformed config is spread into the widget state.\n *\n * **Cancellation:** Newer executions for the same widget automatically cancel\n * in-progress ones via a version counter.\n *\n * **No-op optimization:** Skips the final `set()` when the config object is unchanged\n * and all its properties already match what's in the store.\n */\n executeConfigPipeline: async (widgetId: string, baseConfig: object) => {\n const widget = get().widgets[widgetId]\n if (!widget) return\n\n // Cancel any in-progress config pipeline for this widget\n const currentExecution = (activeConfigPipelines.get(widgetId) ?? 0) + 1\n activeConfigPipelines.set(widgetId, currentExecution)\n\n // Build set of tool IDs that should be disabled (cross-type disabling works)\n const disabledToolIds = new Set<string>()\n for (const tool of widget.registeredTools ?? []) {\n if (tool.enabled && tool.disables) {\n tool.disables.forEach((id) => disabledToolIds.add(id))\n }\n }\n\n // Filter to config tools only, sort by order\n const sortedTools = [...(widget.registeredTools ?? [])]\n .filter(\n (tool) =>\n tool.type === 'config' &&\n tool.enabled &&\n !disabledToolIds.has(tool.id),\n )\n .sort((a, b) => a.order - b.order)\n\n // Chain config tools\n let transformedConfig: unknown = baseConfig\n for (const tool of sortedTools) {\n if (activeConfigPipelines.get(widgetId) !== currentExecution) {\n return\n }\n\n try {\n transformedConfig = await tool.fn(transformedConfig)\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\n `Config tool ${tool.id} failed for widget ${widgetId}:`,\n error,\n )\n }\n }\n\n // Build a patch that only includes properties the pipeline should set.\n // A property is applied when:\n // 1. A config tool explicitly changed it (transformedConfig[k] !== baseConfig[k])\n // 2. First pipeline run for this widget (no _lastConfig yet)\n // 3. The widget value still matches what the pipeline last set — meaning the\n // user hasn't modified it via setWidget, so it's safe to overwrite.\n // A property is SKIPPED when the widget value differs from _lastConfig,\n // meaning the user (or a hook) changed it since the last pipeline run.\n const base = baseConfig as Record<string, unknown>\n const result = transformedConfig as Record<string, unknown>\n const widgetNow = get().widgets[widgetId] as unknown as Record<\n string,\n unknown\n >\n const lastConfig = widgetNow?._lastConfig as\n | Record<string, unknown>\n | undefined\n\n const patch: Record<string, unknown> = {}\n for (const key of Object.keys(result)) {\n const toolChanged = !Object.is(result[key], base[key])\n const isFirstRun = !lastConfig || !(key in lastConfig)\n const userUnmodified =\n !isFirstRun && Object.is(widgetNow[key], lastConfig[key])\n\n if (toolChanged || isFirstRun || userUnmodified) {\n patch[key] = result[key]\n }\n }\n\n // Skip store update if every patch value already matches the widget\n const hasChanges = Object.keys(patch).some(\n (k) => !Object.is(widgetNow?.[k], patch[k]),\n )\n const configRefChanged = !Object.is(transformedConfig, lastConfig)\n\n if (!hasChanges && !configRefChanged) {\n if (activeConfigPipelines.get(widgetId) === currentExecution) {\n activeConfigPipelines.delete(widgetId)\n }\n return\n }\n\n // Apply the patch and store the pipeline output for next run's comparison\n set((state) => {\n const currentWidget = state.widgets[widgetId]\n if (!currentWidget) return state\n\n return {\n widgets: {\n ...state.widgets,\n [widgetId]: {\n ...currentWidget,\n ...patch,\n _lastConfig: transformedConfig,\n },\n },\n }\n })\n\n if (activeConfigPipelines.get(widgetId) === currentExecution) {\n activeConfigPipelines.delete(widgetId)\n }\n },\n}))\n\n/**\n * Stable references to store actions, accessible without creating a subscription.\n *\n * Use this instead of `useWidgetStore((state) => state.setWidget)` to avoid\n * unnecessary subscriber evaluations. Actions are stable functions that never\n * change, so subscribing to them wastes cycles on every store update.\n *\n * @example\n * ```tsx\n * import { widgetStoreActions } from '@carto/ps-react-ui/widgets'\n *\n * const { setWidget, registerTool } = widgetStoreActions\n *\n * useEffect(() => {\n * registerTool(id, { id: 'my-tool', order: 10, enabled: true, fn: (d) => d })\n * return () => widgetStoreActions.unregisterTool(id, 'my-tool')\n * }, [id])\n * ```\n */\nexport const widgetStoreActions: WidgetStoreActions = {\n get setWidget() {\n return useWidgetStore.getState().setWidget\n },\n get removeWidget() {\n return useWidgetStore.getState().removeWidget\n },\n get clearWidgets() {\n return useWidgetStore.getState().clearWidgets\n },\n get getWidget() {\n return useWidgetStore.getState().getWidget\n },\n get registerTool() {\n return useWidgetStore.getState().registerTool\n },\n get unregisterTool() {\n return useWidgetStore.getState().unregisterTool\n },\n get setToolEnabled() {\n return useWidgetStore.getState().setToolEnabled\n },\n get triggerToolPipeline() {\n return useWidgetStore.getState().triggerToolPipeline\n },\n get executeToolPipeline() {\n return useWidgetStore.getState().executeToolPipeline\n },\n get executeConfigPipeline() {\n return useWidgetStore.getState().executeConfigPipeline\n },\n} as WidgetStoreActions\n"],"names":["activePipelines","Map","activeConfigPipelines","useWidgetStore","create","set","get","widgets","setWidget","id","widget","state","prev","removeWidget","clearWidgets","getWidget","registerTool","widgetId","tool","existingTool","registeredTools","find","t","order","enabled","type","disables","fn","filteredTools","filter","unregisterTool","toolId","current","triggerToolPipeline","setToolEnabled","updatedTools","map","executeToolPipeline","sourceData","currentExecution","widgetWithTools","disabledToolIds","Set","forEach","add","sortedTools","has","sort","a","b","transformedData","error","console","widgetAfter","Object","is","data","delete","currentWidget","executeConfigPipeline","baseConfig","transformedConfig","base","result","widgetNow","lastConfig","_lastConfig","patch","key","keys","toolChanged","isFirstRun","userUnmodified","hasChanges","some","k","configRefChanged","widgetStoreActions","getState"],"mappings":"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"}