Skip to content

Commit 27dde3a

Browse files
Fix version upgrade toast refresh issue (#179)
1 parent d204123 commit 27dde3a

File tree

7 files changed

+54
-6
lines changed

7 files changed

+54
-6
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Fixed
11+
12+
- Fixed issue with version upgrade toast not appearing without a hard refresh. ([#179](https://github.com/sourcebot-dev/sourcebot/pull/179))
13+
1014
## [2.8.0] - 2025-01-17
1115

1216
### Added

packages/web/src/app/api/(client)/client.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
'use client';
22

33
import { NEXT_PUBLIC_DOMAIN_SUB_PATH } from "@/lib/environment.client";
4-
import { fileSourceResponseSchema, listRepositoriesResponseSchema, searchResponseSchema } from "@/lib/schemas";
5-
import { FileSourceRequest, FileSourceResponse, ListRepositoriesResponse, SearchRequest, SearchResponse } from "@/lib/types";
4+
import { fileSourceResponseSchema, getVersionResponseSchema, listRepositoriesResponseSchema, searchResponseSchema } from "@/lib/schemas";
5+
import { FileSourceRequest, FileSourceResponse, GetVersionResponse, ListRepositoriesResponse, SearchRequest, SearchResponse } from "@/lib/types";
66
import assert from "assert";
77

88
export const search = async (body: SearchRequest): Promise<SearchResponse> => {
@@ -43,6 +43,17 @@ export const getRepos = async (): Promise<ListRepositoriesResponse> => {
4343
return listRepositoriesResponseSchema.parse(result);
4444
}
4545

46+
export const getVersion = async (): Promise<GetVersionResponse> => {
47+
const path = resolveServerPath("/api/version");
48+
const result = await fetch(path, {
49+
method: "GET",
50+
headers: {
51+
"Content-Type": "application/json",
52+
},
53+
}).then(response => response.json());
54+
return getVersionResponseSchema.parse(result);
55+
}
56+
4657
/**
4758
* Given a subpath to a api route on the server (e.g., /api/search),
4859
* returns the full path to that route on the server, taking into account
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { SOURCEBOT_VERSION } from "@/lib/environment";
2+
import { GetVersionResponse } from "@/lib/types";
3+
4+
// Note: In Next.JS 14, GET methods with no params are cached by default at build time.
5+
// This creates issues since environment variables (like SOURCEBOT_VERSION) are
6+
// not available until runtime. To work around this, we fore the route to be
7+
// dynamic and evaluate on each request.
8+
// @see: https://nextjs.org/docs/14/app/building-your-application/routing/route-handlers#caching
9+
export const dynamic = "force-dynamic";
10+
11+
export const GET = async () => {
12+
return Response.json({
13+
version: SOURCEBOT_VERSION,
14+
} satisfies GetVersionResponse);
15+
}

packages/web/src/app/components/upgradeToast.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
import { useToast } from "@/components/hooks/use-toast";
44
import { ToastAction } from "@/components/ui/toast";
5-
import { NEXT_PUBLIC_SOURCEBOT_VERSION } from "@/lib/environment.client";
65
import { useEffect } from "react";
76
import { useLocalStorage } from "usehooks-ts";
7+
import { getVersion } from "../api/(client)/client";
8+
import { useQuery } from "@tanstack/react-query";
89

910
const GITHUB_TAGS_URL = "https://api.github.com/repos/sourcebot-dev/sourcebot/tags";
1011
const SEMVER_REGEX = /^v(\d+)\.(\d+)\.(\d+)$/;
@@ -23,8 +24,18 @@ export const UpgradeToast = () => {
2324
new Date(0).toUTCString()
2425
);
2526

27+
const { data: versionString } = useQuery({
28+
queryKey: ["version"],
29+
queryFn: () => getVersion(),
30+
select: (data) => data.version,
31+
})
32+
2633
useEffect(() => {
27-
const currentVersion = getVersionFromString(NEXT_PUBLIC_SOURCEBOT_VERSION);
34+
if (!versionString) {
35+
return;
36+
}
37+
38+
const currentVersion = getVersionFromString(versionString);
2839
if (!currentVersion) {
2940
return;
3041
}
@@ -71,7 +82,7 @@ export const UpgradeToast = () => {
7182

7283
setUpgradeToastLastShownDate(new Date().toUTCString());
7384
});
74-
}, [setUpgradeToastLastShownDate, toast, upgradeToastLastShownDate]);
85+
}, [setUpgradeToastLastShownDate, toast, upgradeToastLastShownDate, versionString]);
7586

7687
return null;
7788
}

packages/web/src/lib/environment.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ import { getEnv, getEnvNumber } from "./utils";
55
export const ZOEKT_WEBSERVER_URL = getEnv(process.env.ZOEKT_WEBSERVER_URL, "http://localhost:6070")!;
66
export const SHARD_MAX_MATCH_COUNT = getEnvNumber(process.env.SHARD_MAX_MATCH_COUNT, 10000);
77
export const TOTAL_MAX_MATCH_COUNT = getEnvNumber(process.env.TOTAL_MAX_MATCH_COUNT, 100000);
8+
export const SOURCEBOT_VERSION = getEnv(process.env.SOURCEBOT_VERSION, 'unknown')!;
89
export const NODE_ENV = process.env.NODE_ENV;

packages/web/src/lib/schemas.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,7 @@ export const listRepositoriesResponseSchema = z.object({
153153
Stats: repoStatsSchema,
154154
})
155155
});
156+
157+
export const getVersionResponseSchema = z.object({
158+
version: z.string(),
159+
});

packages/web/src/lib/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { z } from "zod";
2-
import { fileSourceRequestSchema, fileSourceResponseSchema, listRepositoriesResponseSchema, locationSchema, rangeSchema, repositorySchema, searchRequestSchema, searchResponseSchema, symbolSchema } from "./schemas";
2+
import { fileSourceRequestSchema, fileSourceResponseSchema, getVersionResponseSchema, listRepositoriesResponseSchema, locationSchema, rangeSchema, repositorySchema, searchRequestSchema, searchResponseSchema, symbolSchema } from "./schemas";
33

44
export type KeymapType = "default" | "vim";
55

@@ -20,6 +20,8 @@ export type Repository = z.infer<typeof repositorySchema>;
2020

2121
export type Symbol = z.infer<typeof symbolSchema>;
2222

23+
export type GetVersionResponse = z.infer<typeof getVersionResponseSchema>;
24+
2325
export enum SearchQueryParams {
2426
query = "query",
2527
maxMatchDisplayCount = "maxMatchDisplayCount",

0 commit comments

Comments
 (0)