@thxgg/steward 0.1.18 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/nitro.json +1 -1
- package/.output/public/_nuxt/B3PShd4B.js +3 -0
- package/.output/public/_nuxt/{CJlXUkTg.js → B7kcsnX1.js} +1 -1
- package/.output/public/_nuxt/B9j1BHt9.js +1 -0
- package/.output/public/_nuxt/BGSfDLaX.js +1 -0
- package/.output/public/_nuxt/{C_HVaH3B.js → BTHAQvnA.js} +1 -1
- package/.output/public/_nuxt/C2LWefrW.js +1 -0
- package/.output/public/_nuxt/{WUF6Thhn.js → CV5HFGKm.js} +1 -1
- package/.output/public/_nuxt/{CGzrvVc6.js → ClxxfTZn.js} +1 -1
- package/.output/public/_nuxt/{QAzsKGuP.js → CzCDTesu.js} +1 -1
- package/.output/public/_nuxt/{DEr8q68O.js → D6aZT905.js} +1 -1
- package/.output/public/_nuxt/{TSsR_oCL.js → D9fz0wy8.js} +1 -1
- package/.output/public/_nuxt/DDV2bymk.js +60 -0
- package/.output/public/_nuxt/DK5VWQk7.js +1 -0
- package/.output/public/_nuxt/{DAnnHVQP.js → DSqaInP-.js} +1 -1
- package/.output/public/_nuxt/Detail.CYc96mGf.css +1 -0
- package/.output/public/_nuxt/{BA4e9-N5.js → Dn6yoG20.js} +2 -2
- package/.output/public/_nuxt/{-z_Gr0GN.js → a87LfEfa.js} +1 -1
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/37438177-5e14-4a46-9af4-eae491ba1f24.json +1 -0
- package/.output/public/_nuxt/entry.Dp3jx0Yw.css +1 -0
- package/.output/public/_nuxt/zhOijcjw.js +30 -0
- package/.output/server/chunks/_/prd-service.mjs +101 -68
- package/.output/server/chunks/_/prd-service.mjs.map +1 -1
- package/.output/server/chunks/_/repos.mjs +3 -179
- package/.output/server/chunks/_/repos.mjs.map +1 -1
- package/.output/server/chunks/_/task-graph.mjs +8 -4
- package/.output/server/chunks/_/task-graph.mjs.map +1 -1
- package/.output/server/chunks/_/watcher.mjs +2 -32
- package/.output/server/chunks/_/watcher.mjs.map +1 -1
- package/.output/server/chunks/build/{Detail-BQSkP9Zm.mjs → Detail-B7yBNjgp.mjs} +324 -140
- package/.output/server/chunks/build/Detail-B7yBNjgp.mjs.map +1 -0
- package/.output/server/chunks/build/DiffViewer-styles-1.mjs-d2dQvARr.mjs +4 -0
- package/.output/server/chunks/build/DiffViewer-styles-1.mjs-d2dQvARr.mjs.map +1 -0
- package/.output/server/chunks/build/DiffViewer-styles.BDwAqkTk.mjs +8 -0
- package/.output/server/chunks/build/DiffViewer-styles.BDwAqkTk.mjs.map +1 -0
- package/.output/server/chunks/build/DiffViewer-styles.DRJh5Ui4.mjs +10 -0
- package/.output/server/chunks/build/DiffViewer-styles.DRJh5Ui4.mjs.map +1 -0
- package/.output/server/chunks/build/{_prd_-CBR_wm9i.mjs → _prd_-DY25apyl.mjs} +81 -6
- package/.output/server/chunks/build/_prd_-DY25apyl.mjs.map +1 -0
- package/.output/server/chunks/build/client.precomputed.mjs +1 -1
- package/.output/server/chunks/build/{default-Cao5eO80.mjs → default-BKKgG7HJ.mjs} +221 -23
- package/.output/server/chunks/build/default-BKKgG7HJ.mjs.map +1 -0
- package/.output/server/chunks/build/error-404-Bf6kdO80.mjs +2 -0
- package/.output/server/chunks/build/error-500-D_bcARXN.mjs +2 -0
- package/.output/server/chunks/build/{index-ljj9uTXI.mjs → index-DE1tjHAd.mjs} +4 -3
- package/.output/server/chunks/build/index-DE1tjHAd.mjs.map +1 -0
- package/.output/server/chunks/build/nuxt-link-SvT1nf8Z.mjs +1 -1
- package/.output/server/chunks/build/{repo-graph-CVnkmn8i.mjs → repo-graph-CUcJKW1F.mjs} +26 -11
- package/.output/server/chunks/build/repo-graph-CUcJKW1F.mjs.map +1 -0
- package/.output/server/chunks/build/server.mjs +15 -13
- package/.output/server/chunks/build/styles.mjs +2 -2
- package/.output/server/chunks/build/{usePrd-f7ylhIqs.mjs → usePrd-hXZOmvAv.mjs} +113 -9
- package/.output/server/chunks/build/usePrd-hXZOmvAv.mjs.map +1 -0
- package/.output/server/chunks/nitro/nitro.mjs +1311 -599
- package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get.mjs +2 -1
- package/.output/server/chunks/routes/api/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.post.mjs +2 -2
- package/.output/server/chunks/routes/api/repos/_repoId/git/commits.get.mjs +2 -1
- package/.output/server/chunks/routes/api/repos/_repoId/git/commits.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/repos/_repoId/git/diff.get.mjs +2 -1
- package/.output/server/chunks/routes/api/repos/_repoId/git/diff.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/repos/_repoId/git/file-content.get.mjs +2 -1
- package/.output/server/chunks/routes/api/repos/_repoId/git/file-content.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/repos/_repoId/git/file-diff.get.mjs +2 -1
- package/.output/server/chunks/routes/api/repos/_repoId/git/file-diff.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/repos/_repoId/graph.get.mjs +27 -4
- package/.output/server/chunks/routes/api/repos/_repoId/graph.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/repos/_repoId/prd/_prdSlug/archive.post.mjs +93 -0
- package/.output/server/chunks/routes/api/repos/_repoId/prd/_prdSlug/archive.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/repos/_repoId/prd/_prdSlug/graph.get.mjs +2 -2
- package/.output/server/chunks/routes/api/repos/_repoId/prd/_prdSlug/progress.get.mjs +3 -3
- package/.output/server/chunks/routes/api/repos/_repoId/prd/_prdSlug/tasks/_taskId/commits.get.mjs +3 -3
- package/.output/server/chunks/routes/api/repos/_repoId/prd/_prdSlug/tasks.get.mjs +3 -3
- package/.output/server/chunks/routes/api/repos/_repoId/prd/_prdSlug_.get.mjs +2 -2
- package/.output/server/chunks/routes/api/repos/_repoId/prds.get.mjs +27 -4
- package/.output/server/chunks/routes/api/repos/_repoId/prds.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/repos/_repoId/refresh-git-repos.post.mjs +2 -1
- package/.output/server/chunks/routes/api/repos/_repoId/refresh-git-repos.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/repos/_repoId_.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/repos/_repoId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/runtime.get.mjs +2 -0
- package/.output/server/chunks/routes/api/runtime.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/state-migration/status.get.mjs +21 -0
- package/.output/server/chunks/routes/api/state-migration/status.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/watch.get.mjs +4 -3
- package/.output/server/chunks/routes/api/watch.get.mjs.map +1 -1
- package/.output/server/chunks/routes/renderer.mjs +1 -1
- package/.output/server/index.mjs +3 -1
- package/.output/server/index.mjs.map +1 -1
- package/.output/server/package.json +1 -1
- package/README.md +3 -0
- package/dist/app/lib/async-request.js +39 -0
- package/dist/server/utils/db.js +15 -0
- package/dist/server/utils/prd-archive.js +53 -0
- package/dist/server/utils/prd-service.js +26 -6
- package/dist/server/utils/prd-state.js +11 -2
- package/dist/server/utils/state-migration.js +225 -0
- package/dist/server/utils/state-schema.js +181 -4
- package/dist/server/utils/task-graph.js +10 -3
- package/package.json +1 -1
- package/.output/public/_nuxt/5LlyHjkF.js +0 -60
- package/.output/public/_nuxt/BA0u_CRT.js +0 -1
- package/.output/public/_nuxt/BO8EM227.js +0 -3
- package/.output/public/_nuxt/C0XT5P3Q.js +0 -1
- package/.output/public/_nuxt/CZsXZugv.js +0 -1
- package/.output/public/_nuxt/Detail.DSyVQNdr.css +0 -1
- package/.output/public/_nuxt/DrXxYwWw.js +0 -30
- package/.output/public/_nuxt/builds/meta/19e0e040-a531-4c25-b46d-a6ca54a1ae3e.json +0 -1
- package/.output/public/_nuxt/entry.LcDOtJnR.css +0 -1
- package/.output/public/_nuxt/i9wn3hS7.js +0 -1
- package/.output/server/chunks/build/Detail-BQSkP9Zm.mjs.map +0 -1
- package/.output/server/chunks/build/DiffViewer-styles-1.mjs-BFsE2PCW.mjs +0 -4
- package/.output/server/chunks/build/DiffViewer-styles-1.mjs-BFsE2PCW.mjs.map +0 -1
- package/.output/server/chunks/build/DiffViewer-styles.D2bqX3nK.mjs +0 -8
- package/.output/server/chunks/build/DiffViewer-styles.D2bqX3nK.mjs.map +0 -1
- package/.output/server/chunks/build/DiffViewer-styles.FoV36wuV.mjs +0 -10
- package/.output/server/chunks/build/DiffViewer-styles.FoV36wuV.mjs.map +0 -1
- package/.output/server/chunks/build/_prd_-CBR_wm9i.mjs.map +0 -1
- package/.output/server/chunks/build/default-Cao5eO80.mjs.map +0 -1
- package/.output/server/chunks/build/index-ByZO4Bvq.mjs +0 -76
- package/.output/server/chunks/build/index-ByZO4Bvq.mjs.map +0 -1
- package/.output/server/chunks/build/index-ljj9uTXI.mjs.map +0 -1
- package/.output/server/chunks/build/repo-graph-CVnkmn8i.mjs.map +0 -1
- package/.output/server/chunks/build/usePrd-f7ylhIqs.mjs.map +0 -1
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { defineComponent,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { defineComponent, unref, mergeProps, withCtx, renderSlot, markRaw, ref, watch, computed, createVNode, useModel, createTextVNode, toDisplayString, openBlock, createBlock, createCommentVNode, resolveDynamicComponent, Fragment, renderList, mergeModels, useSSRContext } from 'vue';
|
|
2
|
+
import { ssrRenderComponent, ssrRenderSlot, ssrRenderAttrs, ssrInterpolate, ssrRenderVNode, ssrRenderList, ssrRenderClass, ssrRenderAttr, ssrRenderStyle } from 'vue/server-renderer';
|
|
3
|
+
import { reactiveOmit, useMediaQuery } from '@vueuse/core';
|
|
4
4
|
import { Background } from '@vue-flow/background';
|
|
5
5
|
import { Controls } from '@vue-flow/controls';
|
|
6
6
|
import { MarkerType, VueFlow, Position, Handle } from '@vue-flow/core';
|
|
7
7
|
import { Loader2, AlertCircle, GitBranch, Circle, Clock3, CheckCircle2, AlertTriangle, Clock, ArrowLeft, Tag, ListOrdered, CheckSquare, Check, Link2, Diff, Calendar, ExternalLink, X, RefreshCw, Keyboard, FileDiff, FileCode, GitCommit, FileText, Plus, Minus, FolderGit2, ArrowRight, FileWarning, ChevronDown, Link, Link2Off, FileEdit, FileX, FilePlus } from 'lucide-vue-next';
|
|
8
|
-
import { B as Button } from './
|
|
8
|
+
import { c as cn, B as Button, b as useToast } from './usePrd-hXZOmvAv.mjs';
|
|
9
9
|
import { _ as _export_sfc } from './_plugin-vue_export-helper-1tPrXgE0.mjs';
|
|
10
10
|
import { Primitive, useForwardPropsEmits, DialogRoot, DialogPortal, DialogContent, DialogClose, DialogTitle, DialogDescription, Separator as Separator$1, DialogOverlay, TooltipProvider as TooltipProvider$1, TooltipRoot, TooltipTrigger as TooltipTrigger$1, TooltipPortal, TooltipContent as TooltipContent$1, TooltipArrow, ScrollAreaRoot, ScrollAreaViewport, ScrollAreaCorner, ScrollAreaScrollbar, ScrollAreaThumb, DialogTrigger } from 'reka-ui';
|
|
11
|
-
import { c as cn, b as useToast } from './usePrd-f7ylhIqs.mjs';
|
|
12
11
|
import { cva } from 'class-variance-authority';
|
|
13
12
|
import { _ as __nuxt_component_0$3 } from './nuxt-link-SvT1nf8Z.mjs';
|
|
14
13
|
|
|
@@ -583,6 +582,14 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
|
|
|
583
582
|
ref(null);
|
|
584
583
|
ref(null);
|
|
585
584
|
ref(false);
|
|
585
|
+
let fullFileHighlightRunVersion = 0;
|
|
586
|
+
let diffHighlightRunVersion = 0;
|
|
587
|
+
watch(
|
|
588
|
+
() => props.filePath,
|
|
589
|
+
() => {
|
|
590
|
+
showAll.value = false;
|
|
591
|
+
}
|
|
592
|
+
);
|
|
586
593
|
const totalLines = computed(() => {
|
|
587
594
|
let count = 0;
|
|
588
595
|
for (const hunk of props.hunks) {
|
|
@@ -672,6 +679,7 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
|
|
|
672
679
|
}
|
|
673
680
|
const displayItems = computed(() => {
|
|
674
681
|
const items = [];
|
|
682
|
+
const idPrefix = props.filePath;
|
|
675
683
|
for (let hunkIndex = 0; hunkIndex < props.hunks.length; hunkIndex++) {
|
|
676
684
|
const hunk = props.hunks[hunkIndex];
|
|
677
685
|
if (hunkIndex > 0) {
|
|
@@ -685,7 +693,7 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
|
|
|
685
693
|
items.push({
|
|
686
694
|
type: "line",
|
|
687
695
|
pair: {
|
|
688
|
-
id: `${hunkIndex}-${i}`,
|
|
696
|
+
id: `${idPrefix}:${hunkIndex}-${i}`,
|
|
689
697
|
left: {
|
|
690
698
|
lineNum: line.oldNumber,
|
|
691
699
|
content: line.content,
|
|
@@ -717,7 +725,7 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
|
|
|
717
725
|
items.push({
|
|
718
726
|
type: "line",
|
|
719
727
|
pair: {
|
|
720
|
-
id: `${hunkIndex}-${i - maxLen + j}`,
|
|
728
|
+
id: `${idPrefix}:${hunkIndex}-${i - maxLen + j}`,
|
|
721
729
|
left: removeLine ? {
|
|
722
730
|
lineNum: removeLine.oldNumber,
|
|
723
731
|
content: removeLine.content,
|
|
@@ -735,7 +743,7 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
|
|
|
735
743
|
items.push({
|
|
736
744
|
type: "line",
|
|
737
745
|
pair: {
|
|
738
|
-
id: `${hunkIndex}-${i}`,
|
|
746
|
+
id: `${idPrefix}:${hunkIndex}-${i}`,
|
|
739
747
|
left: { content: "", type: "empty" },
|
|
740
748
|
right: {
|
|
741
749
|
lineNum: line.newNumber,
|
|
@@ -814,72 +822,109 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
|
|
|
814
822
|
const isLoadingFullFile = ref(false);
|
|
815
823
|
watch(
|
|
816
824
|
() => [props.fileContent, props.filePath],
|
|
817
|
-
async ([content]) => {
|
|
825
|
+
async ([content], _, onCleanup) => {
|
|
826
|
+
const runVersion = ++fullFileHighlightRunVersion;
|
|
827
|
+
let invalidated = false;
|
|
828
|
+
onCleanup(() => {
|
|
829
|
+
invalidated = true;
|
|
830
|
+
});
|
|
831
|
+
highlightedFullFile.value = [];
|
|
818
832
|
if (!content) {
|
|
819
|
-
|
|
833
|
+
isLoadingFullFile.value = false;
|
|
820
834
|
return;
|
|
821
835
|
}
|
|
822
836
|
isLoadingFullFile.value = true;
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
837
|
+
try {
|
|
838
|
+
const highlighted = await highlightFullContent(content, language.value);
|
|
839
|
+
if (invalidated || runVersion !== fullFileHighlightRunVersion) {
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
highlightedFullFile.value = highlighted;
|
|
843
|
+
} finally {
|
|
844
|
+
if (!invalidated && runVersion === fullFileHighlightRunVersion) {
|
|
845
|
+
isLoadingFullFile.value = false;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
826
848
|
},
|
|
827
849
|
{ immediate: true }
|
|
828
850
|
);
|
|
829
851
|
watch(
|
|
830
852
|
() => [props.hunks, props.filePath, highlightedFullFile.value],
|
|
831
|
-
async () => {
|
|
853
|
+
async (_, __, onCleanup) => {
|
|
854
|
+
const runVersion = ++diffHighlightRunVersion;
|
|
855
|
+
let invalidated = false;
|
|
856
|
+
onCleanup(() => {
|
|
857
|
+
invalidated = true;
|
|
858
|
+
});
|
|
832
859
|
isLoading.value = true;
|
|
860
|
+
highlightedLines.value = /* @__PURE__ */ new Map();
|
|
833
861
|
const lang = language.value;
|
|
834
862
|
const newHighlighted = /* @__PURE__ */ new Map();
|
|
835
863
|
const fullFileLines2 = highlightedFullFile.value;
|
|
836
864
|
const linesToHighlight = [];
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
if (
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
865
|
+
try {
|
|
866
|
+
for (const item of displayItems.value) {
|
|
867
|
+
if (invalidated || runVersion !== diffHighlightRunVersion) {
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
if (item.type === "line" && item.pair) {
|
|
871
|
+
if (item.pair.left.content && item.pair.left.type !== "empty") {
|
|
872
|
+
const key = `${item.pair.id}-old`;
|
|
873
|
+
if (item.pair.left.type === "context" && item.pair.left.lineNum && fullFileLines2.length > 0) {
|
|
874
|
+
const lineIndex = item.pair.right.lineNum ? item.pair.right.lineNum - 1 : -1;
|
|
875
|
+
if (lineIndex >= 0 && lineIndex < fullFileLines2.length) {
|
|
876
|
+
newHighlighted.set(key, fullFileLines2[lineIndex] || "");
|
|
877
|
+
} else {
|
|
878
|
+
linesToHighlight.push({ key, content: item.pair.left.content });
|
|
879
|
+
}
|
|
845
880
|
} else {
|
|
846
881
|
linesToHighlight.push({ key, content: item.pair.left.content });
|
|
847
882
|
}
|
|
848
|
-
} else {
|
|
849
|
-
linesToHighlight.push({ key, content: item.pair.left.content });
|
|
850
883
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
884
|
+
if (item.pair.right.content && item.pair.right.type !== "empty") {
|
|
885
|
+
const key = `${item.pair.id}-new`;
|
|
886
|
+
const lineNum = item.pair.right.lineNum;
|
|
887
|
+
if (lineNum && fullFileLines2.length > 0 && lineNum <= fullFileLines2.length) {
|
|
888
|
+
newHighlighted.set(key, fullFileLines2[lineNum - 1] || "");
|
|
889
|
+
} else {
|
|
890
|
+
linesToHighlight.push({ key, content: item.pair.right.content });
|
|
891
|
+
}
|
|
859
892
|
}
|
|
860
893
|
}
|
|
861
894
|
}
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
batch.
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
895
|
+
const limitedLines = linesToHighlight.slice(0, MAX_DIFF_HIGHLIGHT_LINES);
|
|
896
|
+
const overflowLines = linesToHighlight.slice(MAX_DIFF_HIGHLIGHT_LINES);
|
|
897
|
+
for (const { key, content } of overflowLines) {
|
|
898
|
+
newHighlighted.set(key, escapeHtml(content));
|
|
899
|
+
}
|
|
900
|
+
const batchSize = 50;
|
|
901
|
+
for (let i = 0; i < limitedLines.length; i += batchSize) {
|
|
902
|
+
if (invalidated || runVersion !== diffHighlightRunVersion) {
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
const batch = limitedLines.slice(i, i + batchSize);
|
|
906
|
+
const results = await Promise.all(
|
|
907
|
+
batch.map(async ({ key, content }) => {
|
|
908
|
+
const result = await highlightLine(content, lang);
|
|
909
|
+
return { key, result };
|
|
910
|
+
})
|
|
911
|
+
);
|
|
912
|
+
if (invalidated || runVersion !== diffHighlightRunVersion) {
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
for (const { key, result } of results) {
|
|
916
|
+
newHighlighted.set(key, result);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
if (invalidated || runVersion !== diffHighlightRunVersion) {
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
922
|
+
highlightedLines.value = newHighlighted;
|
|
923
|
+
} finally {
|
|
924
|
+
if (!invalidated && runVersion === diffHighlightRunVersion) {
|
|
925
|
+
isLoading.value = false;
|
|
879
926
|
}
|
|
880
927
|
}
|
|
881
|
-
highlightedLines.value = newHighlighted;
|
|
882
|
-
isLoading.value = false;
|
|
883
928
|
},
|
|
884
929
|
{ immediate: true }
|
|
885
930
|
);
|
|
@@ -891,21 +936,21 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
|
|
|
891
936
|
return "context";
|
|
892
937
|
}
|
|
893
938
|
return (_ctx, _push, _parent, _attrs) => {
|
|
894
|
-
_push(`<div${ssrRenderAttrs(mergeProps({ class: "diff-viewer" }, _attrs))} data-v-
|
|
939
|
+
_push(`<div${ssrRenderAttrs(mergeProps({ class: "diff-viewer" }, _attrs))} data-v-9eb8ced7>`);
|
|
895
940
|
if ((unref(isLoading) || __props.isLoadingContent || unref(isLoadingFullFile)) && !__props.binary) {
|
|
896
|
-
_push(`<div class="flex items-center justify-center py-8" data-v-
|
|
941
|
+
_push(`<div class="flex items-center justify-center py-8" data-v-9eb8ced7><div class="size-6 animate-spin rounded-full border-2 border-primary border-t-transparent" data-v-9eb8ced7></div></div>`);
|
|
897
942
|
} else if (__props.binary) {
|
|
898
|
-
_push(`<div class="flex flex-col items-center justify-center gap-3 py-12 text-muted-foreground" data-v-
|
|
943
|
+
_push(`<div class="flex flex-col items-center justify-center gap-3 py-12 text-muted-foreground" data-v-9eb8ced7>`);
|
|
899
944
|
_push(ssrRenderComponent(unref(FileWarning), { class: "size-10 opacity-50" }, null, _parent));
|
|
900
|
-
_push(`<div class="text-center" data-v-
|
|
945
|
+
_push(`<div class="text-center" data-v-9eb8ced7><p class="font-medium" data-v-9eb8ced7>Binary file</p><p class="text-sm" data-v-9eb8ced7>This file cannot be displayed as a diff</p></div></div>`);
|
|
901
946
|
} else if (unref(isEmpty) && !__props.showFullFile) {
|
|
902
|
-
_push(`<div class="flex flex-col items-center justify-center gap-3 py-12 text-muted-foreground" data-v-
|
|
947
|
+
_push(`<div class="flex flex-col items-center justify-center gap-3 py-12 text-muted-foreground" data-v-9eb8ced7>`);
|
|
903
948
|
_push(ssrRenderComponent(unref(AlertTriangle), { class: "size-10 opacity-50" }, null, _parent));
|
|
904
|
-
_push(`<div class="text-center" data-v-
|
|
949
|
+
_push(`<div class="text-center" data-v-9eb8ced7><p class="font-medium" data-v-9eb8ced7>No changes</p><p class="text-sm" data-v-9eb8ced7>This file was touched but has no content changes</p></div></div>`);
|
|
905
950
|
} else if (unref(isLargeFile) && !unref(showAll) && !__props.showFullFile) {
|
|
906
|
-
_push(`<div class="diff-container" data-v-
|
|
951
|
+
_push(`<div class="diff-container" data-v-9eb8ced7><div class="flex flex-col items-center justify-center gap-3 border-b border-border bg-muted/30 py-6" data-v-9eb8ced7>`);
|
|
907
952
|
_push(ssrRenderComponent(unref(AlertTriangle), { class: "size-8 text-yellow-500" }, null, _parent));
|
|
908
|
-
_push(`<div class="text-center" data-v-
|
|
953
|
+
_push(`<div class="text-center" data-v-9eb8ced7><p class="font-medium" data-v-9eb8ced7>Large file</p><p class="text-sm text-muted-foreground" data-v-9eb8ced7> This file has ${ssrInterpolate(unref(totalLines).toLocaleString())} lines (threshold: ${ssrInterpolate(LINE_LIMIT.toLocaleString())}) </p></div>`);
|
|
909
954
|
_push(ssrRenderComponent(unref(Button), {
|
|
910
955
|
variant: "outline",
|
|
911
956
|
size: "sm",
|
|
@@ -926,15 +971,15 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
|
|
|
926
971
|
}, _parent));
|
|
927
972
|
_push(`</div></div>`);
|
|
928
973
|
} else if (__props.showFullFile && __props.fileContent) {
|
|
929
|
-
_push(`<div class="diff-container" data-v-
|
|
974
|
+
_push(`<div class="diff-container" data-v-9eb8ced7><div class="full-file-view" data-v-9eb8ced7><!--[-->`);
|
|
930
975
|
ssrRenderList(unref(fullFileLines), (line, index) => {
|
|
931
976
|
_push(`<div class="${ssrRenderClass([{
|
|
932
977
|
"diff-add": getFullFileLineType(index + 1) === "add"
|
|
933
|
-
}, "full-file-line"])}" data-v-
|
|
978
|
+
}, "full-file-line"])}" data-v-9eb8ced7><div class="diff-gutter" data-v-9eb8ced7><span class="line-number" data-v-9eb8ced7>${ssrInterpolate(index + 1)}</span></div><div class="diff-content" data-v-9eb8ced7><span class="diff-code" data-v-9eb8ced7>${(unref(highlightedFullFile)[index] || escapeHtml(line)) ?? ""}</span></div></div>`);
|
|
934
979
|
});
|
|
935
980
|
_push(`<!--]--></div></div>`);
|
|
936
981
|
} else {
|
|
937
|
-
_push(`<div class="diff-container" data-v-
|
|
982
|
+
_push(`<div class="diff-container" data-v-9eb8ced7><div class="diff-toolbar" data-v-9eb8ced7>`);
|
|
938
983
|
_push(ssrRenderComponent(unref(Button), {
|
|
939
984
|
variant: "ghost",
|
|
940
985
|
size: "sm",
|
|
@@ -954,25 +999,25 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
|
|
|
954
999
|
}),
|
|
955
1000
|
_: 1
|
|
956
1001
|
}, _parent));
|
|
957
|
-
_push(`</div><div class="diff-split" data-v-
|
|
1002
|
+
_push(`</div><div class="diff-split" data-v-9eb8ced7><div class="diff-column diff-column-left" data-v-9eb8ced7><div class="diff-column-content" data-v-9eb8ced7><!--[-->`);
|
|
958
1003
|
ssrRenderList(unref(displayItems), (item) => {
|
|
959
1004
|
_push(`<!--[-->`);
|
|
960
1005
|
if (item.type === "separator") {
|
|
961
|
-
_push(`<div class="diff-separator-half" data-v-
|
|
1006
|
+
_push(`<div class="diff-separator-half" data-v-9eb8ced7><div class="separator-line" data-v-9eb8ced7></div><span class="separator-text" data-v-9eb8ced7>···</span></div>`);
|
|
962
1007
|
} else if (item.pair) {
|
|
963
1008
|
_push(`<div class="${ssrRenderClass([{
|
|
964
1009
|
"diff-remove": item.pair.left.type === "remove",
|
|
965
1010
|
"diff-empty": item.pair.left.type === "empty",
|
|
966
1011
|
"diff-context": item.pair.left.type === "context"
|
|
967
|
-
}, "diff-line"])}" data-v-
|
|
1012
|
+
}, "diff-line"])}" data-v-9eb8ced7><div class="diff-gutter" data-v-9eb8ced7>`);
|
|
968
1013
|
if (item.pair.left.lineNum) {
|
|
969
|
-
_push(`<span class="line-number" data-v-
|
|
1014
|
+
_push(`<span class="line-number" data-v-9eb8ced7>${ssrInterpolate(item.pair.left.lineNum)}</span>`);
|
|
970
1015
|
} else {
|
|
971
1016
|
_push(`<!---->`);
|
|
972
1017
|
}
|
|
973
|
-
_push(`</div><div class="diff-content" data-v-
|
|
1018
|
+
_push(`</div><div class="diff-content" data-v-9eb8ced7>`);
|
|
974
1019
|
if (item.pair.left.type !== "empty") {
|
|
975
|
-
_push(`<span class="diff-code" data-v-
|
|
1020
|
+
_push(`<span class="diff-code" data-v-9eb8ced7>${(getHighlightedContent(item.pair.id, "old") || escapeHtml(item.pair.left.content)) ?? ""}</span>`);
|
|
976
1021
|
} else {
|
|
977
1022
|
_push(`<!---->`);
|
|
978
1023
|
}
|
|
@@ -982,25 +1027,25 @@ const _sfc_main$j = /* @__PURE__ */ defineComponent({
|
|
|
982
1027
|
}
|
|
983
1028
|
_push(`<!--]-->`);
|
|
984
1029
|
});
|
|
985
|
-
_push(`<!--]--></div></div><div class="diff-column diff-column-right" data-v-
|
|
1030
|
+
_push(`<!--]--></div></div><div class="diff-column diff-column-right" data-v-9eb8ced7><div class="diff-column-content" data-v-9eb8ced7><!--[-->`);
|
|
986
1031
|
ssrRenderList(unref(displayItems), (item) => {
|
|
987
1032
|
_push(`<!--[-->`);
|
|
988
1033
|
if (item.type === "separator") {
|
|
989
|
-
_push(`<div class="diff-separator-half" data-v-
|
|
1034
|
+
_push(`<div class="diff-separator-half" data-v-9eb8ced7><span class="separator-text" data-v-9eb8ced7>···</span><div class="separator-line" data-v-9eb8ced7></div></div>`);
|
|
990
1035
|
} else if (item.pair) {
|
|
991
1036
|
_push(`<div class="${ssrRenderClass([{
|
|
992
1037
|
"diff-add": item.pair.right.type === "add",
|
|
993
1038
|
"diff-empty": item.pair.right.type === "empty",
|
|
994
1039
|
"diff-context": item.pair.right.type === "context"
|
|
995
|
-
}, "diff-line"])}" data-v-
|
|
1040
|
+
}, "diff-line"])}" data-v-9eb8ced7><div class="diff-gutter" data-v-9eb8ced7>`);
|
|
996
1041
|
if (item.pair.right.lineNum) {
|
|
997
|
-
_push(`<span class="line-number" data-v-
|
|
1042
|
+
_push(`<span class="line-number" data-v-9eb8ced7>${ssrInterpolate(item.pair.right.lineNum)}</span>`);
|
|
998
1043
|
} else {
|
|
999
1044
|
_push(`<!---->`);
|
|
1000
1045
|
}
|
|
1001
|
-
_push(`</div><div class="diff-content" data-v-
|
|
1046
|
+
_push(`</div><div class="diff-content" data-v-9eb8ced7>`);
|
|
1002
1047
|
if (item.pair.right.type !== "empty") {
|
|
1003
|
-
_push(`<span class="diff-code" data-v-
|
|
1048
|
+
_push(`<span class="diff-code" data-v-9eb8ced7>${(getHighlightedContent(item.pair.id, "new") || escapeHtml(item.pair.right.content)) ?? ""}</span>`);
|
|
1004
1049
|
} else {
|
|
1005
1050
|
_push(`<!---->`);
|
|
1006
1051
|
}
|
|
@@ -1022,7 +1067,7 @@ _sfc_main$j.setup = (props, ctx) => {
|
|
|
1022
1067
|
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("components/git/DiffViewer.vue");
|
|
1023
1068
|
return _sfc_setup$j ? _sfc_setup$j(props, ctx) : void 0;
|
|
1024
1069
|
};
|
|
1025
|
-
const __nuxt_component_1$2 = /* @__PURE__ */ Object.assign(_export_sfc(_sfc_main$j, [["__scopeId", "data-v-
|
|
1070
|
+
const __nuxt_component_1$2 = /* @__PURE__ */ Object.assign(_export_sfc(_sfc_main$j, [["__scopeId", "data-v-9eb8ced7"]]), { __name: "GitDiffViewer" });
|
|
1026
1071
|
const _sfc_main$i = /* @__PURE__ */ defineComponent({
|
|
1027
1072
|
__name: "ScrollBar",
|
|
1028
1073
|
__ssrInlineRender: true,
|
|
@@ -1323,6 +1368,45 @@ _sfc_main$d.setup = (props, ctx) => {
|
|
|
1323
1368
|
return _sfc_setup$d ? _sfc_setup$d(props, ctx) : void 0;
|
|
1324
1369
|
};
|
|
1325
1370
|
const TooltipTrigger = Object.assign(_sfc_main$d, { __name: "UiTooltipTrigger" });
|
|
1371
|
+
function createLatestRequestManager() {
|
|
1372
|
+
let activeTicket = null;
|
|
1373
|
+
function begin() {
|
|
1374
|
+
activeTicket?.controller.abort();
|
|
1375
|
+
const controller = new AbortController();
|
|
1376
|
+
const ticket = {
|
|
1377
|
+
controller,
|
|
1378
|
+
signal: controller.signal,
|
|
1379
|
+
isCurrent: () => activeTicket === ticket && !controller.signal.aborted
|
|
1380
|
+
};
|
|
1381
|
+
activeTicket = ticket;
|
|
1382
|
+
return ticket;
|
|
1383
|
+
}
|
|
1384
|
+
function clear(ticket) {
|
|
1385
|
+
if (activeTicket === ticket) {
|
|
1386
|
+
activeTicket = null;
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
function cancel() {
|
|
1390
|
+
activeTicket?.controller.abort();
|
|
1391
|
+
activeTicket = null;
|
|
1392
|
+
}
|
|
1393
|
+
return {
|
|
1394
|
+
begin,
|
|
1395
|
+
clear,
|
|
1396
|
+
cancel
|
|
1397
|
+
};
|
|
1398
|
+
}
|
|
1399
|
+
function isAbortError(error) {
|
|
1400
|
+
if (!error || typeof error !== "object") {
|
|
1401
|
+
return false;
|
|
1402
|
+
}
|
|
1403
|
+
const abortLike = error;
|
|
1404
|
+
if (abortLike.name === "AbortError" || abortLike.cause?.name === "AbortError") {
|
|
1405
|
+
return true;
|
|
1406
|
+
}
|
|
1407
|
+
const message = abortLike.message || abortLike.cause?.message;
|
|
1408
|
+
return typeof message === "string" && message.toLowerCase().includes("aborted");
|
|
1409
|
+
}
|
|
1326
1410
|
function useGit() {
|
|
1327
1411
|
const { showError } = useToast();
|
|
1328
1412
|
function getErrorMessage(error) {
|
|
@@ -1332,23 +1416,36 @@ function useGit() {
|
|
|
1332
1416
|
}
|
|
1333
1417
|
return "Unknown error";
|
|
1334
1418
|
}
|
|
1335
|
-
const
|
|
1336
|
-
const
|
|
1337
|
-
const
|
|
1338
|
-
const
|
|
1339
|
-
|
|
1419
|
+
const loadingCommitsCount = ref(0);
|
|
1420
|
+
const loadingDiffCount = ref(0);
|
|
1421
|
+
const loadingFileDiffCount = ref(0);
|
|
1422
|
+
const loadingFileContentCount = ref(0);
|
|
1423
|
+
const isLoadingCommits = computed(() => loadingCommitsCount.value > 0);
|
|
1424
|
+
const isLoadingDiff = computed(() => loadingDiffCount.value > 0);
|
|
1425
|
+
const isLoadingFileDiff = computed(() => loadingFileDiffCount.value > 0);
|
|
1426
|
+
const isLoadingFileContent = computed(() => loadingFileContentCount.value > 0);
|
|
1427
|
+
function startLoading(counter) {
|
|
1428
|
+
counter.value += 1;
|
|
1429
|
+
}
|
|
1430
|
+
function stopLoading(counter) {
|
|
1431
|
+
counter.value = Math.max(0, counter.value - 1);
|
|
1432
|
+
}
|
|
1433
|
+
async function fetchCommits(repoId, shas, options) {
|
|
1340
1434
|
if (!repoId || shas.length === 0) {
|
|
1341
1435
|
return { commits: [], failedShas: [] };
|
|
1342
1436
|
}
|
|
1343
|
-
|
|
1437
|
+
startLoading(loadingCommitsCount);
|
|
1344
1438
|
try {
|
|
1345
1439
|
const query = { shas: shas.join(",") };
|
|
1346
|
-
if (repoPath) {
|
|
1347
|
-
query.repo = repoPath;
|
|
1440
|
+
if (options?.repoPath) {
|
|
1441
|
+
query.repo = options.repoPath;
|
|
1348
1442
|
}
|
|
1349
1443
|
const commits = await $fetch(
|
|
1350
1444
|
`/api/repos/${repoId}/git/commits`,
|
|
1351
|
-
{
|
|
1445
|
+
{
|
|
1446
|
+
query,
|
|
1447
|
+
signal: options?.signal
|
|
1448
|
+
}
|
|
1352
1449
|
);
|
|
1353
1450
|
const returnedShortShas = commits.map((c) => c.shortSha);
|
|
1354
1451
|
const failedShas = shas.filter((sha) => {
|
|
@@ -1356,76 +1453,96 @@ function useGit() {
|
|
|
1356
1453
|
});
|
|
1357
1454
|
return { commits, failedShas };
|
|
1358
1455
|
} catch (error) {
|
|
1359
|
-
|
|
1456
|
+
if (isAbortError(error)) {
|
|
1457
|
+
return { commits: [], failedShas: [] };
|
|
1458
|
+
}
|
|
1459
|
+
if (!options?.suppressError) {
|
|
1460
|
+
showError("Failed to fetch commits", getErrorMessage(error));
|
|
1461
|
+
}
|
|
1360
1462
|
return { commits: [], failedShas: shas };
|
|
1361
1463
|
} finally {
|
|
1362
|
-
|
|
1464
|
+
stopLoading(loadingCommitsCount);
|
|
1363
1465
|
}
|
|
1364
1466
|
}
|
|
1365
|
-
async function fetchDiff(repoId, commitSha,
|
|
1467
|
+
async function fetchDiff(repoId, commitSha, options) {
|
|
1366
1468
|
if (!repoId || !commitSha) {
|
|
1367
1469
|
return [];
|
|
1368
1470
|
}
|
|
1369
|
-
|
|
1471
|
+
startLoading(loadingDiffCount);
|
|
1370
1472
|
try {
|
|
1371
1473
|
const query = { commit: commitSha };
|
|
1372
|
-
if (repoPath) {
|
|
1373
|
-
query.repo = repoPath;
|
|
1474
|
+
if (options?.repoPath) {
|
|
1475
|
+
query.repo = options.repoPath;
|
|
1374
1476
|
}
|
|
1375
1477
|
const files = await $fetch(
|
|
1376
1478
|
`/api/repos/${repoId}/git/diff`,
|
|
1377
|
-
{
|
|
1479
|
+
{
|
|
1480
|
+
query,
|
|
1481
|
+
signal: options?.signal
|
|
1482
|
+
}
|
|
1378
1483
|
);
|
|
1379
1484
|
return files;
|
|
1380
1485
|
} catch (error) {
|
|
1381
|
-
|
|
1486
|
+
if (!isAbortError(error) && !options?.suppressError) {
|
|
1487
|
+
showError("Failed to fetch diff", getErrorMessage(error));
|
|
1488
|
+
}
|
|
1382
1489
|
throw error;
|
|
1383
1490
|
} finally {
|
|
1384
|
-
|
|
1491
|
+
stopLoading(loadingDiffCount);
|
|
1385
1492
|
}
|
|
1386
1493
|
}
|
|
1387
|
-
async function fetchFileDiff(repoId, commitSha, filePath,
|
|
1494
|
+
async function fetchFileDiff(repoId, commitSha, filePath, options) {
|
|
1388
1495
|
if (!repoId || !commitSha || !filePath) {
|
|
1389
1496
|
return [];
|
|
1390
1497
|
}
|
|
1391
|
-
|
|
1498
|
+
startLoading(loadingFileDiffCount);
|
|
1392
1499
|
try {
|
|
1393
1500
|
const query = { commit: commitSha, file: filePath };
|
|
1394
|
-
if (repoPath) {
|
|
1395
|
-
query.repo = repoPath;
|
|
1501
|
+
if (options?.repoPath) {
|
|
1502
|
+
query.repo = options.repoPath;
|
|
1396
1503
|
}
|
|
1397
1504
|
const hunks = await $fetch(
|
|
1398
1505
|
`/api/repos/${repoId}/git/file-diff`,
|
|
1399
|
-
{
|
|
1506
|
+
{
|
|
1507
|
+
query,
|
|
1508
|
+
signal: options?.signal
|
|
1509
|
+
}
|
|
1400
1510
|
);
|
|
1401
1511
|
return hunks;
|
|
1402
1512
|
} catch (error) {
|
|
1403
|
-
|
|
1513
|
+
if (!isAbortError(error) && !options?.suppressError) {
|
|
1514
|
+
showError("Failed to fetch file diff", getErrorMessage(error));
|
|
1515
|
+
}
|
|
1404
1516
|
throw error;
|
|
1405
1517
|
} finally {
|
|
1406
|
-
|
|
1518
|
+
stopLoading(loadingFileDiffCount);
|
|
1407
1519
|
}
|
|
1408
1520
|
}
|
|
1409
|
-
async function fetchFileContent(repoId, commitSha, filePath,
|
|
1521
|
+
async function fetchFileContent(repoId, commitSha, filePath, options) {
|
|
1410
1522
|
if (!repoId || !commitSha || !filePath) {
|
|
1411
1523
|
return null;
|
|
1412
1524
|
}
|
|
1413
|
-
|
|
1525
|
+
startLoading(loadingFileContentCount);
|
|
1414
1526
|
try {
|
|
1415
1527
|
const query = { commit: commitSha, file: filePath };
|
|
1416
|
-
if (repoPath) {
|
|
1417
|
-
query.repo = repoPath;
|
|
1528
|
+
if (options?.repoPath) {
|
|
1529
|
+
query.repo = options.repoPath;
|
|
1418
1530
|
}
|
|
1419
1531
|
const result = await $fetch(
|
|
1420
1532
|
`/api/repos/${repoId}/git/file-content`,
|
|
1421
|
-
{
|
|
1533
|
+
{
|
|
1534
|
+
query,
|
|
1535
|
+
signal: options?.signal
|
|
1536
|
+
}
|
|
1422
1537
|
);
|
|
1423
1538
|
return result.content;
|
|
1424
1539
|
} catch (error) {
|
|
1425
|
-
|
|
1540
|
+
if (!isAbortError(error) && !options?.suppressError) {
|
|
1541
|
+
showError("Failed to fetch file content", getErrorMessage(error));
|
|
1542
|
+
}
|
|
1426
1543
|
throw error;
|
|
1427
1544
|
} finally {
|
|
1428
|
-
|
|
1545
|
+
stopLoading(loadingFileContentCount);
|
|
1429
1546
|
}
|
|
1430
1547
|
}
|
|
1431
1548
|
return {
|
|
@@ -1435,10 +1552,10 @@ function useGit() {
|
|
|
1435
1552
|
fetchFileDiff,
|
|
1436
1553
|
fetchFileContent,
|
|
1437
1554
|
// Loading states
|
|
1438
|
-
isLoadingCommits
|
|
1439
|
-
isLoadingDiff
|
|
1440
|
-
isLoadingFileDiff
|
|
1441
|
-
isLoadingFileContent
|
|
1555
|
+
isLoadingCommits,
|
|
1556
|
+
isLoadingDiff,
|
|
1557
|
+
isLoadingFileDiff,
|
|
1558
|
+
isLoadingFileContent
|
|
1442
1559
|
};
|
|
1443
1560
|
}
|
|
1444
1561
|
const _sfc_main$c = /* @__PURE__ */ defineComponent({
|
|
@@ -1460,6 +1577,8 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
|
|
|
1460
1577
|
const error = ref(null);
|
|
1461
1578
|
const fileDiffError = ref(null);
|
|
1462
1579
|
const viewMode = ref("changes");
|
|
1580
|
+
const diffRequestManager = createLatestRequestManager();
|
|
1581
|
+
const fileRequestManager = createLatestRequestManager();
|
|
1463
1582
|
function getErrorMessage(error2, fallback) {
|
|
1464
1583
|
if (error2 && typeof error2 === "object") {
|
|
1465
1584
|
const fetchError = error2;
|
|
@@ -1468,72 +1587,124 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
|
|
|
1468
1587
|
return fallback;
|
|
1469
1588
|
}
|
|
1470
1589
|
const selectedFileDiff = computed(() => files.value.find((f) => f.path === selectedFile.value));
|
|
1471
|
-
|
|
1590
|
+
const diffViewerKey = computed(() => `${props.repoPath || ""}:${props.commitSha}:${selectedFile.value || ""}`);
|
|
1591
|
+
function resetDiffState() {
|
|
1472
1592
|
error.value = null;
|
|
1473
1593
|
files.value = [];
|
|
1474
1594
|
selectedFile.value = void 0;
|
|
1475
1595
|
hunks.value = [];
|
|
1476
1596
|
fileContent.value = null;
|
|
1597
|
+
fileDiffError.value = null;
|
|
1598
|
+
}
|
|
1599
|
+
async function loadDiff() {
|
|
1600
|
+
const requestRepoId = props.repoId;
|
|
1601
|
+
const requestCommitSha = props.commitSha;
|
|
1602
|
+
const requestRepoPath = props.repoPath;
|
|
1603
|
+
const ticket = diffRequestManager.begin();
|
|
1604
|
+
fileRequestManager.cancel();
|
|
1605
|
+
resetDiffState();
|
|
1477
1606
|
try {
|
|
1478
|
-
const result = await fetchDiff(
|
|
1607
|
+
const result = await fetchDiff(requestRepoId, requestCommitSha, {
|
|
1608
|
+
repoPath: requestRepoPath,
|
|
1609
|
+
signal: ticket.signal,
|
|
1610
|
+
suppressError: true
|
|
1611
|
+
});
|
|
1612
|
+
const isCurrentRequest = ticket.isCurrent() && props.repoId === requestRepoId && props.commitSha === requestCommitSha && props.repoPath === requestRepoPath;
|
|
1613
|
+
if (!isCurrentRequest) {
|
|
1614
|
+
return;
|
|
1615
|
+
}
|
|
1479
1616
|
files.value = result;
|
|
1480
1617
|
if (result.length > 0) {
|
|
1481
1618
|
selectedFile.value = result[0].path;
|
|
1482
1619
|
}
|
|
1483
1620
|
} catch (loadError) {
|
|
1621
|
+
if (isAbortError(loadError) || !ticket.isCurrent()) {
|
|
1622
|
+
return;
|
|
1623
|
+
}
|
|
1484
1624
|
error.value = getErrorMessage(loadError, "Could not load commit diff.");
|
|
1625
|
+
} finally {
|
|
1626
|
+
diffRequestManager.clear(ticket);
|
|
1485
1627
|
}
|
|
1486
1628
|
}
|
|
1487
1629
|
async function loadFileDiff() {
|
|
1488
|
-
|
|
1630
|
+
const selectedPath = selectedFile.value;
|
|
1631
|
+
if (!selectedPath) {
|
|
1632
|
+
fileDiffError.value = null;
|
|
1489
1633
|
hunks.value = [];
|
|
1490
1634
|
fileContent.value = null;
|
|
1491
1635
|
return;
|
|
1492
1636
|
}
|
|
1637
|
+
const requestRepoId = props.repoId;
|
|
1638
|
+
const requestCommitSha = props.commitSha;
|
|
1639
|
+
const requestRepoPath = props.repoPath;
|
|
1640
|
+
const requestMode = viewMode.value;
|
|
1641
|
+
const requestPath = selectedPath;
|
|
1642
|
+
const ticket = fileRequestManager.begin();
|
|
1493
1643
|
fileDiffError.value = null;
|
|
1644
|
+
hunks.value = [];
|
|
1645
|
+
fileContent.value = null;
|
|
1646
|
+
const isCurrentRequest = () => {
|
|
1647
|
+
return ticket.isCurrent() && props.repoId === requestRepoId && props.commitSha === requestCommitSha && props.repoPath === requestRepoPath && viewMode.value === requestMode && selectedFile.value === requestPath;
|
|
1648
|
+
};
|
|
1494
1649
|
try {
|
|
1495
|
-
const
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1650
|
+
const diffPromise = fetchFileDiff(requestRepoId, requestCommitSha, requestPath, {
|
|
1651
|
+
repoPath: requestRepoPath,
|
|
1652
|
+
signal: ticket.signal,
|
|
1653
|
+
suppressError: true
|
|
1654
|
+
});
|
|
1655
|
+
if (requestMode === "full") {
|
|
1656
|
+
const [result, content] = await Promise.all([
|
|
1657
|
+
diffPromise,
|
|
1658
|
+
fetchFileContent(requestRepoId, requestCommitSha, requestPath, {
|
|
1659
|
+
repoPath: requestRepoPath,
|
|
1660
|
+
signal: ticket.signal,
|
|
1661
|
+
suppressError: true
|
|
1662
|
+
})
|
|
1663
|
+
]);
|
|
1664
|
+
if (!isCurrentRequest()) {
|
|
1665
|
+
return;
|
|
1666
|
+
}
|
|
1667
|
+
hunks.value = result;
|
|
1499
1668
|
fileContent.value = content;
|
|
1500
1669
|
} else {
|
|
1670
|
+
const result = await diffPromise;
|
|
1671
|
+
if (!isCurrentRequest()) {
|
|
1672
|
+
return;
|
|
1673
|
+
}
|
|
1674
|
+
hunks.value = result;
|
|
1501
1675
|
fileContent.value = null;
|
|
1502
1676
|
}
|
|
1503
1677
|
} catch (loadError) {
|
|
1678
|
+
if (!isCurrentRequest() || isAbortError(loadError)) {
|
|
1679
|
+
return;
|
|
1680
|
+
}
|
|
1504
1681
|
fileDiffError.value = getErrorMessage(loadError, "Could not load file diff.");
|
|
1682
|
+
} finally {
|
|
1683
|
+
fileRequestManager.clear(ticket);
|
|
1505
1684
|
}
|
|
1506
1685
|
}
|
|
1507
1686
|
function toggleViewMode() {
|
|
1508
1687
|
viewMode.value = viewMode.value === "changes" ? "full" : "changes";
|
|
1509
1688
|
}
|
|
1510
|
-
watch(viewMode, async (mode) => {
|
|
1511
|
-
if (mode === "full" && selectedFile.value && !fileContent.value) {
|
|
1512
|
-
try {
|
|
1513
|
-
const content = await fetchFileContent(props.repoId, props.commitSha, selectedFile.value, props.repoPath);
|
|
1514
|
-
fileContent.value = content;
|
|
1515
|
-
fileDiffError.value = null;
|
|
1516
|
-
} catch (loadError) {
|
|
1517
|
-
fileDiffError.value = getErrorMessage(loadError, "Could not load file content.");
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1520
|
-
});
|
|
1521
1689
|
function handleFileSelect(path) {
|
|
1522
1690
|
selectedFile.value = path;
|
|
1523
1691
|
}
|
|
1524
1692
|
function retry() {
|
|
1525
|
-
loadDiff();
|
|
1693
|
+
void loadDiff();
|
|
1526
1694
|
}
|
|
1527
1695
|
function retryFileDiff() {
|
|
1528
|
-
loadFileDiff();
|
|
1696
|
+
void loadFileDiff();
|
|
1529
1697
|
}
|
|
1530
|
-
watch(
|
|
1531
|
-
|
|
1532
|
-
|
|
1698
|
+
watch(
|
|
1699
|
+
() => [selectedFile.value, viewMode.value],
|
|
1700
|
+
() => {
|
|
1701
|
+
void loadFileDiff();
|
|
1702
|
+
}
|
|
1703
|
+
);
|
|
1533
1704
|
watch(
|
|
1534
1705
|
() => [props.repoId, props.commitSha, props.repoPath],
|
|
1535
1706
|
() => {
|
|
1536
|
-
loadDiff();
|
|
1707
|
+
void loadDiff();
|
|
1537
1708
|
},
|
|
1538
1709
|
{ immediate: true }
|
|
1539
1710
|
);
|
|
@@ -1895,6 +2066,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
|
|
|
1895
2066
|
if (_push2) {
|
|
1896
2067
|
_push2(`<div${_scopeId}>`);
|
|
1897
2068
|
_push2(ssrRenderComponent(_component_GitDiffViewer, {
|
|
2069
|
+
key: unref(diffViewerKey),
|
|
1898
2070
|
hunks: unref(hunks),
|
|
1899
2071
|
"file-path": unref(selectedFile),
|
|
1900
2072
|
binary: unref(selectedFileDiff)?.binary,
|
|
@@ -1910,7 +2082,8 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
|
|
|
1910
2082
|
ref_key: "diffViewerRef",
|
|
1911
2083
|
ref: diffViewerRef
|
|
1912
2084
|
}, [
|
|
1913
|
-
|
|
2085
|
+
(openBlock(), createBlock(_component_GitDiffViewer, {
|
|
2086
|
+
key: unref(diffViewerKey),
|
|
1914
2087
|
hunks: unref(hunks),
|
|
1915
2088
|
"file-path": unref(selectedFile),
|
|
1916
2089
|
binary: unref(selectedFileDiff)?.binary,
|
|
@@ -1918,7 +2091,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
|
|
|
1918
2091
|
"file-content": unref(fileContent),
|
|
1919
2092
|
"show-full-file": unref(viewMode) === "full",
|
|
1920
2093
|
"is-loading-content": unref(isLoadingFileContent)
|
|
1921
|
-
}, null, 8, ["hunks", "file-path", "binary", "old-path", "file-content", "show-full-file", "is-loading-content"])
|
|
2094
|
+
}, null, 8, ["hunks", "file-path", "binary", "old-path", "file-content", "show-full-file", "is-loading-content"]))
|
|
1922
2095
|
], 512)
|
|
1923
2096
|
];
|
|
1924
2097
|
}
|
|
@@ -1973,9 +2146,14 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
|
|
|
1973
2146
|
const repos = new Set(props.commits.map((c) => c.repo).filter(Boolean));
|
|
1974
2147
|
return repos.size > 1;
|
|
1975
2148
|
});
|
|
2149
|
+
const commitsRequestManager = createLatestRequestManager();
|
|
1976
2150
|
watch(
|
|
1977
2151
|
() => ({ commits: props.commits, repoId: props.repoId }),
|
|
1978
|
-
async ({ commits, repoId }) => {
|
|
2152
|
+
async ({ commits, repoId }, _, onCleanup) => {
|
|
2153
|
+
const ticket = commitsRequestManager.begin();
|
|
2154
|
+
onCleanup(() => {
|
|
2155
|
+
commitsRequestManager.clear(ticket);
|
|
2156
|
+
});
|
|
1979
2157
|
if (commits.length === 0 || !repoId) {
|
|
1980
2158
|
commitDetails.value = /* @__PURE__ */ new Map();
|
|
1981
2159
|
failedCommits.value = /* @__PURE__ */ new Set();
|
|
@@ -1991,7 +2169,10 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
|
|
|
1991
2169
|
}
|
|
1992
2170
|
const results = await Promise.all(
|
|
1993
2171
|
Array.from(commitsByRepo.entries()).map(async ([repoPath, shas]) => {
|
|
1994
|
-
const result = await fetchCommits(repoId, shas,
|
|
2172
|
+
const result = await fetchCommits(repoId, shas, {
|
|
2173
|
+
repoPath: repoPath || void 0,
|
|
2174
|
+
signal: ticket.signal
|
|
2175
|
+
});
|
|
1995
2176
|
return {
|
|
1996
2177
|
repoPath,
|
|
1997
2178
|
requestedShas: [...shas],
|
|
@@ -2023,6 +2204,9 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
|
|
|
2023
2204
|
failed.add(createCommitKey(sha, repoPath));
|
|
2024
2205
|
}
|
|
2025
2206
|
}
|
|
2207
|
+
if (!ticket.isCurrent()) {
|
|
2208
|
+
return;
|
|
2209
|
+
}
|
|
2026
2210
|
commitDetails.value = detailsMap;
|
|
2027
2211
|
failedCommits.value = failed;
|
|
2028
2212
|
},
|
|
@@ -3541,4 +3725,4 @@ _sfc_main.setup = (props, ctx) => {
|
|
|
3541
3725
|
const __nuxt_component_1 = Object.assign(_sfc_main, { __name: "TasksDetail" });
|
|
3542
3726
|
|
|
3543
3727
|
export { Badge as B, __nuxt_component_0$2 as _, __nuxt_component_1 as a };
|
|
3544
|
-
//# sourceMappingURL=Detail-
|
|
3728
|
+
//# sourceMappingURL=Detail-B7yBNjgp.mjs.map
|