Phase 7c+7d: cache invalidation + offline data layer
7c: Client data cache management via element attributes (sx-cache-invalidate) and response headers (SX-Cache-Invalidate, SX-Cache-Update). Programmatic API: invalidate-page-cache, invalidate-all-page-cache, update-page-cache. 7d: Service Worker (sx-sw.js) with IndexedDB for offline-capable data caching. Network-first for /sx/data/ and /sx/io/, stale-while- revalidate for /static/. Cache invalidation propagates from in-memory cache to SW via postMessage. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -195,6 +195,10 @@
|
||||
;; Triggers (before swap)
|
||||
(dispatch-trigger-events el (get resp-headers "trigger"))
|
||||
|
||||
;; Cache directives — process before navigation so cache is
|
||||
;; ready when the target page loads.
|
||||
(process-cache-directives el resp-headers text)
|
||||
|
||||
(cond
|
||||
;; Redirect
|
||||
(get resp-headers "redirect")
|
||||
@@ -589,6 +593,76 @@
|
||||
{"data" data "ts" (now-ms)})))
|
||||
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Client-side routing — cache management
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(define invalidate-page-cache
|
||||
(fn (page-name)
|
||||
;; Clear cached data for a page. Removes all cache entries whose key
|
||||
;; matches page-name (exact) or starts with "page-name:" (with params).
|
||||
;; Also notifies the service worker to clear its IndexedDB entries.
|
||||
(for-each
|
||||
(fn (k)
|
||||
(when (or (= k page-name) (starts-with? k (str page-name ":")))
|
||||
(dict-set! _page-data-cache k nil)))
|
||||
(keys _page-data-cache))
|
||||
(sw-post-message {"type" "invalidate" "page" page-name})
|
||||
(log-info (str "sx:cache invalidate " page-name))))
|
||||
|
||||
(define invalidate-all-page-cache
|
||||
(fn ()
|
||||
;; Clear all cached page data and notify service worker.
|
||||
(set! _page-data-cache (dict))
|
||||
(sw-post-message {"type" "invalidate" "page" "*"})
|
||||
(log-info "sx:cache invalidate *")))
|
||||
|
||||
(define update-page-cache
|
||||
(fn (page-name data)
|
||||
;; Replace cached data for a page with server-provided data.
|
||||
;; Uses a bare page-name key (no params) — the server knows the
|
||||
;; canonical data shape for the page.
|
||||
(let ((cache-key (page-data-cache-key page-name (dict))))
|
||||
(page-data-cache-set cache-key data)
|
||||
(log-info (str "sx:cache update " page-name)))))
|
||||
|
||||
(define process-cache-directives
|
||||
(fn (el resp-headers response-text)
|
||||
;; Process cache invalidation and update directives from both
|
||||
;; element attributes and response headers.
|
||||
;;
|
||||
;; Element attributes (set by component author):
|
||||
;; sx-cache-invalidate="page-name" — clear page cache on success
|
||||
;; sx-cache-invalidate="*" — clear all page caches
|
||||
;;
|
||||
;; Response headers (set by server):
|
||||
;; SX-Cache-Invalidate: page-name — clear page cache
|
||||
;; SX-Cache-Update: page-name — replace cache with response data
|
||||
|
||||
;; 1. Element-level invalidation
|
||||
(let ((el-invalidate (dom-get-attr el "sx-cache-invalidate")))
|
||||
(when el-invalidate
|
||||
(if (= el-invalidate "*")
|
||||
(invalidate-all-page-cache)
|
||||
(invalidate-page-cache el-invalidate))))
|
||||
|
||||
;; 2. Response header invalidation
|
||||
(let ((hdr-invalidate (get resp-headers "cache-invalidate")))
|
||||
(when hdr-invalidate
|
||||
(if (= hdr-invalidate "*")
|
||||
(invalidate-all-page-cache)
|
||||
(invalidate-page-cache hdr-invalidate))))
|
||||
|
||||
;; 3. Response header cache update (server pushes fresh data)
|
||||
;; parse-sx-data is a platform-provided function that parses SX text
|
||||
;; into a data value (returns nil on parse error).
|
||||
(let ((hdr-update (get resp-headers "cache-update")))
|
||||
(when hdr-update
|
||||
(let ((data (parse-sx-data response-text)))
|
||||
(when data
|
||||
(update-page-cache hdr-update data)))))))
|
||||
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Client-side routing
|
||||
;; --------------------------------------------------------------------------
|
||||
@@ -1061,6 +1135,8 @@
|
||||
;; (resolve-page-data name params cb) → void; resolves data for a named page.
|
||||
;; Platform decides transport (HTTP, cache, IPC, etc). Calls (cb data-dict)
|
||||
;; when data is available. params is a dict of URL/route parameters.
|
||||
;; (parse-sx-data text) → parsed SX data value, or nil on error.
|
||||
;; Used by cache update to parse server-provided data in SX format.
|
||||
;;
|
||||
;; From boot.sx:
|
||||
;; _page-routes → list of route entries
|
||||
@@ -1080,4 +1156,8 @@
|
||||
;; (csrf-token) → string
|
||||
;; (cross-origin? url) → boolean
|
||||
;; (now-ms) → timestamp ms
|
||||
;;
|
||||
;; === Cache management ===
|
||||
;; (parse-sx-data text) → parsed SX data value, or nil on error
|
||||
;; (sw-post-message msg) → void; post message to active service worker
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user