forked from rowyio/rowy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuseUpdateCheck.ts
102 lines (87 loc) · 3.17 KB
/
useUpdateCheck.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import { useState, useCallback, useEffect } from "react";
import createPersistedState from "use-persisted-state";
import { differenceInDays } from "date-fns";
import { compare } from "compare-versions";
import { useProjectContext } from "@src/contexts/ProjectContext";
import { repository, version } from "@root/package.json";
import { EXTERNAL_LINKS } from "@src/constants/externalLinks";
import { runRoutes } from "@src/constants/runRoutes";
// https://docs.github.com/en/rest/reference/repos#get-the-latest-release
const UPDATE_ENDPOINTS = {
rowy: repository.url
.replace("github.com", "api.github.com/repos")
.replace(/.git$/, "/releases/latest"),
rowyRun:
EXTERNAL_LINKS.rowyRunGitHub.replace("github.com", "api.github.com/repos") +
"/releases/latest",
};
export const useLatestUpdateState = createPersistedState(
"__ROWY__UPDATE_CHECK"
);
type LatestUpdateState = {
lastChecked: string;
rowy: null | Record<string, any>;
rowyRun: null | Record<string, any>;
deployedRowy: string;
deployedRowyRun: string;
};
/**
* Get the latest version of Rowy and Rowy Run from GitHub releases,
* and the currently deployed versions
* @returns [latestUpdate, checkForUpdates, loading]
*/
export default function useUpdateCheck() {
const { rowyRun } = useProjectContext();
const [loading, setLoading] = useState(false);
// Store latest release from GitHub
const [latestUpdate, setLatestUpdate] =
useLatestUpdateState<LatestUpdateState>({
lastChecked: "",
rowy: null,
rowyRun: null,
deployedRowy: version,
deployedRowyRun: "",
});
// Check for updates using latest releases from GitHub
const checkForUpdates = useCallback(async () => {
if (!rowyRun) return;
setLoading(true);
const newState = {
lastChecked: new Date().toISOString(),
rowy: null,
rowyRun: null,
deployedRowy: version,
deployedRowyRun: "",
};
// Make all requests simultaneously
const [resRowy, resRowyRun, deployedRowyRun] = await Promise.all([
fetch(UPDATE_ENDPOINTS.rowy, {
headers: { Accept: "application/vnd.github.v3+json" },
}).then((r) => r.json()),
fetch(UPDATE_ENDPOINTS.rowyRun, {
headers: { Accept: "application/vnd.github.v3+json" },
}).then((r) => r.json()),
rowyRun({ route: runRoutes.version }),
]);
// Only store the latest release
if (compare(resRowy.tag_name, version, ">")) newState.rowy = resRowy;
if (compare(resRowyRun.tag_name, deployedRowyRun.version, ">"))
newState.rowyRun = resRowyRun;
// Save deployed version
newState.deployedRowyRun = deployedRowyRun.version;
setLatestUpdate(newState);
setLoading(false);
}, [setLoading, setLatestUpdate, rowyRun]);
// Check for new updates on page load if last check was more than 7 days ago
// or if deployed version has changed
useEffect(() => {
if (loading) return;
if (
!latestUpdate.lastChecked ||
differenceInDays(new Date(), new Date(latestUpdate.lastChecked)) > 7 ||
latestUpdate.deployedRowy !== version
)
checkForUpdates();
}, [latestUpdate, loading, checkForUpdates]);
return [latestUpdate, checkForUpdates, loading] as const;
}