Chantier F - Typage Python - ruff S101 déplacé en per-file-ignores (pyproject.toml) - pyrightconfig.json : mode standard confirmé Chantier G - Assertions & bare-except - 16 blocs except documentés dans config.py - --cov-branch activé, seuil coverage 60→68% Chantier H - Cache settings - Stratégie documentée dans settings.py - _resolve_index_dir() logguée dans config.py Chantier I - Split gros fichiers JS - client.js 1509L → client.js 406L + clientAuth.js + clientOps.js + fetchUtils.js - toolbar.js 927L → toolbar.js 458L + toolbarActions.js + toolbarControls.js - FloatingViewer.js → FloatingViewer.impl.js + floatingViewer*(8 modules) - Viewer_impl.js → ViewerRuntime.js + viewerShell.js + viewerThemeStyles.js + viewerOverlayDismiss.js - model3dRenderer.js → model3dRenderer.impl.js + model3dCore.js + model3dLoaders.js + model3dSupport.js - dialogs.js → dialogs.js + DialogTemplates.js Chantier J - Tests frontend (Phases 1-2) - use_drag_drop.vitest.mjs : 5 tests - use_grid_state.vitest.mjs : 18 tests - security_client_headers, security_deep_merge, security_runtime_state, runtime_store, dialog_templates - Total: 80 fichiers test / 350 tests vitest Chantier K - Pinia migration - runtimeState.js entièrement migré vers Pinia - getOptionalRuntimeStore.js + runtimeEnrichmentState.js ajoutés Chantier L - Durcissement sécurité - tests/security/test_rate_limit.py : 8 tests rate-limit (state machine complète) - clientAuth.js : docstring sessionStorage security boundary - three.js 0.183.2 audité : 0 CVE (Snyk) Chantier M - Simplification config - deps.py, tool_detect.py, utils.py nettoyés docs: PLAN_REFACTO_V2_LONG_TERME.md ajouté et clôturé .gitignore: coverage/ ajouté
102 lines
3.3 KiB
JavaScript
102 lines
3.3 KiB
JavaScript
import { ensureViewerMetadataAsset } from "./genInfo.js";
|
|
import { getAssetMetadata, getFileMetadataScoped } from "../../api/client.js";
|
|
import { MFV_MODES } from "./floatingViewerConstants.js";
|
|
|
|
export function loadFloatingViewerMediaA(viewer, fileData, { autoMode = false } = {}) {
|
|
viewer._mediaA = fileData || null;
|
|
viewer._resetMfvZoom();
|
|
if (autoMode && viewer._mode !== MFV_MODES.SIMPLE) {
|
|
viewer._mode = MFV_MODES.SIMPLE;
|
|
viewer._updateModeBtnUI();
|
|
}
|
|
if (viewer._mediaA && typeof ensureViewerMetadataAsset === "function") {
|
|
const gen = ++viewer._refreshGen;
|
|
(async () => {
|
|
try {
|
|
const enriched = await ensureViewerMetadataAsset(viewer._mediaA, {
|
|
getAssetMetadata,
|
|
getFileMetadataScoped,
|
|
});
|
|
if (viewer._refreshGen !== gen) return;
|
|
if (enriched && typeof enriched === "object") {
|
|
viewer._mediaA = enriched;
|
|
viewer._refresh();
|
|
}
|
|
} catch (e) {
|
|
console.debug?.("[MFV] metadata enrich error", e);
|
|
}
|
|
})();
|
|
} else {
|
|
viewer._refresh();
|
|
}
|
|
}
|
|
|
|
export function loadFloatingViewerMediaPair(viewer, a, b) {
|
|
viewer._mediaA = a || null;
|
|
viewer._mediaB = b || null;
|
|
viewer._resetMfvZoom();
|
|
if (viewer._mode === MFV_MODES.SIMPLE) {
|
|
viewer._mode = MFV_MODES.AB;
|
|
viewer._updateModeBtnUI();
|
|
}
|
|
const gen = ++viewer._refreshGen;
|
|
const hydrate = async (asset) => {
|
|
if (!asset) return asset;
|
|
try {
|
|
const enriched = await ensureViewerMetadataAsset(asset, {
|
|
getAssetMetadata,
|
|
getFileMetadataScoped,
|
|
});
|
|
return enriched || asset;
|
|
} catch {
|
|
return asset;
|
|
}
|
|
};
|
|
(async () => {
|
|
const [A, B] = await Promise.all([hydrate(viewer._mediaA), hydrate(viewer._mediaB)]);
|
|
if (viewer._refreshGen !== gen) return;
|
|
viewer._mediaA = A || null;
|
|
viewer._mediaB = B || null;
|
|
viewer._refresh();
|
|
})();
|
|
}
|
|
|
|
export function loadFloatingViewerMediaQuad(viewer, a, b, c, d) {
|
|
viewer._mediaA = a || null;
|
|
viewer._mediaB = b || null;
|
|
viewer._mediaC = c || null;
|
|
viewer._mediaD = d || null;
|
|
viewer._resetMfvZoom();
|
|
if (viewer._mode !== MFV_MODES.GRID) {
|
|
viewer._mode = MFV_MODES.GRID;
|
|
viewer._updateModeBtnUI();
|
|
}
|
|
const gen = ++viewer._refreshGen;
|
|
const hydrate = async (asset) => {
|
|
if (!asset) return asset;
|
|
try {
|
|
const enriched = await ensureViewerMetadataAsset(asset, {
|
|
getAssetMetadata,
|
|
getFileMetadataScoped,
|
|
});
|
|
return enriched || asset;
|
|
} catch {
|
|
return asset;
|
|
}
|
|
};
|
|
(async () => {
|
|
const [A, B, C, D] = await Promise.all([
|
|
hydrate(viewer._mediaA),
|
|
hydrate(viewer._mediaB),
|
|
hydrate(viewer._mediaC),
|
|
hydrate(viewer._mediaD),
|
|
]);
|
|
if (viewer._refreshGen !== gen) return;
|
|
viewer._mediaA = A || null;
|
|
viewer._mediaB = B || null;
|
|
viewer._mediaC = C || null;
|
|
viewer._mediaD = D || null;
|
|
viewer._refresh();
|
|
})();
|
|
}
|