@dsh-workbench/core 0.1.16 → 0.1.18
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/client.js +665 -127
- package/dist/board.css +31 -0
- package/dist/client/client.body.js +665 -127
- package/dist/client/index.js +665 -127
- package/dist/host/index.js +1510 -263
- package/dist/types/app/client.d.ts +124 -27
- 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-freshness.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/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/package.json +2 -2
- 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 +4 -3
- package/skills/workbench-module-diy/TOOLING.md +2 -2
- package/skills/workbench-module-diy/TOOLS.md +13 -3
package/dist/client/index.js
CHANGED
|
@@ -422,6 +422,133 @@ function probeKeyOf(error) {
|
|
|
422
422
|
if (error === void 0) return null;
|
|
423
423
|
return error.code === "" ? "unknown" : error.code;
|
|
424
424
|
}
|
|
425
|
+
var SUPPORTED_API_VERSIONS = [1];
|
|
426
|
+
var DECLARATION_KEYS = [
|
|
427
|
+
"apiVersion",
|
|
428
|
+
"unit",
|
|
429
|
+
"card",
|
|
430
|
+
"tools",
|
|
431
|
+
"host",
|
|
432
|
+
"env"
|
|
433
|
+
];
|
|
434
|
+
var DECLARATION_REQUIRED_KEYS = [
|
|
435
|
+
"apiVersion",
|
|
436
|
+
"unit",
|
|
437
|
+
"card",
|
|
438
|
+
"tools",
|
|
439
|
+
"host"
|
|
440
|
+
];
|
|
441
|
+
var CARD_KEYS = ["titleKey", "order"];
|
|
442
|
+
var TOOL_KEYS = [
|
|
443
|
+
"name",
|
|
444
|
+
"writes",
|
|
445
|
+
"key"
|
|
446
|
+
];
|
|
447
|
+
var TOOL_KEY_SHAPE = /^[a-z][a-zA-Z0-9]*$/;
|
|
448
|
+
var HOST_KEYS = ["inject", "optional"];
|
|
449
|
+
function text(value) {
|
|
450
|
+
return typeof value === "string" ? value.trim() : "";
|
|
451
|
+
}
|
|
452
|
+
function isRecord(value) {
|
|
453
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
454
|
+
}
|
|
455
|
+
function outsideKeys(value, allowed) {
|
|
456
|
+
return Object.keys(value).filter((key) => !allowed.includes(key));
|
|
457
|
+
}
|
|
458
|
+
function listOf(keys) {
|
|
459
|
+
return keys.map((key) => JSON.stringify(key)).join(" / ");
|
|
460
|
+
}
|
|
461
|
+
function stringArrayProblems(at, value) {
|
|
462
|
+
if (!Array.isArray(value)) return [`${at} 要是一串字符串,现在是 ${JSON.stringify(value)}`];
|
|
463
|
+
return value.flatMap((item, index) => text(item) === "" ? [`${at}[${index}] 不是非空字符串:${JSON.stringify(item)}`] : []);
|
|
464
|
+
}
|
|
465
|
+
function declarationProblemsOf(subject, raw) {
|
|
466
|
+
if (!isRecord(raw)) return [`${subject}: dsh.workbench 不是一个对象 —— ${JSON.stringify(raw)}`];
|
|
467
|
+
const version = raw.apiVersion;
|
|
468
|
+
if (version === void 0) return [`${subject}: dsh.workbench 没有 apiVersion —— 协议从 v1 起,写 \`"apiVersion": 1\`。缺它 = 外壳不认这个模块(ADR-0038 §2.3)`];
|
|
469
|
+
if (!Number.isInteger(version) || !SUPPORTED_API_VERSIONS.includes(version)) return [`${subject}: dsh.workbench.apiVersion 是 ${JSON.stringify(version)},这里只认 ${SUPPORTED_API_VERSIONS.join(" / ")}(要整数)`];
|
|
470
|
+
const problems = [];
|
|
471
|
+
const unknown = outsideKeys(raw, DECLARATION_KEYS);
|
|
472
|
+
if (unknown.length > 0) problems.push(`${subject}: dsh.workbench 里有协议 v1 不认识的键 ${listOf(unknown)} —— 只有 ${listOf(DECLARATION_KEYS)}。(拼错的键会被外壳**静默忽略**:那句声明等于没写)`);
|
|
473
|
+
for (const key of DECLARATION_REQUIRED_KEYS) if (raw[key] === void 0) problems.push(`${subject}: dsh.workbench 缺 ${key}` + (key === "card" ? "(这个模块没有卡片就写 `\"card\": null`)" : ""));
|
|
474
|
+
const card = raw.card;
|
|
475
|
+
if (card !== void 0 && card !== null) {
|
|
476
|
+
if (!isRecord(card)) problems.push(`${subject}: dsh.workbench.card 要么是对象、要么是 null,现在是 ${JSON.stringify(card)}`);
|
|
477
|
+
else {
|
|
478
|
+
const extra = outsideKeys(card, CARD_KEYS);
|
|
479
|
+
if (extra.length > 0) problems.push(`${subject}: dsh.workbench.card 里有不认的键 ${listOf(extra)} —— card 只有 ${listOf(CARD_KEYS)}(卡片默认显不显示由运行期的面板配置决定,清单里没有这一位)`);
|
|
480
|
+
if (text(card.titleKey) === "") problems.push(`${subject}: dsh.workbench.card.titleKey 要是非空字符串(面板那一格的文案键)`);
|
|
481
|
+
if (typeof card.order !== "number" || !Number.isFinite(card.order)) problems.push(`${subject}: dsh.workbench.card.order 要是数字,现在是 ${JSON.stringify(card.order)}`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
const tools = raw.tools;
|
|
485
|
+
if (tools !== void 0) {
|
|
486
|
+
if (!Array.isArray(tools)) problems.push(`${subject}: dsh.workbench.tools 要是一串声明,现在是 ${JSON.stringify(tools)}`);
|
|
487
|
+
else {
|
|
488
|
+
const seen = /* @__PURE__ */ new Set();
|
|
489
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
490
|
+
tools.forEach((tool, index) => {
|
|
491
|
+
const at = `dsh.workbench.tools[${index}]`;
|
|
492
|
+
if (!isRecord(tool)) {
|
|
493
|
+
problems.push(`${subject}: ${at} 要是对象,现在是 ${JSON.stringify(tool)}`);
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
const extra = outsideKeys(tool, TOOL_KEYS);
|
|
497
|
+
if (extra.length > 0) problems.push(`${subject}: ${at} 里有不认的键 ${listOf(extra)} —— tools 只有 ${listOf(TOOL_KEYS)}`);
|
|
498
|
+
const name = text(tool.name);
|
|
499
|
+
if (name === "") problems.push(`${subject}: ${at}.name 要是非空字符串`);
|
|
500
|
+
else if (seen.has(name)) problems.push(`${subject}: ${at}.name「${name}」与前面那条撞了 —— 工具名会进 dsh 的工具表,不许重`);
|
|
501
|
+
else seen.add(name);
|
|
502
|
+
if (typeof tool.writes !== "boolean") problems.push(`${subject}: ${at}.writes 要是 true / false(它是"这会写"的唯一声明,缺了审批无从认领)`);
|
|
503
|
+
if (tool.key !== void 0) {
|
|
504
|
+
const key = text(tool.key);
|
|
505
|
+
if (!TOOL_KEY_SHAPE.test(key)) problems.push(`${subject}: ${at}.key 要是 lowerCamelCase 的标识符(如 \`sync\` / \`podLogs\`),现在是 ${JSON.stringify(tool.key)} —— 它会变成生成物里的键名,所以不引号、不许带点或横线`);
|
|
506
|
+
else if (seenKeys.has(key)) problems.push(`${subject}: ${at}.key「${key}」与前面那条撞了 —— 生成物里的键只能有一个`);
|
|
507
|
+
else seenKeys.add(key);
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
const host = raw.host;
|
|
513
|
+
if (host !== void 0) {
|
|
514
|
+
if (!isRecord(host)) problems.push(`${subject}: dsh.workbench.host 要是对象,现在是 ${JSON.stringify(host)}`);
|
|
515
|
+
else {
|
|
516
|
+
const extra = outsideKeys(host, HOST_KEYS);
|
|
517
|
+
if (extra.length > 0) problems.push(`${subject}: dsh.workbench.host 里有不认的键 ${listOf(extra)} —— host 只有 ${listOf(HOST_KEYS)}`);
|
|
518
|
+
if (host.inject === void 0) problems.push(`${subject}: dsh.workbench.host.inject 没写 —— 它声明这个模块要外壳的哪几个服务,外壳靠它判"能不能挂"。一个都不要也要写 \`"inject": []\``);
|
|
519
|
+
else problems.push(...stringArrayProblems(`${subject}: dsh.workbench.host.inject`, host.inject));
|
|
520
|
+
if (host.optional !== void 0) problems.push(...stringArrayProblems(`${subject}: dsh.workbench.host.optional`, host.optional));
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
if (raw.env !== void 0 && !isRecord(raw.env)) problems.push(`${subject}: dsh.workbench.env 要是对象(command / plugins / libs)—— 语义由门禁的 env 判据查,这里只查形状`);
|
|
524
|
+
return problems;
|
|
525
|
+
}
|
|
526
|
+
function readDeclaration(subject, raw) {
|
|
527
|
+
const problems = declarationProblemsOf(subject, raw);
|
|
528
|
+
if (problems.length > 0) return { problems };
|
|
529
|
+
const declaration = raw;
|
|
530
|
+
const card = declaration.card;
|
|
531
|
+
return {
|
|
532
|
+
declaration,
|
|
533
|
+
problems: [],
|
|
534
|
+
manifest: {
|
|
535
|
+
id: text(declaration.unit),
|
|
536
|
+
card: card === null ? null : {
|
|
537
|
+
titleKey: text(card.titleKey),
|
|
538
|
+
order: card.order
|
|
539
|
+
},
|
|
540
|
+
tools: declaration.tools.map((tool) => ({
|
|
541
|
+
name: text(tool.name),
|
|
542
|
+
writes: tool.writes
|
|
543
|
+
})),
|
|
544
|
+
host: {
|
|
545
|
+
inject: [...declaration.host.inject ?? []],
|
|
546
|
+
...declaration.host.optional === void 0 ? {} : { optional: [...declaration.host.optional] }
|
|
547
|
+
},
|
|
548
|
+
...declaration.env === void 0 ? {} : { env: declaration.env }
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
}
|
|
425
552
|
//#endregion
|
|
426
553
|
//#region ../shared/dist/config/constants.js
|
|
427
554
|
var PLUGIN_ID = "@dsh-workbench/core";
|
|
@@ -609,7 +736,7 @@ function ApprovalDetail(props) {
|
|
|
609
736
|
if (owner?.approval !== void 0) {
|
|
610
737
|
const Render = owner.approval.render;
|
|
611
738
|
return h(CardBoundary, {
|
|
612
|
-
unit: owner.
|
|
739
|
+
unit: owner.unit,
|
|
613
740
|
resetKey: props.callId ?? "",
|
|
614
741
|
t
|
|
615
742
|
}, h(Render, {
|
|
@@ -1110,7 +1237,7 @@ var en = {
|
|
|
1110
1237
|
"panels.market.missing": "not installed",
|
|
1111
1238
|
"panels.market.unchecked": "unknown",
|
|
1112
1239
|
"panels.market.checking": "checking",
|
|
1113
|
-
"panels.market.sectionInstalled": "Installed",
|
|
1240
|
+
"panels.market.sectionInstalled": "Installed modules",
|
|
1114
1241
|
"panels.market.sectionPending": "Not installed",
|
|
1115
1242
|
"panels.market.sectionShared": "Shared dependencies",
|
|
1116
1243
|
"panels.market.sharedUsedBy": "Used by {modules}",
|
|
@@ -1138,11 +1265,19 @@ var en = {
|
|
|
1138
1265
|
"panels.market.noSource": "This module declares no install method — install it yourself",
|
|
1139
1266
|
"panels.market.badSource": "The install method is incomplete — install it yourself",
|
|
1140
1267
|
"panels.market.empty": "No modules available",
|
|
1141
|
-
"panels.market.
|
|
1142
|
-
"panels.market.sectionLocal": "Linked locally",
|
|
1268
|
+
"panels.market.sectionLocal": "Local modules",
|
|
1143
1269
|
"panels.market.sectionUnlisted": "Not from the market",
|
|
1270
|
+
"panels.market.sectionPlugins": "Installed opencli plugins",
|
|
1144
1271
|
"panels.market.moduleOutdated": "update available",
|
|
1272
|
+
"panels.market.moduleRefused": "This module was built for an older version of the workbench, so it does not work here. Update it, or uninstall.",
|
|
1273
|
+
"panels.market.moduleRefusedDetail": "Why it cannot be used: {reason}",
|
|
1145
1274
|
"panels.market.moduleRestartHint": "installed but not active — restart dsh once to bring it up",
|
|
1275
|
+
"panels.market.pluginKeptInUse": "Files kept for now: {names} still uses it.",
|
|
1276
|
+
"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.",
|
|
1277
|
+
"panels.market.pluginKeptHeld": "Files kept: this one is yours, and a module letting go will not remove it.",
|
|
1278
|
+
"panels.market.pluginKeptUnnamed": "Files kept for now: this one cannot be identified as a plugin, so it is unclear who needs it.",
|
|
1279
|
+
"panels.market.pluginAlsoKnownAs": "Its package is {pkg} (updates and uninstall use that)",
|
|
1280
|
+
"panels.market.pluginBroken": "This install is broken: it cannot be identified as a plugin. Uninstall it, or install it again by package name above.",
|
|
1146
1281
|
"panels.market.restartNeeded": "The new version is installed — restart once to pick it up.",
|
|
1147
1282
|
"panels.market.foot": "After installing, enable it in the panel page of that project.",
|
|
1148
1283
|
"panels.market.recheck": "Check for updates",
|
|
@@ -1190,7 +1325,11 @@ var en = {
|
|
|
1190
1325
|
"panels.market.add.problemInstalled": "This module is already installed",
|
|
1191
1326
|
"panels.market.add.problemNotFound": "No such module found",
|
|
1192
1327
|
"panels.market.add.problemNotPackage": "That path does not exist or is not a valid module package",
|
|
1193
|
-
"panels.market.add.problemNotBundle": "This package
|
|
1328
|
+
"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.",
|
|
1329
|
+
"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.",
|
|
1330
|
+
"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.",
|
|
1331
|
+
"panels.market.add.failureNotModuleOrPlugin": "This package is neither a workbench module nor an opencli plugin, so installing it would do nothing",
|
|
1332
|
+
"panels.market.add.installedPlugin": "Installed: the opencli plugin {name}",
|
|
1194
1333
|
"panels.market.add.problemNetwork": "Cannot reach the module source; check the network and retry",
|
|
1195
1334
|
"panels.market.add.problemUnknown": "Cannot fetch module information: {reason}",
|
|
1196
1335
|
"panels.market.add.failureNetwork": "The network connection failed",
|
|
@@ -1221,6 +1360,7 @@ var en = {
|
|
|
1221
1360
|
"panels.market.add.registryPnpm": "pnpm's own registry",
|
|
1222
1361
|
"panels.market.add.check": "Check",
|
|
1223
1362
|
"panels.market.add.checking": "Checking…",
|
|
1363
|
+
"panels.market.add.classifying": "Working out what it is…",
|
|
1224
1364
|
"panels.market.add.change": "Edit",
|
|
1225
1365
|
"panels.market.add.previewTitle": "About to install",
|
|
1226
1366
|
"panels.market.add.fieldName": "Package",
|
|
@@ -1425,7 +1565,7 @@ var zh = {
|
|
|
1425
1565
|
"panels.market.missing": "未装",
|
|
1426
1566
|
"panels.market.unchecked": "状态未知",
|
|
1427
1567
|
"panels.market.checking": "检测中",
|
|
1428
|
-
"panels.market.sectionInstalled": "
|
|
1568
|
+
"panels.market.sectionInstalled": "已安装模块",
|
|
1429
1569
|
"panels.market.sectionPending": "未安装",
|
|
1430
1570
|
"panels.market.sectionShared": "共用依赖",
|
|
1431
1571
|
"panels.market.sharedUsedBy": "供 {modules} 使用",
|
|
@@ -1453,11 +1593,19 @@ var zh = {
|
|
|
1453
1593
|
"panels.market.noSource": "这个模块没声明怎么装,只能自己动手",
|
|
1454
1594
|
"panels.market.badSource": "安装方式没写全,只能自己动手",
|
|
1455
1595
|
"panels.market.empty": "暂无可用模块",
|
|
1456
|
-
"panels.market.
|
|
1457
|
-
"panels.market.sectionLocal": "本地装的",
|
|
1596
|
+
"panels.market.sectionLocal": "本地模块",
|
|
1458
1597
|
"panels.market.sectionUnlisted": "不是从市场装的",
|
|
1598
|
+
"panels.market.sectionPlugins": "已安装 opencli 插件",
|
|
1459
1599
|
"panels.market.moduleOutdated": "有新版",
|
|
1600
|
+
"panels.market.moduleRefused": "这个模块是给旧版本的工作台写的,现在用不了。更新它,或者卸载。",
|
|
1601
|
+
"panels.market.moduleRefusedDetail": "装不上的原因:{reason}",
|
|
1460
1602
|
"panels.market.moduleRestartHint": "装好了但还没生效 —— 重启一次 dsh 就会出来",
|
|
1603
|
+
"panels.market.pluginKeptInUse": "文件先留着:{names} 还要用它。",
|
|
1604
|
+
"panels.market.pluginKeptUnsure": "文件先留着:这台机器上还有模块看不出用了什么,说不准谁在用它。",
|
|
1605
|
+
"panels.market.pluginKeptHeld": "文件留着:你自己装的那一份,模块放手不动它。",
|
|
1606
|
+
"panels.market.pluginKeptUnnamed": "文件先留着:看不出这是哪个插件,说不准谁在用它。",
|
|
1607
|
+
"panels.market.pluginAlsoKnownAs": "包名是 {pkg}(更新与卸载按它来)",
|
|
1608
|
+
"panels.market.pluginBroken": "这份装坏了:看不出它是个插件。可以卸载,或者去上面按包名再装一次。",
|
|
1461
1609
|
"panels.market.restartNeeded": "新版装好了,重启一次才生效。",
|
|
1462
1610
|
"panels.market.foot": "装好后到那个项目的面板页勾选它,模块才会出现。",
|
|
1463
1611
|
"panels.market.recheck": "重新检查更新",
|
|
@@ -1505,7 +1653,11 @@ var zh = {
|
|
|
1505
1653
|
"panels.market.add.problemInstalled": "该模块已安装",
|
|
1506
1654
|
"panels.market.add.problemNotFound": "未找到相关模块",
|
|
1507
1655
|
"panels.market.add.problemNotPackage": "该路径不存在或不是有效的模块包",
|
|
1508
|
-
"panels.market.add.problemNotBundle": "
|
|
1656
|
+
"panels.market.add.problemNotBundle": "这个包装不进这里:{reason}。要是它其实是个 opencli 插件,请改用包名(例如 opencli-plugin-cmdb)或者本地目录 —— 从 git 地址和 tarball 判断不出它是什么。",
|
|
1657
|
+
"panels.market.add.problemNotWorkbenchModule": "这个包跟现在的工作台对不上,装上也用不了。换一个版本,或者找这个模块的作者。",
|
|
1658
|
+
"panels.market.add.problemNotModuleOrPlugin": "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上。换一个版本,或者找这个包的作者。",
|
|
1659
|
+
"panels.market.add.failureNotModuleOrPlugin": "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上",
|
|
1660
|
+
"panels.market.add.installedPlugin": "装上了:opencli 插件 {name}",
|
|
1509
1661
|
"panels.market.add.problemNetwork": "无法连接模块源,请检查网络后重试",
|
|
1510
1662
|
"panels.market.add.problemUnknown": "无法获取模块信息:{reason}",
|
|
1511
1663
|
"panels.market.add.failureNetwork": "网络连接失败",
|
|
@@ -1536,6 +1688,7 @@ var zh = {
|
|
|
1536
1688
|
"panels.market.add.registryPnpm": "pnpm 自己配的源",
|
|
1537
1689
|
"panels.market.add.check": "预检",
|
|
1538
1690
|
"panels.market.add.checking": "正在预检…",
|
|
1691
|
+
"panels.market.add.classifying": "判定中…",
|
|
1539
1692
|
"panels.market.add.change": "改一下",
|
|
1540
1693
|
"panels.market.add.previewTitle": "将要安装",
|
|
1541
1694
|
"panels.market.add.fieldName": "包名",
|
|
@@ -1812,6 +1965,8 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1812
1965
|
CenteredState: () => CenteredState,
|
|
1813
1966
|
ChoiceGroup: () => ChoiceGroup,
|
|
1814
1967
|
Component: () => Component,
|
|
1968
|
+
DECLARATION_KEYS: () => DECLARATION_KEYS,
|
|
1969
|
+
DECLARATION_REQUIRED_KEYS: () => DECLARATION_REQUIRED_KEYS,
|
|
1815
1970
|
DEFAULT_WORKSPACE_TITLE: () => DEFAULT_WORKSPACE_TITLE,
|
|
1816
1971
|
EVENTS_PATH: () => EVENTS_PATH,
|
|
1817
1972
|
EmptyState: () => EmptyState,
|
|
@@ -1850,6 +2005,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1850
2005
|
STORAGE_KEY_PROJECT: () => STORAGE_KEY_PROJECT,
|
|
1851
2006
|
STORAGE_KEY_RIGHTBAR: () => STORAGE_KEY_RIGHTBAR,
|
|
1852
2007
|
STORAGE_KEY_RIGHTBAR_COLUMN: () => STORAGE_KEY_RIGHTBAR_COLUMN,
|
|
2008
|
+
SUPPORTED_API_VERSIONS: () => SUPPORTED_API_VERSIONS,
|
|
1853
2009
|
SaveBar: () => SaveBar,
|
|
1854
2010
|
SettingsSection: () => SettingsSection,
|
|
1855
2011
|
SkeletonRows: () => SkeletonRows,
|
|
@@ -1860,6 +2016,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1860
2016
|
VERSION_CHECK_TIMEOUT_MS: () => VERSION_CHECK_TIMEOUT_MS,
|
|
1861
2017
|
VERSION_CHECK_TTL_MS: () => VERSION_CHECK_TTL_MS,
|
|
1862
2018
|
WARM_TIMEOUT_MS: () => WARM_TIMEOUT_MS,
|
|
2019
|
+
WORKBENCH_API_VERSION: () => 1,
|
|
1863
2020
|
apiGet: () => apiGet,
|
|
1864
2021
|
apiPost: () => apiPost,
|
|
1865
2022
|
blockerActionLabel: () => blockerActionLabel,
|
|
@@ -1869,6 +2026,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1869
2026
|
buildMarker: () => buildMarker,
|
|
1870
2027
|
createFactChannel: () => createFactChannel,
|
|
1871
2028
|
cx: () => cx,
|
|
2029
|
+
declarationProblemsOf: () => declarationProblemsOf,
|
|
1872
2030
|
decodeRef: () => decodeRef,
|
|
1873
2031
|
dictionaries: () => dictionaries,
|
|
1874
2032
|
en: () => en,
|
|
@@ -1892,6 +2050,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
|
|
|
1892
2050
|
parseMarkers: () => parseMarkers,
|
|
1893
2051
|
probeKeyOf: () => probeKeyOf,
|
|
1894
2052
|
quoteShellArg: () => quoteShellArg,
|
|
2053
|
+
readDeclaration: () => readDeclaration,
|
|
1895
2054
|
readFlag: () => readFlag,
|
|
1896
2055
|
readText: () => readText,
|
|
1897
2056
|
relativeTime: () => relativeTime,
|
|
@@ -2004,6 +2163,7 @@ function createAdaptiveTransport() {
|
|
|
2004
2163
|
//#endregion
|
|
2005
2164
|
//#region src/shared/hooks/use-facts.ts
|
|
2006
2165
|
var use_facts_exports = /* @__PURE__ */ __exportAll({
|
|
2166
|
+
subscribeFactRevision: () => subscribeFactRevision,
|
|
2007
2167
|
useFactInvalidate: () => useFactInvalidate,
|
|
2008
2168
|
useFactRevision: () => useFactRevision
|
|
2009
2169
|
});
|
|
@@ -2011,6 +2171,9 @@ var channel = createFactChannel({ transport: createAdaptiveTransport() });
|
|
|
2011
2171
|
function useFactRevision(fact) {
|
|
2012
2172
|
return useSyncExternalStore(useCallback((listener) => channel.subscribe(fact, listener), [fact]), useCallback(() => channel.revisionOf(fact), [fact]));
|
|
2013
2173
|
}
|
|
2174
|
+
function subscribeFactRevision(fact, listener) {
|
|
2175
|
+
return channel.subscribe(fact, listener);
|
|
2176
|
+
}
|
|
2014
2177
|
function useFactInvalidate() {
|
|
2015
2178
|
return useCallback((fact) => channel.refresh(fact), []);
|
|
2016
2179
|
}
|
|
@@ -2238,6 +2401,9 @@ function panelRowName(label, hint, t) {
|
|
|
2238
2401
|
//#endregion
|
|
2239
2402
|
//#region src/app/layouts/rightbar/market-freshness.ts
|
|
2240
2403
|
var MARKET_STALE_MS = VERSION_CHECK_TTL_MS;
|
|
2404
|
+
function marketSettled(freshness, installedRead) {
|
|
2405
|
+
return freshness.loaded && installedRead !== false;
|
|
2406
|
+
}
|
|
2241
2407
|
function shouldProbeOnEnter(input) {
|
|
2242
2408
|
if (input.checkedAt === null) return true;
|
|
2243
2409
|
return input.now - input.checkedAt >= input.staleMs;
|
|
@@ -2535,8 +2701,7 @@ function buildMarketMocks(roster) {
|
|
|
2535
2701
|
...mine,
|
|
2536
2702
|
card: {
|
|
2537
2703
|
titleKey: "一个名字特别特别长的模块用来验证省略号会不会把按钮挤下去",
|
|
2538
|
-
order: 10
|
|
2539
|
-
enabledByDefault: true
|
|
2704
|
+
order: 10
|
|
2540
2705
|
}
|
|
2541
2706
|
}],
|
|
2542
2707
|
capabilities: probe$1(id, "ok"),
|
|
@@ -2640,6 +2805,24 @@ function buildMarketMocks(roster) {
|
|
|
2640
2805
|
installedActions: ["update-bundle", "remove-bundle"]
|
|
2641
2806
|
}
|
|
2642
2807
|
},
|
|
2808
|
+
{
|
|
2809
|
+
id: "installed-client-refused",
|
|
2810
|
+
label: "本机装了,但浏览器这半没挂上(拒因由客户端报告)",
|
|
2811
|
+
manifests: [found],
|
|
2812
|
+
capabilities: {},
|
|
2813
|
+
installed: [{
|
|
2814
|
+
unit: id,
|
|
2815
|
+
pkg: "@dsh-workbench/module-one",
|
|
2816
|
+
installed: "0.1.2",
|
|
2817
|
+
clientRefused: [`宿主没有担保 unit「${id}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]
|
|
2818
|
+
}],
|
|
2819
|
+
expect: {
|
|
2820
|
+
rows: 0,
|
|
2821
|
+
installed: 1,
|
|
2822
|
+
installedActions: ["remove-bundle"],
|
|
2823
|
+
installedNote: true
|
|
2824
|
+
}
|
|
2825
|
+
},
|
|
2643
2826
|
{
|
|
2644
2827
|
id: "installed-confirm",
|
|
2645
2828
|
label: "卸载本机模块(Modal 确认,标题带模块名)",
|
|
@@ -2688,6 +2871,94 @@ function buildMarketMocks(roster) {
|
|
|
2688
2871
|
actions: ["uninstall"]
|
|
2689
2872
|
}
|
|
2690
2873
|
},
|
|
2874
|
+
{
|
|
2875
|
+
id: "plugin-outdated",
|
|
2876
|
+
label: "用户装的 opencli 插件:有新版(给更新 / 卸载)",
|
|
2877
|
+
manifests: [],
|
|
2878
|
+
capabilities: {},
|
|
2879
|
+
plugins: [{
|
|
2880
|
+
pkg: "opencli-plugin-cmdb",
|
|
2881
|
+
name: "cmdb",
|
|
2882
|
+
installed: "1.0.24",
|
|
2883
|
+
latest: "1.0.25"
|
|
2884
|
+
}],
|
|
2885
|
+
expect: {
|
|
2886
|
+
rows: 0,
|
|
2887
|
+
plugins: 1,
|
|
2888
|
+
pluginActions: ["update-plugin", "uninstall-plugin"]
|
|
2889
|
+
}
|
|
2890
|
+
},
|
|
2891
|
+
{
|
|
2892
|
+
id: "plugin-local",
|
|
2893
|
+
label: "本地目录装的 opencli 插件:没有版本源,只给卸载",
|
|
2894
|
+
manifests: [],
|
|
2895
|
+
capabilities: {},
|
|
2896
|
+
plugins: [{
|
|
2897
|
+
pkg: "/Users/me/my-local-plugin",
|
|
2898
|
+
name: "my-local-plugin",
|
|
2899
|
+
local: true
|
|
2900
|
+
}],
|
|
2901
|
+
expect: {
|
|
2902
|
+
rows: 0,
|
|
2903
|
+
plugins: 1,
|
|
2904
|
+
pluginActions: ["uninstall-plugin"],
|
|
2905
|
+
pluginNote: false
|
|
2906
|
+
}
|
|
2907
|
+
},
|
|
2908
|
+
{
|
|
2909
|
+
id: "plugin-alias",
|
|
2910
|
+
label: "插件名 ≠ 包名:行上两个都写出来(更新 / 卸载按包名)",
|
|
2911
|
+
manifests: [],
|
|
2912
|
+
capabilities: {},
|
|
2913
|
+
plugins: [{
|
|
2914
|
+
pkg: "opencli-plugin-cmdb",
|
|
2915
|
+
name: "cmdb",
|
|
2916
|
+
installed: "1.0.24",
|
|
2917
|
+
latest: "1.0.25"
|
|
2918
|
+
}],
|
|
2919
|
+
expect: {
|
|
2920
|
+
rows: 0,
|
|
2921
|
+
plugins: 1,
|
|
2922
|
+
pluginActions: ["update-plugin", "uninstall-plugin"],
|
|
2923
|
+
pluginNoteKey: "panels.market.pluginAlsoKnownAs"
|
|
2924
|
+
}
|
|
2925
|
+
},
|
|
2926
|
+
{
|
|
2927
|
+
id: "plugin-broken",
|
|
2928
|
+
label: "装坏了的那一份(目录在但看不出是个插件):行上直说,给卸载与指路",
|
|
2929
|
+
manifests: [],
|
|
2930
|
+
capabilities: {},
|
|
2931
|
+
plugins: [{
|
|
2932
|
+
pkg: "opencli-plugin-cmdb",
|
|
2933
|
+
name: "cmdb",
|
|
2934
|
+
installed: "1.0.24",
|
|
2935
|
+
broken: true
|
|
2936
|
+
}],
|
|
2937
|
+
expect: {
|
|
2938
|
+
rows: 0,
|
|
2939
|
+
plugins: 1,
|
|
2940
|
+
pluginActions: ["uninstall-plugin"],
|
|
2941
|
+
pluginNoteKey: "panels.market.pluginBroken"
|
|
2942
|
+
}
|
|
2943
|
+
},
|
|
2944
|
+
{
|
|
2945
|
+
id: "plugin-kept",
|
|
2946
|
+
label: "卸掉用户装的插件,但还有模块在用:文件先留着(行上给一句为什么)",
|
|
2947
|
+
manifests: [],
|
|
2948
|
+
capabilities: {},
|
|
2949
|
+
plugins: [{
|
|
2950
|
+
pkg: "opencli-plugin-cmdb",
|
|
2951
|
+
name: "cmdb",
|
|
2952
|
+
installed: "1.0.24"
|
|
2953
|
+
}],
|
|
2954
|
+
notice: "文件先留着:cmdb、argocd 还要用它。",
|
|
2955
|
+
expect: {
|
|
2956
|
+
rows: 0,
|
|
2957
|
+
plugins: 1,
|
|
2958
|
+
pluginActions: ["uninstall-plugin"],
|
|
2959
|
+
notice: true
|
|
2960
|
+
}
|
|
2961
|
+
},
|
|
2691
2962
|
{
|
|
2692
2963
|
id: "empty",
|
|
2693
2964
|
label: "市场空态",
|
|
@@ -2745,7 +3016,6 @@ function createBoardRegistry() {
|
|
|
2745
3016
|
};
|
|
2746
3017
|
},
|
|
2747
3018
|
all: () => sorted,
|
|
2748
|
-
visible: () => sorted.filter((module) => module.enabledByDefault),
|
|
2749
3019
|
byId: (id) => index.get(id),
|
|
2750
3020
|
stepOwner: (kind) => steps.get(kind),
|
|
2751
3021
|
subscribe(listener) {
|
|
@@ -2757,20 +3027,21 @@ function createBoardRegistry() {
|
|
|
2757
3027
|
}
|
|
2758
3028
|
//#endregion
|
|
2759
3029
|
//#region src/app/units/registry.ts
|
|
2760
|
-
function toBoardModule(face) {
|
|
3030
|
+
function toBoardModule(face, manifest) {
|
|
2761
3031
|
return {
|
|
2762
|
-
id:
|
|
2763
|
-
titleKey:
|
|
2764
|
-
order:
|
|
2765
|
-
enabledByDefault: face.manifest.card?.enabledByDefault ?? false,
|
|
3032
|
+
id: manifest.id,
|
|
3033
|
+
titleKey: manifest.card?.titleKey ?? manifest.id,
|
|
3034
|
+
order: manifest.card?.order ?? 100,
|
|
2766
3035
|
View: face.card,
|
|
2767
3036
|
...face.steps === void 0 ? {} : { steps: face.steps }
|
|
2768
3037
|
};
|
|
2769
3038
|
}
|
|
2770
|
-
function createClientUnitRegistry() {
|
|
2771
|
-
const
|
|
3039
|
+
function createClientUnitRegistry(options = {}) {
|
|
3040
|
+
const registrations = [];
|
|
3041
|
+
const refusals = [];
|
|
2772
3042
|
const listeners = /* @__PURE__ */ new Set();
|
|
2773
3043
|
const board = createBoardRegistry();
|
|
3044
|
+
let known = /* @__PURE__ */ new Map();
|
|
2774
3045
|
let revision = 0;
|
|
2775
3046
|
let manifestsCache;
|
|
2776
3047
|
function notify() {
|
|
@@ -2781,28 +3052,86 @@ function createClientUnitRegistry() {
|
|
|
2781
3052
|
console.warn(`[dsh-workbench] 套件注册的订阅者报错(不影响其它订阅者与这次注册):${String(error)}`);
|
|
2782
3053
|
}
|
|
2783
3054
|
}
|
|
3055
|
+
function warnRefusal(unit, reasons) {
|
|
3056
|
+
refusals.push({
|
|
3057
|
+
unit,
|
|
3058
|
+
reasons
|
|
3059
|
+
});
|
|
3060
|
+
console.warn(`[dsh-workbench] ${unit === "" ? "这个模块" : unit} 的卡片没挂上:${reasons.join(";")}`);
|
|
3061
|
+
}
|
|
3062
|
+
function takeBackRefusal(unit) {
|
|
3063
|
+
for (let at = refusals.length - 1; at >= 0; at -= 1) if (refusals[at]?.unit === unit) refusals.splice(at, 1);
|
|
3064
|
+
}
|
|
3065
|
+
function attach(entry) {
|
|
3066
|
+
const manifest = known.get(entry.unit);
|
|
3067
|
+
if (manifest === void 0) return false;
|
|
3068
|
+
entry.mounted = {
|
|
3069
|
+
manifest,
|
|
3070
|
+
unmount: board.register(toBoardModule(entry.face, manifest))
|
|
3071
|
+
};
|
|
3072
|
+
takeBackRefusal(entry.unit);
|
|
3073
|
+
return true;
|
|
3074
|
+
}
|
|
3075
|
+
function detach(entry) {
|
|
3076
|
+
entry.mounted?.unmount();
|
|
3077
|
+
entry.mounted = null;
|
|
3078
|
+
}
|
|
2784
3079
|
return {
|
|
2785
3080
|
register(face) {
|
|
2786
|
-
const
|
|
2787
|
-
if (
|
|
2788
|
-
|
|
2789
|
-
|
|
3081
|
+
const unit = typeof face?.unit === "string" ? face.unit.trim() : "";
|
|
3082
|
+
if (unit === "") {
|
|
3083
|
+
warnRefusal("", ["registerUnit({ unit, card }) 里的 unit 是空的 —— U1b 之前的旧形状是 registerUnit({ manifest, card });现在清单由外壳从**已装清单**读出来、按 unit 交给浏览器(ADR-0038 §2.2)"]);
|
|
3084
|
+
notify();
|
|
3085
|
+
return () => {};
|
|
3086
|
+
}
|
|
3087
|
+
if (registrations.some((entry) => entry.unit === unit)) throw new Error(`套件 id 重复:${unit}(id 会进持久化配置,不能撞)`);
|
|
3088
|
+
const entry = {
|
|
3089
|
+
face,
|
|
3090
|
+
unit,
|
|
3091
|
+
mounted: null
|
|
3092
|
+
};
|
|
3093
|
+
registrations.push(entry);
|
|
2790
3094
|
manifestsCache = void 0;
|
|
3095
|
+
if (!attach(entry)) {
|
|
3096
|
+
warnRefusal(unit, [`宿主没有担保 unit「${unit}」的清单 —— 这个包要么没装进这份 profile,要么它的 dsh.workbench 没通过校验。卡片先不挂:清单只有一处真相(ADR-0038 §2.2)`]);
|
|
3097
|
+
options.onUnknownUnit?.(unit);
|
|
3098
|
+
}
|
|
2791
3099
|
notify();
|
|
2792
3100
|
return () => {
|
|
2793
|
-
const at =
|
|
3101
|
+
const at = registrations.indexOf(entry);
|
|
2794
3102
|
if (at < 0) return;
|
|
2795
|
-
|
|
3103
|
+
registrations.splice(at, 1);
|
|
3104
|
+
detach(entry);
|
|
3105
|
+
takeBackRefusal(unit);
|
|
2796
3106
|
manifestsCache = void 0;
|
|
2797
|
-
unregisterBoard();
|
|
2798
3107
|
notify();
|
|
2799
3108
|
};
|
|
2800
3109
|
},
|
|
2801
|
-
all: () =>
|
|
3110
|
+
all: () => registrations.map((entry) => entry.face),
|
|
2802
3111
|
manifests: () => {
|
|
2803
|
-
manifestsCache ??=
|
|
3112
|
+
manifestsCache ??= registrations.flatMap((entry) => entry.mounted === null ? [] : [entry.mounted.manifest]);
|
|
2804
3113
|
return manifestsCache;
|
|
2805
3114
|
},
|
|
3115
|
+
refusals: () => refusals,
|
|
3116
|
+
setManifests(manifests) {
|
|
3117
|
+
known = new Map(manifests.map((manifest) => [manifest.id, manifest]));
|
|
3118
|
+
let changed = false;
|
|
3119
|
+
for (const entry of registrations) {
|
|
3120
|
+
const next = known.get(entry.unit);
|
|
3121
|
+
if (entry.mounted === null) {
|
|
3122
|
+
if (next !== void 0 && attach(entry)) changed = true;
|
|
3123
|
+
continue;
|
|
3124
|
+
}
|
|
3125
|
+
if (next === void 0) {
|
|
3126
|
+
detach(entry);
|
|
3127
|
+
warnRefusal(entry.unit, [`宿主不再担保 unit「${entry.unit}」的清单(模块被卸了?)—— 这张卡片先摘下来`]);
|
|
3128
|
+
changed = true;
|
|
3129
|
+
}
|
|
3130
|
+
}
|
|
3131
|
+
if (!changed) return;
|
|
3132
|
+
manifestsCache = void 0;
|
|
3133
|
+
notify();
|
|
3134
|
+
},
|
|
2806
3135
|
board,
|
|
2807
3136
|
subscribe(listener) {
|
|
2808
3137
|
listeners.add(listener);
|
|
@@ -2837,11 +3166,9 @@ var messages = {
|
|
|
2837
3166
|
};
|
|
2838
3167
|
var manifest = {
|
|
2839
3168
|
id: FIXTURE_UNIT_ID,
|
|
2840
|
-
kind: "board",
|
|
2841
3169
|
card: {
|
|
2842
3170
|
titleKey: KEY.cardTitle,
|
|
2843
|
-
order: 900
|
|
2844
|
-
enabledByDefault: true
|
|
3171
|
+
order: 900
|
|
2845
3172
|
},
|
|
2846
3173
|
tools: [],
|
|
2847
3174
|
host: { inject: [] }
|
|
@@ -2864,6 +3191,7 @@ function FixtureCard({ t, onRefresh }) {
|
|
|
2864
3191
|
}))));
|
|
2865
3192
|
}
|
|
2866
3193
|
var FIXTURE_FACE = {
|
|
3194
|
+
unit: FIXTURE_UNIT_ID,
|
|
2867
3195
|
manifest,
|
|
2868
3196
|
messages,
|
|
2869
3197
|
card: FixtureCard
|
|
@@ -2884,11 +3212,9 @@ var crashMessages = {
|
|
|
2884
3212
|
};
|
|
2885
3213
|
var crashManifest = {
|
|
2886
3214
|
id: CRASH_UNIT_ID,
|
|
2887
|
-
kind: "board",
|
|
2888
3215
|
card: {
|
|
2889
3216
|
titleKey: CRASH_KEY.cardTitle,
|
|
2890
|
-
order: 899
|
|
2891
|
-
enabledByDefault: true
|
|
3217
|
+
order: 899
|
|
2892
3218
|
},
|
|
2893
3219
|
tools: [],
|
|
2894
3220
|
host: { inject: [] }
|
|
@@ -2897,6 +3223,7 @@ function CrashingCard() {
|
|
|
2897
3223
|
throw new Error("夹具:这张卡片按 wbCrash=1 故意渲染失败(守「一张卡片崩溃不带走面板」)");
|
|
2898
3224
|
}
|
|
2899
3225
|
var CRASH_FACE = {
|
|
3226
|
+
unit: CRASH_UNIT_ID,
|
|
2900
3227
|
manifest: crashManifest,
|
|
2901
3228
|
messages: crashMessages,
|
|
2902
3229
|
card: CrashingCard
|
|
@@ -2909,8 +3236,8 @@ function fixtureRoster(roster) {
|
|
|
2909
3236
|
return hasCard(roster) ? roster : SAMPLE_ROSTER;
|
|
2910
3237
|
}
|
|
2911
3238
|
function fixtureSeed(roster, all, crash = false) {
|
|
2912
|
-
const base = hasCard(roster) ? all : [toBoardModule(FIXTURE_FACE)];
|
|
2913
|
-
return crash ? [toBoardModule(CRASH_FACE), ...base] : base;
|
|
3239
|
+
const base = hasCard(roster) ? all : [toBoardModule(FIXTURE_FACE, FIXTURE_FACE.manifest)];
|
|
3240
|
+
return crash ? [toBoardModule(CRASH_FACE, CRASH_FACE.manifest), ...base] : base;
|
|
2914
3241
|
}
|
|
2915
3242
|
//#endregion
|
|
2916
3243
|
//#region src/app/layouts/rightbar/market-rows.ts
|
|
@@ -2930,6 +3257,25 @@ var MARKET_DOT = {
|
|
|
2930
3257
|
unchecked: "idle",
|
|
2931
3258
|
unknown: "idle"
|
|
2932
3259
|
};
|
|
3260
|
+
function marketRowTitle(row, t) {
|
|
3261
|
+
return row.label ?? t(row.titleKey);
|
|
3262
|
+
}
|
|
3263
|
+
function withClientRefusals(modules, refusals) {
|
|
3264
|
+
if (refusals.length === 0) return modules;
|
|
3265
|
+
const byUnit = new Map(refusals.map((one) => [one.unit, one.reasons]));
|
|
3266
|
+
return modules.map((module) => {
|
|
3267
|
+
const reasons = byUnit.get(module.unit);
|
|
3268
|
+
return reasons === void 0 ? module : {
|
|
3269
|
+
...module,
|
|
3270
|
+
clientRefused: reasons
|
|
3271
|
+
};
|
|
3272
|
+
});
|
|
3273
|
+
}
|
|
3274
|
+
function refusalReasons(host, client) {
|
|
3275
|
+
const reported = host ?? [];
|
|
3276
|
+
if (reported.length > 0) return reported;
|
|
3277
|
+
return [...new Set(client ?? [])];
|
|
3278
|
+
}
|
|
2933
3279
|
function mergeTitles(known, manifests) {
|
|
2934
3280
|
let next = null;
|
|
2935
3281
|
for (const manifest of manifests) {
|
|
@@ -2948,11 +3294,16 @@ function installedRows(modules, manifests, listed, known) {
|
|
|
2948
3294
|
const latest = module.latest;
|
|
2949
3295
|
const outdated = latest !== void 0 && latest !== module.installed;
|
|
2950
3296
|
const loaded = titles.has(module.unit);
|
|
3297
|
+
const refused = refusalReasons(module.refused, module.clientRefused);
|
|
2951
3298
|
rows.push({
|
|
2952
3299
|
id: module.unit,
|
|
2953
3300
|
titleKey: titles.get(module.unit) ?? known?.get(module.unit) ?? module.pkg,
|
|
2954
3301
|
state: outdated ? "outdated" : "installed",
|
|
2955
|
-
...loaded ? {} : { hint: "panels.market.moduleRestartHint" },
|
|
3302
|
+
...loaded || refused.length > 0 ? {} : { hint: "panels.market.moduleRestartHint" },
|
|
3303
|
+
...refused.length === 0 ? {} : { note: {
|
|
3304
|
+
key: "panels.market.moduleRefused",
|
|
3305
|
+
params: { reason: refused.join(";") }
|
|
3306
|
+
} },
|
|
2956
3307
|
...module.local === true ? { local: true } : {},
|
|
2957
3308
|
pkg: module.pkg,
|
|
2958
3309
|
canInstall: false,
|
|
@@ -2971,6 +3322,7 @@ function installedRows(modules, manifests, listed, known) {
|
|
|
2971
3322
|
return rows;
|
|
2972
3323
|
}
|
|
2973
3324
|
function marketActions$1(row) {
|
|
3325
|
+
if (row.plugin === true) return [...row.canUpdate ? ["update-plugin"] : [], ...row.canUninstall ? ["uninstall-plugin"] : []];
|
|
2974
3326
|
return [
|
|
2975
3327
|
...row.canInstall ? ["install"] : [],
|
|
2976
3328
|
...row.moduleUpdate === void 0 ? row.canUpdate ? ["update"] : [] : ["update-bundle"],
|
|
@@ -2994,7 +3346,7 @@ function envNameOf(source) {
|
|
|
2994
3346
|
if (source.kind === "npm") return source.registryEnv;
|
|
2995
3347
|
return "";
|
|
2996
3348
|
}
|
|
2997
|
-
function noteOf(state, install, manifest) {
|
|
3349
|
+
function noteOf$1(state, install, manifest) {
|
|
2998
3350
|
if (state === "installed") return void 0;
|
|
2999
3351
|
if (install === "env-missing") return {
|
|
3000
3352
|
key: "panels.market.needEnv",
|
|
@@ -3053,7 +3405,7 @@ function marketRows(manifests, capabilities, updates = {}) {
|
|
|
3053
3405
|
const capability = capabilities?.[manifest.id];
|
|
3054
3406
|
const install = capability?.install;
|
|
3055
3407
|
const state = capabilities === null ? "checking" : stateOf(capability);
|
|
3056
|
-
const note = noteOf(state, install, manifest);
|
|
3408
|
+
const note = noteOf$1(state, install, manifest);
|
|
3057
3409
|
const onMachine = isOnMachine(state);
|
|
3058
3410
|
const reAdopt = capability?.released === true && install === void 0;
|
|
3059
3411
|
const entry = updates[manifest.id];
|
|
@@ -3225,6 +3577,60 @@ function useHostWrite(options) {
|
|
|
3225
3577
|
};
|
|
3226
3578
|
}
|
|
3227
3579
|
//#endregion
|
|
3580
|
+
//#region src/app/layouts/rightbar/market-plugin-rows.ts
|
|
3581
|
+
function installedPluginKept(value) {
|
|
3582
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
3583
|
+
const kept = value.kept;
|
|
3584
|
+
if (typeof kept !== "object" || kept === null) return void 0;
|
|
3585
|
+
const kind = kept.kind;
|
|
3586
|
+
if (kind === "held") return { key: "panels.market.pluginKeptHeld" };
|
|
3587
|
+
if (kind === "unnamed") return { key: "panels.market.pluginKeptUnnamed" };
|
|
3588
|
+
if (kind === "unsure") return { key: "panels.market.pluginKeptUnsure" };
|
|
3589
|
+
if (kind !== "claimed") return void 0;
|
|
3590
|
+
const raw = kept.by;
|
|
3591
|
+
const names = Array.isArray(raw) ? raw.filter((item) => typeof item === "string") : [];
|
|
3592
|
+
return names.length === 0 ? { key: "panels.market.pluginKeptUnsure" } : {
|
|
3593
|
+
key: "panels.market.pluginKeptInUse",
|
|
3594
|
+
names
|
|
3595
|
+
};
|
|
3596
|
+
}
|
|
3597
|
+
function noteOf(plugin) {
|
|
3598
|
+
if (plugin.broken === true) return {
|
|
3599
|
+
key: "panels.market.pluginBroken",
|
|
3600
|
+
params: {}
|
|
3601
|
+
};
|
|
3602
|
+
if (plugin.local === true) return void 0;
|
|
3603
|
+
if (plugin.name !== void 0 && plugin.name !== plugin.pkg) return {
|
|
3604
|
+
key: "panels.market.pluginAlsoKnownAs",
|
|
3605
|
+
params: { pkg: plugin.pkg }
|
|
3606
|
+
};
|
|
3607
|
+
}
|
|
3608
|
+
function installedPluginRows(plugins) {
|
|
3609
|
+
return plugins.map((plugin) => {
|
|
3610
|
+
const name = plugin.name ?? plugin.pkg;
|
|
3611
|
+
const outdated = plugin.installed !== void 0 && plugin.latest !== void 0 && plugin.latest !== plugin.installed;
|
|
3612
|
+
const note = noteOf(plugin);
|
|
3613
|
+
return {
|
|
3614
|
+
id: `plugin:${plugin.pkg}`,
|
|
3615
|
+
titleKey: plugin.pkg,
|
|
3616
|
+
label: name,
|
|
3617
|
+
plugin: true,
|
|
3618
|
+
state: outdated ? "outdated" : "installed",
|
|
3619
|
+
canInstall: false,
|
|
3620
|
+
canUpdate: outdated,
|
|
3621
|
+
canUninstall: true,
|
|
3622
|
+
...plugin.local === true ? { local: true } : {},
|
|
3623
|
+
...plugin.broken === true ? { broken: true } : {},
|
|
3624
|
+
...note === void 0 ? {} : { note },
|
|
3625
|
+
pkg: plugin.pkg,
|
|
3626
|
+
...plugin.installed === void 0 ? {} : { version: {
|
|
3627
|
+
installed: plugin.installed,
|
|
3628
|
+
...plugin.latest === void 0 ? {} : { latest: plugin.latest }
|
|
3629
|
+
} }
|
|
3630
|
+
};
|
|
3631
|
+
});
|
|
3632
|
+
}
|
|
3633
|
+
//#endregion
|
|
3228
3634
|
//#region src/app/layouts/market/add-module-text.ts
|
|
3229
3635
|
var GUIDE_ITEMS = [
|
|
3230
3636
|
{
|
|
@@ -3343,17 +3749,23 @@ var PROBLEM_KEYS = {
|
|
|
3343
3749
|
"not-found": "panels.market.add.problemNotFound",
|
|
3344
3750
|
"not-a-package": "panels.market.add.problemNotPackage",
|
|
3345
3751
|
"not-a-bundle": "panels.market.add.problemNotBundle",
|
|
3752
|
+
"not-a-workbench-module": "panels.market.add.problemNotWorkbenchModule",
|
|
3753
|
+
"not-a-module-or-plugin": "panels.market.add.problemNotModuleOrPlugin",
|
|
3346
3754
|
network: "panels.market.add.problemNetwork",
|
|
3347
3755
|
unknown: "panels.market.add.problemUnknown"
|
|
3348
3756
|
};
|
|
3349
3757
|
function problemKey(problem) {
|
|
3350
3758
|
return PROBLEM_KEYS[problem] ?? PROBLEM_KEYS.unknown;
|
|
3351
3759
|
}
|
|
3760
|
+
function heldWizardPhase(phase, classifying) {
|
|
3761
|
+
return classifying && (phase === "preview" || phase === "idle") ? "inspecting" : phase;
|
|
3762
|
+
}
|
|
3352
3763
|
var FAILURE_KEYS = {
|
|
3353
3764
|
network: "panels.market.add.failureNetwork",
|
|
3354
3765
|
"spec-host": "panels.market.add.failureNetworkHost",
|
|
3355
3766
|
"not-found": "panels.market.add.failureNotFound",
|
|
3356
3767
|
"no-matching-version": "panels.market.add.failureNoMatchingVersion",
|
|
3768
|
+
"not-a-module-or-plugin": "panels.market.add.failureNotModuleOrPlugin",
|
|
3357
3769
|
"disk-full": "panels.market.add.failureDiskFull",
|
|
3358
3770
|
permission: "panels.market.add.failurePermission",
|
|
3359
3771
|
"build-blocked": "panels.market.add.failureBuildBlocked",
|
|
@@ -3458,7 +3870,9 @@ var PROGRESS_KEY = {
|
|
|
3458
3870
|
"update-bundle": "panels.market.updating",
|
|
3459
3871
|
"remove-bundle": "panels.market.uninstalling",
|
|
3460
3872
|
uninstall: "panels.market.uninstalling",
|
|
3461
|
-
"update-dependency": "panels.market.updating"
|
|
3873
|
+
"update-dependency": "panels.market.updating",
|
|
3874
|
+
"update-plugin": "panels.market.updating",
|
|
3875
|
+
"uninstall-plugin": "panels.market.uninstalling"
|
|
3462
3876
|
};
|
|
3463
3877
|
var ACTION_LABEL_KEY = {
|
|
3464
3878
|
install: "panels.market.install",
|
|
@@ -3466,7 +3880,9 @@ var ACTION_LABEL_KEY = {
|
|
|
3466
3880
|
"update-bundle": "panels.market.update",
|
|
3467
3881
|
"remove-bundle": "panels.market.uninstall",
|
|
3468
3882
|
uninstall: "panels.market.uninstall",
|
|
3469
|
-
"update-dependency": "panels.market.update"
|
|
3883
|
+
"update-dependency": "panels.market.update",
|
|
3884
|
+
"update-plugin": "panels.market.update",
|
|
3885
|
+
"uninstall-plugin": "panels.market.uninstall"
|
|
3470
3886
|
};
|
|
3471
3887
|
//#endregion
|
|
3472
3888
|
//#region src/app/layouts/rightbar/SharedSection.tsx
|
|
@@ -3528,7 +3944,11 @@ function PanelFoot({ text, size = "sm", children }) {
|
|
|
3528
3944
|
}
|
|
3529
3945
|
//#endregion
|
|
3530
3946
|
//#region src/app/layouts/rightbar/MarketView.tsx
|
|
3531
|
-
var CONFIRM_UNINSTALL = [
|
|
3947
|
+
var CONFIRM_UNINSTALL = [
|
|
3948
|
+
"uninstall",
|
|
3949
|
+
"remove-bundle",
|
|
3950
|
+
"uninstall-plugin"
|
|
3951
|
+
];
|
|
3532
3952
|
var CONFIRM_REMOVE = ["remove-bundle"];
|
|
3533
3953
|
function MarketLine({ t, row, pending, failure, onAct }) {
|
|
3534
3954
|
const running = pending !== null && pending.id === row.id ? pending : null;
|
|
@@ -3538,7 +3958,7 @@ function MarketLine({ t, row, pending, failure, onAct }) {
|
|
|
3538
3958
|
return /* @__PURE__ */ h("li", { className: MarketPage_module_default.marketRow }, /* @__PURE__ */ h("span", {
|
|
3539
3959
|
className: MarketPage_module_default.marketIcon,
|
|
3540
3960
|
"aria-hidden": "true"
|
|
3541
|
-
}, /* @__PURE__ */ h(IconModules, { size: 18 })), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketMain }, /* @__PURE__ */ h("span", { className: MarketPage_module_default.marketName },
|
|
3961
|
+
}, /* @__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", {
|
|
3542
3962
|
from: row.version.installed,
|
|
3543
3963
|
to: row.version.latest
|
|
3544
3964
|
}) : row.version.installed ?? row.version.latest ?? "")), /* @__PURE__ */ h("span", {
|
|
@@ -3563,11 +3983,14 @@ function MarketLine({ t, row, pending, failure, onAct }) {
|
|
|
3563
3983
|
variant: action === "install" ? "primary" : "outline",
|
|
3564
3984
|
className: danger ? "wb-dangerAction" : void 0,
|
|
3565
3985
|
icon: danger ? /* @__PURE__ */ h(IconTrashOutlineRegular, { size: 13 }) : void 0,
|
|
3566
|
-
"aria-label": danger ? t("panels.market.uninstallLabel", { name:
|
|
3986
|
+
"aria-label": danger ? t("panels.market.uninstallLabel", { name: marketRowTitle(row, t) }) : void 0,
|
|
3567
3987
|
disabled: locked,
|
|
3568
3988
|
onClick: () => onAct(action)
|
|
3569
3989
|
}, t(ACTION_LABEL_KEY[action]));
|
|
3570
|
-
}))), row.note === void 0 ? null : /* @__PURE__ */ h("div", {
|
|
3990
|
+
}))), row.note === void 0 ? null : /* @__PURE__ */ h("div", {
|
|
3991
|
+
className: MarketPage_module_default.marketNote,
|
|
3992
|
+
title: row.note.params.reason === void 0 ? void 0 : t("panels.market.moduleRefusedDetail", row.note.params)
|
|
3993
|
+
}, t(row.note.key, row.note.params)), failure === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketFailure }, failure));
|
|
3571
3994
|
}
|
|
3572
3995
|
function ConfirmUninstall({ t, name, onConfirm, onCancel }) {
|
|
3573
3996
|
const [acknowledged, setAcknowledged] = useState(false);
|
|
@@ -3596,7 +4019,48 @@ function MarketSection({ t, titleKey, rows, pending, failureOf, act, confirmActi
|
|
|
3596
4019
|
onAct: (action) => confirmActions.includes(action) ? onConfirming(row.id) : void act(row.id, action)
|
|
3597
4020
|
}))));
|
|
3598
4021
|
}
|
|
3599
|
-
function
|
|
4022
|
+
function MarketBody({ t, shown, pluginList, installedList, shared, pending, failed, notice, act, onConfirming }) {
|
|
4023
|
+
const failureOf = (id) => failed?.id === id ? failed.message : null;
|
|
4024
|
+
return /* @__PURE__ */ h(Fragment, null, notice === null ? null : /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketNote }, notice), marketSections(shown).map((section) => /* @__PURE__ */ h(MarketSection, {
|
|
4025
|
+
key: section.id,
|
|
4026
|
+
t,
|
|
4027
|
+
titleKey: section.titleKey,
|
|
4028
|
+
rows: section.rows,
|
|
4029
|
+
pending,
|
|
4030
|
+
failureOf,
|
|
4031
|
+
act,
|
|
4032
|
+
confirmActions: CONFIRM_UNINSTALL,
|
|
4033
|
+
onConfirming
|
|
4034
|
+
})), /* @__PURE__ */ h(MarketSection, {
|
|
4035
|
+
t,
|
|
4036
|
+
titleKey: "panels.market.sectionPlugins",
|
|
4037
|
+
rows: pluginList,
|
|
4038
|
+
pending,
|
|
4039
|
+
failureOf,
|
|
4040
|
+
act,
|
|
4041
|
+
confirmActions: CONFIRM_UNINSTALL,
|
|
4042
|
+
onConfirming
|
|
4043
|
+
}), /* @__PURE__ */ h(MarketSection, {
|
|
4044
|
+
t,
|
|
4045
|
+
titleKey: installedList.length > 0 && installedList.every((row) => row.local === true) ? "panels.market.sectionLocal" : "panels.market.sectionUnlisted",
|
|
4046
|
+
rows: installedList,
|
|
4047
|
+
pending,
|
|
4048
|
+
failureOf,
|
|
4049
|
+
act,
|
|
4050
|
+
confirmActions: CONFIRM_REMOVE,
|
|
4051
|
+
onConfirming
|
|
4052
|
+
}), /* @__PURE__ */ h(PanelFoot, {
|
|
4053
|
+
size: "md",
|
|
4054
|
+
text: t("panels.market.foot")
|
|
4055
|
+
}), /* @__PURE__ */ h(SharedSection, {
|
|
4056
|
+
t,
|
|
4057
|
+
rows: shared,
|
|
4058
|
+
pending,
|
|
4059
|
+
failureOf,
|
|
4060
|
+
act
|
|
4061
|
+
}));
|
|
4062
|
+
}
|
|
4063
|
+
function MarketView({ t, manifests, capabilities, freshness, onChanged, updates, installed, installedRead, plugins, settling, mock }) {
|
|
3600
4064
|
const [titles, setTitles] = useState(/* @__PURE__ */ new Map());
|
|
3601
4065
|
useEffect(() => {
|
|
3602
4066
|
if (mock === void 0) setTitles((known) => mergeTitles(known, manifests));
|
|
@@ -3613,6 +4077,7 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3613
4077
|
});
|
|
3614
4078
|
const [confirming, setConfirming] = useState(mock?.confirming ?? null);
|
|
3615
4079
|
const [failed, setFailed] = useState(mock?.failure ?? null);
|
|
4080
|
+
const [notice, setNotice] = useState(mock?.notice ?? null);
|
|
3616
4081
|
const removing = pending !== null && pending.action === "remove-bundle" && failed?.id !== pending.id ? pending.id : null;
|
|
3617
4082
|
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);
|
|
3618
4083
|
const pendingRow = removing === null || pending === null || rows.some((row) => row.id === removing) ? void 0 : {
|
|
@@ -3626,7 +4091,12 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3626
4091
|
...pending.version === void 0 ? {} : { version: { installed: pending.version } }
|
|
3627
4092
|
};
|
|
3628
4093
|
const shown = pendingRow === void 0 ? rows : [...rows, pendingRow];
|
|
3629
|
-
const
|
|
4094
|
+
const pluginList = installedPluginRows(mock?.plugins ?? plugins ?? []);
|
|
4095
|
+
const rowById = new Map([
|
|
4096
|
+
...shown,
|
|
4097
|
+
...installedList,
|
|
4098
|
+
...pluginList
|
|
4099
|
+
].map((row) => [row.id, row]));
|
|
3630
4100
|
const confirmingRow = confirming === null ? void 0 : rowById.get(confirming);
|
|
3631
4101
|
const act = async (id, action) => {
|
|
3632
4102
|
if (mock !== void 0) return;
|
|
@@ -3640,13 +4110,15 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3640
4110
|
});
|
|
3641
4111
|
setConfirming(null);
|
|
3642
4112
|
setFailed(null);
|
|
4113
|
+
if (action !== "uninstall-plugin") setNotice(null);
|
|
3643
4114
|
const dependency = action === "update-dependency";
|
|
4115
|
+
const byName = action === "remove-bundle" || action === "update-plugin" || action === "uninstall-plugin";
|
|
3644
4116
|
const outcome = await provision.send(dependency ? {
|
|
3645
4117
|
action,
|
|
3646
4118
|
id
|
|
3647
|
-
} :
|
|
4119
|
+
} : byName ? {
|
|
3648
4120
|
action,
|
|
3649
|
-
name:
|
|
4121
|
+
name: row?.pkg ?? ""
|
|
3650
4122
|
} : {
|
|
3651
4123
|
action,
|
|
3652
4124
|
unit: id
|
|
@@ -3660,6 +4132,10 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3660
4132
|
});
|
|
3661
4133
|
return;
|
|
3662
4134
|
}
|
|
4135
|
+
if (action === "uninstall-plugin") {
|
|
4136
|
+
const kept = installedPluginKept(outcome.value);
|
|
4137
|
+
setNotice(kept === void 0 ? null : t(kept.key, kept.names === void 0 ? {} : { names: kept.names.join(t("panels.market.listSeparator")) }));
|
|
4138
|
+
}
|
|
3663
4139
|
const reason = changeFailure(changeOf(outcome.value), t);
|
|
3664
4140
|
onChanged();
|
|
3665
4141
|
if (reason !== void 0) setFailed({
|
|
@@ -3667,46 +4143,32 @@ function MarketView({ t, manifests, capabilities, freshness, onChanged, updates,
|
|
|
3667
4143
|
message: t("panels.market.failed", { reason })
|
|
3668
4144
|
});
|
|
3669
4145
|
};
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
4146
|
+
const settled = marketSettled(freshness, installedRead);
|
|
4147
|
+
const nothing = shown.length === 0 && installedList.length === 0 && pluginList.length === 0;
|
|
4148
|
+
if (!settled || (settling?.size ?? 0) > 0 && shown.length === 0 && installedList.length === 0) return /* @__PURE__ */ h(MarketChecking, { t });
|
|
4149
|
+
if (nothing) return /* @__PURE__ */ h(MarketEmpty, { t });
|
|
4150
|
+
return /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h(MarketBody, {
|
|
3674
4151
|
t,
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
act,
|
|
3680
|
-
confirmActions: CONFIRM_UNINSTALL,
|
|
3681
|
-
onConfirming: setConfirming
|
|
3682
|
-
})), /* @__PURE__ */ h(MarketSection, {
|
|
3683
|
-
t,
|
|
3684
|
-
titleKey: installedList.length > 0 && installedList.every((row) => row.local === true) ? "panels.market.sectionLocal" : "panels.market.sectionUnlisted",
|
|
3685
|
-
rows: installedList,
|
|
4152
|
+
shown,
|
|
4153
|
+
pluginList,
|
|
4154
|
+
installedList,
|
|
4155
|
+
shared,
|
|
3686
4156
|
pending,
|
|
3687
|
-
|
|
4157
|
+
failed,
|
|
4158
|
+
notice,
|
|
3688
4159
|
act,
|
|
3689
|
-
confirmActions: CONFIRM_REMOVE,
|
|
3690
4160
|
onConfirming: setConfirming
|
|
3691
|
-
}), /* @__PURE__ */ h(PanelFoot, {
|
|
3692
|
-
size: "md",
|
|
3693
|
-
text: t("panels.market.foot")
|
|
3694
|
-
}), /* @__PURE__ */ h(SharedSection, {
|
|
3695
|
-
t,
|
|
3696
|
-
rows: shared,
|
|
3697
|
-
pending,
|
|
3698
|
-
failureOf: (id) => failed?.id === id ? failed.message : null,
|
|
3699
|
-
act
|
|
3700
4161
|
}), /* @__PURE__ */ h(ConfirmUninstall, {
|
|
3701
4162
|
key: confirming ?? "",
|
|
3702
4163
|
t,
|
|
3703
|
-
name: confirmingRow === void 0 ? null :
|
|
4164
|
+
name: confirmingRow === void 0 ? null : marketRowTitle(confirmingRow, t),
|
|
3704
4165
|
onCancel: () => setConfirming(null),
|
|
3705
4166
|
onConfirm: () => {
|
|
3706
4167
|
const id = confirming;
|
|
3707
4168
|
setConfirming(null);
|
|
3708
4169
|
if (id === null) return;
|
|
3709
|
-
|
|
4170
|
+
const row = rowById.get(id);
|
|
4171
|
+
act(id, row?.plugin === true ? "uninstall-plugin" : row?.pkg === void 0 ? "uninstall" : "remove-bundle");
|
|
3710
4172
|
}
|
|
3711
4173
|
}));
|
|
3712
4174
|
}
|
|
@@ -3716,6 +4178,9 @@ var BUNDLE_REGISTRIES_ROUTE = "bundle-registries";
|
|
|
3716
4178
|
var BUNDLE_INSPECT_ROUTE = "bundle-inspect";
|
|
3717
4179
|
var MODULE_VERSIONS_ROUTE = "module-versions";
|
|
3718
4180
|
//#endregion
|
|
4181
|
+
//#region src/shared/api/installed-plugins.ts
|
|
4182
|
+
var INSTALLED_PLUGINS_ROUTE = "panels/plugins";
|
|
4183
|
+
//#endregion
|
|
3719
4184
|
//#region src/shared/hooks/bundle-queries.ts
|
|
3720
4185
|
function readBundleRegistries() {
|
|
3721
4186
|
return apiGet(BUNDLE_REGISTRIES_ROUTE);
|
|
@@ -3729,10 +4194,14 @@ function readBundleInspection(spec, registry) {
|
|
|
3729
4194
|
function readModuleVersions(force = false) {
|
|
3730
4195
|
return apiGet(MODULE_VERSIONS_ROUTE, force ? { force: "1" } : void 0);
|
|
3731
4196
|
}
|
|
4197
|
+
function readInstalledPlugins(force = false) {
|
|
4198
|
+
return apiGet(INSTALLED_PLUGINS_ROUTE, force ? { force: "1" } : void 0);
|
|
4199
|
+
}
|
|
3732
4200
|
//#endregion
|
|
3733
4201
|
//#region src/app/layouts/market/use-module-versions.ts
|
|
3734
4202
|
var state = {
|
|
3735
4203
|
modules: null,
|
|
4204
|
+
plugins: null,
|
|
3736
4205
|
read: false,
|
|
3737
4206
|
checkedAt: null
|
|
3738
4207
|
};
|
|
@@ -3757,10 +4226,13 @@ function runModuleVersionsRead(force = false) {
|
|
|
3757
4226
|
if (inFlight !== null && inFlight.force === force) return inFlight.promise;
|
|
3758
4227
|
const seq = readSeq += 1;
|
|
3759
4228
|
if (force) newestForceSeq = seq;
|
|
3760
|
-
const promise = readModuleVersions(force).catch(() => null).then((
|
|
4229
|
+
const promise = Promise.all([readModuleVersions(force), readInstalledPlugins(force)]).catch(() => null).then((responses) => {
|
|
3761
4230
|
if (!force && seq < newestForceSeq) return;
|
|
4231
|
+
const versions = responses?.[0];
|
|
4232
|
+
const plugins = responses?.[1];
|
|
3762
4233
|
publish({
|
|
3763
|
-
modules:
|
|
4234
|
+
modules: versions?.ok === true ? versions.modules : state.modules,
|
|
4235
|
+
plugins: plugins?.ok === true ? plugins.plugins : state.plugins,
|
|
3764
4236
|
read: true,
|
|
3765
4237
|
checkedAt: Date.now()
|
|
3766
4238
|
});
|
|
@@ -3792,6 +4264,7 @@ function useModuleVersions() {
|
|
|
3792
4264
|
}, []);
|
|
3793
4265
|
return {
|
|
3794
4266
|
modules: value.modules,
|
|
4267
|
+
plugins: value.plugins,
|
|
3795
4268
|
read: value.read,
|
|
3796
4269
|
checkedAt: value.checkedAt,
|
|
3797
4270
|
reload
|
|
@@ -4010,7 +4483,7 @@ function AddModulePending({ t, kind }) {
|
|
|
4010
4483
|
})), /* @__PURE__ */ h("h2", {
|
|
4011
4484
|
className: AddModule_module_default.pendingTitle,
|
|
4012
4485
|
role: "status"
|
|
4013
|
-
}, kind === "inspecting" ? t("panels.market.add.
|
|
4486
|
+
}, kind === "inspecting" ? t("panels.market.add.classifying") : t("panels.market.add.installingTitle"))));
|
|
4014
4487
|
}
|
|
4015
4488
|
function AddModulePreview({ t, state }) {
|
|
4016
4489
|
const preview = state.preview;
|
|
@@ -4028,6 +4501,7 @@ function AddModuleResult({ t, state }) {
|
|
|
4028
4501
|
const restart = outcome.change.application === "restart-required";
|
|
4029
4502
|
const cancelled = outcome.change.application === "cancelled";
|
|
4030
4503
|
const notModule = outcome.supply.state === "not-a-module";
|
|
4504
|
+
const plugin = outcome.plugin;
|
|
4031
4505
|
const name = outcome.module.kind === "module" ? outcome.module.unit : outcome.module.pkg;
|
|
4032
4506
|
return /* @__PURE__ */ h("div", { className: AddModule_module_default.body }, /* @__PURE__ */ h("div", { className: AddModule_module_default.hero }, /* @__PURE__ */ h("span", {
|
|
4033
4507
|
className: AddModule_module_default.heroIcon,
|
|
@@ -4039,7 +4513,7 @@ function AddModuleResult({ t, state }) {
|
|
|
4039
4513
|
}) : /* @__PURE__ */ h(IconCheckCircleFillRegular, { size: 28 })), /* @__PURE__ */ h("h2", {
|
|
4040
4514
|
className: AddModule_module_default.wizardTitle,
|
|
4041
4515
|
role: failed ? "alert" : "status"
|
|
4042
|
-
}, 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", {
|
|
4516
|
+
}, 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", {
|
|
4043
4517
|
className: AddModule_module_default.resultWarn,
|
|
4044
4518
|
role: "alert"
|
|
4045
4519
|
}, 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)));
|
|
@@ -4110,6 +4584,7 @@ var ADD_MODULE_MOCKS = [
|
|
|
4110
4584
|
refused("not-found"),
|
|
4111
4585
|
refused("not-a-package"),
|
|
4112
4586
|
refused("not-a-bundle"),
|
|
4587
|
+
refused("not-a-module-or-plugin", "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上"),
|
|
4113
4588
|
refused("network", "getaddrinfo ENOTFOUND registry.example.com"),
|
|
4114
4589
|
refused("unknown", "pnpm 的返回码是 1"),
|
|
4115
4590
|
{
|
|
@@ -4191,6 +4666,25 @@ var ADD_MODULE_MOCKS = [
|
|
|
4191
4666
|
spec: "@dsh-workbench/module-hello",
|
|
4192
4667
|
outcome: outcome({})
|
|
4193
4668
|
},
|
|
4669
|
+
{
|
|
4670
|
+
id: "done-plugin",
|
|
4671
|
+
label: "装好了(opencli 插件)",
|
|
4672
|
+
phase: "result",
|
|
4673
|
+
spec: "opencli-plugin-cmdb",
|
|
4674
|
+
outcome: {
|
|
4675
|
+
change: change({ target: "opencli-plugin-cmdb" }),
|
|
4676
|
+
module: {
|
|
4677
|
+
kind: "unknown",
|
|
4678
|
+
pkg: "opencli-plugin-cmdb"
|
|
4679
|
+
},
|
|
4680
|
+
supply: { state: "no-needs" },
|
|
4681
|
+
plugin: {
|
|
4682
|
+
kind: "opencli-plugin",
|
|
4683
|
+
pkg: "opencli-plugin-cmdb",
|
|
4684
|
+
name: "cmdb"
|
|
4685
|
+
}
|
|
4686
|
+
}
|
|
4687
|
+
},
|
|
4194
4688
|
{
|
|
4195
4689
|
id: "done-restart",
|
|
4196
4690
|
label: "装好了(要重启)",
|
|
@@ -4285,6 +4779,42 @@ function stateOfMock(base, mock) {
|
|
|
4285
4779
|
};
|
|
4286
4780
|
}
|
|
4287
4781
|
//#endregion
|
|
4782
|
+
//#region src/shared/hooks/use-visible-busy.ts
|
|
4783
|
+
var use_visible_busy_exports = /* @__PURE__ */ __exportAll({
|
|
4784
|
+
busyView: () => busyView,
|
|
4785
|
+
heldPhase: () => heldPhase,
|
|
4786
|
+
useVisibleBusy: () => useVisibleBusy
|
|
4787
|
+
});
|
|
4788
|
+
function heldPhase(phase, refreshing) {
|
|
4789
|
+
return refreshing && phase === "ready" ? "loading" : phase;
|
|
4790
|
+
}
|
|
4791
|
+
function busyView(active, visible) {
|
|
4792
|
+
return {
|
|
4793
|
+
busy: visible,
|
|
4794
|
+
settling: visible && !active
|
|
4795
|
+
};
|
|
4796
|
+
}
|
|
4797
|
+
function useVisibleBusy(active, floorMs) {
|
|
4798
|
+
const [visible, setVisible] = useState(active);
|
|
4799
|
+
const since = useRef(null);
|
|
4800
|
+
useEffect(() => {
|
|
4801
|
+
if (active) {
|
|
4802
|
+
if (since.current === null) since.current = Date.now();
|
|
4803
|
+
setVisible(true);
|
|
4804
|
+
return;
|
|
4805
|
+
}
|
|
4806
|
+
const held = holdBusy(since.current, Date.now(), floorMs);
|
|
4807
|
+
since.current = null;
|
|
4808
|
+
if (!held.visible) {
|
|
4809
|
+
setVisible(false);
|
|
4810
|
+
return;
|
|
4811
|
+
}
|
|
4812
|
+
const timer = setTimeout(() => setVisible(false), held.releaseInMs);
|
|
4813
|
+
return () => clearTimeout(timer);
|
|
4814
|
+
}, [active, floorMs]);
|
|
4815
|
+
return busyView(active, visible);
|
|
4816
|
+
}
|
|
4817
|
+
//#endregion
|
|
4288
4818
|
//#region src/app/layouts/market/use-add-module.ts
|
|
4289
4819
|
function newRequestId() {
|
|
4290
4820
|
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -4307,6 +4837,7 @@ function useAddModule(options) {
|
|
|
4307
4837
|
const [failure, setFailure] = useState(null);
|
|
4308
4838
|
const generationRef = useRef(0);
|
|
4309
4839
|
const requestIdRef = useRef("");
|
|
4840
|
+
const { busy: classifying } = useVisibleBusy(phase === "inspecting", 500);
|
|
4310
4841
|
const write = useHostWrite({
|
|
4311
4842
|
channel: "provision",
|
|
4312
4843
|
networkText: failedText
|
|
@@ -4404,7 +4935,8 @@ function useAddModule(options) {
|
|
|
4404
4935
|
setOutcome({
|
|
4405
4936
|
change: value.change,
|
|
4406
4937
|
module: value.module,
|
|
4407
|
-
supply: value.supply
|
|
4938
|
+
supply: value.supply,
|
|
4939
|
+
...value.plugin === void 0 ? {} : { plugin: value.plugin }
|
|
4408
4940
|
});
|
|
4409
4941
|
setPhase("result");
|
|
4410
4942
|
if (value.change.application === "applied" || value.change.application === "restart-required") onInstalled();
|
|
@@ -4449,7 +4981,7 @@ function useAddModule(options) {
|
|
|
4449
4981
|
custom,
|
|
4450
4982
|
registryOpen,
|
|
4451
4983
|
guideOpen,
|
|
4452
|
-
phase,
|
|
4984
|
+
phase: heldWizardPhase(phase, classifying),
|
|
4453
4985
|
choices,
|
|
4454
4986
|
problem,
|
|
4455
4987
|
preview,
|
|
@@ -4607,10 +5139,10 @@ function makeMarketEntryIcon(units) {
|
|
|
4607
5139
|
function MarketPanel({ t, units }) {
|
|
4608
5140
|
const manifests = useLiveManifests(units);
|
|
4609
5141
|
const { capabilities, checkedAt, checking, forceProbe, reload: reloadCapability } = useCapabilityMap(0);
|
|
4610
|
-
const { modules, read: installedRead, reload: reloadVersions } = useModuleVersions();
|
|
5142
|
+
const { modules, plugins, read: installedRead, reload: reloadVersions } = useModuleVersions();
|
|
4611
5143
|
const [adding, setAdding] = useState(false);
|
|
4612
5144
|
const updates = useMemo(() => marketUpdatesOf(modules), [modules]);
|
|
4613
|
-
const installed = modules
|
|
5145
|
+
const installed = modules === null ? void 0 : withClientRefusals(modules, units.refusals());
|
|
4614
5146
|
const reload = useCallback(() => {
|
|
4615
5147
|
reloadCapability();
|
|
4616
5148
|
reloadVersions();
|
|
@@ -4667,11 +5199,14 @@ function MarketPanel({ t, units }) {
|
|
|
4667
5199
|
});
|
|
4668
5200
|
const mock = fixturePick.enabled ? fixturePick.current : void 0;
|
|
4669
5201
|
const mockNonce = fixturePick.nonce;
|
|
5202
|
+
const shownFreshness = mock === void 0 ? freshness : mock.loaded === false ? pendingFreshness : MOCK_FRESHNESS;
|
|
5203
|
+
const shownRead = mock === void 0 ? installedRead : mock.installedRead ?? true;
|
|
5204
|
+
const busy = !marketSettled(shownFreshness, shownRead) || shownFreshness.checking;
|
|
4670
5205
|
return /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketPage }, /* @__PURE__ */ h("header", { className: MarketPage_module_default.marketPageHead }, /* @__PURE__ */ h("div", null, /* @__PURE__ */ h("h1", { className: MarketPage_module_default.marketPageTitle }, t("panels.tab.market")), /* @__PURE__ */ h("p", { className: MarketPage_module_default.marketPageIntro }, t("panels.market.lead"))), /* @__PURE__ */ h("div", { className: MarketPage_module_default.marketPageTools }, /* @__PURE__ */ h(Tip, { label: t("panels.market.recheck") }, /* @__PURE__ */ h("button", {
|
|
4671
5206
|
type: "button",
|
|
4672
|
-
className: `${MarketPage_module_default.marketIconButton}${checking ? ` ${MarketPage_module_default.marketIconButtonSpinning}` : ""}`,
|
|
5207
|
+
className: `${MarketPage_module_default.marketIconButton}${shownFreshness.checking ? ` ${MarketPage_module_default.marketIconButtonSpinning}` : ""}`,
|
|
4673
5208
|
"aria-label": t("panels.market.checkUpdates"),
|
|
4674
|
-
disabled:
|
|
5209
|
+
disabled: busy,
|
|
4675
5210
|
onClick: () => {
|
|
4676
5211
|
forceProbe();
|
|
4677
5212
|
reloadVersions({ force: true });
|
|
@@ -4684,6 +5219,7 @@ function MarketPanel({ t, units }) {
|
|
|
4684
5219
|
size: "sm",
|
|
4685
5220
|
className: MarketPage_module_default.marketAddButton,
|
|
4686
5221
|
icon: /* @__PURE__ */ h(IconPlusOutlineRegular, { size: 13 }),
|
|
5222
|
+
disabled: busy,
|
|
4687
5223
|
onClick: () => setAdding(true)
|
|
4688
5224
|
}, t("panels.market.add.open")))), fixturePick.enabled ? /* @__PURE__ */ h(MockStrip, {
|
|
4689
5225
|
mocks: marketMocks,
|
|
@@ -4694,11 +5230,12 @@ function MarketPanel({ t, units }) {
|
|
|
4694
5230
|
t,
|
|
4695
5231
|
manifests,
|
|
4696
5232
|
capabilities,
|
|
4697
|
-
freshness:
|
|
5233
|
+
freshness: shownFreshness,
|
|
4698
5234
|
onChanged: reload,
|
|
4699
5235
|
updates,
|
|
4700
5236
|
installed,
|
|
4701
|
-
installedRead:
|
|
5237
|
+
installedRead: shownRead,
|
|
5238
|
+
plugins,
|
|
4702
5239
|
settling: mock === void 0 ? settling : void 0,
|
|
4703
5240
|
mock
|
|
4704
5241
|
}), /* @__PURE__ */ h(AddModuleDialog, {
|
|
@@ -4754,6 +5291,41 @@ var CLIENT_UNITS = [];
|
|
|
4754
5291
|
function assembleClientUnits(registry) {
|
|
4755
5292
|
for (const face of CLIENT_UNITS) registry.register(face);
|
|
4756
5293
|
}
|
|
5294
|
+
//#endregion
|
|
5295
|
+
//#region src/shared/api/unit-manifests.ts
|
|
5296
|
+
var UNIT_MANIFESTS_ROUTE = "unit-manifests";
|
|
5297
|
+
//#endregion
|
|
5298
|
+
//#region src/app/units/manifests.ts
|
|
5299
|
+
function createUnitManifestLoader(options = {}) {
|
|
5300
|
+
let inFlight = false;
|
|
5301
|
+
let queued = false;
|
|
5302
|
+
let watching = false;
|
|
5303
|
+
const subscribeFacts = options.subscribeFacts ?? subscribeFactRevision;
|
|
5304
|
+
const load = async (registry) => {
|
|
5305
|
+
if (inFlight) {
|
|
5306
|
+
queued = true;
|
|
5307
|
+
return;
|
|
5308
|
+
}
|
|
5309
|
+
inFlight = true;
|
|
5310
|
+
try {
|
|
5311
|
+
const response = await apiGet(UNIT_MANIFESTS_ROUTE).catch(() => null);
|
|
5312
|
+
if (response?.ok === true && Array.isArray(response.manifests)) registry.setManifests(response.manifests);
|
|
5313
|
+
} finally {
|
|
5314
|
+
inFlight = false;
|
|
5315
|
+
if (queued) {
|
|
5316
|
+
queued = false;
|
|
5317
|
+
load(registry);
|
|
5318
|
+
}
|
|
5319
|
+
}
|
|
5320
|
+
};
|
|
5321
|
+
return (registry) => {
|
|
5322
|
+
if (!watching) {
|
|
5323
|
+
watching = true;
|
|
5324
|
+
subscribeFacts(factOfRoute(UNIT_MANIFESTS_ROUTE), () => void load(registry));
|
|
5325
|
+
}
|
|
5326
|
+
load(registry);
|
|
5327
|
+
};
|
|
5328
|
+
}
|
|
4757
5329
|
var BootGate_module_default = {
|
|
4758
5330
|
actions: "_actions_jlw8j_1",
|
|
4759
5331
|
progress: "_progress_jlw8j_2",
|
|
@@ -7431,42 +8003,6 @@ function useLongTask(options) {
|
|
|
7431
8003
|
return { runs };
|
|
7432
8004
|
}
|
|
7433
8005
|
//#endregion
|
|
7434
|
-
//#region src/shared/hooks/use-visible-busy.ts
|
|
7435
|
-
var use_visible_busy_exports = /* @__PURE__ */ __exportAll({
|
|
7436
|
-
busyView: () => busyView,
|
|
7437
|
-
heldPhase: () => heldPhase,
|
|
7438
|
-
useVisibleBusy: () => useVisibleBusy
|
|
7439
|
-
});
|
|
7440
|
-
function heldPhase(phase, refreshing) {
|
|
7441
|
-
return refreshing && phase === "ready" ? "loading" : phase;
|
|
7442
|
-
}
|
|
7443
|
-
function busyView(active, visible) {
|
|
7444
|
-
return {
|
|
7445
|
-
busy: visible,
|
|
7446
|
-
settling: visible && !active
|
|
7447
|
-
};
|
|
7448
|
-
}
|
|
7449
|
-
function useVisibleBusy(active, floorMs) {
|
|
7450
|
-
const [visible, setVisible] = useState(active);
|
|
7451
|
-
const since = useRef(null);
|
|
7452
|
-
useEffect(() => {
|
|
7453
|
-
if (active) {
|
|
7454
|
-
if (since.current === null) since.current = Date.now();
|
|
7455
|
-
setVisible(true);
|
|
7456
|
-
return;
|
|
7457
|
-
}
|
|
7458
|
-
const held = holdBusy(since.current, Date.now(), floorMs);
|
|
7459
|
-
since.current = null;
|
|
7460
|
-
if (!held.visible) {
|
|
7461
|
-
setVisible(false);
|
|
7462
|
-
return;
|
|
7463
|
-
}
|
|
7464
|
-
const timer = setTimeout(() => setVisible(false), held.releaseInMs);
|
|
7465
|
-
return () => clearTimeout(timer);
|
|
7466
|
-
}, [active, floorMs]);
|
|
7467
|
-
return busyView(active, visible);
|
|
7468
|
-
}
|
|
7469
|
-
//#endregion
|
|
7470
8006
|
//#region src/shared/hooks/use-unit-board.ts
|
|
7471
8007
|
var use_unit_board_exports = /* @__PURE__ */ __exportAll({ useUnitBoard: () => useUnitBoard });
|
|
7472
8008
|
function useUnitBoard(options) {
|
|
@@ -7680,7 +8216,7 @@ var kit = {
|
|
|
7680
8216
|
};
|
|
7681
8217
|
function messagesOf(units) {
|
|
7682
8218
|
return units.map((face) => ({
|
|
7683
|
-
unit: face.
|
|
8219
|
+
unit: face.unit,
|
|
7684
8220
|
...face.messages === void 0 ? {} : { messages: face.messages }
|
|
7685
8221
|
}));
|
|
7686
8222
|
}
|
|
@@ -7721,12 +8257,14 @@ function apply(ctx) {
|
|
|
7721
8257
|
}
|
|
7722
8258
|
}
|
|
7723
8259
|
function mount(ctx) {
|
|
7724
|
-
const
|
|
8260
|
+
const loadUnitManifests = createUnitManifestLoader();
|
|
8261
|
+
const units = createClientUnitRegistry({ onUnknownUnit: () => loadUnitManifests(units) });
|
|
7725
8262
|
ctx.provide(UNITS_SERVICE, {
|
|
7726
8263
|
registerUnit: (face) => units.register(face),
|
|
7727
8264
|
manifests: () => units.manifests()
|
|
7728
8265
|
});
|
|
7729
8266
|
assembleClientUnits(units);
|
|
8267
|
+
loadUnitManifests(units);
|
|
7730
8268
|
const store = rightbarStore;
|
|
7731
8269
|
const observable = {
|
|
7732
8270
|
getSnapshot: () => store.getSnapshot(),
|