discovery-media-player 0.1.90 → 0.1.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "discovery-media-player",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.92",
|
|
4
4
|
"description": "Self-hosted document viewer: per-recipient tracked links, reading analytics, live presentation. The core knows nothing about the application hosting it — everything it borrows arrives through an injected context.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pdf-viewer",
|
package/server/schema.js
CHANGED
|
@@ -303,7 +303,35 @@ async function vraimentSonderTout() {
|
|
|
303
303
|
for (const [cle] of quandNegatif) { connues.delete(cle); reponses.delete(cle); }
|
|
304
304
|
quandNegatif.clear();
|
|
305
305
|
for (const nom of Object.keys(ATTENDUES)) await attendue(nom);
|
|
306
|
-
|
|
306
|
+
const etat = etatDuSchema();
|
|
307
|
+
await ajouterSansRang(etat);
|
|
308
|
+
return etat;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* ⚠️ `mod_seq` NUL EST AMBIGU, ET UN NOMBRE AMBIGU NE MESURE RIEN. Le rattrapage de 0016 laisse
|
|
313
|
+
* DÉLIBÉRÉMENT sans rang les messages des présentations scellées (le scellé refuse de les écrire). Mais
|
|
314
|
+
* rien ne distingue « nul par décision » de « nul parce que le rattrapage n'a jamais tourné » : les
|
|
315
|
+
* deux se lisent « ligne sans rang ». On rend donc les DEUX nombres — total, et la part qui est
|
|
316
|
+
* légitimement scellée. Égaux ⇒ tout nul est un scellé attendu ; divergents ⇒ le rattrapage a laissé
|
|
317
|
+
* des lignes NON scellées derrière lui, anomalie à corriger. C'est la classe « une garde qu'on n'a pas
|
|
318
|
+
* vue refuser ne garde rien » appliquée à un compteur : le compteur devient un verdict. (relevé 2e hôte)
|
|
319
|
+
*
|
|
320
|
+
* Seulement si la colonne est là (sinon la question n'a pas de sens), et JAMAIS bloquant : un
|
|
321
|
+
* diagnostic ne doit pas casser la carte qu'il enrichit — mieux vaut pas de compteur qu'une carte muette.
|
|
322
|
+
*/
|
|
323
|
+
async function ajouterSansRang(etat) {
|
|
324
|
+
const r = reponses.get("doc_presentation_messages.mod_seq");
|
|
325
|
+
if (!r || !r.present) return;
|
|
326
|
+
try {
|
|
327
|
+
const scellees = await PLAYER.db.request("doc_presentations?active=eq.false&control_hash=is.null&select=slug");
|
|
328
|
+
const setScellees = new Set((Array.isArray(scellees) ? scellees : []).map((p) => p.slug));
|
|
329
|
+
// `limit` borne un diagnostic sur une base gravement cassée : au-delà, la divergence suffit déjà à
|
|
330
|
+
// alerter, le compte exact n'ajoute rien. `is.null` et `eq` restent de la syntaxe portable.
|
|
331
|
+
const nuls = await PLAYER.db.request("doc_presentation_messages?mod_seq=is.null&select=slug&limit=1000");
|
|
332
|
+
const liste = Array.isArray(nuls) ? nuls : [];
|
|
333
|
+
etat.sansRang = { total: liste.length, dontScellees: liste.filter((m) => setScellees.has(m.slug)).length };
|
|
334
|
+
} catch { /* best-effort : un compteur absent vaut mieux qu'une carte en échec */ }
|
|
307
335
|
}
|
|
308
336
|
|
|
309
337
|
/** La réponse, retenue pour qui la demandera — sans repasser par la base. */
|
package/supabase/init.sql
CHANGED
|
@@ -240,9 +240,15 @@ drop trigger if exists dpm_bump_modseq on public.doc_presentation_messages;
|
|
|
240
240
|
create trigger dpm_bump_modseq
|
|
241
241
|
before insert or update on public.doc_presentation_messages
|
|
242
242
|
for each row execute function public.player_bump_message_seq();
|
|
243
|
-
|
|
243
|
+
-- ⚠️ Le rattrapage EXCLUT les présentations scellées (0007/0010) : le trigger dpm_archive_scellee lève
|
|
244
|
+
-- sur toute écriture dans une présentation gelée, et une seule de ses lignes ferait échouer l'install.
|
|
245
|
+
update public.doc_presentation_messages m
|
|
244
246
|
set mod_seq = nextval('public.doc_presentation_messages_modseq')
|
|
245
|
-
where mod_seq is null
|
|
247
|
+
where m.mod_seq is null
|
|
248
|
+
and not exists (
|
|
249
|
+
select 1 from public.doc_presentations p
|
|
250
|
+
where p.slug = m.slug and p.active = false and p.control_hash is null
|
|
251
|
+
);
|
|
246
252
|
create index if not exists idx_dpm_slug_modseq
|
|
247
253
|
on public.doc_presentation_messages (slug, mod_seq);
|
|
248
254
|
|
|
@@ -47,10 +47,20 @@ create trigger dpm_bump_modseq
|
|
|
47
47
|
for each row execute function public.player_bump_message_seq();
|
|
48
48
|
|
|
49
49
|
-- Rattrapage des lignes déjà présentes : sans `mod_seq`, elles seraient invisibles au différentiel.
|
|
50
|
-
--
|
|
51
|
-
|
|
50
|
+
-- ⚠️ IL RESPECTE LE SCELLÉ D'ARCHIVE (0007/0010). Cet update écrit CHAQUE ligne — or le trigger
|
|
51
|
+
-- dpm_archive_scellee LÈVE sur toute écriture dans une présentation scellée (active=false ET
|
|
52
|
+
-- control_hash IS NULL). Une seule ligne d'une présentation scellée ferait échouer la migration
|
|
53
|
+
-- ENTIÈRE. On exclut donc ces lignes — une présentation scellée est GELÉE, y compris son rang : ses
|
|
54
|
+
-- messages restent sans mod_seq (historiques, jamais resynchronisés en direct, servis par la charge
|
|
55
|
+
-- complète). Deux gardes correctes — le scellé (0007) et ce rattrapage — dont la COMPOSITION
|
|
56
|
+
-- bloquerait sans cette exclusion, et qu'aucun des deux fichiers ne pouvait prévoir seul.
|
|
57
|
+
update public.doc_presentation_messages m
|
|
52
58
|
set mod_seq = nextval('public.doc_presentation_messages_modseq')
|
|
53
|
-
where mod_seq is null
|
|
59
|
+
where m.mod_seq is null
|
|
60
|
+
and not exists (
|
|
61
|
+
select 1 from public.doc_presentations p
|
|
62
|
+
where p.slug = m.slug and p.active = false and p.control_hash is null
|
|
63
|
+
);
|
|
54
64
|
|
|
55
65
|
-- La lecture différentielle `slug=eq.X&mod_seq=gt.N&order=mod_seq.asc` doit rester rapide.
|
|
56
66
|
create index if not exists idx_dpm_slug_modseq
|