wicked-brain 0.14.0 → 0.14.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/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { watch, readFileSync, existsSync, readdirSync, statSync } from "node:fs";
|
|
1
|
+
import { watch, readFileSync, existsSync, readdirSync, statSync, realpathSync } from "node:fs";
|
|
2
2
|
import { join, relative } from "node:path";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
|
|
@@ -6,6 +6,31 @@ function normalizePath(p) {
|
|
|
6
6
|
return p.replace(/\\/g, "/");
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
// Canonicalize to the real (long) path before watching. On Windows, calling
|
|
10
|
+
// fs.watch on an 8.3 short-name path (e.g. C:\Users\RUNNER~1\AppData\Local\Temp)
|
|
11
|
+
// makes libuv abort the process with "Assertion failed: !_wcsnicmp(...)" in
|
|
12
|
+
// fs-event.c — change events report the long filename, which no longer shares
|
|
13
|
+
// the watched (short) directory prefix. That abort is a native crash, so it
|
|
14
|
+
// bypasses the try/catch → polling fallback below. filename in the callbacks
|
|
15
|
+
// stays relative to the watched dir, so the logical relPath construction is
|
|
16
|
+
// unaffected.
|
|
17
|
+
//
|
|
18
|
+
// realpathSync.native (OS GetFinalPathNameByHandle) is required to expand 8.3
|
|
19
|
+
// short names to their long form; the JS realpathSync only resolves symlinks
|
|
20
|
+
// and leaves short-name components like RUNNER~1 intact. Fall back to the JS
|
|
21
|
+
// implementation, then to the original path.
|
|
22
|
+
function canonicalDir(p) {
|
|
23
|
+
try {
|
|
24
|
+
return realpathSync.native(p);
|
|
25
|
+
} catch {
|
|
26
|
+
try {
|
|
27
|
+
return realpathSync(p);
|
|
28
|
+
} catch {
|
|
29
|
+
return p;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
9
34
|
const IGNORE_DIRS = new Set([
|
|
10
35
|
"node_modules", ".git", "__pycache__", ".venv", "venv",
|
|
11
36
|
"target", "dist", "build", ".next", ".nuxt", "coverage",
|
|
@@ -70,7 +95,7 @@ export class FileWatcher {
|
|
|
70
95
|
if (!existsSync(project.path)) continue;
|
|
71
96
|
this.#scanAndHashProject(project);
|
|
72
97
|
try {
|
|
73
|
-
const watcher = watch(project.path, { recursive: true }, (eventType, filename) => {
|
|
98
|
+
const watcher = watch(canonicalDir(project.path), { recursive: true }, (eventType, filename) => {
|
|
74
99
|
if (!filename) return;
|
|
75
100
|
const parts = filename.split(/[/\\]/);
|
|
76
101
|
if (parts.some(p => IGNORE_DIRS.has(p))) return;
|
|
@@ -96,7 +121,7 @@ export class FileWatcher {
|
|
|
96
121
|
const absDir = join(this.#brainPath, dir);
|
|
97
122
|
if (!existsSync(absDir)) return false;
|
|
98
123
|
try {
|
|
99
|
-
const watcher = watch(absDir, { recursive: true }, (eventType, filename) => {
|
|
124
|
+
const watcher = watch(canonicalDir(absDir), { recursive: true }, (eventType, filename) => {
|
|
100
125
|
if (!filename || !filename.endsWith(".md")) return;
|
|
101
126
|
const relPath = normalizePath(`${dir}/${filename}`);
|
|
102
127
|
this.#debounce(relPath, () => this.#handleChange(relPath));
|
|
@@ -795,10 +795,10 @@ export class SqliteSearch {
|
|
|
795
795
|
d.id,
|
|
796
796
|
d.path,
|
|
797
797
|
d.brain_id,
|
|
798
|
-
snippet(
|
|
798
|
+
snippet(documents_fts, 2, '<b>', '</b>', '…', 32) AS snippet
|
|
799
799
|
FROM ${attached}.documents_fts f
|
|
800
800
|
JOIN ${attached}.documents d ON d.id = f.id
|
|
801
|
-
WHERE
|
|
801
|
+
WHERE documents_fts MATCH ?
|
|
802
802
|
ORDER BY rank
|
|
803
803
|
LIMIT ?
|
|
804
804
|
`)
|