Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use Workers for manifest fetching & optimizations #572

Merged
merged 28 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
215f882
feat(fetch-remotes): use Github Contents API
kyrie25 Aug 5, 2023
d18cea7
style: lint
kyrie25 Aug 5, 2023
c606a89
Update FetchRemotes.ts
kyrie25 Aug 5, 2023
a810750
fix: display error handling
kyrie25 Aug 5, 2023
9f76571
Update marketplace-types.d.ts
kyrie25 Aug 5, 2023
ca6779a
chore: types
kyrie25 Aug 5, 2023
fc96bd6
Merge branch 'feat/fetch-gh-contents' of https://github.com/spicetify…
kyrie25 Aug 5, 2023
2d2249e
fix: workaround rate limit when switching tabs
kyrie25 Aug 5, 2023
8e1809b
perf: use cached repo results
kyrie25 Aug 5, 2023
aa35cdc
style: header alignment
kyrie25 Aug 5, 2023
fbeb29c
Merge branch 'main' into feat/fetch-gh-contents
theRealPadster Aug 5, 2023
4964bfd
perf: cache tld & display warning
kyrie25 Aug 6, 2023
578d4fb
Merge branch 'feat/fetch-gh-contents' of https://github.com/spicetify…
kyrie25 Aug 6, 2023
a39274e
feat: display notification if fail to connect to CDN
kyrie25 Aug 6, 2023
c721038
chore: move comment
kyrie25 Aug 6, 2023
33e5aa0
fix: working cache from preload
kyrie25 Aug 6, 2023
760a124
refactor: simplify
kyrie25 Aug 6, 2023
2aab6e6
perf: fix/optimize cache & remove duplicate requests
kyrie25 Aug 6, 2023
b68f212
chore: remove log
kyrie25 Aug 6, 2023
8b862be
refactor: simplify
kyrie25 Aug 6, 2023
96da572
revert: use raw file URL
kyrie25 Aug 6, 2023
f9d90f4
chore: cleanup
kyrie25 Aug 6, 2023
37111f2
chore: cleanup
kyrie25 Aug 6, 2023
f7a7fe0
feat: use Workers for manifest fetch
kyrie25 Aug 6, 2023
36248ce
fix: value mixing
kyrie25 Aug 6, 2023
cbd137f
Merge branch 'main' into feat/fetch-gh-contents
kyrie25 Aug 7, 2023
0ad0a44
Update src/extensions/extension.tsx
kyrie25 Aug 7, 2023
08787a3
Update src/components/Card/Card.tsx
kyrie25 Aug 7, 2023
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
14 changes: 12 additions & 2 deletions src/components/Grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -340,15 +340,25 @@ class Grid extends React.Component<
this.setState({ rest: false });
quantity += this.cardList.length;

this.requestPage = await this.loadPage(queue);
try {
this.requestPage = await this.loadPage(queue);
} catch (e) {
console.error(e);
this.requestPage = -1;
}

while (
this.requestPage &&
this.requestPage !== -1 &&
this.cardList.length < quantity &&
!this.state.endOfList
) {
this.requestPage = await this.loadPage(queue);
try {
this.requestPage = await this.loadPage(queue);
} catch (e) {
console.error(e);
this.requestPage = -1;
}
}

if (this.requestPage === -1) {
Expand Down
25 changes: 16 additions & 9 deletions src/extensions/extension.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,22 @@
})();

async function appendInformationToLocalStorage(array, type: RepoType) {
// This system should make it so themes and extensions are stored concurrently
for (const repo of array.items) {
// console.log(repo);
const data = (type === "theme")
? await fetchThemeManifest(repo.contents_url, repo.default_branch, repo.stargazers_count)
: await fetchExtensionManifest(repo.contents_url, repo.default_branch, repo.stargazers_count);
if (data) {
addToSessionStorage(data);
await sleep(5000);
try {
// This system should make it so themes and extensions are stored concurrently
for (const repo of array.items) {
// console.log(repo);
const data = (type === "theme")
? await fetchThemeManifest(repo.contents_url, repo.default_branch, repo.stargazers_count)
: await fetchExtensionManifest(repo.contents_url, repo.default_branch, repo.stargazers_count);
if (data) {
addToSessionStorage(data);
await sleep(5000);
}
}
} catch (err: any) {

Check warning on line 254 in src/extensions/extension.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
if (err.message.includes("API rate limit exceeded")) return Spicetify.showNotification("Too Many Requests, Cool Down.", true);

Spicetify.showNotification("Error loading themes and extensions", true);
console.error(err);
}
}
49 changes: 32 additions & 17 deletions src/logic/FetchRemotes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BLACKLIST_URL, ITEMS_PER_REQUEST } from "../constants";
import { CardItem, Snippet } from "../types/marketplace-types";
import { CardItem, GithubContents, GithubMessage, Snippet } from "../types/marketplace-types";
import { addToSessionStorage, processAuthors } from "./Utils";

import { RepoTopic } from "../types/marketplace-types";
Expand Down Expand Up @@ -28,7 +28,7 @@
const allRepos = await fetch(url).then(res => res.json()).catch(() => []);
if (!allRepos.items) {
Spicetify.showNotification("Too Many Requests, Cool Down.", true);
return;
return { items: [] };
}
const filteredResults = {
...allRepos,
Expand All @@ -41,6 +41,20 @@
return filteredResults;
}

async function fetchRepoManifest(contents: GithubContents[] | GithubMessage) {
if (Array.isArray(contents)) {
const manifest = contents.find(item => item.name === "manifest.json");
if (!manifest) throw new Error("No manifest");

const manifestContents = await fetch(manifest.download_url).then(res => res.json()).catch(() => null);
if (!manifestContents) return null;

return manifestContents;
} else {
return contents.message;
}
}

// TODO: add try/catch here?
// TODO: can we add a return type here?
/**
Expand All @@ -50,17 +64,18 @@
* @param branch Default branch name (e.g. main or master)
* @returns The manifest object
*/
async function getRepoManifest(user: string, repo: string, branch: string) {
async function getRepoManifest(user: string, repo: string, contentsUrl: string) {
const sessionStorageItem = window.sessionStorage.getItem(`${user}-${repo}`);
const failedSessionStorageItems = window.sessionStorage.getItem("noManifests");
if (sessionStorageItem) return JSON.parse(sessionStorageItem);
if (failedSessionStorageItems?.includes(contentsUrl)) return null;

const url = `https://raw.githubusercontent.com/${user}/${repo}/${branch}/manifest.json`;
if (failedSessionStorageItems?.includes(url)) return null;
const manifest = await fetch(contentsUrl)
.then(res => res.json())
.then(fetchRepoManifest)
.catch(() => addToSessionStorage([contentsUrl], "noManifests"));

const manifest = await fetch(url).then(res => res.json()).catch(
() => addToSessionStorage([url], "noManifests"),
);
if (typeof manifest === "string") throw new Error(manifest);
if (manifest) window.sessionStorage.setItem(`${user}-${repo}`, JSON.stringify(manifest));

return manifest;
Expand All @@ -83,7 +98,7 @@
if (!regex_result || !regex_result.groups) return null;
const { user, repo } = regex_result.groups;

manifests = await getRepoManifest(user, repo, branch);
manifests = await getRepoManifest(user, repo, regex_result[0]);
kyrie25 marked this conversation as resolved.
Show resolved Hide resolved

// If the manifest returned is not an array, initialize it as one
if (!Array.isArray(manifests)) manifests = [manifests];
Expand Down Expand Up @@ -130,8 +145,8 @@

return parsedManifests;
}
catch (err) {
// console.warn(contents_url, err);
catch (err: any) {

Check warning on line 148 in src/logic/FetchRemotes.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
kyrie25 marked this conversation as resolved.
Show resolved Hide resolved
if (err.message.includes("API rate limit exceeded")) throw err;
return null;
}
}
Expand All @@ -152,7 +167,7 @@
if (!regex_result || !regex_result.groups) return null;
const { user, repo } = regex_result.groups;

manifests = await getRepoManifest(user, repo, branch);
manifests = await getRepoManifest(user, repo, regex_result[0]);

// If the manifest returned is not an array, initialize it as one
if (!Array.isArray(manifests)) manifests = [manifests];
Expand Down Expand Up @@ -197,8 +212,8 @@
}, []);
return parsedManifests;
}
catch (err) {
// console.warn(contents_url, err);
catch (err: any) {

Check warning on line 215 in src/logic/FetchRemotes.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
if (err.message.includes("API rate limit exceeded")) throw err;
return null;
}
}
Expand All @@ -219,7 +234,7 @@
if (!regex_result || !regex_result.groups) return null;
const { user, repo } = regex_result.groups;

manifests = await getRepoManifest(user, repo, branch);
manifests = await getRepoManifest(user, repo, regex_result[0]);

// If the manifest returned is not an array, initialize it as one
if (!Array.isArray(manifests)) manifests = [manifests];
Expand Down Expand Up @@ -264,8 +279,8 @@

return parsedManifests;
}
catch (err) {
// console.warn(contents_url, err);
catch (err: any) {

Check warning on line 282 in src/logic/FetchRemotes.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
if (err.message.includes("API rate limit exceeded")) throw err;
return null;
}
}
Expand Down
22 changes: 22 additions & 0 deletions src/types/marketplace-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,25 @@ export type Config = {
activeScheme?: string | null;
},
};

export type GithubContents = {
name: string;
path: string;
sha: string;
size: number;
url: string;
html_url: string;
git_url: string;
download_url: string;
type: "file" | "dir" | "symlink";
_links: {
self: string;
git: string;
html: string;
};
};

export type GithubMessage = {
message: string;
documentation_url: string;
};
kyrie25 marked this conversation as resolved.
Show resolved Hide resolved