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.
i nomi dei tag, in un punto solo
I tre tag, per nome
getCollectionTag('pages') // 'pages-list'
getDocumentIdTag('pages', '6a6d…') // 'pages_6a6d…'
getDocumentSlugTag('pages', 'chi-siamo') // 'pages_chi-siamo'la porta dell’area: i fetcher e i registri
un documento per id
Come si chiama
const doc = await getEntityById(await context.getPayload(), 'pages', id, 2)
Cosa torna se non c'e
null // e non un'eccezione: uno slot puo legittimamente non contenere niente
un documento per slug
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.
ricava i tag dei record incastonati (relazioni polimorfe: { relationTo, value })
la versione a due livelli per i documenti
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.
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.
il viewMode fuso con il tema, pronto per il renderer
la fusione base ⊕ tema (merge, non replace)
le ricette di animazione, lette dallo store
le aperture di ogni viewMode, risolte come le risolve il renderer
Continua
Altro in «Il motore · src/engine»
Il motoreI resolverTutte le diciassette pagineindice