| 65 | } |
| 66 | |
| 67 | export class CommitManager { |
| 68 | private static instancesMap = new Map<string, CommitManager>(); |
| 69 | private static _commitMap = new Map<string, Commit>(); // commitSha -> CommitWithDirection |
| 70 | // if `previous` or `next` is null, it means this is an end node |
| 71 | private static _relationMap = new Map<string, Map<string, { previous?: string | null; next?: string | null }>>(); |
| 72 | |
| 73 | private _latestCommitSha: string | null = null; |
| 74 | private _currentPage = 1; |
| 75 | private _pageSize = 100; |
| 76 | |
| 77 | public static getInstance(scheme: string, repo: string, from: string, filePath: string) { |
| 78 | const mapKey = `${scheme} ${repo} ${from} ${filePath}`; |
| 79 | if (!CommitManager.instancesMap.has(mapKey)) { |
| 80 | CommitManager.instancesMap.set(mapKey, new CommitManager(scheme, repo, from, filePath)); |
| 81 | } |
| 82 | return CommitManager.instancesMap.get(mapKey)!; |
| 83 | } |
| 84 | |
| 85 | private constructor( |
| 86 | private _scheme: string, |
| 87 | private _repo: string, |
| 88 | private _from: string, |
| 89 | private _filePath: string, |
| 90 | ) {} |
| 91 | |
| 92 | // link two commitSha |
| 93 | private linkCommitShas(previousCommitSha: string | null, nextCommitSha: string | null) { |
| 94 | if (!CommitManager._relationMap.has(this._filePath)) { |
| 95 | CommitManager._relationMap.set(this._filePath, new Map()); |
| 96 | } |
| 97 | const relation = CommitManager._relationMap.get(this._filePath)!; |
| 98 | if (previousCommitSha) { |
| 99 | !relation.has(previousCommitSha) && relation.set(previousCommitSha, {}); |
| 100 | relation.get(previousCommitSha)!.next = nextCommitSha; |
| 101 | } |
| 102 | if (nextCommitSha) { |
| 103 | !relation.has(nextCommitSha) && relation.set(nextCommitSha, {}); |
| 104 | relation.get(nextCommitSha)!.previous = previousCommitSha; |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | // construct commit list with commit relations |
| 109 | private resolveCommitList() { |
| 110 | const commitList: Commit[] = []; |
| 111 | const relation = CommitManager._relationMap.get(this._filePath); |
| 112 | let currentCommitSha: string | undefined | null = this._latestCommitSha; |
| 113 | while (currentCommitSha && CommitManager._commitMap.has(currentCommitSha)) { |
| 114 | const commit = CommitManager._commitMap.get(currentCommitSha)!; |
| 115 | commitList.push(commit); |
| 116 | currentCommitSha = relation?.get(commit.sha)?.previous; |
| 117 | } |
| 118 | return commitList; |
| 119 | } |
| 120 | |
| 121 | getList = reuseable(async (forceUpdate: boolean = false): Promise<Commit[]> => { |
| 122 | const hasMore = await this.hasMore(); |
| 123 | const commitList = this.resolveCommitList(); |
| 124 | const shouldLoadMore = hasMore && commitList.length < this._pageSize; |
nothing calls this directly
no test coverage detected