mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-24 18:12:48 +03:00
feat: update dependencies and refactor pullRequestsStore to use RxJS Observable
This commit is contained in:
parent
b4c11c9e6a
commit
94ff6cb3b9
@ -75,6 +75,7 @@
|
||||
"prettier-plugin-svelte": "^3.0.3",
|
||||
"prettier-plugin-tailwindcss": "^0.5.6",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rxjs": "^7.8.1",
|
||||
"svelte": "^4.2.2",
|
||||
"svelte-check": "^3.5.2",
|
||||
"svelte-floating-ui": "^1.5.3",
|
||||
|
@ -1,34 +1,41 @@
|
||||
import { asyncWritable, type Loadable } from '@square/svelte-store';
|
||||
import type { Loadable } from '@square/svelte-store';
|
||||
import lscache from 'lscache';
|
||||
import { Observable, EMPTY } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { storeToObservable } from '$lib/rxjs/store';
|
||||
|
||||
import { PullRequest, type GitHubIntegrationContext } from '$lib/github/types';
|
||||
import { newClient } from '$lib/github/client';
|
||||
import type { CustomStore } from '$lib/vbranches/types';
|
||||
|
||||
// Uses the cached value as the initial state and also in the event of being offline
|
||||
export function listPullRequestsWithCache(
|
||||
ghContextStore: Loadable<GitHubIntegrationContext | undefined>
|
||||
): CustomStore<PullRequest[] | undefined> {
|
||||
const store = asyncWritable(
|
||||
ghContextStore,
|
||||
async (ctx, set) => {
|
||||
if (!ctx) return [];
|
||||
const key = ctx.owner + '/' + ctx.repo;
|
||||
const cachedValue = lscache.get(key);
|
||||
if (cachedValue) set(cachedValue);
|
||||
const prs = await listPullRequests(ctx);
|
||||
if (prs) {
|
||||
lscache.set(key, prs, 1440); // 1 day ttl
|
||||
}
|
||||
return prs;
|
||||
},
|
||||
undefined,
|
||||
{ trackState: true }
|
||||
) as CustomStore<PullRequest[] | undefined>;
|
||||
return store;
|
||||
): Observable<PullRequest[]> {
|
||||
const ghContextObservable = storeToObservable(ghContextStore);
|
||||
const prsObservable = ghContextObservable.pipe(
|
||||
switchMap((ctx) => {
|
||||
if (!ctx) return EMPTY;
|
||||
const obs: Observable<PullRequest[]> = new Observable((observer) => {
|
||||
const key = ctx.owner + '/' + ctx.repo;
|
||||
const cachedPrs = lscache.get(key);
|
||||
if (cachedPrs) {
|
||||
observer.next(cachedPrs);
|
||||
}
|
||||
const request = listPullRequests(ctx);
|
||||
request.then((prs) => {
|
||||
if (prs) {
|
||||
observer.next(prs);
|
||||
lscache.set(key, prs, 1440); // 1 day ttl
|
||||
}
|
||||
});
|
||||
});
|
||||
return obs;
|
||||
})
|
||||
);
|
||||
return prsObservable;
|
||||
}
|
||||
|
||||
async function listPullRequests(ctx: GitHubIntegrationContext): Promise<PullRequest[] | undefined> {
|
||||
async function listPullRequests(ctx: GitHubIntegrationContext): Promise<PullRequest[]> {
|
||||
const octokit = newClient(ctx);
|
||||
try {
|
||||
const rsp = await octokit.rest.pulls.list({
|
||||
@ -37,7 +44,8 @@ async function listPullRequests(ctx: GitHubIntegrationContext): Promise<PullRequ
|
||||
});
|
||||
return rsp.data.map(PullRequest.fromApi);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
console.error(e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
15
packages/ui/src/lib/rxjs/store.ts
Normal file
15
packages/ui/src/lib/rxjs/store.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import type { Readable, Writable, Unsubscriber } from 'svelte/store';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export function storeToObservable<T>(svelteStore: Writable<T> | Readable<T>): Observable<T> {
|
||||
let unsubscribe: Unsubscriber;
|
||||
const observable = new Observable<T>((subscriber) => {
|
||||
unsubscribe = svelteStore.subscribe((val) => {
|
||||
subscriber.next(val);
|
||||
});
|
||||
return () => {
|
||||
unsubscribe();
|
||||
};
|
||||
});
|
||||
return observable;
|
||||
}
|
@ -51,7 +51,6 @@ export const load: LayoutLoad = async ({ params }) => {
|
||||
const projectStore = getProjectStore(params.projectId);
|
||||
|
||||
const pullRequestsStore = listPullRequestsWithCache(githubContextStore);
|
||||
const pullRequestsState = pullRequestsStore.state;
|
||||
|
||||
return {
|
||||
projectId,
|
||||
@ -68,7 +67,6 @@ export const load: LayoutLoad = async ({ params }) => {
|
||||
remoteBranchState,
|
||||
projectStore,
|
||||
githubContextStore,
|
||||
pullRequestsStore,
|
||||
pullRequestsState
|
||||
pullRequestsStore
|
||||
};
|
||||
};
|
||||
|
@ -17,11 +17,12 @@
|
||||
import DomainButton from './DomainButton.svelte';
|
||||
import IconBranch from '$lib/icons/IconBranch.svelte';
|
||||
import IconSettings from '$lib/icons/IconSettings.svelte';
|
||||
import type { Observable } from 'rxjs';
|
||||
|
||||
export let branchesWithContentStore: CustomStore<Branch[] | undefined>;
|
||||
export let remoteBranchStore: CustomStore<RemoteBranch[] | undefined>;
|
||||
export let baseBranchStore: CustomStore<BaseBranch | undefined>;
|
||||
export let pullRequestsStore: CustomStore<PullRequest[] | undefined>;
|
||||
export let pullRequestsStore: Observable<PullRequest[]>;
|
||||
export let branchController: BranchController;
|
||||
export let project: Project;
|
||||
export let githubContext: GitHubIntegrationContext | undefined;
|
||||
|
@ -6,11 +6,10 @@
|
||||
import type { PullRequest } from '$lib/github/types';
|
||||
import { showMenu } from 'tauri-plugin-context-menu';
|
||||
import { projectPullRequestListingFilter, ListPRsFilter } from '$lib/config/config';
|
||||
import type { Loadable } from '@square/svelte-store';
|
||||
import type { Observable } from 'rxjs';
|
||||
|
||||
export let projectId: string;
|
||||
export let pullRequestsStore: Loadable<PullRequest[] | undefined>;
|
||||
$: pullRequestsState = pullRequestsStore?.state;
|
||||
export let pullRequestsStore: Observable<PullRequest[]>;
|
||||
|
||||
let rbViewport: HTMLElement;
|
||||
let rbContents: HTMLElement;
|
||||
@ -72,11 +71,9 @@
|
||||
class="hide-native-scrollbar flex max-h-full flex-grow flex-col overflow-y-scroll overscroll-none"
|
||||
>
|
||||
<div bind:this={rbContents}>
|
||||
{#if $pullRequestsState?.isLoading}
|
||||
{#if !$pullRequestsStore}
|
||||
<span>loading...</span>
|
||||
{:else if $pullRequestsState?.isError}
|
||||
<span>something went wrong</span>
|
||||
{:else if $pullRequestsStore}
|
||||
{:else}
|
||||
{#each filterPRs($pullRequestsStore, $filterChoice) as pr, i}
|
||||
<a
|
||||
href="/{projectId}/pull/{pr.number}"
|
||||
|
@ -188,6 +188,9 @@ importers:
|
||||
reflect-metadata:
|
||||
specifier: ^0.1.13
|
||||
version: 0.1.13
|
||||
rxjs:
|
||||
specifier: ^7.8.1
|
||||
version: 7.8.1
|
||||
svelte:
|
||||
specifier: ^4.2.2
|
||||
version: 4.2.2
|
||||
@ -3857,6 +3860,12 @@ packages:
|
||||
queue-microtask: 1.2.3
|
||||
dev: true
|
||||
|
||||
/rxjs@7.8.1:
|
||||
resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
|
||||
dependencies:
|
||||
tslib: 2.6.2
|
||||
dev: true
|
||||
|
||||
/sade@1.8.1:
|
||||
resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
|
||||
engines: {node: '>=6'}
|
||||
|
Loading…
Reference in New Issue
Block a user