Files
MBN_STOCK_WEBVIEW/Web/playout-safety.js

105 lines
3.7 KiB
JavaScript

(function (root, factory) {
"use strict";
const api = Object.freeze(factory());
if (typeof module === "object" && module.exports) module.exports = api;
if (root) root.MbnPlayoutSafety = api;
})(typeof globalThis === "object" ? globalThis : this, function () {
"use strict";
const connectionStates = new Set([
"disabled", "dry-run-ready", "disconnected", "connecting", "connected",
"reconnecting", "disconnecting", "faulted", "outcome-unknown", "disposed"
]);
function normalizeConnectionState(value) {
const normalized = String(value || "unavailable")
.trim()
.toLocaleLowerCase("en-US")
.replace(/[\s_]+/g, "-");
return connectionStates.has(normalized) ? normalized : "unavailable";
}
function responseTimeoutFromNative(value) {
const operationTimeout = Number(value);
if (!Number.isFinite(operationTimeout) || operationTimeout < 100 || operationTimeout > 300000) {
return 15000;
}
return Math.min(305000, Math.max(5100, Math.trunc(operationTimeout) + 5000));
}
function commandBlockReason(snapshot, command) {
if (!snapshot || snapshot.pending) return "busy";
if (snapshot.outcomeUnknown) return "outcome-unknown";
if (!snapshot.commandAvailable) return "unavailable";
if (snapshot.refreshFaulted && command !== "take-out") return "refresh-fault";
const onAir = snapshot.engineState === "PROGRAM" || Boolean(snapshot.onAirCode);
const prepared = snapshot.engineState === "PREPARED" || Boolean(snapshot.preparedCode);
if (command === "next" && !onAir) return "next-requires-on-air";
if (command === "take-in" && !prepared) return "take-in-requires-prepare";
if (command === "take-out" && !onAir && !prepared) return "nothing-to-take-out";
return null;
}
function matchesPendingCommand(pending, payload) {
return Boolean(
pending && payload &&
payload.requestId === pending.requestId &&
payload.command === pending.command);
}
function canClearCommandError(error, sessionQuarantined) {
if (sessionQuarantined || !error) return !sessionQuarantined;
return error.outcomeUnknown !== true && error.code !== "WEB_TIMEOUT" &&
error.nonClearable !== true;
}
function playlistSnapshotLocked(snapshot) {
return Boolean(snapshot && (
snapshot.pending ||
snapshot.outcomeUnknown ||
snapshot.engineState === "PREPARED" ||
snapshot.engineState === "PROGRAM" ||
snapshot.preparedCode ||
snapshot.onAirCode));
}
function shouldClearRefreshError(error, refreshFaulted) {
return !refreshFaulted && error?.isRefreshFault === true;
}
function isNewerDatabaseStatusSequence(latestSequence, incomingSequence) {
const latest = Number.isSafeInteger(latestSequence) && latestSequence >= 0
? latestSequence
: 0;
return Number.isSafeInteger(incomingSequence) &&
incomingSequence > 0 && incomingSequence > latest;
}
function resolveStoredCatalogIndex(catalog, builderKey, cutCode) {
if (!Array.isArray(catalog)) return -1;
const exact = catalog.findIndex(item =>
item && item.reachable !== false && item.builderKey === builderKey);
if (exact >= 0) return exact;
const code = String(cutCode || "");
return catalog.findIndex(item => {
if (!item || item.reachable === false) return false;
const aliases = Array.isArray(item.aliases) ? item.aliases : [String(item.code || "")];
return aliases.includes(code);
});
}
return {
normalizeConnectionState,
responseTimeoutFromNative,
commandBlockReason,
matchesPendingCommand,
canClearCommandError,
playlistSnapshotLocked,
shouldClearRefreshError,
isNewerDatabaseStatusSequence,
resolveStoredCatalogIndex
};
});