@trops/dash-core 0.1.439 → 0.1.440

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/index.js CHANGED
@@ -8382,6 +8382,60 @@ var DashboardWizardModal = function DashboardWizardModal(_ref) {
8382
8382
  });
8383
8383
  };
8384
8384
 
8385
+ /**
8386
+ * useWidgetRegistryVersion
8387
+ *
8388
+ * Returns a counter that increments every time the
8389
+ * `dash:widgets-updated` window event fires. Components that derive
8390
+ * lists from `ComponentManager.componentMap()` should pass the
8391
+ * returned value into their `useMemo` / `useEffect` deps so they
8392
+ * re-run when widgets are installed, updated, or uninstalled.
8393
+ *
8394
+ * Background: `componentMap()` returns a plain JS object held at
8395
+ * module scope. React doesn't observe it. Without a counter that
8396
+ * consumers can include in deps, every list (widget sidebar,
8397
+ * Settings → Widgets, Add Widget dropdown, Dependencies tab, etc.)
8398
+ * stays frozen at whatever it derived on first render even after
8399
+ * a new package installs and re-registers configs.
8400
+ *
8401
+ * The producer side is the single dispatch in dash-electron's
8402
+ * `Dash.js#handleWidgetInstalled` (and the `handleWidgetsLoaded`
8403
+ * + `handleWidgetUninstalled` siblings). That fires
8404
+ * `dash:widgets-updated` once per registry mutation; this hook is
8405
+ * the consumer-side contract.
8406
+ *
8407
+ * Usage:
8408
+ *
8409
+ * const widgetVersion = useWidgetRegistryVersion();
8410
+ * const allWidgets = useMemo(() => {
8411
+ * const cm = ComponentManager.componentMap();
8412
+ * return Object.keys(cm).filter((k) => cm[k].type === "widget");
8413
+ * }, [widgetVersion]);
8414
+ *
8415
+ * The hook subscribes once on mount and cleans up on unmount, so
8416
+ * adding it to a component is free.
8417
+ *
8418
+ * @returns {number} monotonically increasing counter, starts at 0
8419
+ */
8420
+ function useWidgetRegistryVersion() {
8421
+ var _useState = React.useState(0),
8422
+ _useState2 = _slicedToArray(_useState, 2),
8423
+ version = _useState2[0],
8424
+ setVersion = _useState2[1];
8425
+ React.useEffect(function () {
8426
+ var bump = function bump() {
8427
+ return setVersion(function (v) {
8428
+ return v + 1;
8429
+ });
8430
+ };
8431
+ window.addEventListener("dash:widgets-updated", bump);
8432
+ return function () {
8433
+ return window.removeEventListener("dash:widgets-updated", bump);
8434
+ };
8435
+ }, []);
8436
+ return version;
8437
+ }
8438
+
8385
8439
  var LayoutBuilderAddItemModal = function LayoutBuilderAddItemModal(_ref) {
8386
8440
  var workspace = _ref.workspace,
8387
8441
  open = _ref.open,
@@ -8390,6 +8444,11 @@ var LayoutBuilderAddItemModal = function LayoutBuilderAddItemModal(_ref) {
8390
8444
  item = _ref$item === void 0 ? null : _ref$item,
8391
8445
  _ref$onSaveItem = _ref.onSaveItem,
8392
8446
  onSaveItem = _ref$onSaveItem === void 0 ? null : _ref$onSaveItem;
8447
+ // Re-render when the widget registry mutates (install / update /
8448
+ // uninstall) so the available-widgets list reflects the live state
8449
+ // without requiring the modal to be closed and reopened.
8450
+ // eslint-disable-next-line no-unused-vars
8451
+ useWidgetRegistryVersion();
8393
8452
  var _useContext = React.useContext(DashReact.ThemeContext),
8394
8453
  currentTheme = _useContext.currentTheme;
8395
8454
  var _useState = React.useState(""),
@@ -18347,18 +18406,13 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
18347
18406
  return Object.values(groups);
18348
18407
  };
18349
18408
 
18350
- // Refresh widget list when installed widgets change
18409
+ // Refresh widget list when installed widgets change. Subscribing
18410
+ // via the shared registry-version hook keeps this in sync with
18411
+ // every other widget-list surface (sidebar, settings, etc.).
18412
+ var widgetRegistryVersion = useWidgetRegistryVersion();
18351
18413
  React.useEffect(function () {
18352
- var handleWidgetsUpdated = function handleWidgetsUpdated() {
18353
- if (isOpen && selectedSource === "Installed") {
18354
- loadWidgets();
18355
- }
18356
- };
18357
- window.addEventListener("dash:widgets-updated", handleWidgetsUpdated);
18358
- return function () {
18359
- return window.removeEventListener("dash:widgets-updated", handleWidgetsUpdated);
18360
- };
18361
- }, [isOpen, selectedSource, loadWidgets]);
18414
+ if (isOpen && selectedSource === "Installed") loadWidgets();
18415
+ }, [widgetRegistryVersion, isOpen, selectedSource, loadWidgets]);
18362
18416
 
18363
18417
  // Load widgets when source changes
18364
18418
  React.useEffect(function () {
@@ -49367,16 +49421,15 @@ var DiscoverWidgetsDetail = function DiscoverWidgetsDetail(_ref) {
49367
49421
  }
49368
49422
  }, _callee2, null, [[0, 2]]);
49369
49423
  })), []);
49424
+
49425
+ // Re-load whenever the registry mutates (install / update /
49426
+ // uninstall). The shared hook means this surface stays in sync
49427
+ // with the widget sidebar and Settings → Widgets without each
49428
+ // re-implementing the same listener.
49429
+ var widgetRegistryVersion = useWidgetRegistryVersion();
49370
49430
  React.useEffect(function () {
49371
49431
  loadInstalledPackages();
49372
- var handleWidgetsUpdated = function handleWidgetsUpdated() {
49373
- return loadInstalledPackages();
49374
- };
49375
- window.addEventListener("dash:widgets-updated", handleWidgetsUpdated);
49376
- return function () {
49377
- return window.removeEventListener("dash:widgets-updated", handleWidgetsUpdated);
49378
- };
49379
- }, [loadInstalledPackages]);
49432
+ }, [loadInstalledPackages, widgetRegistryVersion]);
49380
49433
 
49381
49434
  // Watch for install completion — same pattern as WidgetSidebar
49382
49435
  React.useEffect(function () {
@@ -50066,16 +50119,10 @@ var useInstalledWidgets = function useInstalledWidgets() {
50066
50119
  return _ref2.apply(this, arguments);
50067
50120
  };
50068
50121
  }(), [refresh, widgets]);
50122
+ var widgetRegistryVersion = useWidgetRegistryVersion();
50069
50123
  React.useEffect(function () {
50070
50124
  refresh();
50071
- var handleWidgetsUpdated = function handleWidgetsUpdated() {
50072
- return refresh();
50073
- };
50074
- window.addEventListener("dash:widgets-updated", handleWidgetsUpdated);
50075
- return function () {
50076
- return window.removeEventListener("dash:widgets-updated", handleWidgetsUpdated);
50077
- };
50078
- }, [refresh]);
50125
+ }, [refresh, widgetRegistryVersion]);
50079
50126
  return {
50080
50127
  widgets: widgets,
50081
50128
  isLoading: isLoading,
@@ -54384,22 +54431,9 @@ var WidgetSidebar = function WidgetSidebar(_ref4) {
54384
54431
  filterHasHandlers = _useState22[0],
54385
54432
  setFilterHasHandlers = _useState22[1];
54386
54433
 
54387
- // Counter to trigger re-computation when installed widgets change
54388
- var _useState23 = React.useState(0),
54389
- _useState24 = _slicedToArray(_useState23, 2),
54390
- widgetVersion = _useState24[0],
54391
- setWidgetVersion = _useState24[1];
54392
- React.useEffect(function () {
54393
- var handleWidgetsUpdated = function handleWidgetsUpdated() {
54394
- return setWidgetVersion(function (v) {
54395
- return v + 1;
54396
- });
54397
- };
54398
- window.addEventListener("dash:widgets-updated", handleWidgetsUpdated);
54399
- return function () {
54400
- return window.removeEventListener("dash:widgets-updated", handleWidgetsUpdated);
54401
- };
54402
- }, []);
54434
+ // Counter from the shared `dash:widgets-updated` event so the
54435
+ // sidebar re-derives whenever widgets install / update / uninstall.
54436
+ var widgetVersion = useWidgetRegistryVersion();
54403
54437
 
54404
54438
  // Flat list of all widgets
54405
54439
  var allWidgets = React.useMemo(function () {
@@ -54416,10 +54450,10 @@ var WidgetSidebar = function WidgetSidebar(_ref4) {
54416
54450
 
54417
54451
  // Set of installed package identifiers for "Installed" badge in Discover tab.
54418
54452
  // Stores folder names, package names, and "author/name" keys for matching.
54419
- var _useState25 = React.useState(new Set()),
54420
- _useState26 = _slicedToArray(_useState25, 2),
54421
- installedPackageNames = _useState26[0],
54422
- setInstalledPackageNames = _useState26[1];
54453
+ var _useState23 = React.useState(new Set()),
54454
+ _useState24 = _slicedToArray(_useState23, 2),
54455
+ installedPackageNames = _useState24[0],
54456
+ setInstalledPackageNames = _useState24[1];
54423
54457
  React.useEffect(function () {
54424
54458
  var cancelled = false;
54425
54459
  var loadInstalled = /*#__PURE__*/function () {
@@ -54815,18 +54849,10 @@ var useMissingWidgets = function useMissingWidgets(workspace) {
54815
54849
  })));
54816
54850
  setMissingComponents(missing);
54817
54851
  }, [workspace === null || workspace === void 0 ? void 0 : workspace.layout]);
54852
+ var widgetRegistryVersion = useWidgetRegistryVersion();
54818
54853
  React.useEffect(function () {
54819
54854
  check();
54820
- }, [check]);
54821
- React.useEffect(function () {
54822
- var handler = function handler() {
54823
- return check();
54824
- };
54825
- window.addEventListener("dash:widgets-updated", handler);
54826
- return function () {
54827
- return window.removeEventListener("dash:widgets-updated", handler);
54828
- };
54829
- }, [check]);
54855
+ }, [check, widgetRegistryVersion]);
54830
54856
  return {
54831
54857
  missingComponents: missingComponents,
54832
54858
  hasMissing: missingComponents.length > 0
@@ -62797,6 +62823,7 @@ exports.useScheduler = useScheduler;
62797
62823
  exports.useWebSocketProvider = useWebSocketProvider;
62798
62824
  exports.useWidgetEvents = useWidgetEvents;
62799
62825
  exports.useWidgetProviders = useWidgetProviders;
62826
+ exports.useWidgetRegistryVersion = useWidgetRegistryVersion;
62800
62827
  exports.useWidgetSchedulerStatus = useWidgetSchedulerStatus;
62801
62828
  exports.useWizardState = useWizardState;
62802
62829
  exports.validateCellMerge = validateCellMerge;