Skip to content

Commit

Permalink
use custom KV adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
dario-piotrowicz committed Dec 24, 2023
1 parent 02dc05c commit ac3f05e
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 9 deletions.
151 changes: 151 additions & 0 deletions cache-handlers/kv.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// ../../Repos/my-repos/next-on-pages/packages/next-on-pages/templates/cache/builtInCacheHandler.ts
var SUSPENSE_CACHE_URL = "INTERNAL_SUSPENSE_CACHE_HOSTNAME.local";
var NEXT_CACHE_IMPLICIT_TAG_ID = "_N_T_";
var BuiltInCacheHandler = class {
constructor(ctx) {
this.ctx = ctx;
this.revalidatedTags = new Set(ctx.revalidatedTags);
}
tagsManifest;
tagsManifestKey = "tags-manifest";
revalidatedTags;
async retrieve(key) {
throw new Error(`Method not implemented - ${key}`);
}
async update(key, value) {
throw new Error(`Method not implemented - ${key}, ${value}`);
}
async set(key, value, extra = {}) {
const newEntry = {
lastModified: Date.now(),
value
};
await this.update(key, JSON.stringify(newEntry));
switch (newEntry.value?.kind) {
case "FETCH": {
const tags = getTagsFromEntry(newEntry) ?? extra.tags ?? [];
await this.setTags(tags, { cacheKey: key });
const derivedTags = getDerivedTags(tags);
const implicitTags = derivedTags.map(
(tag) => `${NEXT_CACHE_IMPLICIT_TAG_ID}${tag}`
);
[...derivedTags, ...implicitTags].forEach(
(tag) => this.revalidatedTags.delete(tag)
);
}
}
}
async get(key, { softTags }) {
const entry = await this.retrieve(key);
if (!entry)
return null;
let data;
try {
data = JSON.parse(entry);
} catch (e) {
return null;
}
switch (data.value?.kind) {
case "FETCH": {
await this.loadTagsManifest();
const tags = getTagsFromEntry(data);
const combinedTags = softTags ? [...tags ?? [], ...softTags] : getDerivedTags(tags ?? []);
const isStale = combinedTags.some((tag) => {
if (this.revalidatedTags.has(tag))
return true;
const tagEntry = this.tagsManifest?.items?.[tag];
return tagEntry?.revalidatedAt && tagEntry?.revalidatedAt >= (data.lastModified ?? Date.now());
});
return isStale ? null : data;
}
default: {
return data;
}
}
}
async revalidateTag(tag) {
await this.setTags([tag], { revalidatedAt: Date.now() });
this.revalidatedTags.add(tag);
}
async loadTagsManifest() {
try {
const rawManifest = await this.retrieve(this.tagsManifestKey);
if (rawManifest) {
this.tagsManifest = JSON.parse(rawManifest);
}
} catch (e) {
}
this.tagsManifest ??= { version: 1, items: {} };
}
async saveTagsManifest() {
if (this.tagsManifest) {
const newValue = JSON.stringify(this.tagsManifest);
await this.update(this.tagsManifestKey, newValue);
}
}
async setTags(tags, { cacheKey, revalidatedAt }) {
await this.loadTagsManifest();
const tagsManifest = this.tagsManifest;
for (const tag of tags) {
const data = tagsManifest.items[tag] ?? { keys: [] };
if (cacheKey && !data.keys.includes(cacheKey)) {
data.keys.push(cacheKey);
}
if (revalidatedAt) {
data.revalidatedAt = revalidatedAt;
}
tagsManifest.items[tag] = data;
}
await this.saveTagsManifest();
}
buildCacheKey(key) {
return `https://${SUSPENSE_CACHE_URL}/entry/${key}`;
}
};
function getDerivedTags(tags) {
const derivedTags = ["/"];
for (const tag of tags || []) {
if (tag.startsWith("/")) {
const pathnameParts = tag.split("/");
for (let i = 1; i < pathnameParts.length + 1; i++) {
const curPathname = pathnameParts.slice(0, i).join("/");
if (curPathname) {
derivedTags.push(curPathname);
if (!derivedTags.includes(curPathname)) {
derivedTags.push(curPathname);
}
}
}
} else if (!derivedTags.includes(tag)) {
derivedTags.push(tag);
}
}
return derivedTags;
}
function getTagsFromEntry(entry) {
return entry.value?.tags ?? entry.value?.data?.tags;
}

// ../../Repos/my-repos/next-on-pages/packages/next-on-pages/templates/cache/KVCacheHandler.ts
var KVCacheHandler = class extends BuiltInCacheHandler {
constructor(ctx) {
super(ctx);
}
async retrieve(key) {
const value = await process.env.MY_CUSTOM_SUS_KV.get(
this.buildCacheKey(key)
);
return value ?? null;
}
async update(key, value) {
await process.env.MY_CUSTOM_SUS_KV.put(
this.buildCacheKey(key),
value
);
}
};

module.exports = KVCacheHandler;
// export {
// KVCacheHandler as default
// };
21 changes: 18 additions & 3 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
/** @type {import('next').NextConfig} */
module.exports = (phase, { defaultConfig }) => {

/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
experimental: {
fetchCacheKeyPrefix: "my-unused-fetch-cache-key-prefix",
incrementalCacheHandlerPath: require.resolve(
"./cache-handlers/supabase-rest.js"
),
incrementalCacheHandlerPath: getIncrementalCacheHandler('kv'),
},
};
return nextConfig;
};

/**
* @param {null|'supabase'|'kv'} handler
*/
function getIncrementalCacheHandler(handler) {
if(handler === null) {
return undefined;
}

const cachePath = {
supabase: 'supabase-rest.js',
kv: 'kv.js'
}[handler];

return require.resolve(`./cache-handlers/${cachePath}`);
}
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
"pages:build": "npx @cloudflare/next-on-pages",
"pages:deploy": "wrangler pages deploy .vercel/output/static",
"pages:watch": "npx @cloudflare/next-on-pages --watch",
"pages:dev": "npx wrangler pages dev .vercel/output/static --compatibility-date=2023-12-18 --compatibility-flag=nodejs_compat"
"pages:dev": "npx wrangler pages dev .vercel/output/static --compatibility-date=2023-12-18 --compatibility-flag=nodejs_compat --kv MY_CUSTOM_SUS_KV"
},
"dependencies": {
"next": "latest",
"react": "latest",
"react-dom": "latest"
},
"devDependencies": {
"@cloudflare/next-on-pages": "https://prerelease-registry.devprod.cloudflare.dev/next-on-pages/runs/7313865693/npm-package-next-on-pages-606",
"@cloudflare/next-on-pages": "https://prerelease-registry.devprod.cloudflare.dev/next-on-pages/runs/7315046801/npm-package-next-on-pages-606",
"@types/node": "^17.0.45",
"@types/react": "^17.0.53",
"autoprefixer": "^10.4.14",
Expand Down

0 comments on commit ac3f05e

Please sign in to comment.