82 lines
3.4 KiB
JavaScript
82 lines
3.4 KiB
JavaScript
|
|
import { createHash } from "node:crypto";
|
||
|
|
import { readdirSync, readFileSync, statSync } from "node:fs";
|
||
|
|
import path from "node:path";
|
||
|
|
|
||
|
|
const rootDir = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..");
|
||
|
|
const statePath = path.join(rootDir, "data", "runtime", "state.json");
|
||
|
|
const distDir = path.join(rootDir, "apps", "admin", "dist", "assets");
|
||
|
|
|
||
|
|
const state = JSON.parse(readFileSync(statePath, "utf8"));
|
||
|
|
const revision = (value) => createHash("sha1").update(JSON.stringify(value)).digest("hex");
|
||
|
|
const pendingCount = state.photoAssets.filter((asset) => asset.moderationStatus === "pending" && state.submissions.find((submission) => submission.id === asset.submissionId)?.source !== "admin_upload").length;
|
||
|
|
const approvedCount = state.photoAssets.filter((asset) => asset.moderationStatus === "approved").length;
|
||
|
|
const libraryRevision = revision({
|
||
|
|
photoAssets: state.photoAssets.map((asset) => ({
|
||
|
|
id: asset.id,
|
||
|
|
submissionId: asset.submissionId,
|
||
|
|
moderationStatus: asset.moderationStatus,
|
||
|
|
processingStatus: asset.processingStatus,
|
||
|
|
thumbKey: asset.thumbKey,
|
||
|
|
previewKey: asset.previewKey,
|
||
|
|
renderKey: asset.renderKey,
|
||
|
|
approvedAt: asset.approvedAt
|
||
|
|
})),
|
||
|
|
submissions: state.submissions.map((submission) => ({
|
||
|
|
id: submission.id,
|
||
|
|
status: submission.status,
|
||
|
|
contributorName: submission.contributorName,
|
||
|
|
lovedOneName: submission.lovedOneName,
|
||
|
|
displayName: submission.displayName,
|
||
|
|
caption: submission.caption,
|
||
|
|
promptAnswer: submission.promptAnswer,
|
||
|
|
notes: submission.notes,
|
||
|
|
source: submission.source
|
||
|
|
})),
|
||
|
|
collections: state.collections.map((collection) => ({
|
||
|
|
id: collection.id,
|
||
|
|
assetIds: collection.assetIds,
|
||
|
|
coverAssetId: collection.coverAssetId
|
||
|
|
}))
|
||
|
|
});
|
||
|
|
const programRevision = revision({
|
||
|
|
cues: state.cues.map((cue) => ({
|
||
|
|
id: cue.id,
|
||
|
|
orderIndex: cue.orderIndex,
|
||
|
|
sceneDefinitionId: cue.sceneDefinitionId,
|
||
|
|
effectPresetId: cue.effectPresetId,
|
||
|
|
updated: [cue.transitionIn, cue.transitionOut, cue.assetIds, cue.notes, cue.triggerMode, cue.durationMs, cue.nextCueId, cue.collectionId]
|
||
|
|
})),
|
||
|
|
safeSceneCueId: state.showConfig.safeSceneCueId
|
||
|
|
});
|
||
|
|
|
||
|
|
const payloads = {
|
||
|
|
bootstrap: JSON.stringify({ ...state, libraryRevision, programRevision }).length,
|
||
|
|
library: JSON.stringify({ photoAssets: state.photoAssets, submissions: state.submissions, collections: state.collections, revision: libraryRevision }).length,
|
||
|
|
live: JSON.stringify({ cues: state.cues, pendingCount, approvedCount, libraryRevision, programRevision }).length
|
||
|
|
};
|
||
|
|
|
||
|
|
const chunks = readdirSync(distDir)
|
||
|
|
.filter((file) => file.endsWith('.js') || file.endsWith('.css'))
|
||
|
|
.map((file) => ({ file, size: statSync(path.join(distDir, file)).size }))
|
||
|
|
.sort((left, right) => right.size - left.size);
|
||
|
|
|
||
|
|
const totalJs = chunks.filter((chunk) => chunk.file.endsWith('.js')).reduce((sum, chunk) => sum + chunk.size, 0);
|
||
|
|
|
||
|
|
console.log(JSON.stringify({
|
||
|
|
assets: chunks,
|
||
|
|
totalJsBytes: totalJs,
|
||
|
|
payloadBytes: payloads,
|
||
|
|
stablePollingBytesPerMinute: payloads.live * 15,
|
||
|
|
legacyPollingBytesPerMinute: (payloads.live + payloads.library) * 15,
|
||
|
|
stateCounts: {
|
||
|
|
photoAssets: state.photoAssets.length,
|
||
|
|
submissions: state.submissions.length,
|
||
|
|
cues: state.cues.length
|
||
|
|
},
|
||
|
|
viewportProfiles: {
|
||
|
|
preview: { targetFps: '18-24', dprCap: 0.85 },
|
||
|
|
programMonitor: { targetFps: '20-30', dprCap: 1 },
|
||
|
|
programOutput: { targetFps: '30-45', dprCap: 1.35 }
|
||
|
|
}
|
||
|
|
}, null, 2));
|