Skip to content

feature: cache key modification#578

Open
termorey wants to merge 6 commits intoeffector:masterfrom
termorey:feature/cache-key-modification
Open

feature: cache key modification#578
termorey wants to merge 6 commits intoeffector:masterfrom
termorey:feature/cache-key-modification

Conversation

@termorey
Copy link

@termorey termorey commented Mar 3, 2026

Problem

When you need create unique cache key you can do it in custom adapter only with duplicated logic on get/set methods. Also useful for params not included in query params: SSR, localization, etc.

Solution

Added some kind of optional middleware on key creation step: allow developers modify already created inner key. It can be represented as tag creation based on stores.

Changes description

  • feat: added key modification param to operator cache
  • chore: added key modification test
  • chore: updated docs for cache with param usage

Example

With localization

Cache posts with localization, using a query call without parameters. After switched locale on new and back you will receive cached data.

import { attach, createEffect, createStore, restore } from "effector";
import { cache, createQuery inMemoryCache, keepFresh } from "@farfetched/core";

const changeLocale = createEvent<string>();

const $locale = restore<string>(changeLocale, "en");

const query = createQuery({ effect: createEffect(async () => (await fetch("/api/posts")).json()) });
keepFresh(query, { triggers: [changeLocale] });
cache(query, {
 adapter: inMemoryCache(),
 maxAge: "1h",
 modifyKey: attach({
  source: { locale: $locale },
  effect: ({locale}, key: string) => key + ":" + locale,
 }),
});

SSR + user id

// user.ts
const $userId = createStore<null | string>(null);

// queries.ts
const query = createQuery({ effect: createEffect(async () => (await fetch("/api/posts")).json()) });
if (isServer()) {
 cache(query, {
  adapter: redisCache(),
  maxAge: "5m",
  modifyKey: attach({
   source: $userId,
   effect: (userId, key: string) => key + ":" + (userId || "_"),
  }),
 });
}

// server-loader.ts
const handler = async (request) => {
 const cookie = parseCookie(request.headers.get("Cookie"));
 const userId: string | null = cookies.get("id");
 const scope = fork();
 if (userId)
  await allSettled($userId, { scope, params: userId });
 }
 await allSettled(query.start, { scope });
 return serialized(scope)
}

With caution before merge

  • Not included Badge with version on cache page in docs

@netlify
Copy link

netlify bot commented Mar 3, 2026

Deploy Preview for farfetched ready!

Name Link
🔨 Latest commit 122e8a9
🔍 Latest deploy log https://app.netlify.com/projects/farfetched/deploys/69a7217c02a8b0000777a23b
😎 Deploy Preview https://deploy-preview-578--farfetched.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant