Export Web/SCORM : port complet du runtime jouable côté navigateur
Build and deploy / test-python (push) Successful in 9m20s
Build and deploy / test-js (push) Successful in 1m6s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped

Phase 1.2 de la feuille de route produit — un paquet SCORM tourne seul
dans le LMS du client, sans serveur Forge Engine disponible. Ajoute
static/js/play/offline/ (miroir JS de screens/rendering/ et
data_actions/, sous window.FORGE_OFFLINE) pour que variables, score,
données d'objet, répéteurs et conditions de visibilité fonctionnent
entièrement en mémoire côté navigateur ; branche actions.js et
bindings.js dessus au lieu d'un fetch() serveur. Ajoute
publish/build_scorm_package.py (paquet statique + imsmanifest.xml
SCORM 1.2 + wrapper API SCORM) et le bouton "Exporter (Web/SCORM)".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-09-02 07:43:02 +02:00
co-authored by Claude Sonnet 5
parent 9776fbc057
commit f3b72d73c9
32 changed files with 2469 additions and 22 deletions
+15 -2
View File
@@ -158,9 +158,23 @@ function applyOpenRowBindings() {
// "Modifier un élément" (ex: masquer une boîte) déclenchée par le même
// clic, puisque ces changements ne sont jamais enregistrés côté serveur.
function refreshRuntimeData() {
// Export Web/SCORM (voir le plan "port complet du runtime jouable côté
// navigateur") : window.FORGE_OFFLINE (posé UNIQUEMENT dans le paquet
// exporté, jamais dans /game/<slug>/play ni /jouer/<slug>) recalcule le
// payload EN MÉMOIRE (static/js/play/offline/full-payload.js) au lieu
// d'un fetch — le mécanisme de repérage/remplacement DOM qui suit
// (_forgeApplyFreshRuntimeData) reste ensuite EXACTEMENT le même code,
// en ligne comme hors ligne.
if (window.FORGE_OFFLINE) {
forgeRecomputeFullPayloadOffline(gameData);
return Promise.resolve().then(function () { return _forgeApplyFreshRuntimeData(gameData); });
}
return fetch(FORGE_PLAY_URLS.runtimePayload)
.then(r => r.json())
.then(newData => {
.then(_forgeApplyFreshRuntimeData);
}
function _forgeApplyFreshRuntimeData(newData) {
gameData = newData;
screensData = gameData.screens;
const screenData = screensData.find(s => s.id === window.currentScreenId);
@@ -305,5 +319,4 @@ function refreshRuntimeData() {
// qu'on vient de débloquer), donc l'affichage doit se mettre à jour
// tout de suite, sans attendre un aller-retour d'écran.
runScreenShowTriggers(window.currentScreenId);
});
}