Files
ST-Bionic-Memory-Ecology/host-adapter/capabilities.js
2026-03-26 22:24:45 +08:00

114 lines
2.9 KiB
JavaScript

const DEFAULT_UNAVAILABLE_REASON = "宿主能力不可用";
export const HOST_ADAPTER_VERSION = "phase1-bridge-skeleton";
export function normalizeVersionHints(versionHints = {}) {
const normalized = {};
for (const [key, rawValue] of Object.entries(versionHints || {})) {
if (rawValue == null || rawValue === "") continue;
if (Array.isArray(rawValue)) {
const values = rawValue
.map((value) => String(value ?? "").trim())
.filter(Boolean);
if (values.length > 0) {
normalized[key] = values;
}
continue;
}
if (typeof rawValue === "object") {
const nested = normalizeVersionHints(rawValue);
if (Object.keys(nested).length > 0) {
normalized[key] = nested;
}
continue;
}
normalized[key] = String(rawValue).trim();
}
return Object.freeze(normalized);
}
export function mergeVersionHints(...sources) {
const merged = {};
for (const source of sources) {
if (!source || typeof source !== "object") continue;
for (const [key, value] of Object.entries(source)) {
if (value == null || value === "") continue;
merged[key] = Array.isArray(value) ? [...value] : value;
}
}
return normalizeVersionHints(merged);
}
export function buildCapabilityStatus({
available = false,
mode = "",
fallbackReason = "",
versionHints = {},
} = {}) {
const normalizedAvailable = Boolean(available);
const normalizedMode =
String(mode || "").trim() ||
(normalizedAvailable ? "available" : "unavailable");
return Object.freeze({
available: normalizedAvailable,
mode: normalizedMode,
fallbackReason: normalizedAvailable
? String(fallbackReason || "").trim()
: String(fallbackReason || DEFAULT_UNAVAILABLE_REASON).trim(),
versionHints: normalizeVersionHints(versionHints),
});
}
export function buildCapabilityCollectionSnapshot(
capabilities = {},
options = {},
) {
const normalizedCapabilities = {};
const capabilityNames = Object.keys(capabilities || {});
let availableCount = 0;
for (const name of capabilityNames) {
const capability = buildCapabilityStatus(capabilities[name]);
normalizedCapabilities[name] = capability;
if (capability.available) {
availableCount += 1;
}
}
const totalCount = capabilityNames.length;
const available = availableCount > 0;
const mode =
totalCount === 0
? "empty"
: availableCount === totalCount
? "full"
: available
? "partial"
: "fallback";
return Object.freeze({
available,
mode,
fallbackReason:
available || totalCount === 0 ? "" : "未检测到可用宿主桥接能力",
versionHints: mergeVersionHints(
{
adapter: HOST_ADAPTER_VERSION,
availableCount: String(availableCount),
totalCount: String(totalCount),
},
options.versionHints,
),
...normalizedCapabilities,
});
}