@dsh-workbench/core 0.1.15 → 0.1.17
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/README.md +19 -0
- package/bin/dsh-workbench +5 -1
- package/client.js +660 -128
- package/cordis.patch.yml +22 -0
- package/dist/client/client.body.js +660 -128
- package/dist/client/index.js +660 -128
- package/dist/host/index.js +1733 -324
- package/dist/types/app/client.d.ts +124 -9
- package/dist/types/app/layouts/market/add-module-text.d.ts +2 -0
- package/dist/types/app/layouts/market/use-add-module.d.ts +4 -3
- package/dist/types/app/layouts/market/use-module-versions.d.ts +2 -0
- package/dist/types/app/layouts/rightbar/MarketView.d.ts +3 -1
- package/dist/types/app/layouts/rightbar/__tests__/market-rows-plugins.test.d.ts +1 -0
- package/dist/types/app/layouts/rightbar/market-mock.d.ts +9 -0
- package/dist/types/app/layouts/rightbar/market-plugin-rows.d.ts +8 -0
- package/dist/types/app/layouts/rightbar/market-rows.d.ts +14 -3
- package/dist/types/app/layouts/rightbar/registry.d.ts +0 -1
- package/dist/types/app/units/__tests__/manifests.test.d.ts +1 -0
- package/dist/types/app/units/fixture-unit-mock.d.ts +3 -3
- package/dist/types/app/units/host.d.ts +2 -2
- package/dist/types/app/units/manifests.d.ts +5 -0
- package/dist/types/app/units/registry.d.ts +10 -2
- package/dist/types/modules/panels/__tests__/market-env.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/market-plugin.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/market-route.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/plugin-actions.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/plugin-ledger.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/plugin-section.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/scope.test.d.ts +1 -0
- package/dist/types/modules/panels/__tests__/service-release.test.d.ts +1 -0
- package/dist/types/modules/panels/index.d.ts +2 -2
- package/dist/types/modules/panels/model/config.d.ts +27 -9
- package/dist/types/modules/panels/model/market-dispatch.d.ts +9 -0
- package/dist/types/modules/panels/model/market-env.d.ts +20 -0
- package/dist/types/modules/panels/model/market-route.d.ts +26 -0
- package/dist/types/modules/panels/model/market-types.d.ts +71 -0
- package/dist/types/modules/panels/model/market.d.ts +7 -66
- package/dist/types/modules/panels/model/plugin-actions.d.ts +50 -0
- package/dist/types/modules/panels/model/plugin-ledger.d.ts +22 -0
- package/dist/types/modules/panels/model/plugin-name.d.ts +8 -0
- package/dist/types/modules/panels/model/plugin-name.test.d.ts +1 -0
- package/dist/types/modules/panels/model/plugin-section.d.ts +13 -0
- package/dist/types/modules/panels/model/service.d.ts +8 -6
- package/dist/types/shared/api/bundle-install.d.ts +8 -1
- package/dist/types/shared/api/host/__tests__/registry-declaration.test.d.ts +1 -0
- package/dist/types/shared/api/host/__tests__/unit-roster-facts.test.d.ts +1 -0
- package/dist/types/shared/api/host/bundle-routes.d.ts +1 -0
- package/dist/types/shared/api/host/installed-module.d.ts +7 -0
- package/dist/types/shared/api/host/mount-units.d.ts +5 -3
- package/dist/types/shared/api/host/package-content.d.ts +6 -0
- package/dist/types/shared/api/host/package-content.test.d.ts +1 -0
- package/dist/types/shared/api/host/package-kind.d.ts +21 -0
- package/dist/types/shared/api/host/package-kind.test.d.ts +1 -0
- package/dist/types/shared/api/host/package-route.d.ts +23 -0
- package/dist/types/shared/api/host/package-route.test.d.ts +1 -0
- package/dist/types/shared/api/host/registry-declaration.d.ts +23 -0
- package/dist/types/shared/api/host/runtime-seed.d.ts +40 -0
- package/dist/types/shared/api/host/runtime-seed.test.d.ts +1 -0
- package/dist/types/shared/api/host/unit-registry.d.ts +33 -4
- package/dist/types/shared/api/host/unit-roster-facts.d.ts +5 -0
- package/dist/types/shared/api/installed-plugins.d.ts +12 -0
- package/dist/types/shared/api/unit-manifests.d.ts +5 -0
- package/dist/types/shared/api/unit-manifests.test.d.ts +1 -0
- package/dist/types/shared/hooks/bundle-queries.d.ts +2 -0
- package/dist/types/shared/hooks/use-facts.d.ts +1 -0
- package/docs/HANDOFF.md +82 -44
- package/docs/OPERATIONS.md +22 -1
- package/package.json +5 -4
- package/scripts/seed-workshop.sh +216 -0
- package/skills/workbench-module-diy/BUILD.md +5 -5
- package/skills/workbench-module-diy/DESIGN.md +7 -1
- package/skills/workbench-module-diy/REVIEW.md +3 -2
- package/skills/workbench-module-diy/TOOLING.md +2 -2
- package/skills/workbench-module-diy/TOOLS.md +9 -2
|
@@ -419,6 +419,121 @@ function probeKeyOf(error) {
|
|
|
419
419
|
if (error === void 0) return null;
|
|
420
420
|
return error.code === "" ? "unknown" : error.code;
|
|
421
421
|
}
|
|
422
|
+
var SUPPORTED_API_VERSIONS = [1];
|
|
423
|
+
var DECLARATION_KEYS = [
|
|
424
|
+
"apiVersion",
|
|
425
|
+
"unit",
|
|
426
|
+
"card",
|
|
427
|
+
"tools",
|
|
428
|
+
"host",
|
|
429
|
+
"env"
|
|
430
|
+
];
|
|
431
|
+
var DECLARATION_REQUIRED_KEYS = [
|
|
432
|
+
"apiVersion",
|
|
433
|
+
"unit",
|
|
434
|
+
"card",
|
|
435
|
+
"tools",
|
|
436
|
+
"host"
|
|
437
|
+
];
|
|
438
|
+
var CARD_KEYS = ["titleKey", "order"];
|
|
439
|
+
var TOOL_KEYS = ["name", "writes"];
|
|
440
|
+
var HOST_KEYS = ["inject", "optional"];
|
|
441
|
+
function text(value) {
|
|
442
|
+
return typeof value === "string" ? value.trim() : "";
|
|
443
|
+
}
|
|
444
|
+
function isRecord(value) {
|
|
445
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
446
|
+
}
|
|
447
|
+
function outsideKeys(value, allowed) {
|
|
448
|
+
return Object.keys(value).filter((key) => !allowed.includes(key));
|
|
449
|
+
}
|
|
450
|
+
function listOf(keys) {
|
|
451
|
+
return keys.map((key) => JSON.stringify(key)).join(" / ");
|
|
452
|
+
}
|
|
453
|
+
function stringArrayProblems(at, value) {
|
|
454
|
+
if (!Array.isArray(value)) return [`${at} 要是一串字符串,现在是 ${JSON.stringify(value)}`];
|
|
455
|
+
return value.flatMap((item, index) => text(item) === "" ? [`${at}[${index}] 不是非空字符串:${JSON.stringify(item)}`] : []);
|
|
456
|
+
}
|
|
457
|
+
function declarationProblemsOf(subject, raw) {
|
|
458
|
+
if (!isRecord(raw)) return [`${subject}: dsh.workbench 不是一个对象 —— ${JSON.stringify(raw)}`];
|
|
459
|
+
const version = raw.apiVersion;
|
|
460
|
+
if (version === void 0) return [`${subject}: dsh.workbench 没有 apiVersion —— 协议从 v1 起,写 \`"apiVersion": 1\`。缺它 = 外壳不认这个模块(ADR-0038 §2.3)`];
|
|
461
|
+
if (!Number.isInteger(version) || !SUPPORTED_API_VERSIONS.includes(version)) return [`${subject}: dsh.workbench.apiVersion 是 ${JSON.stringify(version)},这里只认 ${SUPPORTED_API_VERSIONS.join(" / ")}(要整数)`];
|
|
462
|
+
const problems = [];
|
|
463
|
+
const unknown = outsideKeys(raw, DECLARATION_KEYS);
|
|
464
|
+
if (unknown.length > 0) problems.push(`${subject}: dsh.workbench 里有协议 v1 不认识的键 ${listOf(unknown)} —— 只有 ${listOf(DECLARATION_KEYS)}。(拼错的键会被外壳**静默忽略**:那句声明等于没写)`);
|
|
465
|
+
for (const key of DECLARATION_REQUIRED_KEYS) if (raw[key] === void 0) problems.push(`${subject}: dsh.workbench 缺 ${key}` + (key === "card" ? "(这个模块没有卡片就写 `\"card\": null`)" : ""));
|
|
466
|
+
const card = raw.card;
|
|
467
|
+
if (card !== void 0 && card !== null) {
|
|
468
|
+
if (!isRecord(card)) problems.push(`${subject}: dsh.workbench.card 要么是对象、要么是 null,现在是 ${JSON.stringify(card)}`);
|
|
469
|
+
else {
|
|
470
|
+
const extra = outsideKeys(card, CARD_KEYS);
|
|
471
|
+
if (extra.length > 0) problems.push(`${subject}: dsh.workbench.card 里有不认的键 ${listOf(extra)} —— card 只有 ${listOf(CARD_KEYS)}(卡片默认显不显示由运行期的面板配置决定,清单里没有这一位)`);
|
|
472
|
+
if (text(card.titleKey) === "") problems.push(`${subject}: dsh.workbench.card.titleKey 要是非空字符串(面板那一格的文案键)`);
|
|
473
|
+
if (typeof card.order !== "number" || !Number.isFinite(card.order)) problems.push(`${subject}: dsh.workbench.card.order 要是数字,现在是 ${JSON.stringify(card.order)}`);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
const tools = raw.tools;
|
|
477
|
+
if (tools !== void 0) {
|
|
478
|
+
if (!Array.isArray(tools)) problems.push(`${subject}: dsh.workbench.tools 要是一串声明,现在是 ${JSON.stringify(tools)}`);
|
|
479
|
+
else {
|
|
480
|
+
const seen = /* @__PURE__ */ new Set();
|
|
481
|
+
tools.forEach((tool, index) => {
|
|
482
|
+
const at = `dsh.workbench.tools[${index}]`;
|
|
483
|
+
if (!isRecord(tool)) {
|
|
484
|
+
problems.push(`${subject}: ${at} 要是对象,现在是 ${JSON.stringify(tool)}`);
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
const extra = outsideKeys(tool, TOOL_KEYS);
|
|
488
|
+
if (extra.length > 0) problems.push(`${subject}: ${at} 里有不认的键 ${listOf(extra)} —— tools 只有 ${listOf(TOOL_KEYS)}`);
|
|
489
|
+
const name = text(tool.name);
|
|
490
|
+
if (name === "") problems.push(`${subject}: ${at}.name 要是非空字符串`);
|
|
491
|
+
else if (seen.has(name)) problems.push(`${subject}: ${at}.name「${name}」与前面那条撞了 —— 工具名会进 dsh 的工具表,不许重`);
|
|
492
|
+
else seen.add(name);
|
|
493
|
+
if (typeof tool.writes !== "boolean") problems.push(`${subject}: ${at}.writes 要是 true / false(它是"这会写"的唯一声明,缺了审批无从认领)`);
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
const host = raw.host;
|
|
498
|
+
if (host !== void 0) {
|
|
499
|
+
if (!isRecord(host)) problems.push(`${subject}: dsh.workbench.host 要是对象,现在是 ${JSON.stringify(host)}`);
|
|
500
|
+
else {
|
|
501
|
+
const extra = outsideKeys(host, HOST_KEYS);
|
|
502
|
+
if (extra.length > 0) problems.push(`${subject}: dsh.workbench.host 里有不认的键 ${listOf(extra)} —— host 只有 ${listOf(HOST_KEYS)}`);
|
|
503
|
+
if (host.inject === void 0) problems.push(`${subject}: dsh.workbench.host.inject 没写 —— 它声明这个模块要外壳的哪几个服务,外壳靠它判"能不能挂"。一个都不要也要写 \`"inject": []\``);
|
|
504
|
+
else problems.push(...stringArrayProblems(`${subject}: dsh.workbench.host.inject`, host.inject));
|
|
505
|
+
if (host.optional !== void 0) problems.push(...stringArrayProblems(`${subject}: dsh.workbench.host.optional`, host.optional));
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
if (raw.env !== void 0 && !isRecord(raw.env)) problems.push(`${subject}: dsh.workbench.env 要是对象(command / plugins / libs)—— 语义由门禁的 env 判据查,这里只查形状`);
|
|
509
|
+
return problems;
|
|
510
|
+
}
|
|
511
|
+
function readDeclaration(subject, raw) {
|
|
512
|
+
const problems = declarationProblemsOf(subject, raw);
|
|
513
|
+
if (problems.length > 0) return { problems };
|
|
514
|
+
const declaration = raw;
|
|
515
|
+
const card = declaration.card;
|
|
516
|
+
return {
|
|
517
|
+
declaration,
|
|
518
|
+
problems: [],
|
|
519
|
+
manifest: {
|
|
520
|
+
id: text(declaration.unit),
|
|
521
|
+
card: card === null ? null : {
|
|
522
|
+
titleKey: text(card.titleKey),
|
|
523
|
+
order: card.order
|
|
524
|
+
},
|
|
525
|
+
tools: declaration.tools.map((tool) => ({
|
|
526
|
+
name: text(tool.name),
|
|
527
|
+
writes: tool.writes
|
|
528
|
+
})),
|
|
529
|
+
host: {
|
|
530
|
+
inject: [...declaration.host.inject ?? []],
|
|
531
|
+
...declaration.host.optional === void 0 ? {} : { optional: [...declaration.host.optional] }
|
|
532
|
+
},
|
|
533
|
+
...declaration.env === void 0 ? {} : { env: declaration.env }
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
}
|
|
422
537
|
//#endregion
|
|
423
538
|
//#region ../shared/dist/config/constants.js
|
|
424
539
|
var PLUGIN_ID = "@dsh-workbench/core";
|
|
@@ -606,7 +721,7 @@ function ApprovalDetail(props) {
|
|
|
606
721
|
if (owner?.approval !== void 0) {
|
|
607
722
|
const Render = owner.approval.render;
|
|
608
723
|
return h(CardBoundary, {
|
|
609
|
-
unit: owner.
|
|
724
|
+
unit: owner.unit,
|
|
610
725
|
resetKey: props.callId ?? "",
|
|
611
726
|
t
|
|
612
727
|
}, h(Render, {
|
|
@@ -1111,6 +1226,7 @@ var en = {
|
|
|
1111
1226
|
"panels.market.sectionPending": "Not installed",
|
|
1112
1227
|
"panels.market.sectionShared": "Shared dependencies",
|
|
1113
1228
|
"panels.market.sharedUsedBy": "Used by {modules}",
|
|
1229
|
+
"panels.market.sharedFoot": "These cannot be uninstalled here: they come with modules, and would be reinstalled anyway. To stop using one, turn off the modules that use it.",
|
|
1114
1230
|
"panels.market.listSeparator": ", ",
|
|
1115
1231
|
"panels.market.sharedMissing": "not installed",
|
|
1116
1232
|
"panels.market.sharedOutdated": "update available",
|
|
@@ -1138,8 +1254,18 @@ var en = {
|
|
|
1138
1254
|
"panels.market.installedSection": "Installed",
|
|
1139
1255
|
"panels.market.sectionLocal": "Linked locally",
|
|
1140
1256
|
"panels.market.sectionUnlisted": "Not from the market",
|
|
1257
|
+
"panels.market.sectionPlugins": "Installed opencli plugins",
|
|
1141
1258
|
"panels.market.moduleOutdated": "update available",
|
|
1259
|
+
"panels.market.moduleRefused": "This module was built for an older version of the workbench, so it does not work here. Update it, or uninstall.",
|
|
1260
|
+
"panels.market.moduleRefusedDetail": "Why it cannot be used: {reason}",
|
|
1142
1261
|
"panels.market.moduleRestartHint": "installed but not active — restart dsh once to bring it up",
|
|
1262
|
+
"panels.market.pluginLocalNoUpdate": "Installed from a local folder, so there is nowhere to check for a newer version — uninstall only",
|
|
1263
|
+
"panels.market.pluginKeptInUse": "Files kept for now: {names} still uses it.",
|
|
1264
|
+
"panels.market.pluginKeptUnsure": "Files kept for now: some modules on this machine do not say what they use, so it is unclear who needs it.",
|
|
1265
|
+
"panels.market.pluginKeptHeld": "Files kept: this one is yours, and a module letting go will not remove it.",
|
|
1266
|
+
"panels.market.pluginKeptUnnamed": "Files kept for now: this one cannot be identified as a plugin, so it is unclear who needs it.",
|
|
1267
|
+
"panels.market.pluginAlsoKnownAs": "Its package is {pkg} (updates and uninstall use that)",
|
|
1268
|
+
"panels.market.pluginBroken": "This install is broken: it cannot be identified as a plugin. Uninstall it, or install it again by package name above.",
|
|
1143
1269
|
"panels.market.restartNeeded": "The new version is installed — restart once to pick it up.",
|
|
1144
1270
|
"panels.market.foot": "After installing, enable it in the panel page of that project.",
|
|
1145
1271
|
"panels.market.recheck": "Check for updates",
|
|
@@ -1187,7 +1313,11 @@ var en = {
|
|
|
1187
1313
|
"panels.market.add.problemInstalled": "This module is already installed",
|
|
1188
1314
|
"panels.market.add.problemNotFound": "No such module found",
|
|
1189
1315
|
"panels.market.add.problemNotPackage": "That path does not exist or is not a valid module package",
|
|
1190
|
-
"panels.market.add.problemNotBundle": "This package
|
|
1316
|
+
"panels.market.add.problemNotBundle": "This package cannot be installed here: {reason}. If it is actually an opencli plugin, use its package name (for example opencli-plugin-cmdb) or a local folder — a git URL or tarball does not reveal what it is.",
|
|
1317
|
+
"panels.market.add.problemNotWorkbenchModule": "This package does not match the workbench you are running, so installing it would not work. Pick another version, or ask the module author.",
|
|
1318
|
+
"panels.market.add.problemNotModuleOrPlugin": "This package is neither a workbench module nor an opencli plugin, so installing it would do nothing. Pick another version, or ask the package author.",
|
|
1319
|
+
"panels.market.add.failureNotModuleOrPlugin": "This package is neither a workbench module nor an opencli plugin, so installing it would do nothing",
|
|
1320
|
+
"panels.market.add.installedPlugin": "Installed: the opencli plugin {name}",
|
|
1191
1321
|
"panels.market.add.problemNetwork": "Cannot reach the module source; check the network and retry",
|
|
1192
1322
|
"panels.market.add.problemUnknown": "Cannot fetch module information: {reason}",
|
|
1193
1323
|
"panels.market.add.failureNetwork": "The network connection failed",
|
|
@@ -1218,6 +1348,7 @@ var en = {
|
|
|
1218
1348
|
"panels.market.add.registryPnpm": "pnpm's own registry",
|
|
1219
1349
|
"panels.market.add.check": "Check",
|
|
1220
1350
|
"panels.market.add.checking": "Checking…",
|
|
1351
|
+
"panels.market.add.classifying": "Working out what it is…",
|
|
1221
1352
|
"panels.market.add.change": "Edit",
|
|
1222
1353
|
"panels.market.add.previewTitle": "About to install",
|
|
1223
1354
|
"panels.market.add.fieldName": "Package",
|
|
@@ -1426,6 +1557,7 @@ var zh = {
|
|
|
1426
1557
|
"panels.market.sectionPending": "未安装",
|
|
1427
1558
|
"panels.market.sectionShared": "共用依赖",
|
|
1428
1559
|
"panels.market.sharedUsedBy": "供 {modules} 使用",
|
|
1560
|
+
"panels.market.sharedFoot": "这一段不给卸载:它们跟着模块来,卸掉也会被装回来。要停用一份,就去关掉正在用它的那些模块。",
|
|
1429
1561
|
"panels.market.listSeparator": "、",
|
|
1430
1562
|
"panels.market.sharedMissing": "未装",
|
|
1431
1563
|
"panels.market.sharedOutdated": "有新版",
|
|
@@ -1453,8 +1585,18 @@ var zh = {
|
|
|
1453
1585
|
"panels.market.installedSection": "已安装",
|
|
1454
1586
|
"panels.market.sectionLocal": "本地装的",
|
|
1455
1587
|
"panels.market.sectionUnlisted": "不是从市场装的",
|
|
1588
|
+
"panels.market.sectionPlugins": "已安装 opencli 插件",
|
|
1456
1589
|
"panels.market.moduleOutdated": "有新版",
|
|
1590
|
+
"panels.market.moduleRefused": "这个模块是给旧版本的工作台写的,现在用不了。更新它,或者卸载。",
|
|
1591
|
+
"panels.market.moduleRefusedDetail": "装不上的原因:{reason}",
|
|
1457
1592
|
"panels.market.moduleRestartHint": "装好了但还没生效 —— 重启一次 dsh 就会出来",
|
|
1593
|
+
"panels.market.pluginLocalNoUpdate": "本地装的,没地方查新版,所以只给卸载",
|
|
1594
|
+
"panels.market.pluginKeptInUse": "文件先留着:{names} 还要用它。",
|
|
1595
|
+
"panels.market.pluginKeptUnsure": "文件先留着:这台机器上还有模块看不出用了什么,说不准谁在用它。",
|
|
1596
|
+
"panels.market.pluginKeptHeld": "文件留着:你自己装的那一份,模块放手不动它。",
|
|
1597
|
+
"panels.market.pluginKeptUnnamed": "文件先留着:看不出这是哪个插件,说不准谁在用它。",
|
|
1598
|
+
"panels.market.pluginAlsoKnownAs": "包名是 {pkg}(更新与卸载按它来)",
|
|
1599
|
+
"panels.market.pluginBroken": "这份装坏了:看不出它是个插件。可以卸载,或者去上面按包名再装一次。",
|
|
1458
1600
|
"panels.market.restartNeeded": "新版装好了,重启一次才生效。",
|
|
1459
1601
|
"panels.market.foot": "装好后到那个项目的面板页勾选它,模块才会出现。",
|
|
1460
1602
|
"panels.market.recheck": "重新检查更新",
|
|
@@ -1502,7 +1644,11 @@ var zh = {
|
|
|
1502
1644
|
"panels.market.add.problemInstalled": "该模块已安装",
|
|
1503
1645
|
"panels.market.add.problemNotFound": "未找到相关模块",
|
|
1504
1646
|
"panels.market.add.problemNotPackage": "该路径不存在或不是有效的模块包",
|
|
1505
|
-
"panels.market.add.problemNotBundle": "
|
|
1647
|
+
"panels.market.add.problemNotBundle": "这个包装不进这里:{reason}。要是它其实是个 opencli 插件,请改用包名(例如 opencli-plugin-cmdb)或者本地目录 —— 从 git 地址和 tarball 判断不出它是什么。",
|
|
1648
|
+
"panels.market.add.problemNotWorkbenchModule": "这个包跟现在的工作台对不上,装上也用不了。换一个版本,或者找这个模块的作者。",
|
|
1649
|
+
"panels.market.add.problemNotModuleOrPlugin": "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上。换一个版本,或者找这个包的作者。",
|
|
1650
|
+
"panels.market.add.failureNotModuleOrPlugin": "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上",
|
|
1651
|
+
"panels.market.add.installedPlugin": "装上了:opencli 插件 {name}",
|
|
1506
1652
|
"panels.market.add.problemNetwork": "无法连接模块源,请检查网络后重试",
|
|
1507
1653
|
"panels.market.add.problemUnknown": "无法获取模块信息:{reason}",
|
|
1508
1654
|
"panels.market.add.failureNetwork": "网络连接失败",
|
|
@@ -1533,6 +1679,7 @@ var zh = {
|
|
|
1533
1679
|
"panels.market.add.registryPnpm": "pnpm 自己配的源",
|
|
1534
1680
|
"panels.market.add.check": "预检",
|
|
1535
1681
|
"panels.market.add.checking": "正在预检…",
|
|
1682
|
+
"panels.market.add.classifying": "判定中…",
|
|
1536
1683
|
"panels.market.add.change": "改一下",
|
|
1537
1684
|
"panels.market.add.previewTitle": "将要安装",
|
|
1538
1685
|
"panels.market.add.fieldName": "包名",
|
|
@@ -1809,6 +1956,8 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1809
1956
|
CenteredState: () => CenteredState,
|
|
1810
1957
|
ChoiceGroup: () => ChoiceGroup,
|
|
1811
1958
|
Component: () => Component,
|
|
1959
|
+
DECLARATION_KEYS: () => DECLARATION_KEYS,
|
|
1960
|
+
DECLARATION_REQUIRED_KEYS: () => DECLARATION_REQUIRED_KEYS,
|
|
1812
1961
|
DEFAULT_WORKSPACE_TITLE: () => DEFAULT_WORKSPACE_TITLE,
|
|
1813
1962
|
EVENTS_PATH: () => EVENTS_PATH,
|
|
1814
1963
|
EmptyState: () => EmptyState,
|
|
@@ -1847,6 +1996,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1847
1996
|
STORAGE_KEY_PROJECT: () => STORAGE_KEY_PROJECT,
|
|
1848
1997
|
STORAGE_KEY_RIGHTBAR: () => STORAGE_KEY_RIGHTBAR,
|
|
1849
1998
|
STORAGE_KEY_RIGHTBAR_COLUMN: () => STORAGE_KEY_RIGHTBAR_COLUMN,
|
|
1999
|
+
SUPPORTED_API_VERSIONS: () => SUPPORTED_API_VERSIONS,
|
|
1850
2000
|
SaveBar: () => SaveBar,
|
|
1851
2001
|
SettingsSection: () => SettingsSection,
|
|
1852
2002
|
SkeletonRows: () => SkeletonRows,
|
|
@@ -1857,6 +2007,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1857
2007
|
VERSION_CHECK_TIMEOUT_MS: () => VERSION_CHECK_TIMEOUT_MS,
|
|
1858
2008
|
VERSION_CHECK_TTL_MS: () => VERSION_CHECK_TTL_MS,
|
|
1859
2009
|
WARM_TIMEOUT_MS: () => WARM_TIMEOUT_MS,
|
|
2010
|
+
WORKBENCH_API_VERSION: () => 1,
|
|
1860
2011
|
apiGet: () => apiGet,
|
|
1861
2012
|
apiPost: () => apiPost,
|
|
1862
2013
|
blockerActionLabel: () => blockerActionLabel,
|
|
@@ -1866,6 +2017,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1866
2017
|
buildMarker: () => buildMarker,
|
|
1867
2018
|
createFactChannel: () => createFactChannel,
|
|
1868
2019
|
cx: () => cx,
|
|
2020
|
+
declarationProblemsOf: () => declarationProblemsOf,
|
|
1869
2021
|
decodeRef: () => decodeRef,
|
|
1870
2022
|
dictionaries: () => dictionaries,
|
|
1871
2023
|
en: () => en,
|
|
@@ -1889,6 +2041,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1889
2041
|
parseMarkers: () => parseMarkers,
|
|
1890
2042
|
probeKeyOf: () => probeKeyOf,
|
|
1891
2043
|
quoteShellArg: () => quoteShellArg,
|
|
2044
|
+
readDeclaration: () => readDeclaration,
|
|
1892
2045
|
readFlag: () => readFlag,
|
|
1893
2046
|
readText: () => readText,
|
|
1894
2047
|
relativeTime: () => relativeTime,
|
|
@@ -2001,6 +2154,7 @@ function createAdaptiveTransport() {
|
|
|
2001
2154
|
//#endregion
|
|
2002
2155
|
//#region src/shared/hooks/use-facts.ts
|
|
2003
2156
|
var use_facts_exports = /* @__PURE__ */ __exportAll({
|
|
2157
|
+
subscribeFactRevision: () => subscribeFactRevision,
|
|
2004
2158
|
useFactInvalidate: () => useFactInvalidate,
|
|
2005
2159
|
useFactRevision: () => useFactRevision
|
|
2006
2160
|
});
|
|
@@ -2008,6 +2162,9 @@ var channel = createFactChannel({ transport: createAdaptiveTransport() });
|
|
|
2008
2162
|
function useFactRevision(fact) {
|
|
2009
2163
|
return useSyncExternalStore(useCallback((listener) => channel.subscribe(fact, listener), [fact]), useCallback(() => channel.revisionOf(fact), [fact]));
|
|
2010
2164
|
}
|
|
2165
|
+
function subscribeFactRevision(fact, listener) {
|
|
2166
|
+
return channel.subscribe(fact, listener);
|
|
2167
|
+
}
|
|
2011
2168
|
function useFactInvalidate() {
|
|
2012
2169
|
return useCallback((fact) => channel.refresh(fact), []);
|
|
2013
2170
|
}
|
|
@@ -2532,8 +2689,7 @@ function buildMarketMocks(roster) {
|
|
|
2532
2689
|
...mine,
|
|
2533
2690
|
card: {
|
|
2534
2691
|
titleKey: "一个名字特别特别长的模块用来验证省略号会不会把按钮挤下去",
|
|
2535
|
-
order: 10
|
|
2536
|
-
enabledByDefault: true
|
|
2692
|
+
order: 10
|
|
2537
2693
|
}
|
|
2538
2694
|
}],
|
|
2539
2695
|
capabilities: probe$1(id, "ok"),
|
|
@@ -2637,6 +2793,24 @@ function buildMarketMocks(roster) {
|
|
|
2637
2793
|
installedActions: ["update-bundle", "remove-bundle"]
|
|
2638
2794
|
}
|
|
2639
2795
|
},
|
|
2796
|
+
{
|
|
2797
|
+
id: "installed-client-refused",
|
|
2798
|
+
label: "本机装了,但浏览器这半没挂上(拒因由客户端报告)",
|
|
2799
|
+
manifests: [found],
|
|
2800
|
+
capabilities: {},
|
|
2801
|
+
installed: [{
|
|
2802
|
+
unit: id,
|
|
2803
|
+
pkg: "@dsh-workbench/module-one",
|
|
2804
|
+
installed: "0.1.2",
|
|
2805
|
+
clientRefused: [`宿主没有担保 unit「${id}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]
|
|
2806
|
+
}],
|
|
2807
|
+
expect: {
|
|
2808
|
+
rows: 0,
|
|
2809
|
+
installed: 1,
|
|
2810
|
+
installedActions: ["remove-bundle"],
|
|
2811
|
+
installedNote: true
|
|
2812
|
+
}
|
|
2813
|
+
},
|
|
2640
2814
|
{
|
|
2641
2815
|
id: "installed-confirm",
|
|
2642
2816
|
label: "卸载本机模块(Modal 确认,标题带模块名)",
|
|
@@ -2685,6 +2859,95 @@ function buildMarketMocks(roster) {
|
|
|
2685
2859
|
actions: ["uninstall"]
|
|
2686
2860
|
}
|
|
2687
2861
|
},
|
|
2862
|
+
{
|
|
2863
|
+
id: "plugin-outdated",
|
|
2864
|
+
label: "用户装的 opencli 插件:有新版(给更新 / 卸载)",
|
|
2865
|
+
manifests: [],
|
|
2866
|
+
capabilities: {},
|
|
2867
|
+
plugins: [{
|
|
2868
|
+
pkg: "opencli-plugin-cmdb",
|
|
2869
|
+
name: "cmdb",
|
|
2870
|
+
installed: "1.0.24",
|
|
2871
|
+
latest: "1.0.25"
|
|
2872
|
+
}],
|
|
2873
|
+
expect: {
|
|
2874
|
+
rows: 0,
|
|
2875
|
+
plugins: 1,
|
|
2876
|
+
pluginActions: ["update-plugin", "uninstall-plugin"]
|
|
2877
|
+
}
|
|
2878
|
+
},
|
|
2879
|
+
{
|
|
2880
|
+
id: "plugin-local",
|
|
2881
|
+
label: "本地目录装的 opencli 插件:没有版本源(只给卸载,行上说清为什么)",
|
|
2882
|
+
manifests: [],
|
|
2883
|
+
capabilities: {},
|
|
2884
|
+
plugins: [{
|
|
2885
|
+
pkg: "/Users/me/my-local-plugin",
|
|
2886
|
+
name: "my-local-plugin",
|
|
2887
|
+
local: true
|
|
2888
|
+
}],
|
|
2889
|
+
expect: {
|
|
2890
|
+
rows: 0,
|
|
2891
|
+
plugins: 1,
|
|
2892
|
+
pluginActions: ["uninstall-plugin"],
|
|
2893
|
+
pluginNote: true,
|
|
2894
|
+
pluginNoteKey: "panels.market.pluginLocalNoUpdate"
|
|
2895
|
+
}
|
|
2896
|
+
},
|
|
2897
|
+
{
|
|
2898
|
+
id: "plugin-alias",
|
|
2899
|
+
label: "插件名 ≠ 包名:行上两个都写出来(更新 / 卸载按包名)",
|
|
2900
|
+
manifests: [],
|
|
2901
|
+
capabilities: {},
|
|
2902
|
+
plugins: [{
|
|
2903
|
+
pkg: "opencli-plugin-cmdb",
|
|
2904
|
+
name: "cmdb",
|
|
2905
|
+
installed: "1.0.24",
|
|
2906
|
+
latest: "1.0.25"
|
|
2907
|
+
}],
|
|
2908
|
+
expect: {
|
|
2909
|
+
rows: 0,
|
|
2910
|
+
plugins: 1,
|
|
2911
|
+
pluginActions: ["update-plugin", "uninstall-plugin"],
|
|
2912
|
+
pluginNoteKey: "panels.market.pluginAlsoKnownAs"
|
|
2913
|
+
}
|
|
2914
|
+
},
|
|
2915
|
+
{
|
|
2916
|
+
id: "plugin-broken",
|
|
2917
|
+
label: "装坏了的那一份(目录在但看不出是个插件):行上直说,给卸载与指路",
|
|
2918
|
+
manifests: [],
|
|
2919
|
+
capabilities: {},
|
|
2920
|
+
plugins: [{
|
|
2921
|
+
pkg: "opencli-plugin-cmdb",
|
|
2922
|
+
name: "cmdb",
|
|
2923
|
+
installed: "1.0.24",
|
|
2924
|
+
broken: true
|
|
2925
|
+
}],
|
|
2926
|
+
expect: {
|
|
2927
|
+
rows: 0,
|
|
2928
|
+
plugins: 1,
|
|
2929
|
+
pluginActions: ["uninstall-plugin"],
|
|
2930
|
+
pluginNoteKey: "panels.market.pluginBroken"
|
|
2931
|
+
}
|
|
2932
|
+
},
|
|
2933
|
+
{
|
|
2934
|
+
id: "plugin-kept",
|
|
2935
|
+
label: "卸掉用户装的插件,但还有模块在用:文件先留着(行上给一句为什么)",
|
|
2936
|
+
manifests: [],
|
|
2937
|
+
capabilities: {},
|
|
2938
|
+
plugins: [{
|
|
2939
|
+
pkg: "opencli-plugin-cmdb",
|
|
2940
|
+
name: "cmdb",
|
|
2941
|
+
installed: "1.0.24"
|
|
2942
|
+
}],
|
|
2943
|
+
notice: "文件先留着:cmdb、argocd 还要用它。",
|
|
2944
|
+
expect: {
|
|
2945
|
+
rows: 0,
|
|
2946
|
+
plugins: 1,
|
|
2947
|
+
pluginActions: ["uninstall-plugin"],
|
|
2948
|
+
notice: true
|
|
2949
|
+
}
|
|
2950
|
+
},
|
|
2688
2951
|
{
|
|
2689
2952
|
id: "empty",
|
|
2690
2953
|
label: "市场空态",
|
|
@@ -2742,7 +3005,6 @@ function createBoardRegistry() {
|
|
|
2742
3005
|
};
|
|
2743
3006
|
},
|
|
2744
3007
|
all: () => sorted,
|
|
2745
|
-
visible: () => sorted.filter((module) => module.enabledByDefault),
|
|
2746
3008
|
byId: (id) => index.get(id),
|
|
2747
3009
|
stepOwner: (kind) => steps.get(kind),
|
|
2748
3010
|
subscribe(listener) {
|
|
@@ -2754,20 +3016,21 @@ function createBoardRegistry() {
|
|
|
2754
3016
|
}
|
|
2755
3017
|
//#endregion
|
|
2756
3018
|
//#region src/app/units/registry.ts
|
|
2757
|
-
function toBoardModule(face) {
|
|
3019
|
+
function toBoardModule(face, manifest) {
|
|
2758
3020
|
return {
|
|
2759
|
-
id:
|
|
2760
|
-
titleKey:
|
|
2761
|
-
order:
|
|
2762
|
-
enabledByDefault: face.manifest.card?.enabledByDefault ?? false,
|
|
3021
|
+
id: manifest.id,
|
|
3022
|
+
titleKey: manifest.card?.titleKey ?? manifest.id,
|
|
3023
|
+
order: manifest.card?.order ?? 100,
|
|
2763
3024
|
View: face.card,
|
|
2764
3025
|
...face.steps === void 0 ? {} : { steps: face.steps }
|
|
2765
3026
|
};
|
|
2766
3027
|
}
|
|
2767
|
-
function createClientUnitRegistry() {
|
|
2768
|
-
const
|
|
3028
|
+
function createClientUnitRegistry(options = {}) {
|
|
3029
|
+
const registrations = [];
|
|
3030
|
+
const refusals = [];
|
|
2769
3031
|
const listeners = /* @__PURE__ */ new Set();
|
|
2770
3032
|
const board = createBoardRegistry();
|
|
3033
|
+
let known = /* @__PURE__ */ new Map();
|
|
2771
3034
|
let revision = 0;
|
|
2772
3035
|
let manifestsCache;
|
|
2773
3036
|
function notify() {
|
|
@@ -2778,28 +3041,86 @@ function createClientUnitRegistry() {
|
|
|
2778
3041
|
console.warn(`[dsh-workbench] 套件注册的订阅者报错(不影响其它订阅者与这次注册):${String(error)}`);
|
|
2779
3042
|
}
|
|
2780
3043
|
}
|
|
3044
|
+
function warnRefusal(unit, reasons) {
|
|
3045
|
+
refusals.push({
|
|
3046
|
+
unit,
|
|
3047
|
+
reasons
|
|
3048
|
+
});
|
|
3049
|
+
console.warn(`[dsh-workbench] ${unit === "" ? "这个模块" : unit} 的卡片没挂上:${reasons.join(";")}`);
|
|
3050
|
+
}
|
|
3051
|
+
function takeBackRefusal(unit) {
|
|
3052
|
+
for (let at = refusals.length - 1; at >= 0; at -= 1) if (refusals[at]?.unit === unit) refusals.splice(at, 1);
|
|
3053
|
+
}
|
|
3054
|
+
function attach(entry) {
|
|
3055
|
+
const manifest = known.get(entry.unit);
|
|
3056
|
+
if (manifest === void 0) return false;
|
|
3057
|
+
entry.mounted = {
|
|
3058
|
+
manifest,
|
|
3059
|
+
unmount: board.register(toBoardModule(entry.face, manifest))
|
|
3060
|
+
};
|
|
3061
|
+
takeBackRefusal(entry.unit);
|
|
3062
|
+
return true;
|
|
3063
|
+
}
|
|
3064
|
+
function detach(entry) {
|
|
3065
|
+
entry.mounted?.unmount();
|
|
3066
|
+
entry.mounted = null;
|
|
3067
|
+
}
|
|
2781
3068
|
return {
|
|
2782
3069
|
register(face) {
|
|
2783
|
-
const
|
|
2784
|
-
if (
|
|
2785
|
-
|
|
2786
|
-
|
|
3070
|
+
const unit = typeof face?.unit === "string" ? face.unit.trim() : "";
|
|
3071
|
+
if (unit === "") {
|
|
3072
|
+
warnRefusal("", ["registerUnit({ unit, card }) 里的 unit 是空的 —— U1b 之前的旧形状是 registerUnit({ manifest, card });现在清单由外壳从**已装清单**读出来、按 unit 交给浏览器(ADR-0038 §2.2)"]);
|
|
3073
|
+
notify();
|
|
3074
|
+
return () => {};
|
|
3075
|
+
}
|
|
3076
|
+
if (registrations.some((entry) => entry.unit === unit)) throw new Error(`套件 id 重复:${unit}(id 会进持久化配置,不能撞)`);
|
|
3077
|
+
const entry = {
|
|
3078
|
+
face,
|
|
3079
|
+
unit,
|
|
3080
|
+
mounted: null
|
|
3081
|
+
};
|
|
3082
|
+
registrations.push(entry);
|
|
2787
3083
|
manifestsCache = void 0;
|
|
3084
|
+
if (!attach(entry)) {
|
|
3085
|
+
warnRefusal(unit, [`宿主没有担保 unit「${unit}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]);
|
|
3086
|
+
options.onUnknownUnit?.(unit);
|
|
3087
|
+
}
|
|
2788
3088
|
notify();
|
|
2789
3089
|
return () => {
|
|
2790
|
-
const at =
|
|
3090
|
+
const at = registrations.indexOf(entry);
|
|
2791
3091
|
if (at < 0) return;
|
|
2792
|
-
|
|
3092
|
+
registrations.splice(at, 1);
|
|
3093
|
+
detach(entry);
|
|
3094
|
+
takeBackRefusal(unit);
|
|
2793
3095
|
manifestsCache = void 0;
|
|
2794
|
-
unregisterBoard();
|
|
2795
3096
|
notify();
|
|
2796
3097
|
};
|
|
2797
3098
|
},
|
|
2798
|
-
all: () =>
|
|
3099
|
+
all: () => registrations.map((entry) => entry.face),
|
|
2799
3100
|
manifests: () => {
|
|
2800
|
-
manifestsCache ??=
|
|
3101
|
+
manifestsCache ??= registrations.flatMap((entry) => entry.mounted === null ? [] : [entry.mounted.manifest]);
|
|
2801
3102
|
return manifestsCache;
|
|
2802
3103
|
},
|
|
3104
|
+
refusals: () => refusals,
|
|
3105
|
+
setManifests(manifests) {
|
|
3106
|
+
known = new Map(manifests.map((manifest) => [manifest.id, manifest]));
|
|
3107
|
+
let changed = false;
|
|
3108
|
+
for (const entry of registrations) {
|
|
3109
|
+
const next = known.get(entry.unit);
|
|
3110
|
+
if (entry.mounted === null) {
|
|
3111
|
+
if (next !== void 0 && attach(entry)) changed = true;
|
|
3112
|
+
continue;
|
|
3113
|
+
}
|
|
3114
|
+
if (next === void 0) {
|
|
3115
|
+
detach(entry);
|
|
3116
|
+
warnRefusal(entry.unit, [`宿主不再担保 unit「${entry.unit}」的清单(模块被卸了?)—— 这张卡片先摘下来`]);
|
|
3117
|
+
changed = true;
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3120
|
+
if (!changed) return;
|
|
3121
|
+
manifestsCache = void 0;
|
|
3122
|
+
notify();
|
|
3123
|
+
},
|
|
2803
3124
|
board,
|
|
2804
3125
|
subscribe(listener) {
|
|
2805
3126
|
listeners.add(listener);
|
|
@@ -2834,11 +3155,9 @@ var messages = {
|
|
|
2834
3155
|
};
|
|
2835
3156
|
var manifest = {
|
|
2836
3157
|
id: FIXTURE_UNIT_ID,
|
|
2837
|
-
kind: "board",
|
|
2838
3158
|
card: {
|
|
2839
3159
|
titleKey: KEY.cardTitle,
|
|
2840
|
-
order: 900
|
|
2841
|
-
enabledByDefault: true
|
|
3160
|
+
order: 900
|
|
2842
3161
|
},
|
|
2843
3162
|
tools: [],
|
|
2844
3163
|
host: { inject: [] }
|
|
@@ -2861,6 +3180,7 @@ function FixtureCard({ t, onRefresh }) {
|
|
|
2861
3180
|
}))));
|
|
2862
3181
|
}
|
|
2863
3182
|
var FIXTURE_FACE = {
|
|
3183
|
+
unit: FIXTURE_UNIT_ID,
|
|
2864
3184
|
manifest,
|
|
2865
3185
|
messages,
|
|
2866
3186
|
card: FixtureCard
|
|
@@ -2881,11 +3201,9 @@ var crashMessages = {
|
|
|
2881
3201
|
};
|
|
2882
3202
|
var crashManifest = {
|
|
2883
3203
|
id: CRASH_UNIT_ID,
|
|
2884
|
-
kind: "board",
|
|
2885
3204
|
card: {
|
|
2886
3205
|
titleKey: CRASH_KEY.cardTitle,
|
|
2887
|
-
order: 899
|
|
2888
|
-
enabledByDefault: true
|
|
3206
|
+
order: 899
|
|
2889
3207
|
},
|
|
2890
3208
|
tools: [],
|
|
2891
3209
|
host: { inject: [] }
|
|
@@ -2894,6 +3212,7 @@ function CrashingCard() {
|
|
|
2894
3212
|
throw new Error("夹具:这张卡片按 wbCrash=1 故意渲染失败(守「一张卡片崩溃不带走面板」)");
|
|
2895
3213
|
}
|
|
2896
3214
|
var CRASH_FACE = {
|
|
3215
|
+
unit: CRASH_UNIT_ID,
|
|
2897
3216
|
manifest: crashManifest,
|
|
2898
3217
|
messages: crashMessages,
|
|
2899
3218
|
card: CrashingCard
|
|
@@ -2906,8 +3225,8 @@ function fixtureRoster(roster) {
|
|
|
2906
3225
|
return hasCard(roster) ? roster : SAMPLE_ROSTER;
|
|
2907
3226
|
}
|
|
2908
3227
|
function fixtureSeed(roster, all, crash = false) {
|
|
2909
|
-
const base = hasCard(roster) ? all : [toBoardModule(FIXTURE_FACE)];
|
|
2910
|
-
return crash ? [toBoardModule(CRASH_FACE), ...base] : base;
|
|
3228
|
+
const base = hasCard(roster) ? all : [toBoardModule(FIXTURE_FACE, FIXTURE_FACE.manifest)];
|
|
3229
|
+
return crash ? [toBoardModule(CRASH_FACE, CRASH_FACE.manifest), ...base] : base;
|
|
2911
3230
|
}
|
|
2912
3231
|
//#endregion
|
|
2913
3232
|
//#region src/app/layouts/rightbar/market-rows.ts
|
|
@@ -2927,6 +3246,25 @@ var MARKET_DOT = {
|
|
|
2927
3246
|
unchecked: "idle",
|
|
2928
3247
|
unknown: "idle"
|
|
2929
3248
|
};
|
|
3249
|
+
function marketRowTitle(row, t) {
|
|
3250
|
+
return row.label ?? t(row.titleKey);
|
|
3251
|
+
}
|
|
3252
|
+
function withClientRefusals(modules, refusals) {
|
|
3253
|
+
if (refusals.length === 0) return modules;
|
|
3254
|
+
const byUnit = new Map(refusals.map((one) => [one.unit, one.reasons]));
|
|
3255
|
+
return modules.map((module) => {
|
|
3256
|
+
const reasons = byUnit.get(module.unit);
|
|
3257
|
+
return reasons === void 0 ? module : {
|
|
3258
|
+
...module,
|
|
3259
|
+
clientRefused: reasons
|
|
3260
|
+
};
|
|
3261
|
+
});
|
|
3262
|
+
}
|
|
3263
|
+
function refusalReasons(host, client) {
|
|
3264
|
+
const reported = host ?? [];
|
|
3265
|
+
if (reported.length > 0) return reported;
|
|
3266
|
+
return [...new Set(client ?? [])];
|
|
3267
|
+
}
|
|
2930
3268
|
function mergeTitles(known, manifests) {
|
|
2931
3269
|
let next = null;
|
|
2932
3270
|
for (const manifest of manifests) {
|
|
@@ -2945,11 +3283,16 @@ function installedRows(modules, manifests, listed, known) {
|
|
|
2945
3283
|
const latest = module.latest;
|
|
2946
3284
|
const outdated = latest !== void 0 && latest !== module.installed;
|
|
2947
3285
|
const loaded = titles.has(module.unit);
|
|
3286
|
+
const refused = refusalReasons(module.refused, module.clientRefused);
|
|
2948
3287
|
rows.push({
|
|
2949
3288
|
id: module.unit,
|
|
2950
3289
|
titleKey: titles.get(module.unit) ?? known?.get(module.unit) ?? module.pkg,
|
|
2951
3290
|
state: outdated ? "outdated" : "installed",
|
|
2952
|
-
...loaded ? {} : { hint: "panels.market.moduleRestartHint" },
|
|
3291
|
+
...loaded || refused.length > 0 ? {} : { hint: "panels.market.moduleRestartHint" },
|
|
3292
|
+
...refused.length === 0 ? {} : { note: {
|
|
3293
|
+
key: "panels.market.moduleRefused",
|
|
3294
|
+
params: { reason: refused.join(";") }
|
|
3295
|
+
} },
|
|
2953
3296
|
...module.local === true ? { local: true } : {},
|
|
2954
3297
|
pkg: module.pkg,
|
|
2955
3298
|
canInstall: false,
|
|
@@ -2968,6 +3311,7 @@ function installedRows(modules, manifests, listed, known) {
|
|
|
2968
3311
|
return rows;
|
|
2969
3312
|
}
|
|
2970
3313
|
function marketActions$1(row) {
|
|
3314
|
+
if (row.plugin === true) return [...row.canUpdate ? ["update-plugin"] : [], ...row.canUninstall ? ["uninstall-plugin"] : []];
|
|
2971
3315
|
return [
|
|
2972
3316
|
...row.canInstall ? ["install"] : [],
|
|
2973
3317
|
...row.moduleUpdate === void 0 ? row.canUpdate ? ["update"] : [] : ["update-bundle"],
|
|
@@ -2991,7 +3335,7 @@ function envNameOf(source) {
|
|
|
2991
3335
|
if (source.kind === "npm") return source.registryEnv;
|
|
2992
3336
|
return "";
|
|
2993
3337
|
}
|
|
2994
|
-
function noteOf(state, install, manifest) {
|
|
3338
|
+
function noteOf$1(state, install, manifest) {
|
|
2995
3339
|
if (state === "installed") return void 0;
|
|
2996
3340
|
if (install === "env-missing") return {
|
|
2997
3341
|
key: "panels.market.needEnv",
|
|
@@ -3050,7 +3394,7 @@ function marketRows(manifests, capabilities, updates = {}) {
|
|
|
3050
3394
|
const capability = capabilities?.[manifest.id];
|
|
3051
3395
|
const install = capability?.install;
|
|
3052
3396
|
const state = capabilities === null ? "checking" : stateOf(capability);
|
|
3053
|
-
const note = noteOf(state, install, manifest);
|
|
3397
|
+
const note = noteOf$1(state, install, manifest);
|
|
3054
3398
|
const onMachine = isOnMachine(state);
|
|
3055
3399
|
const reAdopt = capability?.released === true && install === void 0;
|
|
3056
3400
|
const entry = updates[manifest.id];
|
|
@@ -3222,6 +3566,63 @@ function useHostWrite(options) {
|
|
|
3222
3566
|
};
|
|
3223
3567
|
}
|
|
3224
3568
|
//#endregion
|
|
3569
|
+
//#region src/app/layouts/rightbar/market-plugin-rows.ts
|
|
3570
|
+
function installedPluginKept(value) {
|
|
3571
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
3572
|
+
const kept = value.kept;
|
|
3573
|
+
if (typeof kept !== "object" || kept === null) return void 0;
|
|
3574
|
+
const kind = kept.kind;
|
|
3575
|
+
if (kind === "held") return { key: "panels.market.pluginKeptHeld" };
|
|
3576
|
+
if (kind === "unnamed") return { key: "panels.market.pluginKeptUnnamed" };
|
|
3577
|
+
if (kind === "unsure") return { key: "panels.market.pluginKeptUnsure" };
|
|
3578
|
+
if (kind !== "claimed") return void 0;
|
|
3579
|
+
const raw = kept.by;
|
|
3580
|
+
const names = Array.isArray(raw) ? raw.filter((item) => typeof item === "string") : [];
|
|
3581
|
+
return names.length === 0 ? { key: "panels.market.pluginKeptUnsure" } : {
|
|
3582
|
+
key: "panels.market.pluginKeptInUse",
|
|
3583
|
+
names
|
|
3584
|
+
};
|
|
3585
|
+
}
|
|
3586
|
+
function noteOf(plugin) {
|
|
3587
|
+
if (plugin.broken === true) return {
|
|
3588
|
+
key: "panels.market.pluginBroken",
|
|
3589
|
+
params: {}
|
|
3590
|
+
};
|
|
3591
|
+
if (plugin.local === true) return {
|
|
3592
|
+
key: "panels.market.pluginLocalNoUpdate",
|
|
3593
|
+
params: {}
|
|
3594
|
+
};
|
|
3595
|
+
if (plugin.name !== void 0 && plugin.name !== plugin.pkg) return {
|
|
3596
|
+
key: "panels.market.pluginAlsoKnownAs",
|
|
3597
|
+
params: { pkg: plugin.pkg }
|
|
3598
|
+
};
|
|
3599
|
+
}
|
|
3600
|
+
function installedPluginRows(plugins) {
|
|
3601
|
+
return plugins.map((plugin) => {
|
|
3602
|
+
const name = plugin.name ?? plugin.pkg;
|
|
3603
|
+
const outdated = plugin.installed !== void 0 && plugin.latest !== void 0 && plugin.latest !== plugin.installed;
|
|
3604
|
+
const note = noteOf(plugin);
|
|
3605
|
+
return {
|
|
3606
|
+
id: `plugin:${plugin.pkg}`,
|
|
3607
|
+
titleKey: plugin.pkg,
|
|
3608
|
+
label: name,
|
|
3609
|
+
plugin: true,
|
|
3610
|
+
state: outdated ? "outdated" : "installed",
|
|
3611
|
+
canInstall: false,
|
|
3612
|
+
canUpdate: outdated,
|
|
3613
|
+
canUninstall: true,
|
|
3614
|
+
...plugin.local === true ? { local: true } : {},
|
|
3615
|
+
...plugin.broken === true ? { broken: true } : {},
|
|
3616
|
+
...note === void 0 ? {} : { note },
|
|
3617
|
+
pkg: plugin.pkg,
|
|
3618
|
+
...plugin.installed === void 0 ? {} : { version: {
|
|
3619
|
+
installed: plugin.installed,
|
|
3620
|
+
...plugin.latest === void 0 ? {} : { latest: plugin.latest }
|
|
3621
|
+
} }
|
|
3622
|
+
};
|
|
3623
|
+
});
|
|
3624
|
+
}
|
|
3625
|
+
//#endregion
|
|
3225
3626
|
//#region src/app/layouts/market/add-module-text.ts
|
|
3226
3627
|
var GUIDE_ITEMS = [
|
|
3227
3628
|
{
|
|
@@ -3340,17 +3741,23 @@ var PROBLEM_KEYS = {
|
|
|
3340
3741
|
"not-found": "panels.market.add.problemNotFound",
|
|
3341
3742
|
"not-a-package": "panels.market.add.problemNotPackage",
|
|
3342
3743
|
"not-a-bundle": "panels.market.add.problemNotBundle",
|
|
3744
|
+
"not-a-workbench-module": "panels.market.add.problemNotWorkbenchModule",
|
|
3745
|
+
"not-a-module-or-plugin": "panels.market.add.problemNotModuleOrPlugin",
|
|
3343
3746
|
network: "panels.market.add.problemNetwork",
|
|
3344
3747
|
unknown: "panels.market.add.problemUnknown"
|
|
3345
3748
|
};
|
|
3346
3749
|
function problemKey(problem) {
|
|
3347
3750
|
return PROBLEM_KEYS[problem] ?? PROBLEM_KEYS.unknown;
|
|
3348
3751
|
}
|
|
3752
|
+
function heldWizardPhase(phase, classifying) {
|
|
3753
|
+
return classifying && (phase === "preview" || phase === "idle") ? "inspecting" : phase;
|
|
3754
|
+
}
|
|
3349
3755
|
var FAILURE_KEYS = {
|
|
3350
3756
|
network: "panels.market.add.failureNetwork",
|
|
3351
3757
|
"spec-host": "panels.market.add.failureNetworkHost",
|
|
3352
3758
|
"not-found": "panels.market.add.failureNotFound",
|
|
3353
3759
|
"no-matching-version": "panels.market.add.failureNoMatchingVersion",
|
|
3760
|
+
"not-a-module-or-plugin": "panels.market.add.failureNotModuleOrPlugin",
|
|
3354
3761
|
"disk-full": "panels.market.add.failureDiskFull",
|
|
3355
3762
|
permission: "panels.market.add.failurePermission",
|
|
3356
3763
|
"build-blocked": "panels.market.add.failureBuildBlocked",
|
|
@@ -3447,6 +3854,16 @@ function MarketChecking({ t }) {
|
|
|
3447
3854
|
function MarketEmpty({ t }) {
|
|
3448
3855
|
return /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmpty }, /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketEmptyTitle }, t("panels.market.empty")));
|
|
3449
3856
|
}
|
|
3857
|
+
var PanelFoot_module_default = {
|
|
3858
|
+
foot: "_foot_1us83_1",
|
|
3859
|
+
footText: "_footText_1us83_12",
|
|
3860
|
+
footTextMd: "_footTextMd_1us83_17"
|
|
3861
|
+
};
|
|
3862
|
+
//#endregion
|
|
3863
|
+
//#region src/shared/components/PanelFoot.tsx
|
|
3864
|
+
function PanelFoot({ text, size = "sm", children }) {
|
|
3865
|
+
return /* @__PURE__ */ h("footer", { className: PanelFoot_module_default.foot }, /* @__PURE__ */ h("span", { className: size === "md" ? PanelFoot_module_default.footTextMd : PanelFoot_module_default.footText }, text), children ?? null);
|
|
3866
|
+
}
|
|
3450
3867
|
//#endregion
|
|
3451
3868
|
//#region src/app/layouts/rightbar/market-view-text.ts
|
|
3452
3869
|
var PROGRESS_KEY = {
|
|
@@ -3455,7 +3872,9 @@ var PROGRESS_KEY = {
|
|
|
3455
3872
|
"update-bundle": "panels.market.updating",
|
|
3456
3873
|
"remove-bundle": "panels.market.uninstalling",
|
|
3457
3874
|
uninstall: "panels.market.uninstalling",
|
|
3458
|
-
"update-dependency": "panels.market.updating"
|
|
3875
|
+
"update-dependency": "panels.market.updating",
|
|
3876
|
+
"update-plugin": "panels.market.updating",
|
|
3877
|
+
"uninstall-plugin": "panels.market.uninstalling"
|
|
3459
3878
|
};
|
|
3460
3879
|
var ACTION_LABEL_KEY = {
|
|
3461
3880
|
install: "panels.market.install",
|
|
@@ -3463,7 +3882,9 @@ var ACTION_LABEL_KEY = {
|
|
|
3463
3882
|
"update-bundle": "panels.market.update",
|
|
3464
3883
|
"remove-bundle": "panels.market.uninstall",
|
|
3465
3884
|
uninstall: "panels.market.uninstall",
|
|
3466
|
-
"update-dependency": "panels.market.update"
|
|
3885
|
+
"update-dependency": "panels.market.update",
|
|
3886
|
+
"update-plugin": "panels.market.update",
|
|
3887
|
+
"uninstall-plugin": "panels.market.uninstall"
|
|
3467
3888
|
};
|
|
3468
3889
|
//#endregion
|
|
3469
3890
|
//#region src/app/layouts/rightbar/SharedSection.tsx
|
|
@@ -3511,21 +3932,18 @@ function SharedSection({ t, rows, pending, failureOf, act }) {
|
|
|
3511
3932
|
pending,
|
|
3512
3933
|
failure: failureOf(row.id),
|
|
3513
3934
|
onAct: (action) => void act(row.id, action)
|
|
3514
|
-
})))
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
footText: "_footText_1us83_12",
|
|
3519
|
-
footTextMd: "_footTextMd_1us83_17"
|
|
3520
|
-
};
|
|
3521
|
-
//#endregion
|
|
3522
|
-
//#region src/shared/components/PanelFoot.tsx
|
|
3523
|
-
function PanelFoot({ text, size = "sm", children }) {
|
|
3524
|
-
return /* @__PURE__ */ h("footer", { className: PanelFoot_module_default.foot }, /* @__PURE__ */ h("span", { className: size === "md" ? PanelFoot_module_default.footTextMd : PanelFoot_module_default.footText }, text), children ?? null);
|
|
3935
|
+
}))), /* @__PURE__ */ h(PanelFoot, {
|
|
3936
|
+
size: "md",
|
|
3937
|
+
text: t("panels.market.sharedFoot")
|
|
3938
|
+
}));
|
|
3525
3939
|
}
|
|
3526
3940
|
//#endregion
|
|
3527
3941
|
//#region src/app/layouts/rightbar/MarketView.tsx
|
|
3528
|
-
var CONFIRM_UNINSTALL = [
|
|
3942
|
+
var CONFIRM_UNINSTALL = [
|
|
3943
|
+
"uninstall",
|
|
3944
|
+
"remove-bundle",
|
|
3945
|
+
"uninstall-plugin"
|
|
3946
|
+
];
|
|
3529
3947
|
var CONFIRM_REMOVE = ["remove-bundle"];
|
|
3530
3948
|
function MarketLine({ t, row, pending, failure, onAct }) {
|
|
3531
3949
|
const running = pending !== null && pending.id === row.id ? pending : null;
|
|
@@ -3535,7 +3953,7 @@ function MarketLine({ t, row, pending, failure, onAct }) {
|
|
|
3535
3953
|
return /* @__PURE__ */ h("li", { className: MarketPage_module_default.marketRow }, /* @__PURE__ */ h("span", {
|
|
3536
3954
|
className: MarketPage_module_default.marketIcon,
|
|
3537
3955
|
"aria-hidden": "true"
|
|
3538
|
-
}, /* @__PURE__ */ h(IconModules, { size: 18 })), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketMain }, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketName },
|
|
3956
|
+
}, /* @__PURE__ */ h(IconModules, { size: 18 })), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketMain }, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketName }, marketRowTitle(row, t), row.version === void 0 ? null : /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketVersion }, row.version.installed !== void 0 && row.version.latest !== void 0 && row.version.installed !== row.version.latest ? t("panels.market.versionArrow", {
|
|
3539
3957
|
from: row.version.installed,
|
|
3540
3958
|
to: row.version.latest
|
|
3541
3959
|
}) : row.version.installed ?? row.version.latest ?? "")), /* @__PURE__ */ h("span", {
|
|
@@ -3560,11 +3978,14 @@ function MarketLine({ t, row, pending, failure, onAct }) {
|
|
|
3560
3978
|
variant: action === "install" ? "primary" : "outline",
|
|
3561
3979
|
className: danger ? "wb-dangerAction" : void 0,
|
|
3562
3980
|
icon: danger ? /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutlineRegular, { size: 13 }) : void 0,
|
|
3563
|
-
"aria-label": danger ? t("panels.market.uninstallLabel", { name:
|
|
3981
|
+
"aria-label": danger ? t("panels.market.uninstallLabel", { name: marketRowTitle(row, t) }) : void 0,
|
|
3564
3982
|
disabled: locked,
|
|
3565
3983
|
onClick: () => onAct(action)
|
|
3566
3984
|
}, t(ACTION_LABEL_KEY[action]));
|
|
3567
|
-
}))), row.note === void 0 ? null : /* @__PURE__ */ h("div", {
|
|
3985
|
+
}))), row.note === void 0 ? null : /* @__PURE__ */ h("div", {
|
|
3986
|
+
className: MarketPage_module_default.marketNote,
|
|
3987
|
+
title: row.note.params.reason === void 0 ? void 0 : t("panels.market.moduleRefusedDetail", row.note.params)
|
|
3988
|
+
}, t(row.note.key, row.note.params)), failure === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketFailure }, failure));
|
|
3568
3989
|
}
|
|
3569
3990
|
function ConfirmUninstall({ t, name, onConfirm, onCancel }) {
|
|
3570
3991
|
const [acknowledged, setAcknowledged] = useState(false);
|
|
@@ -3593,7 +4014,48 @@ function MarketSection({ t, titleKey, rows, pending, failureOf, act, confirmActi
|
|
|
3593
4014
|
onAct: (action) => confirmActions.includes(action) ? onConfirming(row.id) : void act(row.id, action)
|
|
3594
4015
|
}))));
|
|
3595
4016
|
}
|
|
3596
|
-
function
|
|
4017
|
+
function MarketBody({ t, shown, pluginList, installedList, shared, pending, failed, notice, act, onConfirming }) {
|
|
4018
|
+
const failureOf = (id) => failed?.id === id ? failed.message : null;
|
|
4019
|
+
return /* @__PURE__ */ h(Fragment, null, notice === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketNote }, notice), marketSections(shown).map((section) => /* @__PURE__ */ h(MarketSection, {
|
|
4020
|
+
key: section.id,
|
|
4021
|
+
t,
|
|
4022
|
+
titleKey: section.titleKey,
|
|
4023
|
+
rows: section.rows,
|
|
4024
|
+
pending,
|
|
4025
|
+
failureOf,
|
|
4026
|
+
act,
|
|
4027
|
+
confirmActions: CONFIRM_UNINSTALL,
|
|
4028
|
+
onConfirming
|
|
4029
|
+
})), /* @__PURE__ */ h(MarketSection, {
|
|
4030
|
+
t,
|
|
4031
|
+
titleKey: "panels.market.sectionPlugins",
|
|
4032
|
+
rows: pluginList,
|
|
4033
|
+
pending,
|
|
4034
|
+
failureOf,
|
|
4035
|
+
act,
|
|
4036
|
+
confirmActions: CONFIRM_UNINSTALL,
|
|
4037
|
+
onConfirming
|
|
4038
|
+
}), /* @__PURE__ */ h(MarketSection, {
|
|
4039
|
+
t,
|
|
4040
|
+
titleKey: installedList.length > 0 && installedList.every((row) => row.local === true) ? "panels.market.sectionLocal" : "panels.market.sectionUnlisted",
|
|
4041
|
+
rows: installedList,
|
|
4042
|
+
pending,
|
|
4043
|
+
failureOf,
|
|
4044
|
+
act,
|
|
4045
|
+
confirmActions: CONFIRM_REMOVE,
|
|
4046
|
+
onConfirming
|
|
4047
|
+
}), /* @__PURE__ */ h(PanelFoot, {
|
|
4048
|
+
size: "md",
|
|
4049
|
+
text: t("panels.market.foot")
|
|
4050
|
+
}), /* @__PURE__ */ h(SharedSection, {
|
|
4051
|
+
t,
|
|
4052
|
+
rows: shared,
|
|
4053
|
+
pending,
|
|
4054
|
+
failureOf,
|
|
4055
|
+
act
|
|
4056
|
+
}));
|
|
4057
|
+
}
|
|
4058
|
+
function MarketView({ t, manifests, capabilities, freshness, onChanged, updates, installed, installedRead, plugins, settling, mock }) {
|
|
3597
4059
|
const [titles, setTitles] = useState(/* @__PURE__ */ new Map());
|
|
3598
4060
|
useEffect(() => {
|
|
3599
4061
|
if (mock === void 0) setTitles((known) => mergeTitles(known, manifests));
|
|
@@ -3610,6 +4072,7 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3610
4072
|
});
|
|
3611
4073
|
const [confirming, setConfirming] = useState(mock?.confirming ?? null);
|
|
3612
4074
|
const [failed, setFailed] = useState(mock?.failure ?? null);
|
|
4075
|
+
const [notice, setNotice] = useState(mock?.notice ?? null);
|
|
3613
4076
|
const removing = pending !== null && pending.action === "remove-bundle" && failed?.id !== pending.id ? pending.id : null;
|
|
3614
4077
|
const installedList = installedRows((mock?.installed ?? installed ?? []).filter((module) => !(settling?.has(module.unit) ?? false) && module.unit !== removing), catalog, new Set(rows.map((row) => row.id)), titles);
|
|
3615
4078
|
const pendingRow = removing === null || pending === null || rows.some((row) => row.id === removing) ? void 0 : {
|
|
@@ -3623,7 +4086,12 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3623
4086
|
...pending.version === void 0 ? {} : { version: { installed: pending.version } }
|
|
3624
4087
|
};
|
|
3625
4088
|
const shown = pendingRow === void 0 ? rows : [...rows, pendingRow];
|
|
3626
|
-
const
|
|
4089
|
+
const pluginList = installedPluginRows(mock?.plugins ?? plugins ?? []);
|
|
4090
|
+
const rowById = new Map([
|
|
4091
|
+
...shown,
|
|
4092
|
+
...installedList,
|
|
4093
|
+
...pluginList
|
|
4094
|
+
].map((row) => [row.id, row]));
|
|
3627
4095
|
const confirmingRow = confirming === null ? void 0 : rowById.get(confirming);
|
|
3628
4096
|
const act = async (id, action) => {
|
|
3629
4097
|
if (mock !== void 0) return;
|
|
@@ -3637,13 +4105,15 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3637
4105
|
});
|
|
3638
4106
|
setConfirming(null);
|
|
3639
4107
|
setFailed(null);
|
|
4108
|
+
if (action !== "uninstall-plugin") setNotice(null);
|
|
3640
4109
|
const dependency = action === "update-dependency";
|
|
4110
|
+
const byName = action === "remove-bundle" || action === "update-plugin" || action === "uninstall-plugin";
|
|
3641
4111
|
const outcome = await provision.send(dependency ? {
|
|
3642
4112
|
action,
|
|
3643
4113
|
id
|
|
3644
|
-
} :
|
|
4114
|
+
} : byName ? {
|
|
3645
4115
|
action,
|
|
3646
|
-
name:
|
|
4116
|
+
name: row?.pkg ?? ""
|
|
3647
4117
|
} : {
|
|
3648
4118
|
action,
|
|
3649
4119
|
unit: id
|
|
@@ -3657,6 +4127,10 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3657
4127
|
});
|
|
3658
4128
|
return;
|
|
3659
4129
|
}
|
|
4130
|
+
if (action === "uninstall-plugin") {
|
|
4131
|
+
const kept = installedPluginKept(outcome.value);
|
|
4132
|
+
setNotice(kept === void 0 ? null : t(kept.key, kept.names === void 0 ? {} : { names: kept.names.join(t("panels.market.listSeparator")) }));
|
|
4133
|
+
}
|
|
3660
4134
|
const reason = changeFailure(changeOf(outcome.value), t);
|
|
3661
4135
|
onChanged();
|
|
3662
4136
|
if (reason !== void 0) setFailed({
|
|
@@ -3664,46 +4138,32 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3664
4138
|
message: t("panels.market.failed", { reason })
|
|
3665
4139
|
});
|
|
3666
4140
|
};
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
titleKey: section.titleKey,
|
|
3673
|
-
rows: section.rows,
|
|
3674
|
-
pending,
|
|
3675
|
-
failureOf: (id) => failed?.id === id ? failed.message : null,
|
|
3676
|
-
act,
|
|
3677
|
-
confirmActions: CONFIRM_UNINSTALL,
|
|
3678
|
-
onConfirming: setConfirming
|
|
3679
|
-
})), /* @__PURE__ */ h(MarketSection, {
|
|
4141
|
+
const settled = freshness.loaded && installedRead !== false;
|
|
4142
|
+
const nothing = shown.length === 0 && installedList.length === 0 && pluginList.length === 0;
|
|
4143
|
+
if (!settled || (settling?.size ?? 0) > 0 && shown.length === 0 && installedList.length === 0) return /* @__PURE__ */ h(MarketChecking, { t });
|
|
4144
|
+
if (nothing) return /* @__PURE__ */ h(MarketEmpty, { t });
|
|
4145
|
+
return /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h(MarketBody, {
|
|
3680
4146
|
t,
|
|
3681
|
-
|
|
3682
|
-
|
|
4147
|
+
shown,
|
|
4148
|
+
pluginList,
|
|
4149
|
+
installedList,
|
|
4150
|
+
shared,
|
|
3683
4151
|
pending,
|
|
3684
|
-
|
|
4152
|
+
failed,
|
|
4153
|
+
notice,
|
|
3685
4154
|
act,
|
|
3686
|
-
confirmActions: CONFIRM_REMOVE,
|
|
3687
4155
|
onConfirming: setConfirming
|
|
3688
|
-
}), /* @__PURE__ */ h(PanelFoot, {
|
|
3689
|
-
size: "md",
|
|
3690
|
-
text: t("panels.market.foot")
|
|
3691
|
-
}), /* @__PURE__ */ h(SharedSection, {
|
|
3692
|
-
t,
|
|
3693
|
-
rows: shared,
|
|
3694
|
-
pending,
|
|
3695
|
-
failureOf: (id) => failed?.id === id ? failed.message : null,
|
|
3696
|
-
act
|
|
3697
4156
|
}), /* @__PURE__ */ h(ConfirmUninstall, {
|
|
3698
4157
|
key: confirming ?? "",
|
|
3699
4158
|
t,
|
|
3700
|
-
name: confirmingRow === void 0 ? null :
|
|
4159
|
+
name: confirmingRow === void 0 ? null : marketRowTitle(confirmingRow, t),
|
|
3701
4160
|
onCancel: () => setConfirming(null),
|
|
3702
4161
|
onConfirm: () => {
|
|
3703
4162
|
const id = confirming;
|
|
3704
4163
|
setConfirming(null);
|
|
3705
4164
|
if (id === null) return;
|
|
3706
|
-
|
|
4165
|
+
const row = rowById.get(id);
|
|
4166
|
+
act(id, row?.plugin === true ? "uninstall-plugin" : row?.pkg === void 0 ? "uninstall" : "remove-bundle");
|
|
3707
4167
|
}
|
|
3708
4168
|
}));
|
|
3709
4169
|
}
|
|
@@ -3713,6 +4173,9 @@ var BUNDLE_REGISTRIES_ROUTE = "bundle-registries";
|
|
|
3713
4173
|
var BUNDLE_INSPECT_ROUTE = "bundle-inspect";
|
|
3714
4174
|
var MODULE_VERSIONS_ROUTE = "module-versions";
|
|
3715
4175
|
//#endregion
|
|
4176
|
+
//#region src/shared/api/installed-plugins.ts
|
|
4177
|
+
var INSTALLED_PLUGINS_ROUTE = "panels/plugins";
|
|
4178
|
+
//#endregion
|
|
3716
4179
|
//#region src/shared/hooks/bundle-queries.ts
|
|
3717
4180
|
function readBundleRegistries() {
|
|
3718
4181
|
return apiGet(BUNDLE_REGISTRIES_ROUTE);
|
|
@@ -3726,10 +4189,14 @@ function readBundleInspection(spec, registry) {
|
|
|
3726
4189
|
function readModuleVersions(force = false) {
|
|
3727
4190
|
return apiGet(MODULE_VERSIONS_ROUTE, force ? { force: "1" } : void 0);
|
|
3728
4191
|
}
|
|
4192
|
+
function readInstalledPlugins(force = false) {
|
|
4193
|
+
return apiGet(INSTALLED_PLUGINS_ROUTE, force ? { force: "1" } : void 0);
|
|
4194
|
+
}
|
|
3729
4195
|
//#endregion
|
|
3730
4196
|
//#region src/app/layouts/market/use-module-versions.ts
|
|
3731
4197
|
var state = {
|
|
3732
4198
|
modules: null,
|
|
4199
|
+
plugins: null,
|
|
3733
4200
|
read: false,
|
|
3734
4201
|
checkedAt: null
|
|
3735
4202
|
};
|
|
@@ -3754,10 +4221,13 @@ function runModuleVersionsRead(force = false) {
|
|
|
3754
4221
|
if (inFlight !== null && inFlight.force === force) return inFlight.promise;
|
|
3755
4222
|
const seq = readSeq += 1;
|
|
3756
4223
|
if (force) newestForceSeq = seq;
|
|
3757
|
-
const promise = readModuleVersions(force).catch(() => null).then((
|
|
4224
|
+
const promise = Promise.all([readModuleVersions(force), readInstalledPlugins(force)]).catch(() => null).then((responses) => {
|
|
3758
4225
|
if (!force && seq < newestForceSeq) return;
|
|
4226
|
+
const versions = responses?.[0];
|
|
4227
|
+
const plugins = responses?.[1];
|
|
3759
4228
|
publish({
|
|
3760
|
-
modules:
|
|
4229
|
+
modules: versions?.ok === true ? versions.modules : state.modules,
|
|
4230
|
+
plugins: plugins?.ok === true ? plugins.plugins : state.plugins,
|
|
3761
4231
|
read: true,
|
|
3762
4232
|
checkedAt: Date.now()
|
|
3763
4233
|
});
|
|
@@ -3789,6 +4259,7 @@ function useModuleVersions() {
|
|
|
3789
4259
|
}, []);
|
|
3790
4260
|
return {
|
|
3791
4261
|
modules: value.modules,
|
|
4262
|
+
plugins: value.plugins,
|
|
3792
4263
|
read: value.read,
|
|
3793
4264
|
checkedAt: value.checkedAt,
|
|
3794
4265
|
reload
|
|
@@ -4007,7 +4478,7 @@ function AddModulePending({ t, kind }) {
|
|
|
4007
4478
|
})), /* @__PURE__ */ h("h2", {
|
|
4008
4479
|
className: AddModule_module_default.pendingTitle,
|
|
4009
4480
|
role: "status"
|
|
4010
|
-
}, kind === "inspecting" ? t("panels.market.add.
|
|
4481
|
+
}, kind === "inspecting" ? t("panels.market.add.classifying") : t("panels.market.add.installingTitle"))));
|
|
4011
4482
|
}
|
|
4012
4483
|
function AddModulePreview({ t, state }) {
|
|
4013
4484
|
const preview = state.preview;
|
|
@@ -4025,6 +4496,7 @@ function AddModuleResult({ t, state }) {
|
|
|
4025
4496
|
const restart = outcome.change.application === "restart-required";
|
|
4026
4497
|
const cancelled = outcome.change.application === "cancelled";
|
|
4027
4498
|
const notModule = outcome.supply.state === "not-a-module";
|
|
4499
|
+
const plugin = outcome.plugin;
|
|
4028
4500
|
const name = outcome.module.kind === "module" ? outcome.module.unit : outcome.module.pkg;
|
|
4029
4501
|
return /* @__PURE__ */ h("div", { className: AddModule_module_default.body }, /* @__PURE__ */ h("div", { className: AddModule_module_default.hero }, /* @__PURE__ */ h("span", {
|
|
4030
4502
|
className: AddModule_module_default.heroIcon,
|
|
@@ -4036,7 +4508,7 @@ function AddModuleResult({ t, state }) {
|
|
|
4036
4508
|
}) : /* @__PURE__ */ h(_deepseek_ai_dsh_client_ui_primitives.IconCheckCircleFillRegular, { size: 28 })), /* @__PURE__ */ h("h2", {
|
|
4037
4509
|
className: AddModule_module_default.wizardTitle,
|
|
4038
4510
|
role: failed ? "alert" : "status"
|
|
4039
|
-
}, failed ? t("panels.market.add.failedTitle") : cancelled ? t("panels.market.add.cancelledTitle") : t("panels.market.add.installedTitle"))), /* @__PURE__ */ h("div", { className: AddModule_module_default.subject }, /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectName }, outcome.module.pkg), name === outcome.module.pkg ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, name), outcome.module.version === void 0 ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, t("panels.market.add.installVersion", { version: outcome.module.version }))), failed ? /* @__PURE__ */ h("p", {
|
|
4511
|
+
}, failed ? t("panels.market.add.failedTitle") : cancelled ? t("panels.market.add.cancelledTitle") : t("panels.market.add.installedTitle"))), /* @__PURE__ */ h("div", { className: AddModule_module_default.subject }, /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectName }, outcome.module.pkg), name === outcome.module.pkg ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, name), outcome.module.version === void 0 ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.subjectMeta }, t("panels.market.add.installVersion", { version: outcome.module.version }))), plugin !== void 0 ? /* @__PURE__ */ h("p", { className: AddModule_module_default.result }, t("panels.market.add.installedPlugin", { name: plugin.name ?? plugin.pkg })) : failed ? /* @__PURE__ */ h("p", {
|
|
4040
4512
|
className: AddModule_module_default.resultWarn,
|
|
4041
4513
|
role: "alert"
|
|
4042
4514
|
}, t("panels.market.add.failed", { reason })) : restart ? /* @__PURE__ */ h("p", { className: AddModule_module_default.resultWarn }, t("panels.market.add.doneRestart")) : cancelled || notModule ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.result }, t("panels.market.add.tookEffect")), builds.length === 0 ? null : /* @__PURE__ */ h("div", { className: AddModule_module_default.approval }, /* @__PURE__ */ h("p", { className: AddModule_module_default.approvalTitle }, t("panels.market.add.approveTitle")), /* @__PURE__ */ h("p", { className: AddModule_module_default.approvalText }, t("panels.market.add.approveHint", { packages: builds.join("、") })), /* @__PURE__ */ h("p", { className: AddModule_module_default.approvalCaution }, t("panels.market.add.approveCaution"))), supply === void 0 || outcome.supply.state !== "failed" && (failed || cancelled) ? null : /* @__PURE__ */ h("p", { className: supplyTone(outcome.supply.state) }, t(supply, { reason: outcome.supply.reason ?? "" })), state.failure === null ? null : /* @__PURE__ */ h("p", { className: AddModule_module_default.problem }, state.failure), outcome.change.errorDetail === void 0 ? null : /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h("p", { className: AddModule_module_default.detailLabel }, t("panels.market.add.details")), /* @__PURE__ */ h("p", { className: AddModule_module_default.detail }, outcome.change.errorDetail)));
|
|
@@ -4107,6 +4579,7 @@ var ADD_MODULE_MOCKS = [
|
|
|
4107
4579
|
refused("not-found"),
|
|
4108
4580
|
refused("not-a-package"),
|
|
4109
4581
|
refused("not-a-bundle"),
|
|
4582
|
+
refused("not-a-module-or-plugin", "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上"),
|
|
4110
4583
|
refused("network", "getaddrinfo ENOTFOUND registry.example.com"),
|
|
4111
4584
|
refused("unknown", "pnpm 的返回码是 1"),
|
|
4112
4585
|
{
|
|
@@ -4188,6 +4661,25 @@ var ADD_MODULE_MOCKS = [
|
|
|
4188
4661
|
spec: "@dsh-workbench/module-hello",
|
|
4189
4662
|
outcome: outcome({})
|
|
4190
4663
|
},
|
|
4664
|
+
{
|
|
4665
|
+
id: "done-plugin",
|
|
4666
|
+
label: "装好了(opencli 插件)",
|
|
4667
|
+
phase: "result",
|
|
4668
|
+
spec: "opencli-plugin-cmdb",
|
|
4669
|
+
outcome: {
|
|
4670
|
+
change: change({ target: "opencli-plugin-cmdb" }),
|
|
4671
|
+
module: {
|
|
4672
|
+
kind: "unknown",
|
|
4673
|
+
pkg: "opencli-plugin-cmdb"
|
|
4674
|
+
},
|
|
4675
|
+
supply: { state: "no-needs" },
|
|
4676
|
+
plugin: {
|
|
4677
|
+
kind: "opencli-plugin",
|
|
4678
|
+
pkg: "opencli-plugin-cmdb",
|
|
4679
|
+
name: "cmdb"
|
|
4680
|
+
}
|
|
4681
|
+
}
|
|
4682
|
+
},
|
|
4191
4683
|
{
|
|
4192
4684
|
id: "done-restart",
|
|
4193
4685
|
label: "装好了(要重启)",
|
|
@@ -4282,6 +4774,42 @@ function stateOfMock(base, mock) {
|
|
|
4282
4774
|
};
|
|
4283
4775
|
}
|
|
4284
4776
|
//#endregion
|
|
4777
|
+
//#region src/shared/hooks/use-visible-busy.ts
|
|
4778
|
+
var use_visible_busy_exports = /* @__PURE__ */ __exportAll({
|
|
4779
|
+
busyView: () => busyView,
|
|
4780
|
+
heldPhase: () => heldPhase,
|
|
4781
|
+
useVisibleBusy: () => useVisibleBusy
|
|
4782
|
+
});
|
|
4783
|
+
function heldPhase(phase, refreshing) {
|
|
4784
|
+
return refreshing && phase === "ready" ? "loading" : phase;
|
|
4785
|
+
}
|
|
4786
|
+
function busyView(active, visible) {
|
|
4787
|
+
return {
|
|
4788
|
+
busy: visible,
|
|
4789
|
+
settling: visible && !active
|
|
4790
|
+
};
|
|
4791
|
+
}
|
|
4792
|
+
function useVisibleBusy(active, floorMs) {
|
|
4793
|
+
const [visible, setVisible] = useState(active);
|
|
4794
|
+
const since = useRef(null);
|
|
4795
|
+
useEffect(() => {
|
|
4796
|
+
if (active) {
|
|
4797
|
+
if (since.current === null) since.current = Date.now();
|
|
4798
|
+
setVisible(true);
|
|
4799
|
+
return;
|
|
4800
|
+
}
|
|
4801
|
+
const held = holdBusy(since.current, Date.now(), floorMs);
|
|
4802
|
+
since.current = null;
|
|
4803
|
+
if (!held.visible) {
|
|
4804
|
+
setVisible(false);
|
|
4805
|
+
return;
|
|
4806
|
+
}
|
|
4807
|
+
const timer = setTimeout(() => setVisible(false), held.releaseInMs);
|
|
4808
|
+
return () => clearTimeout(timer);
|
|
4809
|
+
}, [active, floorMs]);
|
|
4810
|
+
return busyView(active, visible);
|
|
4811
|
+
}
|
|
4812
|
+
//#endregion
|
|
4285
4813
|
//#region src/app/layouts/market/use-add-module.ts
|
|
4286
4814
|
function newRequestId() {
|
|
4287
4815
|
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -4304,6 +4832,7 @@ function useAddModule(options) {
|
|
|
4304
4832
|
const [failure, setFailure] = useState(null);
|
|
4305
4833
|
const generationRef = useRef(0);
|
|
4306
4834
|
const requestIdRef = useRef("");
|
|
4835
|
+
const { busy: classifying } = useVisibleBusy(phase === "inspecting", 500);
|
|
4307
4836
|
const write = useHostWrite({
|
|
4308
4837
|
channel: "provision",
|
|
4309
4838
|
networkText: failedText
|
|
@@ -4401,7 +4930,8 @@ function useAddModule(options) {
|
|
|
4401
4930
|
setOutcome({
|
|
4402
4931
|
change: value.change,
|
|
4403
4932
|
module: value.module,
|
|
4404
|
-
supply: value.supply
|
|
4933
|
+
supply: value.supply,
|
|
4934
|
+
...value.plugin === void 0 ? {} : { plugin: value.plugin }
|
|
4405
4935
|
});
|
|
4406
4936
|
setPhase("result");
|
|
4407
4937
|
if (value.change.application === "applied" || value.change.application === "restart-required") onInstalled();
|
|
@@ -4446,7 +4976,7 @@ function useAddModule(options) {
|
|
|
4446
4976
|
custom,
|
|
4447
4977
|
registryOpen,
|
|
4448
4978
|
guideOpen,
|
|
4449
|
-
phase,
|
|
4979
|
+
phase: heldWizardPhase(phase, classifying),
|
|
4450
4980
|
choices,
|
|
4451
4981
|
problem,
|
|
4452
4982
|
preview,
|
|
@@ -4604,10 +5134,10 @@ function makeMarketEntryIcon(units) {
|
|
|
4604
5134
|
function MarketPanel({ t, units }) {
|
|
4605
5135
|
const manifests = useLiveManifests(units);
|
|
4606
5136
|
const { capabilities, checkedAt, checking, forceProbe, reload: reloadCapability } = useCapabilityMap(0);
|
|
4607
|
-
const { modules, read: installedRead, reload: reloadVersions } = useModuleVersions();
|
|
5137
|
+
const { modules, plugins, read: installedRead, reload: reloadVersions } = useModuleVersions();
|
|
4608
5138
|
const [adding, setAdding] = useState(false);
|
|
4609
5139
|
const updates = useMemo(() => marketUpdatesOf(modules), [modules]);
|
|
4610
|
-
const installed = modules
|
|
5140
|
+
const installed = modules === null ? void 0 : withClientRefusals(modules, units.refusals());
|
|
4611
5141
|
const reload = useCallback(() => {
|
|
4612
5142
|
reloadCapability();
|
|
4613
5143
|
reloadVersions();
|
|
@@ -4696,6 +5226,7 @@ function MarketPanel({ t, units }) {
|
|
|
4696
5226
|
updates,
|
|
4697
5227
|
installed,
|
|
4698
5228
|
installedRead: mock === void 0 ? installedRead : mock.installedRead ?? true,
|
|
5229
|
+
plugins,
|
|
4699
5230
|
settling: mock === void 0 ? settling : void 0,
|
|
4700
5231
|
mock
|
|
4701
5232
|
}), /* @__PURE__ */ h(AddModuleDialog, {
|
|
@@ -4751,6 +5282,41 @@ var CLIENT_UNITS = [];
|
|
|
4751
5282
|
function assembleClientUnits(registry) {
|
|
4752
5283
|
for (const face of CLIENT_UNITS) registry.register(face);
|
|
4753
5284
|
}
|
|
5285
|
+
//#endregion
|
|
5286
|
+
//#region src/shared/api/unit-manifests.ts
|
|
5287
|
+
var UNIT_MANIFESTS_ROUTE = "unit-manifests";
|
|
5288
|
+
//#endregion
|
|
5289
|
+
//#region src/app/units/manifests.ts
|
|
5290
|
+
function createUnitManifestLoader(options = {}) {
|
|
5291
|
+
let inFlight = false;
|
|
5292
|
+
let queued = false;
|
|
5293
|
+
let watching = false;
|
|
5294
|
+
const subscribeFacts = options.subscribeFacts ?? subscribeFactRevision;
|
|
5295
|
+
const load = async (registry) => {
|
|
5296
|
+
if (inFlight) {
|
|
5297
|
+
queued = true;
|
|
5298
|
+
return;
|
|
5299
|
+
}
|
|
5300
|
+
inFlight = true;
|
|
5301
|
+
try {
|
|
5302
|
+
const response = await apiGet(UNIT_MANIFESTS_ROUTE).catch(() => null);
|
|
5303
|
+
if (response?.ok === true && Array.isArray(response.manifests)) registry.setManifests(response.manifests);
|
|
5304
|
+
} finally {
|
|
5305
|
+
inFlight = false;
|
|
5306
|
+
if (queued) {
|
|
5307
|
+
queued = false;
|
|
5308
|
+
load(registry);
|
|
5309
|
+
}
|
|
5310
|
+
}
|
|
5311
|
+
};
|
|
5312
|
+
return (registry) => {
|
|
5313
|
+
if (!watching) {
|
|
5314
|
+
watching = true;
|
|
5315
|
+
subscribeFacts(factOfRoute(UNIT_MANIFESTS_ROUTE), () => void load(registry));
|
|
5316
|
+
}
|
|
5317
|
+
load(registry);
|
|
5318
|
+
};
|
|
5319
|
+
}
|
|
4754
5320
|
var BootGate_module_default = {
|
|
4755
5321
|
actions: "_actions_jlw8j_1",
|
|
4756
5322
|
progress: "_progress_jlw8j_2",
|
|
@@ -7428,42 +7994,6 @@ function useLongTask(options) {
|
|
|
7428
7994
|
return { runs };
|
|
7429
7995
|
}
|
|
7430
7996
|
//#endregion
|
|
7431
|
-
//#region src/shared/hooks/use-visible-busy.ts
|
|
7432
|
-
var use_visible_busy_exports = /* @__PURE__ */ __exportAll({
|
|
7433
|
-
busyView: () => busyView,
|
|
7434
|
-
heldPhase: () => heldPhase,
|
|
7435
|
-
useVisibleBusy: () => useVisibleBusy
|
|
7436
|
-
});
|
|
7437
|
-
function heldPhase(phase, refreshing) {
|
|
7438
|
-
return refreshing && phase === "ready" ? "loading" : phase;
|
|
7439
|
-
}
|
|
7440
|
-
function busyView(active, visible) {
|
|
7441
|
-
return {
|
|
7442
|
-
busy: visible,
|
|
7443
|
-
settling: visible && !active
|
|
7444
|
-
};
|
|
7445
|
-
}
|
|
7446
|
-
function useVisibleBusy(active, floorMs) {
|
|
7447
|
-
const [visible, setVisible] = useState(active);
|
|
7448
|
-
const since = useRef(null);
|
|
7449
|
-
useEffect(() => {
|
|
7450
|
-
if (active) {
|
|
7451
|
-
if (since.current === null) since.current = Date.now();
|
|
7452
|
-
setVisible(true);
|
|
7453
|
-
return;
|
|
7454
|
-
}
|
|
7455
|
-
const held = holdBusy(since.current, Date.now(), floorMs);
|
|
7456
|
-
since.current = null;
|
|
7457
|
-
if (!held.visible) {
|
|
7458
|
-
setVisible(false);
|
|
7459
|
-
return;
|
|
7460
|
-
}
|
|
7461
|
-
const timer = setTimeout(() => setVisible(false), held.releaseInMs);
|
|
7462
|
-
return () => clearTimeout(timer);
|
|
7463
|
-
}, [active, floorMs]);
|
|
7464
|
-
return busyView(active, visible);
|
|
7465
|
-
}
|
|
7466
|
-
//#endregion
|
|
7467
7997
|
//#region src/shared/hooks/use-unit-board.ts
|
|
7468
7998
|
var use_unit_board_exports = /* @__PURE__ */ __exportAll({ useUnitBoard: () => useUnitBoard });
|
|
7469
7999
|
function useUnitBoard(options) {
|
|
@@ -7677,7 +8207,7 @@ var kit = {
|
|
|
7677
8207
|
};
|
|
7678
8208
|
function messagesOf(units) {
|
|
7679
8209
|
return units.map((face) => ({
|
|
7680
|
-
unit: face.
|
|
8210
|
+
unit: face.unit,
|
|
7681
8211
|
...face.messages === void 0 ? {} : { messages: face.messages }
|
|
7682
8212
|
}));
|
|
7683
8213
|
}
|
|
@@ -7718,12 +8248,14 @@ function apply(ctx) {
|
|
|
7718
8248
|
}
|
|
7719
8249
|
}
|
|
7720
8250
|
function mount(ctx) {
|
|
7721
|
-
const
|
|
8251
|
+
const loadUnitManifests = createUnitManifestLoader();
|
|
8252
|
+
const units = createClientUnitRegistry({ onUnknownUnit: () => loadUnitManifests(units) });
|
|
7722
8253
|
ctx.provide(UNITS_SERVICE, {
|
|
7723
8254
|
registerUnit: (face) => units.register(face),
|
|
7724
8255
|
manifests: () => units.manifests()
|
|
7725
8256
|
});
|
|
7726
8257
|
assembleClientUnits(units);
|
|
8258
|
+
loadUnitManifests(units);
|
|
7727
8259
|
const store = rightbarStore;
|
|
7728
8260
|
const observable = {
|
|
7729
8261
|
getSnapshot: () => store.getSnapshot(),
|