mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-22 17:11:43 +03:00
make it a class
This commit is contained in:
parent
e4c1329f51
commit
933da5588a
@ -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';
|
||||
|
93
src/lib/vbranches/BranchStoresCache.ts
Normal file
93
src/lib/vbranches/BranchStoresCache.ts
Normal file
@ -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<void | object>;
|
||||
}
|
||||
|
||||
export class BranchStoresCache {
|
||||
virtualBranchStores: Map<string, Refreshable & Readable<Loadable<Branch[]>>> = new Map();
|
||||
remoteBranchStores: Map<string, Refreshable & Readable<Loadable<BranchData[]>>> = new Map();
|
||||
targetBranchStores: Map<string, Readable<Loadable<Target>>> = 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);
|
||||
}
|
@ -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<void | object>;
|
||||
}
|
||||
|
||||
const virtualBranchStores: Map<string, Refreshable & Readable<Loadable<Branch[]>>> = new Map();
|
||||
const remoteBranchStores: Map<string, Refreshable & Readable<Loadable<BranchData[]>>> = new Map();
|
||||
const targetBranchStores: Map<string, Readable<Loadable<Target>>> = 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);
|
||||
}
|
@ -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';
|
||||
|
Loading…
Reference in New Issue
Block a user