@youtyan/code-viewer 0.1.31 → 0.1.33

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.
@@ -11,7 +11,7 @@ import {
11
11
  readFileSync as readFileSync2,
12
12
  realpathSync,
13
13
  renameSync,
14
- statSync,
14
+ statSync as statSync2,
15
15
  unlinkSync,
16
16
  watch,
17
17
  writeFileSync
@@ -106,7 +106,8 @@ import {
106
106
  existsSync,
107
107
  lstatSync as lstatSync2,
108
108
  readdirSync,
109
- readFileSync
109
+ readFileSync,
110
+ statSync
110
111
  } from "node:fs";
111
112
  import { join as join2 } from "node:path";
112
113
 
@@ -767,26 +768,36 @@ function listTree(ref, path, cwd, options = {}) {
767
768
  };
768
769
  }
769
770
  function untrackedMeta(cwd) {
770
- return untracked(cwd).map((path) => {
771
+ return untracked(cwd).flatMap((path) => {
771
772
  const full = join2(cwd, path);
772
773
  let binary = false;
773
774
  let lines = 0;
774
- if (existsSync(full)) {
775
+ let fileExists = false;
776
+ try {
777
+ fileExists = existsSync(full) && statSync(full).isFile();
778
+ } catch {
779
+ fileExists = false;
780
+ }
781
+ if (fileExists) {
775
782
  const data = readFileSync(full);
776
783
  const probe = data.subarray(0, 8192);
777
784
  binary = probe.includes(0);
778
785
  if (!binary)
779
786
  lines = data.toString("utf8").split(`
780
787
  `).length - 1;
788
+ } else {
789
+ return [];
781
790
  }
782
- return {
783
- path,
784
- status: "A",
785
- additions: binary ? 0 : lines,
786
- deletions: 0,
787
- binary,
788
- untracked: true
789
- };
791
+ return [
792
+ {
793
+ path,
794
+ status: "A",
795
+ additions: binary ? 0 : lines,
796
+ deletions: 0,
797
+ binary,
798
+ untracked: true
799
+ }
800
+ ];
790
801
  });
791
802
  }
792
803
  function fileMeta(args, cwd, includeUntracked = false) {
@@ -1982,7 +1993,7 @@ function worktreeFileMetadata(path, knownSize) {
1982
1993
  if (!full)
1983
1994
  return {};
1984
1995
  try {
1985
- const stat = statSync(full);
1996
+ const stat = statSync2(full);
1986
1997
  return {
1987
1998
  size: knownSize ?? stat.size,
1988
1999
  created_at: isoDate(stat.birthtimeMs),
@@ -2007,7 +2018,7 @@ function directoryMetadata(target, path) {
2007
2018
  if (!full)
2008
2019
  return {};
2009
2020
  try {
2010
- const stat = statSync(full);
2021
+ const stat = statSync2(full);
2011
2022
  return {
2012
2023
  created_at: isoDate(stat.birthtimeMs),
2013
2024
  updated_at: isoDate(stat.mtimeMs)
@@ -2334,7 +2345,7 @@ function handleFileDiff(url) {
2334
2345
  }
2335
2346
  function worktreeLineIndexSignature(full) {
2336
2347
  try {
2337
- const stat = statSync(full);
2348
+ const stat = statSync2(full);
2338
2349
  return `size:${stat.size}|mtime:${stat.mtimeMs}|ctime:${stat.ctimeMs}|ino:${stat.ino || 0}`;
2339
2350
  } catch {
2340
2351
  return null;
@@ -2350,7 +2361,7 @@ async function getWorktreeLineIndex(full) {
2350
2361
  lineIndexCache.set(full, cached);
2351
2362
  return cached.index;
2352
2363
  }
2353
- const stat = statSync(full);
2364
+ const stat = statSync2(full);
2354
2365
  if (stat.size > LINE_INDEX_MAX_FILE_BYTES)
2355
2366
  return null;
2356
2367
  const index = await buildLineOffsetIndexFromStream(fileReadableStream(full), stat.size);
@@ -2595,7 +2606,7 @@ function rawFileSize(path, ref) {
2595
2606
  if (!full)
2596
2607
  return null;
2597
2608
  try {
2598
- return statSync(full).size;
2609
+ return statSync2(full).size;
2599
2610
  } catch {
2600
2611
  return null;
2601
2612
  }
@@ -2694,7 +2705,7 @@ async function handleUploadFiles(req) {
2694
2705
  const realDir = safeOpenWorktreePath(dir);
2695
2706
  if (!realDir)
2696
2707
  return text("not found", 404);
2697
- const stats = statSync(realDir);
2708
+ const stats = statSync2(realDir);
2698
2709
  if (!stats.isDirectory())
2699
2710
  return text("not a directory", 400);
2700
2711
  const files = form.getAll("files").filter((item) => item instanceof File);
@@ -2942,7 +2953,7 @@ async function handleOpenPath(req) {
2942
2953
  const target = safeOpenWorktreePath(targetPath);
2943
2954
  if (!target)
2944
2955
  return text("not found", 404);
2945
- const stats = statSync(target);
2956
+ const stats = statSync2(target);
2946
2957
  if (!stats.isDirectory())
2947
2958
  return text("not a directory", 400);
2948
2959
  openOsPath(target);
@@ -3027,7 +3038,7 @@ async function handleCreateDirectory(req) {
3027
3038
  const parent = safeOpenWorktreePath(dir);
3028
3039
  if (!parent)
3029
3040
  return text("not found", 404);
3030
- const stats = statSync(parent);
3041
+ const stats = statSync2(parent);
3031
3042
  if (!stats.isDirectory())
3032
3043
  return text("not a directory", 400);
3033
3044
  const targetPath = dir ? `${dir}/${name}` : name;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@youtyan/code-viewer",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "description": "Local browser-based code and git diff viewer",
5
5
  "type": "module",
6
6
  "bin": {
package/web/app.js CHANGED
@@ -8644,9 +8644,12 @@ ${frontmatter.yaml}
8644
8644
  return false;
8645
8645
  clearDiffLineFocus();
8646
8646
  row.classList.add("gdp-diff-line-target");
8647
- row.scrollIntoView({ behavior: "smooth", block: "center" });
8647
+ scrollDiffElementIntoView(row, "center");
8648
8648
  return true;
8649
8649
  }
8650
+ function scrollDiffElementIntoView(element, block2) {
8651
+ element.scrollIntoView({ behavior: "auto", block: block2 });
8652
+ }
8650
8653
  function applyDiffRouteFocus(card) {
8651
8654
  if (STATE.route.screen !== "diff" || !STATE.route.path || !STATE.route.line)
8652
8655
  return false;
@@ -8674,7 +8677,7 @@ ${frontmatter.yaml}
8674
8677
  enqueueLoad(f2, card, 10);
8675
8678
  }
8676
8679
  if (!line || !focusDiffLine(card, line)) {
8677
- card.scrollIntoView({ behavior: "smooth", block: "start" });
8680
+ scrollDiffElementIntoView(card, "start");
8678
8681
  }
8679
8682
  }
8680
8683
  function sidebarAncestorDirs(path) {
package/web/style.css CHANGED
@@ -1640,6 +1640,12 @@ body.gdp-help-page #content {
1640
1640
 
1641
1641
  #diff > *:first-child { margin-top: 0; }
1642
1642
 
1643
+ body:not(.gdp-file-detail-page) #diff::after {
1644
+ content: "";
1645
+ display: block;
1646
+ height: calc(100vh - var(--chrome-h) - 40px);
1647
+ }
1648
+
1643
1649
  .empty {
1644
1650
  display: flex; flex-direction: column; align-items: center; justify-content: center;
1645
1651
  padding: 80px 16px; color: var(--fg-muted); text-align: center;