@youtyan/code-viewer 0.4.0 → 0.4.1
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/code-viewer.js +256 -252
- package/package.json +1 -1
package/dist/code-viewer.js
CHANGED
|
@@ -3888,10 +3888,260 @@ var init_search = __esm(() => {
|
|
|
3888
3888
|
DEFAULT_EXCLUDE_NAMES = [".DS_Store"];
|
|
3889
3889
|
});
|
|
3890
3890
|
|
|
3891
|
+
// web-src/server/worktree-watcher.ts
|
|
3892
|
+
import {
|
|
3893
|
+
lstatSync as lstatSync3,
|
|
3894
|
+
readdirSync as nodeReaddirSync,
|
|
3895
|
+
watch as nodeWatch
|
|
3896
|
+
} from "node:fs";
|
|
3897
|
+
import { join as join7, relative } from "node:path";
|
|
3898
|
+
function normalizeRelativePath(path) {
|
|
3899
|
+
return path.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
3900
|
+
}
|
|
3901
|
+
function isInsideRoot(root, path) {
|
|
3902
|
+
const rel = relative(root, path).replace(/\\/g, "/");
|
|
3903
|
+
return rel === "" || !rel.startsWith("..") && !rel.startsWith("/");
|
|
3904
|
+
}
|
|
3905
|
+
function startWorktreeUpdateWatch(options) {
|
|
3906
|
+
const watch = options.watch || nodeWatch;
|
|
3907
|
+
const readDirs = options.readdirSync || ((path) => nodeReaddirSync(path, { withFileTypes: true }));
|
|
3908
|
+
const isDirectory = options.isDirectory || ((path) => {
|
|
3909
|
+
try {
|
|
3910
|
+
return lstatSync3(path).isDirectory();
|
|
3911
|
+
} catch {
|
|
3912
|
+
return false;
|
|
3913
|
+
}
|
|
3914
|
+
});
|
|
3915
|
+
const directorySignature = options.directorySignature || ((path) => {
|
|
3916
|
+
try {
|
|
3917
|
+
const stats = lstatSync3(path);
|
|
3918
|
+
if (!stats.isDirectory())
|
|
3919
|
+
return null;
|
|
3920
|
+
return `${stats.dev}:${stats.ino}`;
|
|
3921
|
+
} catch {
|
|
3922
|
+
return null;
|
|
3923
|
+
}
|
|
3924
|
+
});
|
|
3925
|
+
const setTimer = options.setTimeoutFn || setTimeout;
|
|
3926
|
+
const clearTimer = options.clearTimeoutFn || clearTimeout;
|
|
3927
|
+
const debounceMs = options.debounceMs ?? 250;
|
|
3928
|
+
const maxWatchedDirectories = Math.max(1, Math.floor(options.maxWatchedDirectories ?? DEFAULT_WORKTREE_WATCH_DIRECTORY_LIMIT));
|
|
3929
|
+
const watchers = new Map;
|
|
3930
|
+
const signatures = new Map;
|
|
3931
|
+
const initialScanAsync = options.initialScanMode === "async" || (!options.watch || options.watch === nodeWatch) && !options.readdirSync;
|
|
3932
|
+
const initialScanQueue = [];
|
|
3933
|
+
let initialScanTimer = null;
|
|
3934
|
+
const pendingPathInspections = new Map;
|
|
3935
|
+
let pathInspectionTimer = null;
|
|
3936
|
+
let timer = null;
|
|
3937
|
+
const pendingChangedPaths = new Set;
|
|
3938
|
+
let watchLimitReported = false;
|
|
3939
|
+
const ignored = (path) => isSkippableSearchPath(normalizeRelativePath(path), options.omitDirNames, options.excludeNames);
|
|
3940
|
+
const directoryRelativePath = (dir) => normalizeRelativePath(relative(options.root, dir));
|
|
3941
|
+
const ignoredDirectory = (dir) => {
|
|
3942
|
+
const rel = directoryRelativePath(dir);
|
|
3943
|
+
return Boolean(rel && ignored(rel));
|
|
3944
|
+
};
|
|
3945
|
+
const scheduleUpdate = (changedPath) => {
|
|
3946
|
+
if (changedPath)
|
|
3947
|
+
pendingChangedPaths.add(changedPath);
|
|
3948
|
+
if (timer)
|
|
3949
|
+
clearTimer(timer);
|
|
3950
|
+
timer = setTimer(() => {
|
|
3951
|
+
timer = null;
|
|
3952
|
+
const paths = pendingChangedPaths.size ? [...pendingChangedPaths] : undefined;
|
|
3953
|
+
pendingChangedPaths.clear();
|
|
3954
|
+
options.onUpdate(paths);
|
|
3955
|
+
}, debounceMs);
|
|
3956
|
+
};
|
|
3957
|
+
const reportWatchLimit = () => {
|
|
3958
|
+
if (watchLimitReported)
|
|
3959
|
+
return;
|
|
3960
|
+
watchLimitReported = true;
|
|
3961
|
+
options.onWatchLimit?.(maxWatchedDirectories);
|
|
3962
|
+
options.onError?.(new Error(`worktree watcher cap reached (${maxWatchedDirectories}); subsequent changes may be missed`));
|
|
3963
|
+
};
|
|
3964
|
+
const closeSubtree = (dir) => {
|
|
3965
|
+
for (const [watchedDir, watcher] of [...watchers]) {
|
|
3966
|
+
if (watchedDir !== dir && !watchedDir.startsWith(`${dir}/`))
|
|
3967
|
+
continue;
|
|
3968
|
+
try {
|
|
3969
|
+
watcher.close?.();
|
|
3970
|
+
} catch {}
|
|
3971
|
+
watchers.delete(watchedDir);
|
|
3972
|
+
signatures.delete(watchedDir);
|
|
3973
|
+
}
|
|
3974
|
+
};
|
|
3975
|
+
const closeAll = () => {
|
|
3976
|
+
if (initialScanTimer) {
|
|
3977
|
+
clearTimer(initialScanTimer);
|
|
3978
|
+
initialScanTimer = null;
|
|
3979
|
+
}
|
|
3980
|
+
if (pathInspectionTimer) {
|
|
3981
|
+
clearTimer(pathInspectionTimer);
|
|
3982
|
+
pathInspectionTimer = null;
|
|
3983
|
+
}
|
|
3984
|
+
initialScanQueue.length = 0;
|
|
3985
|
+
pendingPathInspections.clear();
|
|
3986
|
+
for (const watcher of [...watchers.values()]) {
|
|
3987
|
+
try {
|
|
3988
|
+
watcher.close?.();
|
|
3989
|
+
} catch {}
|
|
3990
|
+
}
|
|
3991
|
+
watchers.clear();
|
|
3992
|
+
signatures.clear();
|
|
3993
|
+
};
|
|
3994
|
+
const readChildDirectories = (dir) => {
|
|
3995
|
+
let entries;
|
|
3996
|
+
try {
|
|
3997
|
+
entries = readDirs(dir);
|
|
3998
|
+
} catch (error) {
|
|
3999
|
+
options.onError?.(error);
|
|
4000
|
+
return [];
|
|
4001
|
+
}
|
|
4002
|
+
const children = [];
|
|
4003
|
+
for (const entry of entries) {
|
|
4004
|
+
if (!entry.isDirectory())
|
|
4005
|
+
continue;
|
|
4006
|
+
const child = join7(dir, entry.name);
|
|
4007
|
+
if (ignoredDirectory(child))
|
|
4008
|
+
continue;
|
|
4009
|
+
children.push(child);
|
|
4010
|
+
}
|
|
4011
|
+
return children;
|
|
4012
|
+
};
|
|
4013
|
+
const processInitialScanQueue = () => {
|
|
4014
|
+
initialScanTimer = null;
|
|
4015
|
+
if (watchers.size >= maxWatchedDirectories) {
|
|
4016
|
+
reportWatchLimit();
|
|
4017
|
+
initialScanQueue.length = 0;
|
|
4018
|
+
return;
|
|
4019
|
+
}
|
|
4020
|
+
const next = initialScanQueue.shift();
|
|
4021
|
+
if (next)
|
|
4022
|
+
watchDirectory(next, true);
|
|
4023
|
+
if (watchers.size >= maxWatchedDirectories) {
|
|
4024
|
+
reportWatchLimit();
|
|
4025
|
+
initialScanQueue.length = 0;
|
|
4026
|
+
}
|
|
4027
|
+
if (initialScanQueue.length)
|
|
4028
|
+
initialScanTimer = setTimer(processInitialScanQueue, 50);
|
|
4029
|
+
};
|
|
4030
|
+
const queueInitialChildren = (dir) => {
|
|
4031
|
+
const remaining = maxWatchedDirectories - watchers.size;
|
|
4032
|
+
if (remaining <= 0) {
|
|
4033
|
+
reportWatchLimit();
|
|
4034
|
+
return;
|
|
4035
|
+
}
|
|
4036
|
+
const children = readChildDirectories(dir);
|
|
4037
|
+
if (children.length > remaining)
|
|
4038
|
+
reportWatchLimit();
|
|
4039
|
+
initialScanQueue.push(...children.slice(0, remaining));
|
|
4040
|
+
if (!initialScanTimer)
|
|
4041
|
+
initialScanTimer = setTimer(processInitialScanQueue, 5000);
|
|
4042
|
+
};
|
|
4043
|
+
const processChangedPath = (changed, fullChangedPath) => {
|
|
4044
|
+
const known = watchers.has(fullChangedPath);
|
|
4045
|
+
if (isDirectory(fullChangedPath)) {
|
|
4046
|
+
if (known) {
|
|
4047
|
+
const signature = directorySignature(fullChangedPath);
|
|
4048
|
+
if (signature && signature !== signatures.get(fullChangedPath)) {
|
|
4049
|
+
closeSubtree(fullChangedPath);
|
|
4050
|
+
watchDirectory(fullChangedPath, initialScanAsync);
|
|
4051
|
+
}
|
|
4052
|
+
scheduleUpdate(changed);
|
|
4053
|
+
return;
|
|
4054
|
+
}
|
|
4055
|
+
watchDirectory(fullChangedPath, initialScanAsync);
|
|
4056
|
+
} else if (known) {
|
|
4057
|
+
closeSubtree(fullChangedPath);
|
|
4058
|
+
}
|
|
4059
|
+
scheduleUpdate(changed);
|
|
4060
|
+
};
|
|
4061
|
+
const processPathInspections = () => {
|
|
4062
|
+
pathInspectionTimer = null;
|
|
4063
|
+
const entries = [...pendingPathInspections];
|
|
4064
|
+
pendingPathInspections.clear();
|
|
4065
|
+
for (const [changed, fullChangedPath] of entries) {
|
|
4066
|
+
processChangedPath(changed, fullChangedPath);
|
|
4067
|
+
}
|
|
4068
|
+
};
|
|
4069
|
+
const queuePathInspection = (changed, fullChangedPath) => {
|
|
4070
|
+
pendingPathInspections.set(changed, fullChangedPath);
|
|
4071
|
+
if (!pathInspectionTimer)
|
|
4072
|
+
pathInspectionTimer = setTimer(processPathInspections, 25);
|
|
4073
|
+
};
|
|
4074
|
+
const watchDirectory = (dir, initialScan = false) => {
|
|
4075
|
+
if (watchers.has(dir))
|
|
4076
|
+
return;
|
|
4077
|
+
if (watchers.size >= maxWatchedDirectories) {
|
|
4078
|
+
reportWatchLimit();
|
|
4079
|
+
return;
|
|
4080
|
+
}
|
|
4081
|
+
const rel = directoryRelativePath(dir);
|
|
4082
|
+
if (rel && ignored(rel))
|
|
4083
|
+
return;
|
|
4084
|
+
try {
|
|
4085
|
+
const watcher = watch(dir, { persistent: false }, (_event, filename) => {
|
|
4086
|
+
if (!filename) {
|
|
4087
|
+
scheduleUpdate();
|
|
4088
|
+
return;
|
|
4089
|
+
}
|
|
4090
|
+
const changed = normalizeRelativePath(join7(rel, filename.toString()));
|
|
4091
|
+
if (ignored(changed))
|
|
4092
|
+
return;
|
|
4093
|
+
const fullChangedPath = join7(options.root, changed);
|
|
4094
|
+
if (!isInsideRoot(options.root, fullChangedPath))
|
|
4095
|
+
return;
|
|
4096
|
+
if (initialScanAsync) {
|
|
4097
|
+
queuePathInspection(changed, fullChangedPath);
|
|
4098
|
+
return;
|
|
4099
|
+
}
|
|
4100
|
+
processChangedPath(changed, fullChangedPath);
|
|
4101
|
+
}) || {};
|
|
4102
|
+
watchers.set(dir, watcher);
|
|
4103
|
+
const signature = directorySignature(dir);
|
|
4104
|
+
if (signature)
|
|
4105
|
+
signatures.set(dir, signature);
|
|
4106
|
+
watcher.on?.("error", () => {
|
|
4107
|
+
if (watchers.get(dir) === watcher) {
|
|
4108
|
+
watchers.delete(dir);
|
|
4109
|
+
signatures.delete(dir);
|
|
4110
|
+
}
|
|
4111
|
+
});
|
|
4112
|
+
watcher.on?.("close", () => {
|
|
4113
|
+
if (watchers.get(dir) === watcher) {
|
|
4114
|
+
watchers.delete(dir);
|
|
4115
|
+
signatures.delete(dir);
|
|
4116
|
+
}
|
|
4117
|
+
});
|
|
4118
|
+
} catch (error) {
|
|
4119
|
+
options.onError?.(error);
|
|
4120
|
+
return;
|
|
4121
|
+
}
|
|
4122
|
+
if (initialScanAsync && initialScan) {
|
|
4123
|
+
queueInitialChildren(dir);
|
|
4124
|
+
return;
|
|
4125
|
+
}
|
|
4126
|
+
if (watchers.size >= maxWatchedDirectories) {
|
|
4127
|
+
reportWatchLimit();
|
|
4128
|
+
return;
|
|
4129
|
+
}
|
|
4130
|
+
for (const child of readChildDirectories(dir))
|
|
4131
|
+
watchDirectory(child);
|
|
4132
|
+
};
|
|
4133
|
+
watchDirectory(options.root, true);
|
|
4134
|
+
return { started: watchers.size > 0, close: closeAll };
|
|
4135
|
+
}
|
|
4136
|
+
var DEFAULT_WORKTREE_WATCH_DIRECTORY_LIMIT = 1024, MIN_WORKTREE_WATCH_DIRECTORY_LIMIT = 1, MAX_WORKTREE_WATCH_DIRECTORY_LIMIT = 65536;
|
|
4137
|
+
var init_worktree_watcher = __esm(() => {
|
|
4138
|
+
init_search();
|
|
4139
|
+
});
|
|
4140
|
+
|
|
3891
4141
|
// web-src/server/state-store.ts
|
|
3892
|
-
import { join as
|
|
4142
|
+
import { join as join8 } from "node:path";
|
|
3893
4143
|
function codeViewerPath(root, fileName) {
|
|
3894
|
-
return
|
|
4144
|
+
return join8(root, CODE_VIEWER_DIR2, fileName);
|
|
3895
4145
|
}
|
|
3896
4146
|
function isRecord(value) {
|
|
3897
4147
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
@@ -4029,6 +4279,9 @@ function sanitizeSettings(raw) {
|
|
|
4029
4279
|
});
|
|
4030
4280
|
if (scopeExcludeNames)
|
|
4031
4281
|
out.scopeExcludeNames = scopeExcludeNames;
|
|
4282
|
+
const scopeWatchLimit = optionalNumber(raw.scopeWatchLimit, MIN_WORKTREE_WATCH_DIRECTORY_LIMIT, MAX_WORKTREE_WATCH_DIRECTORY_LIMIT);
|
|
4283
|
+
if (scopeWatchLimit !== undefined)
|
|
4284
|
+
out.scopeWatchLimit = scopeWatchLimit;
|
|
4032
4285
|
const uploadEnabled = optionalBoolean(raw.uploadEnabled);
|
|
4033
4286
|
if (uploadEnabled !== undefined)
|
|
4034
4287
|
out.uploadEnabled = uploadEnabled;
|
|
@@ -4350,6 +4603,7 @@ async function patchDbUiState(root, patch) {
|
|
|
4350
4603
|
var CODE_VIEWER_DIR2 = ".code-viewer", SETTINGS_FILE_NAME = "settings.json", VIEW_STATE_FILE_NAME = "view-state.json", DB_UI_FILE_NAME = "db-ui.json", MAX_SETTINGS_BYTES = 200000, MAX_VIEW_STATE_BYTES = 1e6, MAX_DB_UI_BYTES = 1e6, MAX_REF_LEN = 1024, MAX_KEY_LEN = 2048, MAX_VIEW_ITEMS = 20000, MAX_DB_UI_DBS = 200, MAX_DB_UI_TABLES = 500, MAX_DB_UI_COLUMNS = 1000, MAX_DB_UI_EXPANDED_SCOPES = 500, DB_UI_BOOL_PREF_KEYS, settingsStore, viewStateStore, dbUiStore;
|
|
4351
4604
|
var init_state_store = __esm(() => {
|
|
4352
4605
|
init_json_store();
|
|
4606
|
+
init_worktree_watcher();
|
|
4353
4607
|
DB_UI_BOOL_PREF_KEYS = ["s3TooltipEnabled", "inferFkRails"];
|
|
4354
4608
|
settingsStore = createJsonFileStore({
|
|
4355
4609
|
filePath: (root) => codeViewerPath(root, SETTINGS_FILE_NAME),
|
|
@@ -4377,256 +4631,6 @@ var init_state_store = __esm(() => {
|
|
|
4377
4631
|
});
|
|
4378
4632
|
});
|
|
4379
4633
|
|
|
4380
|
-
// web-src/server/worktree-watcher.ts
|
|
4381
|
-
import {
|
|
4382
|
-
lstatSync as lstatSync3,
|
|
4383
|
-
readdirSync as nodeReaddirSync,
|
|
4384
|
-
watch as nodeWatch
|
|
4385
|
-
} from "node:fs";
|
|
4386
|
-
import { join as join8, relative } from "node:path";
|
|
4387
|
-
function normalizeRelativePath(path) {
|
|
4388
|
-
return path.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
4389
|
-
}
|
|
4390
|
-
function isInsideRoot(root, path) {
|
|
4391
|
-
const rel = relative(root, path).replace(/\\/g, "/");
|
|
4392
|
-
return rel === "" || !rel.startsWith("..") && !rel.startsWith("/");
|
|
4393
|
-
}
|
|
4394
|
-
function startWorktreeUpdateWatch(options) {
|
|
4395
|
-
const watch = options.watch || nodeWatch;
|
|
4396
|
-
const readDirs = options.readdirSync || ((path) => nodeReaddirSync(path, { withFileTypes: true }));
|
|
4397
|
-
const isDirectory = options.isDirectory || ((path) => {
|
|
4398
|
-
try {
|
|
4399
|
-
return lstatSync3(path).isDirectory();
|
|
4400
|
-
} catch {
|
|
4401
|
-
return false;
|
|
4402
|
-
}
|
|
4403
|
-
});
|
|
4404
|
-
const directorySignature = options.directorySignature || ((path) => {
|
|
4405
|
-
try {
|
|
4406
|
-
const stats = lstatSync3(path);
|
|
4407
|
-
if (!stats.isDirectory())
|
|
4408
|
-
return null;
|
|
4409
|
-
return `${stats.dev}:${stats.ino}`;
|
|
4410
|
-
} catch {
|
|
4411
|
-
return null;
|
|
4412
|
-
}
|
|
4413
|
-
});
|
|
4414
|
-
const setTimer = options.setTimeoutFn || setTimeout;
|
|
4415
|
-
const clearTimer = options.clearTimeoutFn || clearTimeout;
|
|
4416
|
-
const debounceMs = options.debounceMs ?? 250;
|
|
4417
|
-
const maxWatchedDirectories = Math.max(1, Math.floor(options.maxWatchedDirectories ?? DEFAULT_WORKTREE_WATCH_DIRECTORY_LIMIT));
|
|
4418
|
-
const watchers = new Map;
|
|
4419
|
-
const signatures = new Map;
|
|
4420
|
-
const initialScanAsync = options.initialScanMode === "async" || (!options.watch || options.watch === nodeWatch) && !options.readdirSync;
|
|
4421
|
-
const initialScanQueue = [];
|
|
4422
|
-
let initialScanTimer = null;
|
|
4423
|
-
const pendingPathInspections = new Map;
|
|
4424
|
-
let pathInspectionTimer = null;
|
|
4425
|
-
let timer = null;
|
|
4426
|
-
const pendingChangedPaths = new Set;
|
|
4427
|
-
let watchLimitReported = false;
|
|
4428
|
-
const ignored = (path) => isSkippableSearchPath(normalizeRelativePath(path), options.omitDirNames, options.excludeNames);
|
|
4429
|
-
const directoryRelativePath = (dir) => normalizeRelativePath(relative(options.root, dir));
|
|
4430
|
-
const ignoredDirectory = (dir) => {
|
|
4431
|
-
const rel = directoryRelativePath(dir);
|
|
4432
|
-
return Boolean(rel && ignored(rel));
|
|
4433
|
-
};
|
|
4434
|
-
const scheduleUpdate = (changedPath) => {
|
|
4435
|
-
if (changedPath)
|
|
4436
|
-
pendingChangedPaths.add(changedPath);
|
|
4437
|
-
if (timer)
|
|
4438
|
-
clearTimer(timer);
|
|
4439
|
-
timer = setTimer(() => {
|
|
4440
|
-
timer = null;
|
|
4441
|
-
const paths = pendingChangedPaths.size ? [...pendingChangedPaths] : undefined;
|
|
4442
|
-
pendingChangedPaths.clear();
|
|
4443
|
-
options.onUpdate(paths);
|
|
4444
|
-
}, debounceMs);
|
|
4445
|
-
};
|
|
4446
|
-
const reportWatchLimit = () => {
|
|
4447
|
-
if (watchLimitReported)
|
|
4448
|
-
return;
|
|
4449
|
-
watchLimitReported = true;
|
|
4450
|
-
options.onWatchLimit?.(maxWatchedDirectories);
|
|
4451
|
-
options.onError?.(new Error(`worktree watcher cap reached (${maxWatchedDirectories}); subsequent changes may be missed`));
|
|
4452
|
-
};
|
|
4453
|
-
const closeSubtree = (dir) => {
|
|
4454
|
-
for (const [watchedDir, watcher] of [...watchers]) {
|
|
4455
|
-
if (watchedDir !== dir && !watchedDir.startsWith(`${dir}/`))
|
|
4456
|
-
continue;
|
|
4457
|
-
try {
|
|
4458
|
-
watcher.close?.();
|
|
4459
|
-
} catch {}
|
|
4460
|
-
watchers.delete(watchedDir);
|
|
4461
|
-
signatures.delete(watchedDir);
|
|
4462
|
-
}
|
|
4463
|
-
};
|
|
4464
|
-
const closeAll = () => {
|
|
4465
|
-
if (initialScanTimer) {
|
|
4466
|
-
clearTimer(initialScanTimer);
|
|
4467
|
-
initialScanTimer = null;
|
|
4468
|
-
}
|
|
4469
|
-
if (pathInspectionTimer) {
|
|
4470
|
-
clearTimer(pathInspectionTimer);
|
|
4471
|
-
pathInspectionTimer = null;
|
|
4472
|
-
}
|
|
4473
|
-
initialScanQueue.length = 0;
|
|
4474
|
-
pendingPathInspections.clear();
|
|
4475
|
-
for (const watcher of [...watchers.values()]) {
|
|
4476
|
-
try {
|
|
4477
|
-
watcher.close?.();
|
|
4478
|
-
} catch {}
|
|
4479
|
-
}
|
|
4480
|
-
watchers.clear();
|
|
4481
|
-
signatures.clear();
|
|
4482
|
-
};
|
|
4483
|
-
const readChildDirectories = (dir) => {
|
|
4484
|
-
let entries;
|
|
4485
|
-
try {
|
|
4486
|
-
entries = readDirs(dir);
|
|
4487
|
-
} catch (error) {
|
|
4488
|
-
options.onError?.(error);
|
|
4489
|
-
return [];
|
|
4490
|
-
}
|
|
4491
|
-
const children = [];
|
|
4492
|
-
for (const entry of entries) {
|
|
4493
|
-
if (!entry.isDirectory())
|
|
4494
|
-
continue;
|
|
4495
|
-
const child = join8(dir, entry.name);
|
|
4496
|
-
if (ignoredDirectory(child))
|
|
4497
|
-
continue;
|
|
4498
|
-
children.push(child);
|
|
4499
|
-
}
|
|
4500
|
-
return children;
|
|
4501
|
-
};
|
|
4502
|
-
const processInitialScanQueue = () => {
|
|
4503
|
-
initialScanTimer = null;
|
|
4504
|
-
if (watchers.size >= maxWatchedDirectories) {
|
|
4505
|
-
reportWatchLimit();
|
|
4506
|
-
initialScanQueue.length = 0;
|
|
4507
|
-
return;
|
|
4508
|
-
}
|
|
4509
|
-
const next = initialScanQueue.shift();
|
|
4510
|
-
if (next)
|
|
4511
|
-
watchDirectory(next, true);
|
|
4512
|
-
if (watchers.size >= maxWatchedDirectories) {
|
|
4513
|
-
reportWatchLimit();
|
|
4514
|
-
initialScanQueue.length = 0;
|
|
4515
|
-
}
|
|
4516
|
-
if (initialScanQueue.length)
|
|
4517
|
-
initialScanTimer = setTimer(processInitialScanQueue, 50);
|
|
4518
|
-
};
|
|
4519
|
-
const queueInitialChildren = (dir) => {
|
|
4520
|
-
const remaining = maxWatchedDirectories - watchers.size;
|
|
4521
|
-
if (remaining <= 0) {
|
|
4522
|
-
reportWatchLimit();
|
|
4523
|
-
return;
|
|
4524
|
-
}
|
|
4525
|
-
const children = readChildDirectories(dir);
|
|
4526
|
-
if (children.length > remaining)
|
|
4527
|
-
reportWatchLimit();
|
|
4528
|
-
initialScanQueue.push(...children.slice(0, remaining));
|
|
4529
|
-
if (!initialScanTimer)
|
|
4530
|
-
initialScanTimer = setTimer(processInitialScanQueue, 5000);
|
|
4531
|
-
};
|
|
4532
|
-
const processChangedPath = (changed, fullChangedPath) => {
|
|
4533
|
-
const known = watchers.has(fullChangedPath);
|
|
4534
|
-
if (isDirectory(fullChangedPath)) {
|
|
4535
|
-
if (known) {
|
|
4536
|
-
const signature = directorySignature(fullChangedPath);
|
|
4537
|
-
if (signature && signature !== signatures.get(fullChangedPath)) {
|
|
4538
|
-
closeSubtree(fullChangedPath);
|
|
4539
|
-
watchDirectory(fullChangedPath, initialScanAsync);
|
|
4540
|
-
}
|
|
4541
|
-
scheduleUpdate(changed);
|
|
4542
|
-
return;
|
|
4543
|
-
}
|
|
4544
|
-
watchDirectory(fullChangedPath, initialScanAsync);
|
|
4545
|
-
} else if (known) {
|
|
4546
|
-
closeSubtree(fullChangedPath);
|
|
4547
|
-
}
|
|
4548
|
-
scheduleUpdate(changed);
|
|
4549
|
-
};
|
|
4550
|
-
const processPathInspections = () => {
|
|
4551
|
-
pathInspectionTimer = null;
|
|
4552
|
-
const entries = [...pendingPathInspections];
|
|
4553
|
-
pendingPathInspections.clear();
|
|
4554
|
-
for (const [changed, fullChangedPath] of entries) {
|
|
4555
|
-
processChangedPath(changed, fullChangedPath);
|
|
4556
|
-
}
|
|
4557
|
-
};
|
|
4558
|
-
const queuePathInspection = (changed, fullChangedPath) => {
|
|
4559
|
-
pendingPathInspections.set(changed, fullChangedPath);
|
|
4560
|
-
if (!pathInspectionTimer)
|
|
4561
|
-
pathInspectionTimer = setTimer(processPathInspections, 25);
|
|
4562
|
-
};
|
|
4563
|
-
const watchDirectory = (dir, initialScan = false) => {
|
|
4564
|
-
if (watchers.has(dir))
|
|
4565
|
-
return;
|
|
4566
|
-
if (watchers.size >= maxWatchedDirectories) {
|
|
4567
|
-
reportWatchLimit();
|
|
4568
|
-
return;
|
|
4569
|
-
}
|
|
4570
|
-
const rel = directoryRelativePath(dir);
|
|
4571
|
-
if (rel && ignored(rel))
|
|
4572
|
-
return;
|
|
4573
|
-
try {
|
|
4574
|
-
const watcher = watch(dir, { persistent: false }, (_event, filename) => {
|
|
4575
|
-
if (!filename) {
|
|
4576
|
-
scheduleUpdate();
|
|
4577
|
-
return;
|
|
4578
|
-
}
|
|
4579
|
-
const changed = normalizeRelativePath(join8(rel, filename.toString()));
|
|
4580
|
-
if (ignored(changed))
|
|
4581
|
-
return;
|
|
4582
|
-
const fullChangedPath = join8(options.root, changed);
|
|
4583
|
-
if (!isInsideRoot(options.root, fullChangedPath))
|
|
4584
|
-
return;
|
|
4585
|
-
if (initialScanAsync) {
|
|
4586
|
-
queuePathInspection(changed, fullChangedPath);
|
|
4587
|
-
return;
|
|
4588
|
-
}
|
|
4589
|
-
processChangedPath(changed, fullChangedPath);
|
|
4590
|
-
}) || {};
|
|
4591
|
-
watchers.set(dir, watcher);
|
|
4592
|
-
const signature = directorySignature(dir);
|
|
4593
|
-
if (signature)
|
|
4594
|
-
signatures.set(dir, signature);
|
|
4595
|
-
watcher.on?.("error", () => {
|
|
4596
|
-
if (watchers.get(dir) === watcher) {
|
|
4597
|
-
watchers.delete(dir);
|
|
4598
|
-
signatures.delete(dir);
|
|
4599
|
-
}
|
|
4600
|
-
});
|
|
4601
|
-
watcher.on?.("close", () => {
|
|
4602
|
-
if (watchers.get(dir) === watcher) {
|
|
4603
|
-
watchers.delete(dir);
|
|
4604
|
-
signatures.delete(dir);
|
|
4605
|
-
}
|
|
4606
|
-
});
|
|
4607
|
-
} catch (error) {
|
|
4608
|
-
options.onError?.(error);
|
|
4609
|
-
return;
|
|
4610
|
-
}
|
|
4611
|
-
if (initialScanAsync && initialScan) {
|
|
4612
|
-
queueInitialChildren(dir);
|
|
4613
|
-
return;
|
|
4614
|
-
}
|
|
4615
|
-
if (watchers.size >= maxWatchedDirectories) {
|
|
4616
|
-
reportWatchLimit();
|
|
4617
|
-
return;
|
|
4618
|
-
}
|
|
4619
|
-
for (const child of readChildDirectories(dir))
|
|
4620
|
-
watchDirectory(child);
|
|
4621
|
-
};
|
|
4622
|
-
watchDirectory(options.root, true);
|
|
4623
|
-
return { started: watchers.size > 0, close: closeAll };
|
|
4624
|
-
}
|
|
4625
|
-
var DEFAULT_WORKTREE_WATCH_DIRECTORY_LIMIT = 1024, MIN_WORKTREE_WATCH_DIRECTORY_LIMIT = 1, MAX_WORKTREE_WATCH_DIRECTORY_LIMIT = 65536;
|
|
4626
|
-
var init_worktree_watcher = __esm(() => {
|
|
4627
|
-
init_search();
|
|
4628
|
-
});
|
|
4629
|
-
|
|
4630
4634
|
// web-src/core/control-chars.ts
|
|
4631
4635
|
function hasControlCharacter(value) {
|
|
4632
4636
|
for (const ch of value) {
|