@pixelbyte-software/pixcode 1.54.8 → 1.54.9

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/dist/index.html CHANGED
@@ -35,7 +35,7 @@
35
35
 
36
36
  <!-- Prevent zoom on iOS -->
37
37
  <meta name="format-detection" content="telephone=no" />
38
- <script type="module" crossorigin src="/assets/index-BU3Z3zrh.js"></script>
38
+ <script type="module" crossorigin src="/assets/index-Bm6uAqKU.js"></script>
39
39
  <link rel="modulepreload" crossorigin href="/assets/vendor-react-DB6V5Fl1.js">
40
40
  <link rel="modulepreload" crossorigin href="/assets/vendor-codemirror-CIYNS698.js">
41
41
  <link rel="modulepreload" crossorigin href="/assets/vendor-xterm-C7tpxJl7.js">
@@ -1108,6 +1108,10 @@ const FILE_TREE_MAX_ITEMS = Number.parseInt(process.env.PIXCODE_FILE_TREE_MAX_IT
1108
1108
  const FILE_TREE_MAX_DIRECTORIES = Number.parseInt(process.env.PIXCODE_FILE_TREE_MAX_DIRECTORIES || '', 10) || 1200;
1109
1109
  const FILE_TREE_SCAN_MAX_MS = Number.parseInt(process.env.PIXCODE_FILE_TREE_SCAN_MAX_MS || '', 10) || 4000;
1110
1110
  const FILE_TREE_MAX_ENTRIES_PER_DIRECTORY = Number.parseInt(process.env.PIXCODE_FILE_TREE_MAX_ENTRIES_PER_DIRECTORY || '', 10) || 1500;
1111
+ const FILE_TREE_MAX_DEPTH_DEFAULT = 5; // was 10, reduced to avoid deep traversal on huge projects
1112
+ const FILE_TREE_CACHE_TTL_MS = 3000; // short-lived cache for rapid successive requests
1113
+ const FILE_TREE_CACHE_MAX_ENTRIES = 50;
1114
+ const fileTreeCache = new Map();
1111
1115
  const FILE_TREE_EXCLUDED_ENTRY_NAMES = new Set([
1112
1116
  '.cache',
1113
1117
  '.git',
@@ -2964,7 +2968,7 @@ app.get('/api/projects/:projectName/files', authenticateToken, requireProjectAcc
2964
2968
  catch (e) {
2965
2969
  return res.status(404).json({ error: `Project path not found: ${actualPath}` });
2966
2970
  }
2967
- const files = await getFileTree(actualPath, 10, 0, true);
2971
+ const files = await getFileTree(actualPath, FILE_TREE_MAX_DEPTH_DEFAULT, 0, true);
2968
2972
  res.json(filterFileTreeForUser(files, req.user, {
2969
2973
  name: req.params.projectName,
2970
2974
  projectName: req.params.projectName,
@@ -4794,6 +4798,26 @@ function permToRwx(perm) {
4794
4798
  const x = perm & 1 ? 'x' : '-';
4795
4799
  return r + w + x;
4796
4800
  }
4801
+ // File tree result cache (keyed by path:depth:showHidden, TTL 3s)
4802
+ function readFileTreeCache(cacheKey) {
4803
+ const entry = fileTreeCache.get(cacheKey);
4804
+ if (!entry || entry.expiresAt <= Date.now()) {
4805
+ if (entry)
4806
+ fileTreeCache.delete(cacheKey);
4807
+ // Prune stale entries
4808
+ if (fileTreeCache.size > FILE_TREE_CACHE_MAX_ENTRIES) {
4809
+ const keys = [...fileTreeCache.keys()];
4810
+ for (const k of keys.slice(0, keys.length - FILE_TREE_CACHE_MAX_ENTRIES)) {
4811
+ fileTreeCache.delete(k);
4812
+ }
4813
+ }
4814
+ return undefined;
4815
+ }
4816
+ return entry.tree;
4817
+ }
4818
+ function writeFileTreeCache(cacheKey, tree) {
4819
+ fileTreeCache.set(cacheKey, { tree, expiresAt: Date.now() + FILE_TREE_CACHE_TTL_MS });
4820
+ }
4797
4821
  function createFileTreeScanContext() {
4798
4822
  return {
4799
4823
  startedAt: Date.now(),
@@ -4849,6 +4873,13 @@ async function readDirectoryEntriesBounded(dirPath, context) {
4849
4873
  return entries;
4850
4874
  }
4851
4875
  async function getFileTree(dirPath, maxDepth = 3, currentDepth = 0, showHidden = true, scanContext = null) {
4876
+ // Check cache on top-level call
4877
+ if (currentDepth === 0 && !scanContext) {
4878
+ const cacheKey = `${path.resolve(dirPath)}:${maxDepth}:${showHidden}`;
4879
+ const cached = readFileTreeCache(cacheKey);
4880
+ if (cached)
4881
+ return cached;
4882
+ }
4852
4883
  const context = scanContext || createFileTreeScanContext();
4853
4884
  const items = [];
4854
4885
  if (!hasFileTreeBudget(context)) {
@@ -4895,12 +4926,18 @@ async function getFileTree(dirPath, maxDepth = 3, currentDepth = 0, showHidden =
4895
4926
  }
4896
4927
  items.push(item);
4897
4928
  }
4898
- return items.sort((a, b) => {
4929
+ const sorted = items.sort((a, b) => {
4899
4930
  if (a.type !== b.type) {
4900
4931
  return a.type === 'directory' ? -1 : 1;
4901
4932
  }
4902
4933
  return a.name.localeCompare(b.name);
4903
4934
  });
4935
+ // Store in cache on top-level call
4936
+ if (currentDepth === 0 && !scanContext) {
4937
+ const cacheKey = `${path.resolve(dirPath)}:${maxDepth}:${showHidden}`;
4938
+ writeFileTreeCache(cacheKey, sorted);
4939
+ }
4940
+ return sorted;
4904
4941
  }
4905
4942
  const SERVER_PORT = process.env.SERVER_PORT || 3001;
4906
4943
  const HOST = process.env.HOST || '0.0.0.0';