From 8f37684599d9548ad3dfb1c30e8c1b12f0dd952e Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Fri, 3 Jul 2026 07:11:47 -0600 Subject: [PATCH] docs(resources): make target.loadedFromSource canonical; drop context mirror MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cache disposition is a per-get result — it belongs on the RequestTarget for that get, not the shared request context (which is last-write-wins across every get in the request). Reframe the section around target.loadedFromSource (what the REST handler actually reads) and remove context.loadedFromSource, which is being removed in core (harper#1590). Co-Authored-By: Claude Opus 4.8 --- reference/resources/resource-api.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/reference/resources/resource-api.md b/reference/resources/resource-api.md index 58712ee3..d434e808 100644 --- a/reference/resources/resource-api.md +++ b/reference/resources/resource-api.md @@ -250,21 +250,23 @@ Harper automatically serializes concurrent requests for the same missing or stal #### Observing cache disposition -Each `get` on a caching table records whether the record came from the cache or from the source, in the `loadedFromSource` property of both the request context and the `RequestTarget`: +Whether a `get` on a caching table was served from cache or loaded from the source is a **per-`get` result**, recorded on the `RequestTarget` for that call as `target.loadedFromSource`. Because each `get()` has its own target, the value is precise to that one call and unaffected by any nested or subsequent gets — it is what Harper's REST handler reads to set cache response headers. ```javascript -const context = {}; -const record = await MyCache.get(recordId, context); -console.log(context.loadedFromSource); // true = went to the source, false = served from cache +import { RequestTarget } from 'harper'; + +const target = new RequestTarget(); +target.id = recordId; +const record = await MyCache.get(target); +console.log(target.loadedFromSource); // true = loaded from source, false = served from cache ``` -Within a resource method, the same value is available on the active context via `getContext().loadedFromSource` after the `get` resolves. The flag settles as follows: +The flag settles as follows: - `true` — the get went to the source: either it fetched the record, or the source errored and a stale cached record was served as a fallback (`staleIfError`). `true` means a source request was made, not necessarily that the returned data is fresh. - `false` — the record was served from the cache: fresh hits, `onlyIfCached` requests, stale-while-revalidate responses (the source fetch continues in the background), and requests that waited on another request's in-flight fetch of the same record. This last case means a cache hit can still take as long as an upstream fetch. -- Each get on a caching table in the same context overwrites the value, so read it after the `get` you are measuring. -Note that `get()` returns a plain `RecordObject`, not a resource instance — the record itself does not carry cache disposition; read it from the context (or an explicitly passed `RequestTarget`). Prior to Harper 5.1.16, `context.loadedFromSource` was never assigned and the flag was only observable via an explicitly passed `RequestTarget`. +`get()` returns a plain `RecordObject`, not a resource instance, so the returned record does not itself carry cache disposition — read it from the `RequestTarget` you passed to the get. A `get` called with a plain id has no target to read back, so pass a `RequestTarget` when you need to observe disposition. #### Source `get` — controlling timestamp and expiration @@ -653,7 +655,6 @@ Returns the current context, which includes: - `user` — User object with username, role, and authorization information - `transaction` — The current transaction -- `loadedFromSource` — For caching tables (5.1.16+), cache disposition of the most recent `get` in this context: `true` if it went to the source, `false` if served from cache (see [Observing cache disposition](#observing-cache-disposition)) When triggered by HTTP, the context is the `Request` object with these additional properties: @@ -1159,7 +1160,6 @@ getContext is availabe as export from the `harper` module, or as a global variab - `user` — User object with username, role, and authorization information - `transaction` — The current transaction -- `loadedFromSource` — For caching tables (5.1.16+), cache disposition of the most recent `get` in this context: `true` if it went to the source, `false` if served from cache (see [Observing cache disposition](#observing-cache-disposition)) When triggered by HTTP, the context is the `Request` object with these additional properties: