gestion_table_tournante_libre/src/application/generation_travailleur.js

74 lines
4 KiB
JavaScript
Raw Normal View History

2026-10-07 06:09:45 -04:00
// © 2026 TechnoLibre (http://www.technolibre.ca)
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
// Le côté travailleur de la génération (§ 5.7, § 5.10) : la recherche du
// moteur hors du fil de l'interface, une proposition par message. Un
// travailleur reçoit le rang d'une proposition, la calcule par proposerUne,
// et poste ses avancements puis la proposition ou son erreur ; il attend
// ensuite le rang suivant, que l'exécuteur lui donne ou non :
2026-10-07 06:09:45 -04:00
//
// → { type: 'proposer', configuration, reglages, rang }
2026-10-07 06:09:45 -04:00
// ← { type: 'avancement', fait, total } au plus une fois toutes les
// CADENCE_AVANCEMENT progressions
// du moteur, fait croissant ; fait
// et total comptent dans la seule
// proposition, total valant arret
// ← { type: 'proposition', proposition } celle de rang rang de rechercher,
// telle quelle
2026-10-07 06:09:45 -04:00
// ← { type: 'erreur', code, details } REGLAGE_HORS_DOMAINE {reglage}
// d'exigerReglages, avant tout
// calcul ; puis, par
// versErreurGeneration, le code et
// les détails d'une
// ErreurConfiguration
// ← { type: 'faute', message, pile } une erreur que versErreurGeneration
// ne convertit pas — un rang hors
// de 1 à nombre compris : une faute
// de programmation, son texte et sa
// pile, que l'exécuteur relève
// comme une faute
2026-10-07 06:09:45 -04:00
//
// Le travailleur ne garde rien d'un message à l'autre : chaque proposition
// se calcule à partir du seul message qui la demande. L'annulation est
// terminate() du côté de l'interface : immédiate, sans résultat partiel ; le
// travailleur ne lit aucun signal. Un message d'un autre type ne lance rien.
// Le gestionnaire ne lève jamais : le canal d'erreur du travailleur ne porte
// ainsi que l'échec de son script — qui ne se charge ou ne se compile pas —,
// et l'exécuteur ne confond pas les deux.
import { proposerUne } from '../moteur/recherche.js';
2026-10-07 06:09:45 -04:00
import { ErreurGeneration, exigerReglages, versErreurGeneration } from './generation.js';
/** Progressions du moteur — une toutes les 1 000 itérations — entre deux messages d'avancement. */
export const CADENCE_AVANCEMENT = 50;
/**
* Branche une portée de travailleur — { onmessage, postMessage } — sur
* proposerUne, selon les messages de l'en-tête du module.
2026-10-07 06:09:45 -04:00
*
* @param {{onmessage: ((evenement: {data: unknown}) => void)|null, postMessage: (message: Object) => void}} portee
*/
export function brancherTravailleur(portee) {
portee.onmessage = ({ data }) => {
if (data === null || typeof data !== 'object' || data.type !== 'proposer') return;
2026-10-07 06:09:45 -04:00
let progressions = 0;
const progression = (fait, total) => {
progressions += 1;
if (progressions % CADENCE_AVANCEMENT === 0) portee.postMessage({ type: 'avancement', fait, total });
};
try {
exigerReglages(data.reglages);
const proposition = proposerUne(data.configuration, data.reglages, data.rang, { progression });
portee.postMessage({ type: 'proposition', proposition });
2026-10-07 06:09:45 -04:00
} catch (erreur) {
const convertie = versErreurGeneration(erreur);
if (convertie instanceof ErreurGeneration) {
portee.postMessage({ type: 'erreur', code: convertie.code, details: convertie.details });
} else {
const message = String(convertie);
const pile = typeof convertie?.stack === 'string' ? convertie.stack : message;
portee.postMessage({ type: 'faute', message, pile });
}
2026-10-07 06:09:45 -04:00
}
};
}