WoodyLab
WoodyLabBuild with UIMS

Documentazione · src/engine/dal

La lettura del dato

Tredici file fra la pagina e il database. Ogni lettura è in cache, e ogni cache sa da cosa dipende — comprese le cose che stanno dentro il documento che ha letto.

Ogni lettura porta i suoi tag

Ogni fetcher avvolge la propria query in `unstable_cache` con i tag definiti in un punto solo, e gli stessi tag li invalidano gli hook `revalidateCollection` e `revalidateDelete` quando un documento cambia. Il patto vale solo se le due parti usano la stessa funzione per costruire il tag: per questo `cache-tags.ts` è tre righe e non è inline.

  • dal/cache-tags.ts — i nomi dei tag, in un punto solo
  • dal/index.ts — la porta dell’area: i fetcher e i registri
  • dal/getEntityById.ts — un documento per id
  • dal/getEntityBySlug.ts — un documento per slug
  • dal/getEntitiesByQuery.ts — N documenti da una query

Due letture, quando la dipendenza è dentro il documento

Una pagina dipende anche da quello che ha dentro: il menu incastonato nel blocco navigation dell’header, il record riferito da una card. Se cambia il menu, la pagina che lo mostra è stantia — ma il tag del menu la cache della pagina non ce l’ha, perché Next non sa derivare i tag dal risultato di una lettura.

La soluzione sono due livelli. Una lettura superficiale (`depth: 0`) restituisce gli id dei riferimenti; da quelli si costruiscono i tag; poi si fa la lettura profonda in cache con TUTTI i tag, il proprio e quelli delle dipendenze. Costa una lettura in più, ed è l’unico modo per avere invalidazione corretta senza svuotare tutto a ogni modifica.

  • dal/collectDependencyTags.ts — ricava i tag dei record incastonati (relazioni polimorfe: `{ relationTo, value }`)
  • dal/getEntityBySlugWithDeps.ts — la versione a due livelli per i documenti
  • dal/getCachedGlobalWithDeps.ts — la versione a due livelli per i global (header, footer)

Le sorgenti esterne invecchiano a tempo

Un JSON che sta altrove non ha un `afterChange` che ci avvisi: nessun hook scatterà mai per invalidarlo. Quindi non si invalida per evento ma per tempo — `revalidateSec` limita quanto può essere vecchio — e resta un tag dedicato per poterlo forzare a mano quando si sa che è cambiato.

  • dal/getExternalJson.ts — una sorgente HTTP dentro la DAL: cache a tempo più tag manuale

I registri: la forma letta dagli store, non dal database

Il registro dei viewMode legge `db.viewmodes.json`, applica l’override del tema attivo e restituisce la definizione pronta per il renderer. L’override è una FUSIONE, non una sostituzione: con la sostituzione un tema che dichiarava solo `className` buttava via quello base, che quindi non garantiva più niente e andava ricopiato in ogni tema.

Il registro delle animazioni fa lo stesso per le ricette. La versione precedente prendeva un `BasePayload` e faceva una `payload.find` per OGNI reazione, al momento della risoluzione, senza cache — la cache era stata rinunciata di proposito per evitare un altro problema. Leggendo dallo store il problema non si pone: non c’è query da mettere in cache.

`slotsByViewMode` risolve le aperture ESATTAMENTE come le risolve il renderer. È usato dall’interfaccia per proporre i nomi veri, e la ragione per cui condivide il codice invece di riprodurlo è che una divergenza fra i due produrrebbe elementi che non appaiono.

  • dal/viewModeRegistry.ts — il viewMode fuso con il tema, pronto per il renderer
  • dal/applyThemeOverride.ts — la fusione base ⊕ tema (merge, non replace)
  • dal/animationRegistry.ts — le ricette di animazione, lette dallo store
  • dal/slotsByViewMode.ts — le aperture di ogni viewMode, risolte come le risolve il renderer
Login