@trops/dash-core 0.1.445 → 0.1.447
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/electron/index.js +215 -1
- package/dist/electron/index.js.map +1 -1
- package/dist/index.esm.js +137 -84
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +137 -84
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/electron/index.js
CHANGED
|
@@ -27191,6 +27191,10 @@ var widgetRegistry$1 = {exports: {}};
|
|
|
27191
27191
|
|
|
27192
27192
|
var dynamicWidgetLoader$3 = {exports: {}};
|
|
27193
27193
|
|
|
27194
|
+
function commonjsRequire(path) {
|
|
27195
|
+
throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
|
|
27196
|
+
}
|
|
27197
|
+
|
|
27194
27198
|
/**
|
|
27195
27199
|
* Widget Compiler
|
|
27196
27200
|
*
|
|
@@ -27204,6 +27208,90 @@ var dynamicWidgetLoader$3 = {exports: {}};
|
|
|
27204
27208
|
const fs$7 = require$$0$2;
|
|
27205
27209
|
const path$b = require$$1$2;
|
|
27206
27210
|
|
|
27211
|
+
/**
|
|
27212
|
+
* Structured error thrown by compileWidget() when the underlying
|
|
27213
|
+
* esbuild spawn fails (typically ENOENT — the native helper binary is
|
|
27214
|
+
* missing on this arch in a packaged build). The renderer surfaces
|
|
27215
|
+
* `.code` + `.diagnostics` to give the user something actionable
|
|
27216
|
+
* instead of a raw "spawn ENOENT".
|
|
27217
|
+
*/
|
|
27218
|
+
class WidgetCompileError extends Error {
|
|
27219
|
+
constructor(message, code, diagnostics) {
|
|
27220
|
+
super(message);
|
|
27221
|
+
this.name = "WidgetCompileError";
|
|
27222
|
+
this.code = code;
|
|
27223
|
+
this.diagnostics = diagnostics;
|
|
27224
|
+
}
|
|
27225
|
+
}
|
|
27226
|
+
|
|
27227
|
+
/**
|
|
27228
|
+
* Probe the on-disk state of esbuild + its arch-specific native helper.
|
|
27229
|
+
* Returns a flat object suitable for logging/UI display. Never throws.
|
|
27230
|
+
*/
|
|
27231
|
+
function getEsbuildDiagnostics() {
|
|
27232
|
+
const diagnostics = {
|
|
27233
|
+
platform: process.platform,
|
|
27234
|
+
arch: process.arch,
|
|
27235
|
+
esbuildVersion: null,
|
|
27236
|
+
esbuildPackageDir: null,
|
|
27237
|
+
archPackage: `@esbuild/${process.platform}-${process.arch}`,
|
|
27238
|
+
nativeBinaryPath: null,
|
|
27239
|
+
nativeBinaryExists: false,
|
|
27240
|
+
};
|
|
27241
|
+
|
|
27242
|
+
try {
|
|
27243
|
+
const pkgJsonPath = require.resolve("esbuild/package.json");
|
|
27244
|
+
diagnostics.esbuildPackageDir = path$b.dirname(pkgJsonPath);
|
|
27245
|
+
diagnostics.esbuildVersion = commonjsRequire(pkgJsonPath).version;
|
|
27246
|
+
} catch (err) {
|
|
27247
|
+
diagnostics.esbuildResolveError = err.message;
|
|
27248
|
+
}
|
|
27249
|
+
|
|
27250
|
+
try {
|
|
27251
|
+
const archPkgJson = require.resolve(
|
|
27252
|
+
`${diagnostics.archPackage}/package.json`,
|
|
27253
|
+
);
|
|
27254
|
+
const archDir = path$b.dirname(archPkgJson);
|
|
27255
|
+
// esbuild's native binary on macOS/Linux is bin/esbuild;
|
|
27256
|
+
// on Windows it's esbuild.exe at the package root.
|
|
27257
|
+
const candidate =
|
|
27258
|
+
process.platform === "win32"
|
|
27259
|
+
? path$b.join(archDir, "esbuild.exe")
|
|
27260
|
+
: path$b.join(archDir, "bin", "esbuild");
|
|
27261
|
+
diagnostics.nativeBinaryPath = candidate;
|
|
27262
|
+
diagnostics.nativeBinaryExists = fs$7.existsSync(candidate);
|
|
27263
|
+
} catch (err) {
|
|
27264
|
+
diagnostics.archResolveError = err.message;
|
|
27265
|
+
}
|
|
27266
|
+
|
|
27267
|
+
return diagnostics;
|
|
27268
|
+
}
|
|
27269
|
+
|
|
27270
|
+
/**
|
|
27271
|
+
* Quick liveness probe for the widget compiler. Runs a no-op
|
|
27272
|
+
* `esbuild.transform("")` so any missing-native-binary failure surfaces
|
|
27273
|
+
* before the user tries to compile a real widget. Returns
|
|
27274
|
+
* `{ ok, error?, code?, diagnostics }` — never throws.
|
|
27275
|
+
*/
|
|
27276
|
+
async function healthCheck() {
|
|
27277
|
+
const diagnostics = getEsbuildDiagnostics();
|
|
27278
|
+
try {
|
|
27279
|
+
const esbuild = require("esbuild");
|
|
27280
|
+
await esbuild.transform("", { loader: "js" });
|
|
27281
|
+
return { ok: true, diagnostics };
|
|
27282
|
+
} catch (err) {
|
|
27283
|
+
return {
|
|
27284
|
+
ok: false,
|
|
27285
|
+
error: err.message,
|
|
27286
|
+
code:
|
|
27287
|
+
err.code === "ENOENT" || /spawn|ENOENT/i.test(err.message || "")
|
|
27288
|
+
? "ESBUILD_SPAWN_FAILED"
|
|
27289
|
+
: "ESBUILD_UNAVAILABLE",
|
|
27290
|
+
diagnostics,
|
|
27291
|
+
};
|
|
27292
|
+
}
|
|
27293
|
+
}
|
|
27294
|
+
|
|
27207
27295
|
/**
|
|
27208
27296
|
* Find the widgets/ directory, handling nested ZIP extraction.
|
|
27209
27297
|
*
|
|
@@ -27385,6 +27473,18 @@ async function compileWidget$1(widgetPath) {
|
|
|
27385
27473
|
`[WidgetCompiler] Compilation failed for ${widgetPath}:`,
|
|
27386
27474
|
error,
|
|
27387
27475
|
);
|
|
27476
|
+
// ENOENT on the esbuild path means the native helper binary
|
|
27477
|
+
// wasn't found — usually a packaging issue (wrong arch in the
|
|
27478
|
+
// universal asar, asar-unpacked glob missing the arch package,
|
|
27479
|
+
// dev install never ran for the runtime arch). Wrap with
|
|
27480
|
+
// diagnostics so the UI can show something useful.
|
|
27481
|
+
if (error.code === "ENOENT" || /spawn|ENOENT/i.test(error.message || "")) {
|
|
27482
|
+
throw new WidgetCompileError(
|
|
27483
|
+
`Widget compiler unavailable: ${error.message}`,
|
|
27484
|
+
"ESBUILD_SPAWN_FAILED",
|
|
27485
|
+
getEsbuildDiagnostics(),
|
|
27486
|
+
);
|
|
27487
|
+
}
|
|
27388
27488
|
throw error;
|
|
27389
27489
|
} finally {
|
|
27390
27490
|
// Clean up temporary entry file
|
|
@@ -27402,7 +27502,13 @@ async function compileWidget$1(widgetPath) {
|
|
|
27402
27502
|
}
|
|
27403
27503
|
}
|
|
27404
27504
|
|
|
27405
|
-
var widgetCompiler$1 = {
|
|
27505
|
+
var widgetCompiler$1 = {
|
|
27506
|
+
compileWidget: compileWidget$1,
|
|
27507
|
+
findWidgetsDir: findWidgetsDir$2,
|
|
27508
|
+
healthCheck,
|
|
27509
|
+
getEsbuildDiagnostics,
|
|
27510
|
+
WidgetCompileError,
|
|
27511
|
+
};
|
|
27406
27512
|
|
|
27407
27513
|
/**
|
|
27408
27514
|
* Dynamic Widget Loader
|
|
@@ -74039,6 +74145,99 @@ function findWidget(registry, packageId) {
|
|
|
74039
74145
|
return null;
|
|
74040
74146
|
}
|
|
74041
74147
|
|
|
74148
|
+
/**
|
|
74149
|
+
* Dedup duplicate `{type: "..."}` entries inside a `providers: [...]`
|
|
74150
|
+
* array literal in a .dash.js source string. Mirrors the regex used at
|
|
74151
|
+
* AI-build write time in dash-electron's WidgetBuilderModal so old
|
|
74152
|
+
* AI-generated widgets get healed before publish (the runtime parse
|
|
74153
|
+
* dedup keeps consumers correct, but the raw .dash.js text on disk
|
|
74154
|
+
* stays dirty unless we rewrite it).
|
|
74155
|
+
*
|
|
74156
|
+
* Conservative: only handles a single-level array of object literals.
|
|
74157
|
+
* More exotic forms fall through unchanged and the runtime dedup picks
|
|
74158
|
+
* up the slack.
|
|
74159
|
+
*
|
|
74160
|
+
* @param {string} source
|
|
74161
|
+
* @returns {{ source: string, dropped: number }}
|
|
74162
|
+
*/
|
|
74163
|
+
function dedupProvidersInDashSource(source) {
|
|
74164
|
+
if (!source) return { source, dropped: 0 };
|
|
74165
|
+
let totalDropped = 0;
|
|
74166
|
+
const cleaned = source.replace(
|
|
74167
|
+
/(providers\s*:\s*\[)([^[\]]*?)(\])/,
|
|
74168
|
+
(match, head, body, tail) => {
|
|
74169
|
+
const chunks = body
|
|
74170
|
+
.split(/(\{[^{}]*\})/)
|
|
74171
|
+
.filter((s) => s && /\S/.test(s));
|
|
74172
|
+
const seenTypes = new Set();
|
|
74173
|
+
const kept = [];
|
|
74174
|
+
let dropped = 0;
|
|
74175
|
+
for (const chunk of chunks) {
|
|
74176
|
+
if (!chunk.startsWith("{")) continue;
|
|
74177
|
+
const typeMatch = chunk.match(/type\s*:\s*["']([^"']+)["']/);
|
|
74178
|
+
if (!typeMatch) {
|
|
74179
|
+
kept.push(chunk.trim());
|
|
74180
|
+
continue;
|
|
74181
|
+
}
|
|
74182
|
+
const t = typeMatch[1];
|
|
74183
|
+
if (seenTypes.has(t)) {
|
|
74184
|
+
dropped++;
|
|
74185
|
+
continue;
|
|
74186
|
+
}
|
|
74187
|
+
seenTypes.add(t);
|
|
74188
|
+
kept.push(chunk.trim());
|
|
74189
|
+
}
|
|
74190
|
+
if (dropped === 0) return match;
|
|
74191
|
+
totalDropped += dropped;
|
|
74192
|
+
return `${head}${kept.join(", ")}${tail}`;
|
|
74193
|
+
},
|
|
74194
|
+
);
|
|
74195
|
+
return { source: cleaned, dropped: totalDropped };
|
|
74196
|
+
}
|
|
74197
|
+
|
|
74198
|
+
/**
|
|
74199
|
+
* Walk a widget package's `.dash.js` files and rewrite any with
|
|
74200
|
+
* duplicate provider-type entries. Returns counts so the publish
|
|
74201
|
+
* caller can log what was healed. Errors are non-fatal — a single
|
|
74202
|
+
* unparseable .dash.js shouldn't block the whole publish.
|
|
74203
|
+
*/
|
|
74204
|
+
function cleanupProvidersInWidgetPackage(widgetPath) {
|
|
74205
|
+
const summary = { filesScanned: 0, filesRewritten: 0, totalDropped: 0 };
|
|
74206
|
+
try {
|
|
74207
|
+
const widgetsDir =
|
|
74208
|
+
findWidgetsDir(widgetPath) || path.join(widgetPath, "widgets");
|
|
74209
|
+
if (!fs.existsSync(widgetsDir)) return summary;
|
|
74210
|
+
for (const file of fs.readdirSync(widgetsDir)) {
|
|
74211
|
+
if (!file.endsWith(".dash.js")) continue;
|
|
74212
|
+
const filePath = path.join(widgetsDir, file);
|
|
74213
|
+
try {
|
|
74214
|
+
const original = fs.readFileSync(filePath, "utf8");
|
|
74215
|
+
summary.filesScanned++;
|
|
74216
|
+
const { source: deduped, dropped } =
|
|
74217
|
+
dedupProvidersInDashSource(original);
|
|
74218
|
+
if (dropped > 0 && deduped !== original) {
|
|
74219
|
+
fs.writeFileSync(filePath, deduped, "utf8");
|
|
74220
|
+
summary.filesRewritten++;
|
|
74221
|
+
summary.totalDropped += dropped;
|
|
74222
|
+
console.log(
|
|
74223
|
+
`[widgetRegistry] Cleaned ${dropped} duplicate provider(s) from ${file}`,
|
|
74224
|
+
);
|
|
74225
|
+
}
|
|
74226
|
+
} catch (err) {
|
|
74227
|
+
console.warn(
|
|
74228
|
+
`[widgetRegistry] cleanupProviders skip ${file}: ${err.message}`,
|
|
74229
|
+
);
|
|
74230
|
+
}
|
|
74231
|
+
}
|
|
74232
|
+
} catch (err) {
|
|
74233
|
+
console.warn(
|
|
74234
|
+
"[widgetRegistry] cleanupProvidersInWidgetPackage failed:",
|
|
74235
|
+
err.message,
|
|
74236
|
+
);
|
|
74237
|
+
}
|
|
74238
|
+
return summary;
|
|
74239
|
+
}
|
|
74240
|
+
|
|
74042
74241
|
/**
|
|
74043
74242
|
* Scan a widget package directory for `.dash.js` component configs and
|
|
74044
74243
|
* return the parsed configs. Used when the widget registry's cached
|
|
@@ -74381,6 +74580,21 @@ async function prepareWidgetForPublish$1(appId, packageId, options = {}) {
|
|
|
74381
74580
|
}
|
|
74382
74581
|
}
|
|
74383
74582
|
|
|
74583
|
+
// 5b. Heal `.dash.js` source files that have duplicate
|
|
74584
|
+
// provider-type entries before we read configs / build the
|
|
74585
|
+
// manifest / zip. AI-generated configs occasionally double a
|
|
74586
|
+
// `{type:"..."}` entry; the runtime dedup makes it invisible
|
|
74587
|
+
// on the publisher's machine, but we don't want the dirty raw
|
|
74588
|
+
// text shipping to the registry. Mirrors the write-time dedup
|
|
74589
|
+
// in dash-electron's WidgetBuilderModal so older widgets
|
|
74590
|
+
// authored before that fix landed get cleaned at publish.
|
|
74591
|
+
const providerCleanupSummary = cleanupProvidersInWidgetPackage(widget.path);
|
|
74592
|
+
if (providerCleanupSummary.filesRewritten > 0) {
|
|
74593
|
+
console.log(
|
|
74594
|
+
`[widgetRegistry] Provider cleanup: rewrote ${providerCleanupSummary.filesRewritten} file(s), removed ${providerCleanupSummary.totalDropped} duplicate(s)`,
|
|
74595
|
+
);
|
|
74596
|
+
}
|
|
74597
|
+
|
|
74384
74598
|
// 6. Build manifest using the widget's component configs. The
|
|
74385
74599
|
// registry cache may be missing widgets (orphaned / locally-
|
|
74386
74600
|
// registered packages), so fall back to scanning the package's
|