Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/young-parents-take.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@opennextjs/aws": patch
---

Next 16 takes an array of tags in ComposableCacheHandler#getExpiration
15 changes: 13 additions & 2 deletions packages/open-next/src/adapters/composable-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,25 @@ export default {
// We don't do anything for now, do we want to do something here ???
return;
},
async getExpiration(...tags: string[]) {

/**
* The signature has changed in Next.js 16
* - Before Next.js 16, the method takes `...tags: string[]`
* - From Next.js 16, the method takes `tags: string[]`
*/
async getExpiration(...tags: string[] | string[][]) {
if (globalThis.tagCache.mode === "nextMode") {
return globalThis.tagCache.getLastRevalidated(tags);
// Use `.flat()` to accommodate both signatures
return globalThis.tagCache.getLastRevalidated(tags.flat());
}
// We always return 0 here, original tag cache are handled directly in the get part
// TODO: We need to test this more, i'm not entirely sure that this is working as expected
return 0;
},

/**
* This method is only used before Next.js 16
*/
async expireTags(...tags: string[]) {
if (globalThis.tagCache.mode === "nextMode") {
return writeTags(tags);
Expand Down
8 changes: 7 additions & 1 deletion packages/open-next/src/types/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,13 @@ export interface ComposableCacheHandler {
pendingEntry: Promise<ComposableCacheEntry>,
): Promise<void>;
refreshTags(): Promise<void>;
getExpiration(...tags: string[]): Promise<number>;
/**
* Next 16 takes an array of tags instead of variadic arguments
*/
getExpiration(...tags: string[] | string[][]): Promise<number>;
/**
* Removed from Next.js 16
*/
expireTags(...tags: string[]): Promise<void>;
/**
* This function is only there for older versions and do nothing
Expand Down
33 changes: 32 additions & 1 deletion packages/tests-unit/tests/adapters/composable-cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ describe("Composable cache handler", () => {
});
});

describe("getExpiration", () => {
describe("getExpiration (Next 15)", () => {
it("should return last revalidated time in nextMode", async () => {
tagCache.mode = "nextMode";
tagCache.getLastRevalidated.mockResolvedValueOnce(123456);
Expand Down Expand Up @@ -357,6 +357,37 @@ describe("Composable cache handler", () => {
});
});

describe("getExpiration (Next 16)", () => {
it("should return last revalidated time in nextMode", async () => {
tagCache.mode = "nextMode";
tagCache.getLastRevalidated.mockResolvedValueOnce(123456);

const result = await ComposableCache.getExpiration(["tag1", "tag2"]);

expect(tagCache.getLastRevalidated).toHaveBeenCalledWith([
"tag1",
"tag2",
]);
expect(result).toBe(123456);
});

it("should return 0 in original mode", async () => {
tagCache.mode = "original";

const result = await ComposableCache.getExpiration(["tag1", "tag2"]);

expect(result).toBe(0);
});

it("should return 0 when mode is undefined", async () => {
tagCache.mode = undefined;

const result = await ComposableCache.getExpiration(["tag1", "tag2"]);

expect(result).toBe(0);
});
});

describe("expireTags", () => {
beforeEach(() => {
writtenTags.clear();
Expand Down
Loading