Skip to content

Commit 694d9e1

Browse files
committed
review clarifications
1 parent f0c8403 commit 694d9e1

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

src/content/posts/017-cache-system.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ This is what makes the cache reactive rather than just a glorified `Map`. In a f
146146

147147
And here's the cherry on top: calling `getObservable()` on an entry that doesn't exist yet _automatically triggers a load_. You don't need to call `get()` first. Just subscribe, and the cache takes care of the rest. Lazy loading via subscription — because eagerness is overrated.
148148

149+
One nuance worth knowing: this auto-load only kicks in for _new_ entries (which start in the `loading` state). If an entry previously failed, `getObservable()` returns the failed observable as-is — it won't auto-retry. That's intentional: blindly retrying a persistent failure would just burn through requests. To retry, call `get()` or `reload()` explicitly. `CacheView` handles this for you with a retry button in the error UI.
150+
149151
## Request deduplication: the silent hero
150152

151153
This is one of those features that's invisible until it saves your bacon. If three components call `cache.get('user-42')` simultaneously — before the first request has returned — the cache fires _one_ network request and resolves all three promises with the same result.
@@ -221,15 +223,15 @@ This is incredibly useful for optimistic updates: update the cache with the expe
221223

222224
When a `load()` call throws, the cache catches the error, sets the entry to `failed` state (preserving any previously loaded value), and re-throws so that `get()` and `reload()` callers can handle it in their own try/catch.
223225

224-
But what about `getObservable()`? That triggers a load in the background — there's no caller to catch the error. For that, the `Cache` extends `EventHub` and emits an `onLoadError` event:
226+
But what about `getObservable()`? That triggers a load in the background — there's no caller to catch the error. For those background loads, the `Cache` extends `EventHub` and emits an `onLoadError` event:
225227

226228
```typescript
227229
cache.addListener('onLoadError', ({ args, error }) => {
228230
logger.error(`Failed to load cache entry for args ${JSON.stringify(args)}:`, error);
229231
});
230232
```
231233

232-
Wire this up to your logging, your monitoring, your Slack webhook — whatever helps you sleep at night. The point is: errors don't silently vanish into the void.
234+
Note that `onLoadError` only fires for loads triggered by `getObservable()` — not for direct `get()` or `reload()` calls, since those throw the error to the caller where you can catch it yourself. Wire this up to your logging, your monitoring, your Slack webhook — whatever helps you sleep at night. The point is: background errors don't silently vanish into the void.
233235

234236
## Service-level example: the API memoizer
235237

@@ -411,7 +413,7 @@ const ProductWithActions = Shade<{
411413
/>
412414
```
413415

414-
The `contentProps` are _type-checked_ against the content component's props (minus `data`, which CacheView provides). If your content component expects `{ data: CacheWithValue<Product>; label: string }`, then `contentProps` _must_ include `label: string`. TypeScript enforces this at compile time. No "oops, I forgot a prop" at runtime.
416+
Here's where the type system really earns its keep: `contentProps` isn't just optional — it's _conditionally required_. If your content component only expects `data`, you don't need `contentProps` at all. But the moment your component has extra props (like `onEdit` or `showPrice` above), TypeScript _forces_ you to provide `contentProps` with exactly those fields. Forget one, and you get a compile error — not a runtime mystery. CacheView provides `data` automatically, so `contentProps` only needs to cover the rest.
415417

416418
### View transitions
417419

0 commit comments

Comments
 (0)