From 933da5588a55774108e4d46159f1e0c9f0bcb526 Mon Sep 17 00:00:00 2001 From: Kiril Videlov Date: Sat, 8 Jul 2023 23:15:08 +0200 Subject: [PATCH] make it a class --- src/lib/vbranches/BranchController.ts | 2 +- src/lib/vbranches/BranchStoresCache.ts | 93 ++++++++++++++++++++++++++ src/lib/vbranches/branchStores.ts | 90 ------------------------- src/lib/vbranches/index.ts | 14 ++-- 4 files changed, 101 insertions(+), 98 deletions(-) create mode 100644 src/lib/vbranches/BranchStoresCache.ts delete mode 100644 src/lib/vbranches/branchStores.ts diff --git a/src/lib/vbranches/BranchController.ts b/src/lib/vbranches/BranchController.ts index 3fd5e89e0..51ca09421 100644 --- a/src/lib/vbranches/BranchController.ts +++ b/src/lib/vbranches/BranchController.ts @@ -1,4 +1,4 @@ -import type { Refreshable } from './branchStores'; +import type { Refreshable } from './BranchStoresCache'; import type { Readable } from '@square/svelte-store'; import type { Loadable } from 'svelte-loadable-store'; import type { Branch, BranchData, Target } from './types'; diff --git a/src/lib/vbranches/BranchStoresCache.ts b/src/lib/vbranches/BranchStoresCache.ts new file mode 100644 index 000000000..4d32cbb13 --- /dev/null +++ b/src/lib/vbranches/BranchStoresCache.ts @@ -0,0 +1,93 @@ +import { writable, type Loadable, Value } from 'svelte-loadable-store'; +import type { Readable } from '@square/svelte-store'; +import { git } from '$lib/api/ipc'; +import { stores } from '$lib'; +import type { Branch, BranchData, Target } from './types'; +import * as ipc from './ipc'; + +export interface Refreshable { + refresh(): Promise; +} + +export class BranchStoresCache { + virtualBranchStores: Map>> = new Map(); + remoteBranchStores: Map>> = new Map(); + targetBranchStores: Map>> = new Map(); + + getVirtualBranchStore(projectId: string) { + const cachedStore = this.virtualBranchStores.get(projectId); + if (cachedStore) { + return cachedStore; + } + const writableStore = writable(ipc.listVirtualBranches({ projectId }), (set) => { + stores.sessions({ projectId }).subscribe((sessions) => { + if (sessions.isLoading) return; + if (Value.isError(sessions.value)) return; + const lastSession = sessions.value.at(-1); + if (!lastSession) return; + return stores.deltas({ projectId, sessionId: lastSession.id }).subscribe(() => { + ipc.listVirtualBranches({ projectId }).then(set); + }); + }); + }); + const refreshableStore = { + subscribe: writableStore.subscribe, + refresh: async () => { + const newBranches = await ipc.listVirtualBranches({ projectId }); + return writableStore.set({ isLoading: false, value: newBranches }); + } + }; + this.virtualBranchStores.set(projectId, refreshableStore); + return refreshableStore; + } + + getRemoteBranchStore(projectId: string) { + const cachedStore = this.remoteBranchStores.get(projectId); + if (cachedStore) { + return cachedStore; + } + const writableStore = writable(ipc.getRemoteBranchesData({ projectId }), (set) => { + git.fetches.subscribe({ projectId }, () => { + ipc.getRemoteBranchesData({ projectId }).then((branches) => { + set(sortBranchData(branches)); + }); + }); + }); + const refreshableStore = { + subscribe: writableStore.subscribe, + refresh: async () => { + const newRemoteBranches = await ipc.getRemoteBranchesData({ projectId }); + return writableStore.set({ isLoading: false, value: newRemoteBranches }); + } + }; + this.remoteBranchStores.set(projectId, refreshableStore); + return refreshableStore; + } + + getTargetBranchStore(projectId: string) { + const cachedStore = this.targetBranchStores.get(projectId); + if (cachedStore) { + return cachedStore; + } + const writableStore = writable(ipc.getTargetData({ projectId }), (set) => { + git.fetches.subscribe({ projectId }, () => { + ipc.getTargetData({ projectId }).then((newTarget) => { + set(newTarget); + }); + }); + }); + const refreshableStore = { + subscribe: writableStore.subscribe, + refresh: async () => { + const newTarget = await ipc.getTargetData({ projectId }); + return writableStore.set({ isLoading: false, value: newTarget }); + } + }; + this.targetBranchStores.set(projectId, refreshableStore); + return refreshableStore; + } +} + +function sortBranchData(branchData: BranchData[]): BranchData[] { + return branchData.sort((a, b) => b.lastCommitTs - a.lastCommitTs); +} diff --git a/src/lib/vbranches/branchStores.ts b/src/lib/vbranches/branchStores.ts deleted file mode 100644 index 8044e67c9..000000000 --- a/src/lib/vbranches/branchStores.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { writable, type Loadable, Value } from 'svelte-loadable-store'; -import type { Readable } from '@square/svelte-store'; -import { git } from '$lib/api/ipc'; -import { stores } from '$lib'; -import type { Branch, BranchData, Target } from './types'; -import * as ipc from './ipc'; - -export interface Refreshable { - refresh(): Promise; -} - -const virtualBranchStores: Map>> = new Map(); -const remoteBranchStores: Map>> = new Map(); -const targetBranchStores: Map>> = new Map(); - -export function getVirtualBranchStore(projectId: string) { - const cachedStore = virtualBranchStores.get(projectId); - if (cachedStore) { - return cachedStore; - } - const writableStore = writable(ipc.listVirtualBranches({ projectId }), (set) => { - stores.sessions({ projectId }).subscribe((sessions) => { - if (sessions.isLoading) return; - if (Value.isError(sessions.value)) return; - const lastSession = sessions.value.at(-1); - if (!lastSession) return; - return stores.deltas({ projectId, sessionId: lastSession.id }).subscribe(() => { - ipc.listVirtualBranches({ projectId }).then(set); - }); - }); - }); - const refreshableStore = { - subscribe: writableStore.subscribe, - refresh: async () => { - const newBranches = await ipc.listVirtualBranches({ projectId }); - return writableStore.set({ isLoading: false, value: newBranches }); - } - }; - virtualBranchStores.set(projectId, refreshableStore); - return refreshableStore; -} - -export function getRemoteBranchStore(projectId: string) { - const cachedStore = remoteBranchStores.get(projectId); - if (cachedStore) { - return cachedStore; - } - const writableStore = writable(ipc.getRemoteBranchesData({ projectId }), (set) => { - git.fetches.subscribe({ projectId }, () => { - ipc.getRemoteBranchesData({ projectId }).then((branches) => { - set(sortBranchData(branches)); - }); - }); - }); - const refreshableStore = { - subscribe: writableStore.subscribe, - refresh: async () => { - const newRemoteBranches = await ipc.getRemoteBranchesData({ projectId }); - return writableStore.set({ isLoading: false, value: newRemoteBranches }); - } - }; - remoteBranchStores.set(projectId, refreshableStore); - return refreshableStore; -} -export function getTargetBranchStore(projectId: string) { - const cachedStore = targetBranchStores.get(projectId); - if (cachedStore) { - return cachedStore; - } - const writableStore = writable(ipc.getTargetData({ projectId }), (set) => { - git.fetches.subscribe({ projectId }, () => { - ipc.getTargetData({ projectId }).then((newTarget) => { - set(newTarget); - }); - }); - }); - const refreshableStore = { - subscribe: writableStore.subscribe, - refresh: async () => { - const newTarget = await ipc.getTargetData({ projectId }); - return writableStore.set({ isLoading: false, value: newTarget }); - } - }; - targetBranchStores.set(projectId, refreshableStore); - return refreshableStore; -} - -function sortBranchData(branchData: BranchData[]): BranchData[] { - return branchData.sort((a, b) => b.lastCommitTs - a.lastCommitTs); -} diff --git a/src/lib/vbranches/index.ts b/src/lib/vbranches/index.ts index 41c11e2bf..f77c99499 100644 --- a/src/lib/vbranches/index.ts +++ b/src/lib/vbranches/index.ts @@ -1,12 +1,12 @@ /** * Virtual Branch feature package (experiment) * - * There are three interesting data types coming from the IPC api: + * There are three interesting data types coming from the rust IPC api: * - Branch, representing a virtual branch * - BranchData, representing a remote branch * - Target, representing a target remote branch * - * There are thee respective functions for getting reactive stores for those types: + * The three types are obtained as reactive stores from the BranchStoresCache's methods: * - getVirtualBranchStore - List of Branch (virtual branches) * - getRemoteBranchStore - List of BranchData (remote branches) * - getTargetBranchStore - Target (sinle target branch) @@ -14,12 +14,12 @@ * BranchController is a class where all virtual branch operations are performed * This class gets the three stores injected at construction so that any related updates can be peformed * - * Usage: + * Note to self: * - * - Create the three relevant stores at the top level (where projects are listed), - * so that it can take advantage of caching, making project navigation quicker. - * - Create the BranchController at the level of a specific project and inject it to components that need it + * - Create the BranchStoresCacheat the top level (where projects are listed), + * so that it can take advantage of caching, making project navigation quicker. + * - Create the BranchController at the level of a specific project and inject it to components that need it. */ export type { Branch, File, Hunk, Commit, BranchData, Target } from './types'; -export { getVirtualBranchStore, getRemoteBranchStore, getTargetBranchStore } from './branchStores'; +export { BranchStoresCache } from './BranchStoresCache'; export { BranchController } from './BranchController';