feat: add caching mechanism for pull requests list to improve performance and handle offline scenarios

This commit is contained in:
Kiril Videlov 2023-10-27 16:50:52 +02:00 committed by Kiril Videlov
parent b0374e2f7a
commit 3eba2c9bdb
2 changed files with 74 additions and 55 deletions

View File

@ -1,6 +1,8 @@
import { Octokit } from '@octokit/rest';
import { PullRequest, User, Label, type GitHubIntegrationContext } from '$lib/github/types';
import type { RestEndpointMethodTypes } from '@octokit/rest';
import { asyncWritable, type WritableLoadable, type Loadable } from '@square/svelte-store';
import lscache from 'lscache';
function newClient(ctx: GitHubIntegrationContext) {
return new Octokit({
@ -10,9 +12,27 @@ function newClient(ctx: GitHubIntegrationContext) {
});
}
export async function listPullRequests(
ctx: GitHubIntegrationContext
): Promise<PullRequest[] | undefined> {
// Uses the cached value as the initial state and also in the event of being offline
export function listPullRequestsWithCache(ctx: GitHubIntegrationContext): Loadable<PullRequest[]> {
const key = ctx.owner + '/' + ctx.repo;
const store = asyncWritable(
[],
async () => lscache.get(key) || [],
async (data) => data,
{ trackState: true },
(set) => {
listPullRequests(ctx).then((prs) => {
if (prs !== undefined) {
lscache.set(key, prs, 1440); // 1 day ttl
set(prs);
}
});
}
) as WritableLoadable<PullRequest[]>;
return store;
}
async function listPullRequests(ctx: GitHubIntegrationContext): Promise<PullRequest[] | undefined> {
const octokit = newClient(ctx);
try {
const rsp = await octokit.rest.pulls.list({

View File

@ -1,6 +1,6 @@
<script lang="ts">
import type { GitHubIntegrationContext } from '$lib/github/types';
import { listPullRequests } from '$lib/github/pullrequest';
import { listPullRequestsWithCache } from '$lib/github/pullrequest';
import TimeAgo from '$lib/components/TimeAgo/TimeAgo.svelte';
import { IconPullRequest, IconDraftPullRequest } from '$lib/icons';
import Scrollbar from '$lib/components/Scrollbar.svelte';
@ -10,7 +10,8 @@
import { createEventDispatcher } from 'svelte';
export let githubContext: GitHubIntegrationContext;
let pullRequestsPromise = listPullRequests(githubContext);
let prs = listPullRequestsWithCache(githubContext);
$: pullRequestsState = prs.state;
let rbViewport: HTMLElement;
let rbContents: HTMLElement;
@ -54,11 +55,12 @@
class="hide-native-scrollbar flex max-h-full flex-grow flex-col overflow-y-scroll overscroll-none"
>
<div bind:this={rbContents}>
{#await pullRequestsPromise}
{#if $pullRequestsState?.isLoading}
<span>loading...</span>
{:then prs}
{#if prs}
{#each prs as pr, i}
{:else if $pullRequestsState?.isError}
<span>something went wrong</span>
{:else}
{#each $prs as pr, i}
<div
role="button"
tabindex="0"
@ -105,10 +107,7 @@
</div>
</div>
{/each}
{:else}
<span>something went wrong</span>
{/if}
{/await}
</div>
</div>
<Scrollbar viewport={rbViewport} contents={rbContents} width="0.5rem" />