@trops/dash-core 0.1.431 → 0.1.432

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
@@ -27686,6 +27686,16 @@ var LayoutModel = function LayoutModel(layoutItem, workspaceLayout, dashboardId)
27686
27686
  if (Array.isArray(widgetConfig.eventHandlers)) {
27687
27687
  layout.eventHandlers = widgetConfig.eventHandlers;
27688
27688
  }
27689
+ // Migrate legacy bare `component` references to the canonical
27690
+ // scoped form (`scope.package.Component`). ComponentManager.config
27691
+ // returns the resolved scoped key on `widgetConfig.component`, so
27692
+ // we just lift it. Idempotent: items already scoped pass through
27693
+ // unchanged because resolveComponentKey returns the input verbatim
27694
+ // when it's already in the map. Persisted on next save — no
27695
+ // separate migration step needed.
27696
+ if (typeof widgetConfig.component === "string" && widgetConfig.component && widgetConfig.component !== layout.component) {
27697
+ layout.component = widgetConfig.component;
27698
+ }
27689
27699
  }
27690
27700
 
27691
27701
  // Merge user-entered config values (from EnhancedWidgetDropdown) into userPrefs
@@ -31371,7 +31381,117 @@ var ContextModel = /*#__PURE__*/function () {
31371
31381
  }]);
31372
31382
  }();
31373
31383
 
31384
+ /**
31385
+ * scopedComponentId.js
31386
+ *
31387
+ * Single source of truth for the canonical scoped component id used by
31388
+ * ComponentManager registration, layout items, and publish-time scope
31389
+ * remap. Format: `scope.packageName.ComponentName`.
31390
+ *
31391
+ * Why a 3-part dotted form (and not `@scope/pkg.Component`)?
31392
+ * - Matches existing `config.id` shape that `.dash.js` files already
31393
+ * set when authored explicitly (see ComponentManager.registerWidget:
31394
+ * `const registrationKey = config.id || widgetKey;`).
31395
+ * - Trivial to parse (`split(".")` — three parts, ordered).
31396
+ * - Avoids slashes inside object keys, which some downstream serializers
31397
+ * (older dash-registry indexers) historically choked on.
31398
+ *
31399
+ * The upstream package id may arrive in either of two shapes:
31400
+ * - "@scope/pkg" (npm-style)
31401
+ * - "scope/pkg" (bare scope)
31402
+ * Both produce the same scoped id.
31403
+ */
31404
+
31405
+ /**
31406
+ * Build the canonical scoped component id from a package name and a
31407
+ * bare component name.
31408
+ *
31409
+ * @param {string} packageName e.g. "@ai-built/pipeline" or "ai-built/pipeline"
31410
+ * @param {string} componentName e.g. "ProspectListColumn"
31411
+ * @returns {string} e.g. "ai-built.pipeline.ProspectListColumn"
31412
+ */
31413
+ function makeScopedComponentId(packageName, componentName) {
31414
+ if (!componentName) return "";
31415
+ if (!packageName) return componentName;
31416
+ var cleaned = String(packageName).replace(/^@/, "").replace(/\//g, ".");
31417
+ return "".concat(cleaned, ".").concat(componentName);
31418
+ }
31419
+
31420
+ /**
31421
+ * Parse a scoped component id into its three parts. Returns null when
31422
+ * the input isn't a 3-part dotted id (e.g. legacy bare names).
31423
+ *
31424
+ * @param {string} scopedId
31425
+ * @returns {{scope: string, packageName: string, componentName: string} | null}
31426
+ */
31427
+ function parseScopedComponentId(scopedId) {
31428
+ if (typeof scopedId !== "string") return null;
31429
+ var parts = scopedId.split(".");
31430
+ if (parts.length !== 3) return null;
31431
+ return {
31432
+ scope: parts[0],
31433
+ packageName: parts[1],
31434
+ componentName: parts[2]
31435
+ };
31436
+ }
31437
+
31438
+ /**
31439
+ * Pull the bare component name from a scoped or unscoped id.
31440
+ *
31441
+ * @param {string} idOrName
31442
+ * @returns {string}
31443
+ */
31444
+ function bareComponentName(idOrName) {
31445
+ if (typeof idOrName !== "string") return "";
31446
+ var parts = idOrName.split(".");
31447
+ return parts[parts.length - 1] || "";
31448
+ }
31449
+
31374
31450
  var _componentMap = {};
31451
+
31452
+ /**
31453
+ * Resolve the registry key for a component lookup. Returns null if no
31454
+ * match exists.
31455
+ *
31456
+ * Lookup order (the LAYOUT ITEM is the source of truth):
31457
+ * 1. EXACT match on `component` — covers the new scoped form
31458
+ * (`scope.package.X`) and any legacy `.dash.js` that already set
31459
+ * `config.id` to a scoped value.
31460
+ * 2. If `component` is bare (no dots) AND we have a packageId hint
31461
+ * on the layout item, build the scoped id and try that.
31462
+ * 3. Bare-name fallback: scan the map for any key ending in
31463
+ * `.${component}`. If exactly one matches, use it. If multiple
31464
+ * match (the collision case), prefer the one matching the layout
31465
+ * item's `packageId` / `_sourcePackage`; otherwise fall through
31466
+ * to the first match (deterministic, but also logs a warning so
31467
+ * callers can spot the ambiguity).
31468
+ *
31469
+ * Step (3) is the back-compat path for layouts authored before scoped
31470
+ * registration landed. New layouts ALWAYS resolve via step (1) — the
31471
+ * `component` field is already scoped.
31472
+ */
31473
+ function resolveComponentKey(componentMap, component, data) {
31474
+ if (!component) return null;
31475
+ if (component in componentMap) return component;
31476
+ if (typeof component !== "string") return null;
31477
+ if (component.includes(".")) return null;
31478
+ var packageId = (data === null || data === void 0 ? void 0 : data.packageId) || (data === null || data === void 0 ? void 0 : data._sourcePackage) || (data === null || data === void 0 ? void 0 : data.packageName) || null;
31479
+ if (packageId) {
31480
+ var scoped = makeScopedComponentId(packageId, component);
31481
+ if (scoped in componentMap) return scoped;
31482
+ }
31483
+ var suffix = ".".concat(component);
31484
+ var matches = Object.keys(componentMap).filter(function (k) {
31485
+ return k.endsWith(suffix);
31486
+ });
31487
+ if (matches.length === 0) return null;
31488
+ if (matches.length === 1) return matches[0];
31489
+ if (packageId) {
31490
+ var target = makeScopedComponentId(packageId, component);
31491
+ if (matches.includes(target)) return target;
31492
+ }
31493
+ return matches[0];
31494
+ }
31375
31495
  var _containerComponent = null;
31376
31496
  var _gridContainerComponent = null;
31377
31497
  var ComponentManager = {
@@ -31475,15 +31595,18 @@ var ComponentManager = {
31475
31595
  * @returns {Widget} the Widget in the component map
31476
31596
  */
31477
31597
  getComponent: function getComponent(component) {
31598
+ var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
31478
31599
  try {
31479
31600
  // console.log("get component");
31480
31601
  if (component && this.componentMap()) {
31481
31602
  if (ComponentManager.isLayoutContainer(component) === false) {
31482
31603
  var m = this.componentMap();
31483
- // Try exact match first (works for both scoped ids and legacy names)
31484
- var cmp = component in m ? m[component] : null;
31485
- if (cmp !== null) {
31486
- cmp["componentName"] = component;
31604
+ // Resolve through the scoped/bare lookup pipeline so layouts
31605
+ // authored under either format land at the same registry key.
31606
+ var resolvedKey = resolveComponentKey(m, component, data);
31607
+ var cmp = resolvedKey ? m[resolvedKey] : null;
31608
+ if (cmp !== null && cmp !== undefined) {
31609
+ cmp["componentName"] = resolvedKey;
31487
31610
  return cmp;
31488
31611
  }
31489
31612
  } else {
@@ -31661,17 +31784,20 @@ var ComponentManager = {
31661
31784
 
31662
31785
  // get the component configuration from the map
31663
31786
  var components = this.map();
31664
- if (component in components) {
31787
+ var resolvedKey = resolveComponentKey(components, component, data);
31788
+ if (resolvedKey && resolvedKey in components) {
31665
31789
  // let c = deepCopy(components['component']);
31666
31790
 
31667
31791
  // we have to make sure that we remove the component if this is a context
31668
31792
 
31669
- var tempComponent = components[component];
31793
+ var tempComponent = components[resolvedKey];
31670
31794
  delete tempComponent["component"];
31671
31795
  var c = JSON.parse(JSON.stringify(tempComponent));
31672
31796
 
31673
- // tack on the component name
31674
- c["component"] = component;
31797
+ // Carry the canonical scoped id forward so callers (LayoutModel,
31798
+ // ComponentManager.getComponent) can rewrite layout items'
31799
+ // `component` to the scoped form on first load.
31800
+ c["component"] = resolvedKey;
31675
31801
 
31676
31802
  // if no userConfig key. let's add it for the next step
31677
31803
  if ("userConfig" in c === false) {
@@ -62322,6 +62448,7 @@ exports.WorkspaceModel = WorkspaceModel;
62322
62448
  exports.WorkspaceScopeContext = WorkspaceScopeContext;
62323
62449
  exports.addChildToLayoutItem = addChildToLayoutItem;
62324
62450
  exports.addItemToItemLayout = addItemToItemLayout;
62451
+ exports.bareComponentName = bareComponentName;
62325
62452
  exports.buildMcpConfigFromOverrides = buildMcpConfigFromOverrides;
62326
62453
  exports.canHaveChildren = canHaveChildren;
62327
62454
  exports.changeDirectionForLayoutItem = changeDirectionForLayoutItem;
@@ -62367,10 +62494,12 @@ exports.isWidgetResolvable = isWidgetResolvable;
62367
62494
  exports.isWorkspace = isWorkspace;
62368
62495
  exports.layoutItemHasWorkspaceAsChild = layoutItemHasWorkspaceAsChild;
62369
62496
  exports.loadWidgetBundle = loadWidgetBundle;
62497
+ exports.makeScopedComponentId = makeScopedComponentId;
62370
62498
  exports.mcpJsonToFormState = mcpJsonToFormState;
62371
62499
  exports.moveWidgetAcrossContainers = moveWidgetAcrossContainers;
62372
62500
  exports.numChildrenForLayout = numChildrenForLayout;
62373
62501
  exports.parse = parse;
62502
+ exports.parseScopedComponentId = parseScopedComponentId;
62374
62503
  exports.removeItemFromLayout = removeItemFromLayout;
62375
62504
  exports.renderComponent = renderComponent;
62376
62505
  exports.renderGridLayout = renderGridLayout;