✨ feat(ssr-server): enhance lookup and aggregate handling for SSR cache invalidation
- Improved parsing of `lookup` and `aggregate` options to support JSON strings and arrays. - Added support for object format in `lookup` and `aggregate` to specify collections. - Simplified dependency tracking for SSR cache invalidation based on new formats.
This commit is contained in:
@@ -78,14 +78,17 @@ When content changes, `clear_cache.js` only invalidates SSR entries that depend
|
||||
- `col:id` OR `col:*` on `PUT`/`DELETE`
|
||||
- everything on manual clear (`POST /ssr?clear=1` with no collection context)
|
||||
|
||||
|
||||
## Limit: 1 ensures precise dependencies
|
||||
|
||||
By default, an API query for a collection (like `/api/v1/_/content?filter=...`) sets a list dependency `collection:*`. This means *any* change to ANY entry in that collection will clear the SSR cache for this page.
|
||||
By default, an API query for a collection (like `/api/v1/_/content?filter=...`) sets a list dependency `collection:*`. This means _any_ change to ANY entry in that collection will clear the SSR cache for this page.
|
||||
|
||||
If you are querying a single document (like a page or article based on its path or slug), you should ALWAYS append `limit: 1` to your API call (or pass `limit=1` to `getDBEntries`).
|
||||
If you are querying a single document (like a page or article based on its path or slug), you should ALWAYS append `limit: 1` to your API call (or pass `{ filter: {...}, limit: 1 }` to `getDBEntries`).
|
||||
|
||||
When `api/hooks/lib/ssr-server.js` intercepts a request with `limit === 1` and exactly one result is returned, it will register a precise `collection:id` dependency instead of a wildcard `collection:*`. This optimizes the cache drastically, because edits to *other* pages won't invalidate this page.
|
||||
When `api/hooks/lib/ssr-server.js` intercepts a request with `limit === 1` and exactly one result is returned, it will register a precise `collection:id` dependency instead of a wildcard `collection:*`. This optimizes the cache drastically, because edits to _other_ pages won't invalidate this page.
|
||||
|
||||
### Automatic dependency tracking via `lookup` and `aggregate`
|
||||
|
||||
When options like `lookup` (e.g. `lookup: "image:medialib"`) or `aggregate` (e.g. `aggregate: "comments:contentId:count"`) are provided to an API call, `ssr-server.js` automatically parses these values and adds wildcard cache dependencies (`medialib:*` or `comments:*`) to the page. This guarantees that if a referenced image or child comment changes, the parent's SSR HTML is correctly flushed.
|
||||
|
||||
## How SSR data loading is supposed to work
|
||||
|
||||
@@ -181,6 +184,7 @@ if (typeof window === "undefined") {
|
||||
```
|
||||
|
||||
**Why this works:**
|
||||
|
||||
- The `tibi-types` package declares `var context: HookContext` as a global (available because goja provides it during SSR).
|
||||
- During SSR, `loadContent()` runs synchronously (goja transforms `async`/`await`).
|
||||
- By the time `render(App)` returns in `ssr.ts`, `context.is404` is already `true`.
|
||||
@@ -254,6 +258,7 @@ $effect(() => { loadData() })
|
||||
```
|
||||
|
||||
**Warum das funktioniert:**
|
||||
|
||||
- `loadData()` läuft während der Component-Initialisierung (vor Template-Auswertung)
|
||||
- `getCachedEntries` → `apiRequest` → SSR-Pfad → `context.ssrRequest()` → blockierender HTTP-Fetch in goja
|
||||
- goja's `await` auf einem bereits aufgelösten Promise läuft synchron weiter (kein Microtask-Hickhack)
|
||||
@@ -275,6 +280,7 @@ pathRewrite: function (path, req) {
|
||||
Ohne `noCache` wird die erste SSR-Antwort gecached und bei Code-Änderungen nicht invalidiert. Der Entwickler sieht immer den alten Stand. **Immer zuerst den Cache-Bypass prüfen, bevor SSR-Fehler gesucht werden.**
|
||||
|
||||
**Erkennungsmerkmale für veralteten SSR-Cache:**
|
||||
|
||||
- `X-SSR-Cache: true` im Response-Header
|
||||
- `<!--COMMENT--><!--SSR.ERROR-->` im HTML
|
||||
- `__SSR_CACHE__` enthält nicht die erwarteten Daten
|
||||
|
||||
Reference in New Issue
Block a user