Skip to content

Commit 950a520

Browse files
authored
Merge pull request #32 from pawcoding/next
Force refresh to update all entries
2 parents 1ed241b + d981bcb commit 950a520

File tree

9 files changed

+101
-42
lines changed

9 files changed

+101
-42
lines changed

.github/workflows/release.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ on:
88
permissions:
99
contents: read
1010

11+
env:
12+
HUSKY: 0
13+
1114
jobs:
1215
publish:
1316
# Use the latest version of Ubuntu

.github/workflows/test.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ on:
99
permissions:
1010
contents: read
1111

12+
env:
13+
HUSKY: 0
14+
1215
jobs:
1316
test:
1417
# Use the latest version of Ubuntu

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "astro-loader-pocketbase",
3-
"version": "2.3.1",
3+
"version": "2.4.0-next.1",
44
"description": "A content loader for Astro that uses the PocketBase API",
55
"keywords": [
66
"astro",

src/loader/load-entries.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,11 @@ export async function loadEntries(
8989
} while (page < totalPages);
9090

9191
// Log the number of fetched entries
92-
context.logger.info(
93-
`Fetched ${entries}${lastModified ? " changed" : ""} entries.`
94-
);
92+
if (lastModified) {
93+
context.logger.info(
94+
`Updated ${entries}/${context.store.keys().length} entries.`
95+
);
96+
} else {
97+
context.logger.info(`Fetched ${entries} entries.`);
98+
}
9599
}

src/loader/loader.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export async function loader(
1818
context.refreshContextData,
1919
options.collectionName
2020
);
21-
if (!refresh) {
21+
if (refresh === "skip") {
2222
return;
2323
}
2424

@@ -31,6 +31,12 @@ export async function loader(
3131
// Get the date of the last fetch to only update changed entries.
3232
let lastModified = context.meta.get("last-modified");
3333

34+
// Force a full update if the refresh is forced
35+
if (refresh === "force") {
36+
lastModified = undefined;
37+
context.store.clear();
38+
}
39+
3440
// Check if the version has changed to force an update
3541
const lastVersion = context.meta.get("version");
3642
if (lastVersion !== packageJson.version) {

src/utils/should-refresh.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,32 @@ import type { LoaderContext } from "astro/loaders";
66
export function shouldRefresh(
77
context: LoaderContext["refreshContextData"],
88
collectionName: string
9-
): boolean {
9+
): "refresh" | "skip" | "force" {
1010
// Check if the refresh was triggered by the `astro-integration-pocketbase`
1111
// and the correct metadata is provided.
12-
if (
13-
!context ||
14-
context.source !== "astro-integration-pocketbase" ||
15-
!context.collection
16-
) {
17-
return true;
12+
if (!context || context.source !== "astro-integration-pocketbase") {
13+
return "refresh";
14+
}
15+
16+
// Check if all collections should be refreshed.
17+
if (context.force) {
18+
return "force";
19+
}
20+
21+
if (!context.collection) {
22+
return "refresh";
1823
}
1924

2025
// Check if the collection name matches the current collection.
2126
if (typeof context.collection === "string") {
22-
return context.collection === collectionName;
27+
return context.collection === collectionName ? "refresh" : "skip";
2328
}
2429

2530
// Check if the collection is included in the list of collections.
2631
if (Array.isArray(context.collection)) {
27-
return context.collection.includes(collectionName);
32+
return context.collection.includes(collectionName) ? "refresh" : "skip";
2833
}
2934

3035
// Should not happen but return true to be safe.
31-
return true;
36+
return "refresh";
3237
}

test/loader/loader.spec.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ describe("loader", async () => {
3636
vi.resetAllMocks();
3737
});
3838

39-
test("should not refresh if shouldRefresh returns false", async () => {
40-
srm.shouldRefresh = vi.fn().mockReturnValue(false);
39+
test('should not refresh if shouldRefresh returns "skip"', async () => {
40+
srm.shouldRefresh = vi.fn().mockReturnValue("skip");
4141

4242
await loader(context, options);
4343

@@ -47,7 +47,7 @@ describe("loader", async () => {
4747
});
4848

4949
test("should not refresh if handleRealtimeUpdates handled update", async () => {
50-
srm.shouldRefresh = vi.fn().mockReturnValue(true);
50+
srm.shouldRefresh = vi.fn().mockReturnValue("refresh");
5151
hrum.handleRealtimeUpdates = vi.fn().mockResolvedValue(true);
5252

5353
await loader(context, options);
@@ -56,8 +56,25 @@ describe("loader", async () => {
5656
expect(loadEntries).not.toHaveBeenCalled();
5757
});
5858

59+
test('should clear store and disable incremental builds if shouldRefresh returns "force"', async () => {
60+
srm.shouldRefresh = vi.fn().mockReturnValue("force");
61+
hrum.handleRealtimeUpdates = vi.fn().mockResolvedValue(false);
62+
gstm.getSuperuserToken = vi.fn().mockResolvedValue(undefined);
63+
const storeClearSpy = vi.spyOn(context.store, "clear");
64+
65+
await loader(context, options);
66+
67+
expect(storeClearSpy).toHaveBeenCalledOnce();
68+
expect(loadEntries).toHaveBeenCalledWith(
69+
options,
70+
context,
71+
undefined,
72+
undefined
73+
);
74+
});
75+
5976
test("should clear store and disable incremental builds if version changes", async () => {
60-
srm.shouldRefresh = vi.fn().mockReturnValue(true);
77+
srm.shouldRefresh = vi.fn().mockReturnValue("refresh");
6178
hrum.handleRealtimeUpdates = vi.fn().mockResolvedValue(false);
6279
gstm.getSuperuserToken = vi.fn().mockResolvedValue(undefined);
6380
const storeClearSpy = vi.spyOn(context.store, "clear");
@@ -75,7 +92,7 @@ describe("loader", async () => {
7592
});
7693

7794
test("should disable incremental builds if no updatedField is provided", async () => {
78-
srm.shouldRefresh = vi.fn().mockReturnValue(true);
95+
srm.shouldRefresh = vi.fn().mockReturnValue("refresh");
7996
hrum.handleRealtimeUpdates = vi.fn().mockResolvedValue(false);
8097
gstm.getSuperuserToken = vi.fn().mockResolvedValue(undefined);
8198
options.updatedField = undefined;
@@ -92,7 +109,7 @@ describe("loader", async () => {
92109

93110
test("should get superuser token if superuserCredentials are provided", async () => {
94111
const token = "token";
95-
srm.shouldRefresh = vi.fn().mockReturnValue(true);
112+
srm.shouldRefresh = vi.fn().mockReturnValue("refresh");
96113
hrum.handleRealtimeUpdates = vi.fn().mockResolvedValue(false);
97114
gstm.getSuperuserToken = vi.fn().mockResolvedValue(token);
98115
const entry = createPocketbaseEntry();
@@ -111,7 +128,7 @@ describe("loader", async () => {
111128
});
112129

113130
test("should cleanup old entries if store has keys", async () => {
114-
srm.shouldRefresh = vi.fn().mockReturnValue(true);
131+
srm.shouldRefresh = vi.fn().mockReturnValue("refresh");
115132
hrum.handleRealtimeUpdates = vi.fn().mockResolvedValue(false);
116133
gstm.getSuperuserToken = vi.fn().mockResolvedValue(undefined);
117134
const entry = createPocketbaseEntry();
@@ -123,7 +140,7 @@ describe("loader", async () => {
123140
});
124141

125142
test("should set last-modified and version in meta after loading entries", async () => {
126-
srm.shouldRefresh = vi.fn().mockReturnValue(true);
143+
srm.shouldRefresh = vi.fn().mockReturnValue("refresh");
127144
hrum.handleRealtimeUpdates = vi.fn().mockResolvedValue(false);
128145
gstm.getSuperuserToken = vi.fn().mockResolvedValue(undefined);
129146
context.meta.delete("last-modified");

test/utils/should-refresh.spec.ts

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,100 @@
1-
import { assert, describe, test } from "vitest";
1+
import { describe, expect, test } from "vitest";
22
import { shouldRefresh } from "../../src/utils/should-refresh";
33

44
describe("shouldRefresh", () => {
5-
test("should return true if context is undefined", () => {
5+
test('should return "refresh" if context is undefined', () => {
66
const context = undefined;
77
const collectionName = "testCollection";
88

9-
assert(shouldRefresh(context, collectionName));
9+
expect(shouldRefresh(context, collectionName)).toBe("refresh");
1010
});
1111

12-
test("should return true if context source is not 'astro-integration-pocketbase'", () => {
12+
test("should return \"refresh\" if context source is not 'astro-integration-pocketbase'", () => {
1313
const context = {
1414
source: "other-source",
1515
collection: "testCollection"
1616
};
1717
const collectionName = "testCollection";
1818

19-
assert(shouldRefresh(context, collectionName));
19+
expect(shouldRefresh(context, collectionName)).toBe("refresh");
2020
});
2121

22-
test("should return true if context collection is missing", () => {
22+
test('should return "refresh" if context collection is missing', () => {
2323
const context = {
2424
source: "astro-integration-pocketbase"
2525
};
2626
const collectionName = "testCollection";
2727

28-
assert(shouldRefresh(context, collectionName));
28+
expect(shouldRefresh(context, collectionName)).toBe("refresh");
2929
});
3030

31-
test("should return true if context collection is a string and matches collectionName", () => {
31+
test('should return "refresh" if context collection is a string and matches collectionName', () => {
3232
const context = {
3333
source: "astro-integration-pocketbase",
3434
collection: "testCollection"
3535
};
3636
const collectionName = "testCollection";
3737

38-
assert(shouldRefresh(context, collectionName));
38+
expect(shouldRefresh(context, collectionName)).toBe("refresh");
3939
});
4040

41-
test("should return false if context collection is a string and does not match collectionName", () => {
41+
test('should return "skip" if context collection is a string and does not match collectionName', () => {
4242
const context = {
4343
source: "astro-integration-pocketbase",
4444
collection: "otherCollection"
4545
};
4646
const collectionName = "testCollection";
4747

48-
assert(!shouldRefresh(context, collectionName));
48+
expect(shouldRefresh(context, collectionName)).toBe("skip");
4949
});
5050

51-
test("should return true if context collection is an array and includes collectionName", () => {
51+
test('should return "refresh" if context collection is an array and includes collectionName', () => {
5252
const context = {
5353
source: "astro-integration-pocketbase",
5454
collection: ["testCollection", "otherCollection"]
5555
};
5656
const collectionName = "testCollection";
57-
assert(shouldRefresh(context, collectionName));
57+
58+
expect(shouldRefresh(context, collectionName)).toBe("refresh");
5859
});
5960

60-
test("should return false if context collection is an array and does not include collectionName", () => {
61+
test('should return "skip" if context collection is an array and does not include collectionName', () => {
6162
const context = {
6263
source: "astro-integration-pocketbase",
6364
collection: ["otherCollection"]
6465
};
6566
const collectionName = "testCollection";
6667

67-
assert(!shouldRefresh(context, collectionName));
68+
expect(shouldRefresh(context, collectionName)).toBe("skip");
6869
});
6970

70-
test("should return true if context collection is an unexpected type", () => {
71+
test('should return "refresh" if context collection is an unexpected type', () => {
7172
const context = {
7273
source: "astro-integration-pocketbase",
7374
collection: 123
7475
};
7576
const collectionName = "testCollection";
7677

77-
assert(shouldRefresh(context, collectionName));
78+
expect(shouldRefresh(context, collectionName)).toBe("refresh");
79+
});
80+
81+
test('should return "force" if context force is true', () => {
82+
const context = {
83+
source: "astro-integration-pocketbase",
84+
force: true
85+
};
86+
const collectionName = "testCollection";
87+
88+
expect(shouldRefresh(context, collectionName)).toBe("force");
89+
});
90+
91+
test('should return "refresh" if context force is false', () => {
92+
const context = {
93+
source: "astro-integration-pocketbase",
94+
force: false
95+
};
96+
const collectionName = "testCollection";
97+
98+
expect(shouldRefresh(context, collectionName)).toBe("refresh");
7899
});
79100
});

0 commit comments

Comments
 (0)