@trops/dash-core 0.1.232 → 0.1.234

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.
@@ -29124,16 +29124,27 @@ function buildWidgetDependencies$1(componentNames, widgetRegistry = null) {
29124
29124
  if (seen.has(name)) continue;
29125
29125
  seen.add(name);
29126
29126
 
29127
+ let scope = "";
29127
29128
  let packageName = "";
29129
+ let widgetName = name;
29128
29130
  let version = "*";
29129
29131
  let author = "";
29130
29132
 
29133
+ // Check if name is already a scoped ID (scope.packageName.widgetName)
29134
+ const parts = name.split(".");
29135
+ if (parts.length === 3) {
29136
+ scope = parts[0];
29137
+ packageName = parts[1];
29138
+ widgetName = parts[2];
29139
+ }
29140
+
29131
29141
  // Try to resolve from widget registry
29132
29142
  if (widgetRegistry) {
29133
29143
  const installedWidgets = widgetRegistry.getWidgets();
29134
29144
  for (const w of installedWidgets) {
29135
29145
  if (w.componentNames && w.componentNames.includes(name)) {
29136
- packageName = w.name || "";
29146
+ if (!scope && w.scope) scope = w.scope;
29147
+ if (!packageName || packageName === name) packageName = w.name || "";
29137
29148
  version = w.version || "*";
29138
29149
  author =
29139
29150
  typeof w.author === "string" ? w.author : w.author?.name || "";
@@ -29142,9 +29153,19 @@ function buildWidgetDependencies$1(componentNames, widgetRegistry = null) {
29142
29153
  }
29143
29154
  }
29144
29155
 
29156
+ const id =
29157
+ scope && packageName && widgetName
29158
+ ? `${scope}.${packageName}.${widgetName}`
29159
+ : packageName
29160
+ ? `${packageName}.${widgetName}`
29161
+ : widgetName;
29162
+
29145
29163
  widgets.push({
29146
- id: packageName ? `${packageName}.${name}` : name,
29147
- package: packageName || name,
29164
+ id,
29165
+ scope: scope || "",
29166
+ packageName: packageName || widgetName,
29167
+ widgetName,
29168
+ package: packageName || widgetName,
29148
29169
  version,
29149
29170
  required: true,
29150
29171
  author: author || "",
@@ -29268,11 +29289,18 @@ function checkDashboardCompatibility(
29268
29289
  installedWidgets = [],
29269
29290
  registryPackages = [],
29270
29291
  ) {
29292
+ // Build lookup maps using composite keys (scope.packageName.componentName)
29293
+ const installedByKey = new Map();
29271
29294
  const installedByName = new Map();
29272
29295
  for (const w of installedWidgets) {
29273
29296
  if (w.name) {
29274
29297
  installedByName.set(w.name, w);
29275
29298
  }
29299
+ if (w.scope && w.name && w.componentNames) {
29300
+ for (const cn of w.componentNames) {
29301
+ installedByKey.set(`${w.scope}.${w.name}.${cn}`, w);
29302
+ }
29303
+ }
29276
29304
  }
29277
29305
 
29278
29306
  const registryByName = new Map();
@@ -29289,19 +29317,31 @@ function checkDashboardCompatibility(
29289
29317
  let hasUnavailableRequired = false;
29290
29318
 
29291
29319
  for (const dep of dashboardWidgets) {
29292
- const packageName = dep.package;
29320
+ // Build composite key for scoped matching
29321
+ const key =
29322
+ dep.scope && dep.packageName && dep.widgetName
29323
+ ? `${dep.scope}.${dep.packageName}.${dep.widgetName}`
29324
+ : null;
29325
+ const packageName = dep.package || dep.packageName || "";
29293
29326
  const required = dep.required !== false;
29294
- const installed = installedByName.get(packageName);
29327
+
29328
+ // Try composite key first, then fall back to package name
29329
+ const installed = key
29330
+ ? installedByKey.get(key) || installedByName.get(packageName)
29331
+ : installedByName.get(packageName);
29332
+
29333
+ // Use the dep's id or key for the status map
29334
+ const statusKey = dep.id || key || packageName;
29295
29335
 
29296
29336
  if (installed) {
29297
29337
  installedCount++;
29298
- widgets[packageName] = "installed";
29338
+ widgets[statusKey] = "installed";
29299
29339
  } else if (registryByName.has(packageName)) {
29300
29340
  toInstallCount++;
29301
- widgets[packageName] = "available";
29341
+ widgets[statusKey] = "available";
29302
29342
  } else {
29303
29343
  unavailableCount++;
29304
- widgets[packageName] = "unavailable";
29344
+ widgets[statusKey] = "unavailable";
29305
29345
  if (required) {
29306
29346
  hasUnavailableRequired = true;
29307
29347
  }
@@ -29360,6 +29400,9 @@ function generateRegistryManifest(dashboardConfig, options = {}) {
29360
29400
  publishedAt: new Date().toISOString(),
29361
29401
  widgets: (dashboardConfig.widgets || []).map((w) => ({
29362
29402
  id: w.id,
29403
+ scope: w.scope || "",
29404
+ packageName: w.packageName || w.package || "",
29405
+ widgetName: w.widgetName || (w.id ? w.id.split(".").pop() : w.package),
29363
29406
  name: w.id ? w.id.split(".").pop() : w.package,
29364
29407
  package: w.package,
29365
29408
  version: w.version || "*",
@@ -31364,6 +31407,11 @@ var schedulerController_1 = schedulerController$2;
31364
31407
  registeredAt: new Date().toISOString(),
31365
31408
  };
31366
31409
 
31410
+ // Persist scope from manifest/config if available
31411
+ if (config.scope) {
31412
+ widgetEntry.scope = config.scope;
31413
+ }
31414
+
31367
31415
  this.widgets.set(widgetName, widgetEntry);
31368
31416
  this.saveRegistry();
31369
31417
  console.log(`[WidgetRegistry] Registered widget: ${widgetName}`);
@@ -31424,6 +31472,8 @@ var schedulerController_1 = schedulerController$2;
31424
31472
  // has full display data without needing ComponentManager.
31425
31473
  if (result?.config && existingEntry) {
31426
31474
  const cfg = result.config;
31475
+ if (cfg.scope && !existingEntry.scope)
31476
+ existingEntry.scope = cfg.scope;
31427
31477
  if (cfg.icon && !existingEntry.icon) existingEntry.icon = cfg.icon;
31428
31478
  if (cfg.providers?.length && !existingEntry.providers?.length)
31429
31479
  existingEntry.providers = cfg.providers;
@@ -32248,7 +32298,7 @@ async function installThemeFromRegistry$1(win, appId, packageName) {
32248
32298
 
32249
32299
  const contentType = response.headers.get("content-type") || "";
32250
32300
  const arrayBuffer = await response.arrayBuffer();
32251
- const zipBuffer = Buffer.from(arrayBuffer);
32301
+ let zipBuffer = Buffer.from(arrayBuffer);
32252
32302
  console.log(`${TAG} [3/5 Download] size=${zipBuffer.length} bytes`);
32253
32303
 
32254
32304
  if (zipBuffer.length === 0) {
@@ -32272,8 +32322,10 @@ async function installThemeFromRegistry$1(win, appId, packageName) {
32272
32322
  let themeData;
32273
32323
 
32274
32324
  if (contentType.includes("application/json")) {
32275
- // Registry served theme data as JSON directly parse and use it
32276
- console.log(`${TAG} [4/5 Extract] JSON response — parsing directly`);
32325
+ // Registry returns JSON with a downloadUrl pointing to the actual ZIP
32326
+ console.log(
32327
+ `${TAG} [3/5 Download] JSON response — checking for downloadUrl`,
32328
+ );
32277
32329
  let jsonData;
32278
32330
  try {
32279
32331
  jsonData = JSON.parse(zipBuffer.toString("utf-8"));
@@ -32285,16 +32337,52 @@ async function installThemeFromRegistry$1(win, appId, packageName) {
32285
32337
  }
32286
32338
  if (jsonData.error) {
32287
32339
  console.log(
32288
- `${TAG} [4/5 Extract] FAIL — JSON error: ${jsonData.error}`,
32340
+ `${TAG} [3/5 Download] FAIL — JSON error: ${jsonData.error}`,
32289
32341
  );
32290
32342
  return {
32291
32343
  success: false,
32292
32344
  error: `Download failed: ${jsonData.error}`,
32293
32345
  };
32294
32346
  }
32295
- // The response may be raw theme data, or wrapped in a data/theme key
32296
- themeData = jsonData.data || jsonData.theme || jsonData;
32297
- } else {
32347
+ if (jsonData.downloadUrl) {
32348
+ // Follow the pre-signed URL to get the actual ZIP
32349
+ console.log(`${TAG} [3/5 Download] following downloadUrl to fetch ZIP`);
32350
+ let zipResponse;
32351
+ try {
32352
+ zipResponse = await fetch(jsonData.downloadUrl);
32353
+ } catch (fetchErr) {
32354
+ return {
32355
+ success: false,
32356
+ error: `Download failed: could not fetch ZIP from storage (${fetchErr.message}).`,
32357
+ };
32358
+ }
32359
+ if (!zipResponse.ok) {
32360
+ return {
32361
+ success: false,
32362
+ error: `Download failed: storage returned ${zipResponse.status} ${zipResponse.statusText}`,
32363
+ };
32364
+ }
32365
+ const zipArrayBuffer = await zipResponse.arrayBuffer();
32366
+ zipBuffer = Buffer.from(zipArrayBuffer);
32367
+ console.log(
32368
+ `${TAG} [3/5 Download] ZIP fetched, size=${zipBuffer.length} bytes`,
32369
+ );
32370
+ if (zipBuffer.length === 0) {
32371
+ return {
32372
+ success: false,
32373
+ error: "Download failed: storage returned an empty ZIP file.",
32374
+ };
32375
+ }
32376
+ } else {
32377
+ // No downloadUrl — treat as direct theme data
32378
+ console.log(
32379
+ `${TAG} [4/5 Extract] JSON response with no downloadUrl — using as theme data`,
32380
+ );
32381
+ themeData = jsonData.data || jsonData.theme || jsonData;
32382
+ }
32383
+ }
32384
+
32385
+ if (!themeData) {
32298
32386
  // ZIP response — extract .theme.json from archive
32299
32387
  let zip;
32300
32388
  try {