sensemaking 0.12.2 → 0.13.0
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/cjs/cli/download.js +4 -4
- package/dist/cjs/cli/download.js.map +1 -1
- package/dist/cjs/cli/init.js +4 -4
- package/dist/cjs/cli/init.js.map +1 -1
- package/dist/cjs/cli/map.js +4 -4
- package/dist/cjs/cli/map.js.map +1 -1
- package/dist/cjs/cli/named.js +2 -2
- package/dist/cjs/cli/named.js.map +1 -1
- package/dist/cjs/cli/path.js +6 -6
- package/dist/cjs/cli/path.js.map +1 -1
- package/dist/cjs/cli/peek.js +4 -4
- package/dist/cjs/cli/peek.js.map +1 -1
- package/dist/cjs/cli/related.js +4 -4
- package/dist/cjs/cli/related.js.map +1 -1
- package/dist/cjs/cli/search.js +4 -4
- package/dist/cjs/cli/search.js.map +1 -1
- package/dist/cjs/cli/shared.d.cts +2 -2
- package/dist/cjs/cli/shared.d.ts +2 -2
- package/dist/cjs/cli/shared.js +5 -5
- package/dist/cjs/cli/shared.js.map +1 -1
- package/dist/cjs/cli/status.js +16 -16
- package/dist/cjs/cli/status.js.map +1 -1
- package/dist/cjs/cli/types.d.cts +1 -1
- package/dist/cjs/cli/types.d.ts +1 -1
- package/dist/cjs/cli.js +3 -3
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/commands/index.d.cts +10 -0
- package/dist/cjs/commands/index.d.ts +10 -0
- package/dist/cjs/commands/index.js +42 -0
- package/dist/cjs/commands/index.js.map +1 -0
- package/dist/cjs/commands/map.d.cts +21 -0
- package/dist/cjs/commands/map.d.ts +21 -0
- package/dist/cjs/commands/map.js +90 -0
- package/dist/cjs/commands/map.js.map +1 -0
- package/dist/cjs/commands/peek.d.cts +20 -0
- package/dist/cjs/commands/peek.d.ts +20 -0
- package/dist/cjs/commands/peek.js +175 -0
- package/dist/cjs/commands/peek.js.map +1 -0
- package/dist/cjs/commands/related.d.cts +6 -0
- package/dist/cjs/commands/related.d.ts +6 -0
- package/dist/cjs/commands/related.js +232 -0
- package/dist/cjs/commands/related.js.map +1 -0
- package/dist/cjs/commands/scope.d.cts +10 -0
- package/dist/cjs/commands/scope.d.ts +10 -0
- package/dist/cjs/commands/scope.js +124 -0
- package/dist/cjs/commands/scope.js.map +1 -0
- package/dist/cjs/commands/search.d.cts +12 -0
- package/dist/cjs/commands/search.d.ts +12 -0
- package/dist/cjs/{commands.js → commands/search.js} +20 -358
- package/dist/cjs/commands/search.js.map +1 -0
- package/dist/cjs/commands/status.d.cts +9 -0
- package/dist/cjs/commands/status.d.ts +9 -0
- package/dist/cjs/commands/status.js +25 -0
- package/dist/cjs/commands/status.js.map +1 -0
- package/dist/cjs/config/access.d.cts +19 -0
- package/dist/cjs/config/access.d.ts +19 -0
- package/dist/cjs/config/access.js +149 -0
- package/dist/cjs/config/access.js.map +1 -0
- package/dist/cjs/config/index.d.cts +5 -0
- package/dist/cjs/config/index.d.ts +5 -0
- package/dist/cjs/config/index.js +77 -0
- package/dist/cjs/config/index.js.map +1 -0
- package/dist/cjs/config/load.d.cts +8 -0
- package/dist/cjs/config/load.d.ts +8 -0
- package/dist/cjs/config/load.js +448 -0
- package/dist/cjs/config/load.js.map +1 -0
- package/dist/cjs/config/resolve.d.cts +6 -0
- package/dist/cjs/config/resolve.d.ts +6 -0
- package/dist/cjs/config/resolve.js +50 -0
- package/dist/cjs/config/resolve.js.map +1 -0
- package/dist/{esm/config.d.ts → cjs/config/types.d.cts} +2 -32
- package/dist/cjs/{config.d.cts → config/types.d.ts} +2 -32
- package/dist/cjs/config/types.js +39 -0
- package/dist/cjs/config/types.js.map +1 -0
- package/dist/cjs/config/validate.d.cts +4 -0
- package/dist/cjs/config/validate.d.ts +4 -0
- package/dist/cjs/config/validate.js +363 -0
- package/dist/cjs/config/validate.js.map +1 -0
- package/dist/cjs/db/index.d.cts +4 -0
- package/dist/cjs/db/index.d.ts +4 -0
- package/dist/cjs/db/index.js +42 -0
- package/dist/cjs/db/index.js.map +1 -0
- package/dist/cjs/{db.d.cts → db/open.d.cts} +2 -8
- package/dist/cjs/{db.d.ts → db/open.d.ts} +2 -8
- package/dist/cjs/db/open.js +223 -0
- package/dist/cjs/db/open.js.map +1 -0
- package/dist/cjs/db/reconcile.d.cts +9 -0
- package/dist/cjs/db/reconcile.d.ts +9 -0
- package/dist/cjs/{db.js → db/reconcile.js} +24 -261
- package/dist/cjs/db/reconcile.js.map +1 -0
- package/dist/cjs/db/shared.d.cts +5 -0
- package/dist/cjs/db/shared.d.ts +5 -0
- package/dist/cjs/db/shared.js +45 -0
- package/dist/cjs/db/shared.js.map +1 -0
- package/dist/cjs/features/embed.d.cts +1 -1
- package/dist/cjs/features/embed.d.ts +1 -1
- package/dist/cjs/features/embed.js +4 -3
- package/dist/cjs/features/embed.js.map +1 -1
- package/dist/cjs/features/index.d.cts +1 -1
- package/dist/cjs/features/index.d.ts +1 -1
- package/dist/cjs/features/index.js +4 -2
- package/dist/cjs/features/index.js.map +1 -1
- package/dist/cjs/features/links.js +38 -20
- package/dist/cjs/features/links.js.map +1 -1
- package/dist/cjs/features/tags.d.cts +2 -0
- package/dist/cjs/features/tags.d.ts +2 -0
- package/dist/cjs/features/tags.js +188 -0
- package/dist/cjs/features/tags.js.map +1 -0
- package/dist/cjs/features/types.d.cts +2 -2
- package/dist/cjs/features/types.d.ts +2 -2
- package/dist/cjs/index.d.cts +6 -6
- package/dist/cjs/index.d.ts +6 -6
- package/dist/cjs/index.js +15 -15
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/scan.d.cts +3 -1
- package/dist/cjs/scan.d.ts +3 -1
- package/dist/cjs/scan.js +9 -6
- package/dist/cjs/scan.js.map +1 -1
- package/dist/cjs/sql-functions.d.cts +2 -0
- package/dist/cjs/sql-functions.d.ts +2 -0
- package/dist/cjs/sql-functions.js +64 -0
- package/dist/cjs/sql-functions.js.map +1 -0
- package/dist/cjs/watch.d.cts +1 -1
- package/dist/cjs/watch.d.ts +1 -1
- package/dist/cjs/watch.js +12 -12
- package/dist/cjs/watch.js.map +1 -1
- package/dist/esm/cli/download.js +1 -1
- package/dist/esm/cli/download.js.map +1 -1
- package/dist/esm/cli/init.js +1 -1
- package/dist/esm/cli/init.js.map +1 -1
- package/dist/esm/cli/map.js +1 -1
- package/dist/esm/cli/map.js.map +1 -1
- package/dist/esm/cli/named.js +1 -1
- package/dist/esm/cli/named.js.map +1 -1
- package/dist/esm/cli/path.js +1 -1
- package/dist/esm/cli/path.js.map +1 -1
- package/dist/esm/cli/peek.js +1 -1
- package/dist/esm/cli/peek.js.map +1 -1
- package/dist/esm/cli/related.js +1 -1
- package/dist/esm/cli/related.js.map +1 -1
- package/dist/esm/cli/search.js +1 -1
- package/dist/esm/cli/search.js.map +1 -1
- package/dist/esm/cli/shared.d.ts +2 -2
- package/dist/esm/cli/shared.js +2 -2
- package/dist/esm/cli/shared.js.map +1 -1
- package/dist/esm/cli/status.js +3 -3
- package/dist/esm/cli/status.js.map +1 -1
- package/dist/esm/cli/types.d.ts +1 -1
- package/dist/esm/cli/types.js.map +1 -1
- package/dist/esm/cli.js +1 -1
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/commands/index.d.ts +10 -0
- package/dist/esm/commands/index.js +8 -0
- package/dist/esm/commands/index.js.map +1 -0
- package/dist/esm/commands/map.d.ts +21 -0
- package/dist/esm/commands/map.js +56 -0
- package/dist/esm/commands/map.js.map +1 -0
- package/dist/esm/commands/peek.d.ts +20 -0
- package/dist/esm/commands/peek.js +63 -0
- package/dist/esm/commands/peek.js.map +1 -0
- package/dist/esm/commands/related.d.ts +6 -0
- package/dist/esm/commands/related.js +47 -0
- package/dist/esm/commands/related.js.map +1 -0
- package/dist/esm/commands/scope.d.ts +10 -0
- package/dist/esm/commands/scope.js +60 -0
- package/dist/esm/commands/scope.js.map +1 -0
- package/dist/esm/commands/search.d.ts +12 -0
- package/dist/esm/commands/search.js +258 -0
- package/dist/esm/commands/search.js.map +1 -0
- package/dist/esm/commands/status.d.ts +9 -0
- package/dist/esm/commands/status.js +16 -0
- package/dist/esm/commands/status.js.map +1 -0
- package/dist/esm/config/access.d.ts +19 -0
- package/dist/esm/config/access.js +89 -0
- package/dist/esm/config/access.js.map +1 -0
- package/dist/esm/config/index.d.ts +5 -0
- package/dist/esm/config/index.js +4 -0
- package/dist/esm/config/index.js.map +1 -0
- package/dist/esm/config/load.d.ts +8 -0
- package/dist/esm/config/load.js +242 -0
- package/dist/esm/config/load.js.map +1 -0
- package/dist/esm/config/resolve.d.ts +6 -0
- package/dist/esm/config/resolve.js +35 -0
- package/dist/esm/config/resolve.js.map +1 -0
- package/dist/{cjs/config.d.ts → esm/config/types.d.ts} +2 -32
- package/dist/esm/config/types.js +15 -0
- package/dist/esm/config/types.js.map +1 -0
- package/dist/esm/config/validate.d.ts +4 -0
- package/dist/esm/config/validate.js +226 -0
- package/dist/esm/config/validate.js.map +1 -0
- package/dist/esm/db/index.d.ts +4 -0
- package/dist/esm/db/index.js +5 -0
- package/dist/esm/db/index.js.map +1 -0
- package/dist/esm/{db.d.ts → db/open.d.ts} +2 -8
- package/dist/esm/db/open.js +160 -0
- package/dist/esm/db/open.js.map +1 -0
- package/dist/esm/db/reconcile.d.ts +9 -0
- package/dist/esm/{db.js → db/reconcile.js} +12 -216
- package/dist/esm/db/reconcile.js.map +1 -0
- package/dist/esm/db/shared.d.ts +5 -0
- package/dist/esm/db/shared.js +20 -0
- package/dist/esm/db/shared.js.map +1 -0
- package/dist/esm/features/embed.d.ts +1 -1
- package/dist/esm/features/embed.js +2 -1
- package/dist/esm/features/embed.js.map +1 -1
- package/dist/esm/features/index.d.ts +1 -1
- package/dist/esm/features/index.js +3 -1
- package/dist/esm/features/index.js.map +1 -1
- package/dist/esm/features/links.js +36 -21
- package/dist/esm/features/links.js.map +1 -1
- package/dist/esm/features/tags.d.ts +2 -0
- package/dist/esm/features/tags.js +80 -0
- package/dist/esm/features/tags.js.map +1 -0
- package/dist/esm/features/types.d.ts +2 -2
- package/dist/esm/features/types.js.map +1 -1
- package/dist/esm/index.d.ts +6 -6
- package/dist/esm/index.js +3 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/scan.d.ts +3 -1
- package/dist/esm/scan.js +5 -2
- package/dist/esm/scan.js.map +1 -1
- package/dist/esm/sql-functions.d.ts +2 -0
- package/dist/esm/sql-functions.js +47 -0
- package/dist/esm/sql-functions.js.map +1 -0
- package/dist/esm/watch.d.ts +1 -1
- package/dist/esm/watch.js +2 -2
- package/dist/esm/watch.js.map +1 -1
- package/package.json +2 -1
- package/schema.json +4 -0
- package/skills/sense/SKILL.md +3 -3
- package/skills/sense-bases/EXAMPLES.md +103 -0
- package/skills/sense-bases/SKILL.md +137 -0
- package/skills/sense-setup/SKILL.md +1 -1
- package/dist/cjs/commands.d.cts +0 -58
- package/dist/cjs/commands.d.ts +0 -58
- package/dist/cjs/commands.js.map +0 -1
- package/dist/cjs/config.js +0 -919
- package/dist/cjs/config.js.map +0 -1
- package/dist/cjs/db.js.map +0 -1
- package/dist/esm/commands.d.ts +0 -58
- package/dist/esm/commands.js +0 -486
- package/dist/esm/commands.js.map +0 -1
- package/dist/esm/config.js +0 -599
- package/dist/esm/config.js.map +0 -1
- package/dist/esm/db.js.map +0 -1
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// The Node floor (>=22.20) is explained here and nowhere else: 22.20 is the first release with
|
|
2
|
-
// both FTS5 and row-returning INSERT ... RETURNING. Raise it only for a load-bearing capability.
|
|
3
1
|
"use strict";
|
|
4
2
|
Object.defineProperty(exports, "__esModule", {
|
|
5
3
|
value: true
|
|
@@ -11,40 +9,26 @@ function _export(target, all) {
|
|
|
11
9
|
});
|
|
12
10
|
}
|
|
13
11
|
_export(exports, {
|
|
14
|
-
get
|
|
15
|
-
return
|
|
12
|
+
get changedSignatureKeys () {
|
|
13
|
+
return changedSignatureKeys;
|
|
16
14
|
},
|
|
17
|
-
get
|
|
18
|
-
return
|
|
19
|
-
},
|
|
20
|
-
get clearCache () {
|
|
21
|
-
return clearCache;
|
|
22
|
-
},
|
|
23
|
-
get docCount () {
|
|
24
|
-
return docCount;
|
|
25
|
-
},
|
|
26
|
-
get getMeta () {
|
|
27
|
-
return getMeta;
|
|
28
|
-
},
|
|
29
|
-
get open () {
|
|
30
|
-
return open;
|
|
15
|
+
get rebuildContentTable () {
|
|
16
|
+
return rebuildContentTable;
|
|
31
17
|
},
|
|
32
18
|
get reconcile () {
|
|
33
19
|
return reconcile;
|
|
34
20
|
},
|
|
35
|
-
get
|
|
36
|
-
return
|
|
21
|
+
get signatureDiff () {
|
|
22
|
+
return signatureDiff;
|
|
37
23
|
}
|
|
38
24
|
});
|
|
39
|
-
var
|
|
40
|
-
var
|
|
41
|
-
var
|
|
42
|
-
var
|
|
43
|
-
var
|
|
44
|
-
var
|
|
45
|
-
var
|
|
46
|
-
var _scants = require("./scan.js");
|
|
47
|
-
var _segmentts = require("./segment.js");
|
|
25
|
+
var _indexts = require("../config/index.js");
|
|
26
|
+
var _errorsts = require("../errors.js");
|
|
27
|
+
var _indexts1 = require("../features/index.js");
|
|
28
|
+
var _progressts = require("../progress.js");
|
|
29
|
+
var _scants = require("../scan.js");
|
|
30
|
+
var _segmentts = require("../segment.js");
|
|
31
|
+
var _sharedts = require("./shared.js");
|
|
48
32
|
function _array_like_to_array(arr, len) {
|
|
49
33
|
if (len == null || len > arr.length) len = arr.length;
|
|
50
34
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
@@ -108,137 +92,12 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
108
92
|
var CORE_FRONTMATTER_COLUMNS = new Set([
|
|
109
93
|
'path',
|
|
110
94
|
'_mtime',
|
|
95
|
+
'_ctime',
|
|
111
96
|
'_size',
|
|
112
97
|
'_parse_error'
|
|
113
98
|
]);
|
|
114
|
-
var DB_FILENAME = 'cache.db';
|
|
115
|
-
var SCHEMA_VERSION = '12';
|
|
116
99
|
// SQLite's compile-time SQLITE_MAX_COLUMN, default 2000 (https://www.sqlite.org/limits.html).
|
|
117
100
|
var MAX_FRONTMATTER_COLUMNS = 2000;
|
|
118
|
-
function quoteIdent(name) {
|
|
119
|
-
return '"'.concat(name.split('"').join('""'), '"');
|
|
120
|
-
}
|
|
121
|
-
// has(field, value): JSON-array field -> membership, string field -> substring, NULL -> false.
|
|
122
|
-
function registerFunctions(db, segmenting) {
|
|
123
|
-
db.function('has', {
|
|
124
|
-
deterministic: true,
|
|
125
|
-
varargs: false
|
|
126
|
-
}, function(field, value) {
|
|
127
|
-
if (field === null || field === undefined) return 0;
|
|
128
|
-
var needle = String(value);
|
|
129
|
-
if (typeof field === 'string') {
|
|
130
|
-
if (field.startsWith('[')) {
|
|
131
|
-
try {
|
|
132
|
-
var parsed = JSON.parse(field);
|
|
133
|
-
if (Array.isArray(parsed)) {
|
|
134
|
-
return parsed.some(function(item) {
|
|
135
|
-
return String(item) === needle;
|
|
136
|
-
}) ? 1 : 0;
|
|
137
|
-
}
|
|
138
|
-
} catch (unused) {}
|
|
139
|
-
}
|
|
140
|
-
return field.includes(needle) ? 1 : 0;
|
|
141
|
-
}
|
|
142
|
-
return String(field).includes(needle) ? 1 : 0;
|
|
143
|
-
});
|
|
144
|
-
// Raw `content MATCH '<unspaced text>'` cannot be rewritten behind the author's back, and
|
|
145
|
-
// matches nothing, so the same transform is available to hand-written SQL by name. `segmenting`
|
|
146
|
-
// is the same config predicate commands.ts's search() gates on (contentTokenize(cfg) ===
|
|
147
|
-
// undefined), passed in by open() rather than read back from persisted state.
|
|
148
|
-
db.function('segment', {
|
|
149
|
-
deterministic: true,
|
|
150
|
-
varargs: false
|
|
151
|
-
}, function(terms) {
|
|
152
|
-
var text = terms === null || terms === undefined ? '' : String(terms);
|
|
153
|
-
return segmenting ? (0, _segmentts.segmentMatch)(text) : text;
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
function getColumns(db) {
|
|
157
|
-
var rows = db.prepare('PRAGMA table_info(frontmatter)').all();
|
|
158
|
-
return new Set(rows.map(function(r) {
|
|
159
|
-
return r.name;
|
|
160
|
-
}));
|
|
161
|
-
}
|
|
162
|
-
// Stemming is English-only, but the segmentation underneath it is what decides coverage:
|
|
163
|
-
// unicode61 splits on spaces, so a language written without them (Chinese, Japanese, Thai)
|
|
164
|
-
// indexes a whole run as one token and word search finds nothing. `content.tokenize` is how
|
|
165
|
-
// such a tree picks trigram instead.
|
|
166
|
-
var DEFAULT_TOKENIZE = 'porter unicode61';
|
|
167
|
-
// FTS5 takes its tokenizer as a string literal inside DDL, where nothing can bind, so a
|
|
168
|
-
// configured value has to be concatenated. Probing a throwaway table is what makes that safe
|
|
169
|
-
// and is also the whole validation: anything the linked SQLite accepts passes, anything else
|
|
170
|
-
// fails here with SQLite's own message rather than against the real table. It means no table
|
|
171
|
-
// of which version added which tokenizer has to be maintained.
|
|
172
|
-
function resolveTokenize(db, cfg) {
|
|
173
|
-
var configured = (0, _configts.contentTokenize)(cfg);
|
|
174
|
-
if (configured === undefined) return DEFAULT_TOKENIZE;
|
|
175
|
-
var literal = configured.replace(/'/g, "''");
|
|
176
|
-
try {
|
|
177
|
-
db.exec('DROP TABLE IF EXISTS temp.sense_tokenize_probe');
|
|
178
|
-
db.exec("CREATE VIRTUAL TABLE temp.sense_tokenize_probe USING fts5(x, tokenize = '".concat(literal, "')"));
|
|
179
|
-
db.exec('DROP TABLE IF EXISTS temp.sense_tokenize_probe');
|
|
180
|
-
} catch (err) {
|
|
181
|
-
throw new _errorsts.SenseError('CONFIG_INVALID', 'content.tokenize "'.concat(configured, '" is not a tokenizer this SQLite accepts (').concat(err.message, "); the built-in choices are unicode61, ascii, porter, and trigram, each with their own options"));
|
|
182
|
-
}
|
|
183
|
-
return literal;
|
|
184
|
-
}
|
|
185
|
-
// The tokenizer the content table was actually built with, from its own DDL -- the one
|
|
186
|
-
// record that cannot desynchronize from the table. NULL when the table does not exist yet.
|
|
187
|
-
function storedTokenize(db) {
|
|
188
|
-
var row = db.prepare("SELECT sql FROM sqlite_master WHERE name = 'content'").get();
|
|
189
|
-
if (!row) return null;
|
|
190
|
-
var m = row.sql.match(/tokenize = '((?:[^']|'')*)'/);
|
|
191
|
-
return m ? m[1] : null;
|
|
192
|
-
}
|
|
193
|
-
// Content is a separate table (not a column on frontmatter) so `SELECT * FROM frontmatter`
|
|
194
|
-
// can't dump file text into context. Features add their own tables after the core ones.
|
|
195
|
-
function ensureSchema(db, cfg, tokenize) {
|
|
196
|
-
db.exec('CREATE TABLE IF NOT EXISTS frontmatter ("path" TEXT PRIMARY KEY, "_mtime" REAL, "_size" INTEGER, "_parse_error" TEXT)');
|
|
197
|
-
// IF NOT EXISTS is safe against a tokenizer change: open() compares the table's own DDL
|
|
198
|
-
// against the resolved tokenizer before this runs, so a stale table is already gone by now.
|
|
199
|
-
// The three `_seg` sidecars are appended after path, never inserted: bm25(content, ...) and
|
|
200
|
-
// snippet(content, 2, ...) are documented against the first three columns and keep working
|
|
201
|
-
// (FTS5 defaults the weights it was not given). Each carries its field's exploded unspaced
|
|
202
|
-
// runs for text that needs it, and an empty string for text that does not.
|
|
203
|
-
db.exec("CREATE VIRTUAL TABLE IF NOT EXISTS content USING fts5(title, summary, text, path UNINDEXED, title_seg, summary_seg, text_seg, tokenize = '".concat(tokenize, "')"));
|
|
204
|
-
// Coverage, not ownership: a path can appear under several presets. path leads the PK so the
|
|
205
|
-
// per-doc delete is an index hit -- keyed the other way, cold builds went quadratic.
|
|
206
|
-
db.exec('CREATE TABLE IF NOT EXISTS preset_files ("path" TEXT, preset TEXT, PRIMARY KEY ("path", preset))');
|
|
207
|
-
db.exec('CREATE INDEX IF NOT EXISTS preset_files_preset ON preset_files(preset)');
|
|
208
|
-
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
209
|
-
try {
|
|
210
|
-
for(var _iterator = (0, _indexts.activeFeatures)(cfg)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
211
|
-
var feature = _step.value;
|
|
212
|
-
feature.schema(db);
|
|
213
|
-
}
|
|
214
|
-
} catch (err) {
|
|
215
|
-
_didIteratorError = true;
|
|
216
|
-
_iteratorError = err;
|
|
217
|
-
} finally{
|
|
218
|
-
try {
|
|
219
|
-
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
220
|
-
_iterator.return();
|
|
221
|
-
}
|
|
222
|
-
} finally{
|
|
223
|
-
if (_didIteratorError) {
|
|
224
|
-
throw _iteratorError;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
if (getMeta(db, 'schema_version') === null) setMeta(db, 'schema_version', SCHEMA_VERSION);
|
|
229
|
-
if (getMeta(db, 'features') === null) setMeta(db, 'features', (0, _configts.featureSignature)(cfg));
|
|
230
|
-
}
|
|
231
|
-
function getMeta(db, key) {
|
|
232
|
-
var row = db.prepare('SELECT value FROM meta WHERE key = ?').get(key);
|
|
233
|
-
return row ? row.value : null;
|
|
234
|
-
}
|
|
235
|
-
function setMeta(db, key, value) {
|
|
236
|
-
if (value === null) {
|
|
237
|
-
db.prepare('DELETE FROM meta WHERE key = ?').run(key);
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
db.prepare('INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value').run(key, value);
|
|
241
|
-
}
|
|
242
101
|
// Shared by reconcile() and the tokenize-only rebuild in open(), so both prepare the same
|
|
243
102
|
// literal instead of two copies drifting apart.
|
|
244
103
|
var INSERT_CONTENT_SQL = 'INSERT INTO content (rowid, title, summary, text, "path", title_seg, summary_seg, text_seg) VALUES ((SELECT rowid FROM frontmatter WHERE "path" = ?), ?, ?, ?, ?, ?, ?, ?)';
|
|
@@ -247,10 +106,6 @@ var INSERT_CONTENT_SQL = 'INSERT INTO content (rowid, title, summary, text, "pat
|
|
|
247
106
|
function insertContentRow(insertBody, doc, segmenting) {
|
|
248
107
|
insertBody.run(doc.relPath, doc.search.title, doc.search.summary, doc.search.text, doc.relPath, segmenting ? (0, _segmentts.segmentField)(doc.search.title) : '', segmenting ? (0, _segmentts.segmentField)(doc.search.summary) : '', segmenting ? (0, _segmentts.segmentField)(doc.search.text) : '');
|
|
249
108
|
}
|
|
250
|
-
function docCount(db) {
|
|
251
|
-
var row = db.prepare('SELECT COUNT(*) AS n FROM frontmatter').get();
|
|
252
|
-
return row.n;
|
|
253
|
-
}
|
|
254
109
|
function reconcile(db, cfg, baseDir) {
|
|
255
110
|
var files = (0, _scants.listFiles)(cfg, baseDir);
|
|
256
111
|
var currentSet = new Set(files.map(function(f) {
|
|
@@ -276,8 +131,8 @@ function reconcile(db, cfg, baseDir) {
|
|
|
276
131
|
parsed: 0,
|
|
277
132
|
warnings: []
|
|
278
133
|
};
|
|
279
|
-
var features = (0,
|
|
280
|
-
var seenColumns = getColumns(db);
|
|
134
|
+
var features = (0, _indexts1.activeFeatures)(cfg);
|
|
135
|
+
var seenColumns = (0, _sharedts.getColumns)(db);
|
|
281
136
|
var newColumns = [];
|
|
282
137
|
var parsedDocs = [];
|
|
283
138
|
var warnings = [];
|
|
@@ -352,12 +207,12 @@ function reconcile(db, cfg, baseDir) {
|
|
|
352
207
|
});
|
|
353
208
|
// ON CONFLICT UPDATE (not OR REPLACE) keeps the row's rowid stable across reparses --
|
|
354
209
|
// content rows are coupled to that rowid below.
|
|
355
|
-
var insertSql = "INSERT INTO frontmatter (".concat(writableColumns.map(quoteIdent).join(', '), ") VALUES (").concat(writableColumns.map(function() {
|
|
210
|
+
var insertSql = "INSERT INTO frontmatter (".concat(writableColumns.map(_sharedts.quoteIdent).join(', '), ") VALUES (").concat(writableColumns.map(function() {
|
|
356
211
|
return '?';
|
|
357
212
|
}).join(', '), ') ON CONFLICT("path") DO UPDATE SET ').concat(writableColumns.filter(function(c) {
|
|
358
213
|
return c !== 'path';
|
|
359
214
|
}).map(function(c) {
|
|
360
|
-
return "".concat(quoteIdent(c), " = excluded.").concat(quoteIdent(c));
|
|
215
|
+
return "".concat((0, _sharedts.quoteIdent)(c), " = excluded.").concat((0, _sharedts.quoteIdent)(c));
|
|
361
216
|
}).join(', '));
|
|
362
217
|
var added = toReparse.filter(function(f) {
|
|
363
218
|
return !existing.has(f.relPath);
|
|
@@ -380,7 +235,7 @@ function reconcile(db, cfg, baseDir) {
|
|
|
380
235
|
try {
|
|
381
236
|
for(var _iterator1 = newColumns[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
382
237
|
var col = _step1.value;
|
|
383
|
-
db.exec("ALTER TABLE frontmatter ADD COLUMN ".concat(quoteIdent(col)));
|
|
238
|
+
db.exec("ALTER TABLE frontmatter ADD COLUMN ".concat((0, _sharedts.quoteIdent)(col)));
|
|
384
239
|
}
|
|
385
240
|
} catch (err) {
|
|
386
241
|
_didIteratorError1 = true;
|
|
@@ -455,7 +310,7 @@ function reconcile(db, cfg, baseDir) {
|
|
|
455
310
|
var insertBody = db.prepare(INSERT_CONTENT_SQL);
|
|
456
311
|
// A non-default tokenizer means the tree has chosen its own scheme; a phrase query over
|
|
457
312
|
// grapheme runs would be nonsense against trigram, so the sidecars stay empty.
|
|
458
|
-
var segmenting = (0,
|
|
313
|
+
var segmenting = (0, _indexts.contentTokenize)(cfg) === undefined;
|
|
459
314
|
var _iteratorNormalCompletion4 = true, _didIteratorError4 = false, _iteratorError4 = undefined;
|
|
460
315
|
try {
|
|
461
316
|
var _loop1 = function() {
|
|
@@ -467,6 +322,7 @@ function reconcile(db, cfg, baseDir) {
|
|
|
467
322
|
var _doc_data_col;
|
|
468
323
|
if (col === 'path') return doc.relPath;
|
|
469
324
|
if (col === '_mtime') return doc.mtimeMs;
|
|
325
|
+
if (col === '_ctime') return doc.ctimeMs;
|
|
470
326
|
if (col === '_size') return doc.size;
|
|
471
327
|
// Written per parse, unlike _rank, which a feature pass owns and the upsert skips.
|
|
472
328
|
if (col === '_parse_error') return doc.parseError;
|
|
@@ -587,18 +443,16 @@ function reconcile(db, cfg, baseDir) {
|
|
|
587
443
|
// Reconcile's own write-transaction duration, for open()'s derived busy_timeout (F):
|
|
588
444
|
// keep the observed max so a big watcher reconcile's lock hold is what the next open bounds its wait against.
|
|
589
445
|
var durationMs = Date.now() - txStart;
|
|
590
|
-
var prevRaw = getMeta(db, 'reconcile_max_ms');
|
|
446
|
+
var prevRaw = (0, _sharedts.getMeta)(db, 'reconcile_max_ms');
|
|
591
447
|
// -1, not 0, so a genuinely 0ms first reconcile (sub-millisecond, common on a tiny tree)
|
|
592
448
|
// still gets recorded instead of losing to the "nothing recorded yet" default.
|
|
593
449
|
var prevMax = prevRaw === null ? -1 : Number(prevRaw);
|
|
594
|
-
if (durationMs > prevMax) setMeta(db, 'reconcile_max_ms', String(durationMs));
|
|
450
|
+
if (durationMs > prevMax) (0, _sharedts.setMeta)(db, 'reconcile_max_ms', String(durationMs));
|
|
595
451
|
return {
|
|
596
452
|
parsed: parsedDocs.length,
|
|
597
453
|
warnings: warnings
|
|
598
454
|
};
|
|
599
455
|
}
|
|
600
|
-
// Segment keys that moved between two feature signatures (see config.featureSignature's
|
|
601
|
-
// format: global features, embed provider, tokenize, then one segment per preset).
|
|
602
456
|
function changedSignatureKeys(before, after) {
|
|
603
457
|
var keyOf = function keyOf(part) {
|
|
604
458
|
return part.startsWith('preset:') ? part.split(':').slice(0, 2).join(':') : part.split(':')[0];
|
|
@@ -656,7 +510,6 @@ function changedSignatureKeys(before, after) {
|
|
|
656
510
|
}
|
|
657
511
|
return changed;
|
|
658
512
|
}
|
|
659
|
-
// Names what moved, for the rebuild notice.
|
|
660
513
|
function signatureDiff(before, after) {
|
|
661
514
|
var changed = changedSignatureKeys(before, after);
|
|
662
515
|
var label = function label(key) {
|
|
@@ -664,12 +517,6 @@ function signatureDiff(before, after) {
|
|
|
664
517
|
};
|
|
665
518
|
return changed.size === 0 ? 'features' : _to_consumable_array(changed).map(label).join(', ');
|
|
666
519
|
}
|
|
667
|
-
// The tokenize-only rebuild in open(): content is dropped and repopulated from files already
|
|
668
|
-
// listed in frontmatter, which itself is untouched. Frontmatter, links, sections, and
|
|
669
|
-
// embeddings are file-derived and tokenizer-independent, so they survive. No feature extractors
|
|
670
|
-
// run here -- doc.search (title/summary/text) is all content population needs. Returns
|
|
671
|
-
// parseFile's per-file warnings (e.g. a bad date) so open() can surface them -- mtimes are
|
|
672
|
-
// untouched, so reconcile() never reparses these files and would otherwise never emit them again.
|
|
673
520
|
function rebuildContentTable(db, cfg, baseDir) {
|
|
674
521
|
var known = new Set(db.prepare('SELECT "path" FROM frontmatter').all().map(function(r) {
|
|
675
522
|
return r.path;
|
|
@@ -677,7 +524,7 @@ function rebuildContentTable(db, cfg, baseDir) {
|
|
|
677
524
|
var files = (0, _scants.listFiles)(cfg, baseDir).filter(function(f) {
|
|
678
525
|
return known.has(f.relPath);
|
|
679
526
|
});
|
|
680
|
-
var segmenting = (0,
|
|
527
|
+
var segmenting = (0, _indexts.contentTokenize)(cfg) === undefined;
|
|
681
528
|
var insertBody = db.prepare(INSERT_CONTENT_SQL);
|
|
682
529
|
var warnings = [];
|
|
683
530
|
db.exec('BEGIN');
|
|
@@ -712,88 +559,4 @@ function rebuildContentTable(db, cfg, baseDir) {
|
|
|
712
559
|
}
|
|
713
560
|
return warnings;
|
|
714
561
|
}
|
|
715
|
-
function open(cfg) {
|
|
716
|
-
var _getMeta;
|
|
717
|
-
var stateDir = (0, _nodepath.join)(cfg.baseDir, _configts.STATE_DIR);
|
|
718
|
-
(0, _nodefs.mkdirSync)(stateDir, {
|
|
719
|
-
recursive: true
|
|
720
|
-
});
|
|
721
|
-
var dbPath = (0, _nodepath.join)(stateDir, DB_FILENAME);
|
|
722
|
-
var db = new _nodesqlite.DatabaseSync(dbPath);
|
|
723
|
-
db.exec('PRAGMA journal_mode = WAL');
|
|
724
|
-
// Covers a concurrent watcher's bulk reconcile (~5s for 500 files at 26k notes). A query
|
|
725
|
-
// that outwaits it still fails loudly.
|
|
726
|
-
db.exec('PRAGMA busy_timeout = 30000');
|
|
727
|
-
registerFunctions(db, (0, _configts.contentTokenize)(cfg) === undefined);
|
|
728
|
-
db.exec('CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT)');
|
|
729
|
-
// Before the rebuild branch below, never after: that branch deletes the cache, so a typo'd
|
|
730
|
-
// tokenizer validated later would cost a full re-index (and re-embed) to reach its own error.
|
|
731
|
-
var tokenize = resolveTokenize(db, cfg);
|
|
732
|
-
// Schema-version or feature-set mismatch: reconcile only reparses changed files, so an
|
|
733
|
-
// old cache can't be patched incrementally -- rebuild instead (cheap: nothing expensive lives here).
|
|
734
|
-
var version = getMeta(db, 'schema_version');
|
|
735
|
-
var features = getMeta(db, 'features');
|
|
736
|
-
var wantFeatures = (0, _configts.featureSignature)(cfg);
|
|
737
|
-
var tokenizeOnlyRebuild = false;
|
|
738
|
-
if (version !== null && version !== SCHEMA_VERSION || features !== null && features !== wantFeatures) {
|
|
739
|
-
// Indexing derives from presets, so a config edit rebuilding the cache must say so and
|
|
740
|
-
// name what changed -- silent rebuilds make derived indexing look like a hang or a bug.
|
|
741
|
-
if (version !== null && version !== SCHEMA_VERSION) {
|
|
742
|
-
console.error('sense: cache format changed (new sensemaking version); rebuilding the index');
|
|
743
|
-
db.close();
|
|
744
|
-
clearCache(cfg);
|
|
745
|
-
return open(cfg);
|
|
746
|
-
}
|
|
747
|
-
var changedKeys = changedSignatureKeys(features !== null && features !== void 0 ? features : '', wantFeatures);
|
|
748
|
-
// Only the tokenizer moved: frontmatter, links, sections, and embeddings are file-derived
|
|
749
|
-
// and tokenizer-independent, so they don't need re-deriving. Everything else -- a preset
|
|
750
|
-
// edit, an embed model change -- still takes the full clear/reopen below.
|
|
751
|
-
if (changedKeys.size === 1 && changedKeys.has('tokenize')) {
|
|
752
|
-
console.error('sense: config change (content tokenizer) rebuilds the text index; vectors, links, and sections are kept');
|
|
753
|
-
db.exec('DROP TABLE content');
|
|
754
|
-
tokenizeOnlyRebuild = true;
|
|
755
|
-
} else {
|
|
756
|
-
var changed = signatureDiff(features !== null && features !== void 0 ? features : '', wantFeatures);
|
|
757
|
-
console.error("sense: config change (".concat(changed, ") rebuilds the index"));
|
|
758
|
-
db.close();
|
|
759
|
-
clearCache(cfg);
|
|
760
|
-
return open(cfg);
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
// Meta can lie after a crash between table creation and the signature write; the table's
|
|
764
|
-
// own DDL cannot. A mismatch here rebuilds no matter what meta says. A tokenize-only rebuild
|
|
765
|
-
// just dropped content above, so storedTokenize sees no table and this guard is skipped
|
|
766
|
-
// naturally rather than needing its own case.
|
|
767
|
-
var stored = storedTokenize(db);
|
|
768
|
-
if (stored !== null && stored !== tokenize) {
|
|
769
|
-
console.error('sense: cache was built with a different content tokenizer; rebuilding the index');
|
|
770
|
-
db.close();
|
|
771
|
-
clearCache(cfg);
|
|
772
|
-
return open(cfg);
|
|
773
|
-
}
|
|
774
|
-
ensureSchema(db, cfg, tokenize);
|
|
775
|
-
var rebuildWarnings = [];
|
|
776
|
-
if (tokenizeOnlyRebuild) {
|
|
777
|
-
rebuildWarnings = rebuildContentTable(db, cfg, cfg.baseDir);
|
|
778
|
-
setMeta(db, 'features', wantFeatures);
|
|
779
|
-
}
|
|
780
|
-
// 3x the largest reconcile this cache has recorded, floored at 30s and capped at 10min.
|
|
781
|
-
// Installed before reconcile() -- that call is the one that races a watcher's transaction.
|
|
782
|
-
var recordedMaxMs = Number((_getMeta = getMeta(db, 'reconcile_max_ms')) !== null && _getMeta !== void 0 ? _getMeta : '0');
|
|
783
|
-
db.exec("PRAGMA busy_timeout = ".concat(Math.min(Math.max(30000, 3 * recordedMaxMs), 600000)));
|
|
784
|
-
var _reconcile = reconcile(db, cfg, cfg.baseDir), parsed = _reconcile.parsed, warnings = _reconcile.warnings;
|
|
785
|
-
return {
|
|
786
|
-
db: db,
|
|
787
|
-
cfg: cfg,
|
|
788
|
-
dbPath: dbPath,
|
|
789
|
-
parsed: parsed,
|
|
790
|
-
warnings: _to_consumable_array(rebuildWarnings).concat(_to_consumable_array(warnings))
|
|
791
|
-
};
|
|
792
|
-
}
|
|
793
|
-
function clearCache(cfg) {
|
|
794
|
-
(0, _nodefs.rmSync)((0, _nodepath.join)(cfg.baseDir, _configts.STATE_DIR), {
|
|
795
|
-
recursive: true,
|
|
796
|
-
force: true
|
|
797
|
-
});
|
|
798
|
-
}
|
|
799
562
|
/* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/db/reconcile.ts"],"sourcesContent":["import type { DatabaseSync, StatementSync } from 'node:sqlite';\nimport type { Config } from '../config/index.ts';\nimport { contentTokenize } from '../config/index.ts';\nimport { SenseError } from '../errors.ts';\nimport { activeFeatures } from '../features/index.ts';\nimport type { ReconcileDelta } from '../features/types.ts';\nimport { progress } from '../progress.ts';\nimport type { ParsedDoc } from '../scan.ts';\nimport { listFiles, parseFile, RESERVED_COLUMNS } from '../scan.ts';\nimport { segmentField } from '../segment.ts';\nimport { getColumns, getMeta, quoteIdent, setMeta } from './shared.ts';\n\n// Feature-owned columns (`_rank`) must stay out of the upsert: a reparse would null the last\n// computed value on every touch, not just the reconciles that recompute it.\nconst CORE_FRONTMATTER_COLUMNS = new Set(['path', '_mtime', '_ctime', '_size', '_parse_error']);\n\n// SQLite's compile-time SQLITE_MAX_COLUMN, default 2000 (https://www.sqlite.org/limits.html).\nconst MAX_FRONTMATTER_COLUMNS = 2000;\n\n// Shared by reconcile() and the tokenize-only rebuild in open(), so both prepare the same\n// literal instead of two copies drifting apart.\nconst INSERT_CONTENT_SQL = `INSERT INTO content (rowid, title, summary, text, \"path\", title_seg, summary_seg, text_seg) VALUES ((SELECT rowid FROM frontmatter WHERE \"path\" = ?), ?, ?, ?, ?, ?, ?, ?)`;\n\n// Shared by reconcile() and the tokenize-only rebuild in open(), so content population is\n// defined once. Assumes the frontmatter row for doc.relPath already exists (rowid lookup).\nfunction insertContentRow(insertBody: StatementSync, doc: ParsedDoc, segmenting: boolean): void {\n insertBody.run(doc.relPath, doc.search.title, doc.search.summary, doc.search.text, doc.relPath, segmenting ? segmentField(doc.search.title) : '', segmenting ? segmentField(doc.search.summary) : '', segmenting ? segmentField(doc.search.text) : '');\n}\n\nexport function reconcile(db: DatabaseSync, cfg: Config, baseDir: string): { parsed: number; warnings: string[] } {\n const files = listFiles(cfg, baseDir);\n const currentSet = new Set(files.map((f) => f.relPath));\n\n const existingRows = db.prepare(`SELECT \"path\", \"_mtime\", \"_size\" FROM frontmatter`).all() as Array<{\n path: string;\n _mtime: number;\n _size: number;\n }>;\n const existing = new Map(existingRows.map((r) => [r.path, r]));\n const vanished = existingRows.filter((r) => !currentSet.has(r.path)).map((r) => r.path);\n\n const toReparse = files.filter((f) => {\n const row = existing.get(f.relPath);\n return !row || row._mtime !== f.mtimeMs || row._size !== f.size;\n });\n\n if (vanished.length === 0 && toReparse.length === 0) return { parsed: 0, warnings: [] };\n\n const features = activeFeatures(cfg);\n const seenColumns = getColumns(db);\n const newColumns: string[] = [];\n const parsedDocs: ParsedDoc[] = [];\n const warnings: string[] = [];\n\n // Bulk reparses (a sync, a cold build) are the long silences a query can hit; short\n // reconciles stay silent (progress() has a threshold).\n const report = progress('reparsing files', toReparse.length);\n let parsedCount = 0;\n for (const file of toReparse) {\n // A doc only gets extract/store from features that apply to it (currently: embed, via\n // FileStat.embed -- true iff the config names an embedding model).\n const fileFeatures = features.filter((feature) => !feature.enabledForFile || feature.enabledForFile(cfg, file));\n const { doc, warnings: fileWarnings } = parseFile(file, fileFeatures);\n report.tick(++parsedCount);\n warnings.push(...fileWarnings);\n for (const key of Object.keys(doc.data)) {\n if (!seenColumns.has(key)) {\n seenColumns.add(key);\n newColumns.push(key);\n }\n }\n parsedDocs.push(doc);\n }\n report.finish();\n\n const allColumns = [...seenColumns];\n // Fence before ALTERing: SQLite's own failure past this point is a raw\n // \"too many columns on sqlite_altertab_frontmatter\" with no indication of the boundary or the levers.\n if (allColumns.length > MAX_FRONTMATTER_COLUMNS) {\n throw new SenseError(\n 'COLUMN_LIMIT',\n `frontmatter would need ${allColumns.length} columns, crossing SQLite's compile-time SQLITE_MAX_COLUMN limit (default ${MAX_FRONTMATTER_COLUMNS}; see https://www.sqlite.org/limits.html). Narrow the presets' include globs so fewer/other files are indexed, or fix whatever is generating unbounded frontmatter keys.`\n );\n }\n // Columns the frontmatter upsert actually writes: core + parsed frontmatter keys, never a\n // feature-owned reserved column (see CORE_FRONTMATTER_COLUMNS above).\n const writableColumns = allColumns.filter((c) => CORE_FRONTMATTER_COLUMNS.has(c) || !RESERVED_COLUMNS.has(c));\n // ON CONFLICT UPDATE (not OR REPLACE) keeps the row's rowid stable across reparses --\n // content rows are coupled to that rowid below.\n const insertSql = `INSERT INTO frontmatter (${writableColumns.map(quoteIdent).join(', ')}) VALUES (${writableColumns.map(() => '?').join(', ')}) ON CONFLICT(\"path\") DO UPDATE SET ${writableColumns\n .filter((c) => c !== 'path')\n .map((c) => `${quoteIdent(c)} = excluded.${quoteIdent(c)}`)\n .join(', ')}`;\n\n const added = toReparse.filter((f) => !existing.has(f.relPath)).map((f) => f.relPath);\n const delta: ReconcileDelta = { files, reparsed: parsedDocs.map((d) => d.relPath), added, vanished };\n\n const txStart = Date.now();\n db.exec('BEGIN');\n try {\n for (const col of newColumns) db.exec(`ALTER TABLE frontmatter ADD COLUMN ${quoteIdent(col)}`);\n // FTS5 has no upsert, so delete-before-insert into `content`; coupled to the\n // frontmatter rowid (indexed via its PRIMARY KEY) instead of the UNINDEXED `path`\n // column, which a per-row DELETE would otherwise scan the whole table to find.\n const delBody = db.prepare(`DELETE FROM content WHERE rowid = (SELECT rowid FROM frontmatter WHERE \"path\" = ?)`);\n const delPresetFiles = db.prepare(`DELETE FROM preset_files WHERE \"path\" = ?`);\n const insertPresetFile = db.prepare(`INSERT INTO preset_files (\"path\", preset) VALUES (?, ?)`);\n if (vanished.length > 0) {\n const del = db.prepare(`DELETE FROM frontmatter WHERE \"path\" = ?`);\n for (const path of vanished) {\n // content delete must run first: it looks up the frontmatter rowid by path, which\n // the frontmatter delete below would otherwise have already removed.\n delBody.run(path);\n del.run(path);\n delPresetFiles.run(path);\n for (const feature of features) feature.remove?.(db, path, delta);\n }\n }\n if (parsedDocs.length > 0) {\n const insert = db.prepare(insertSql);\n const insertBody = db.prepare(INSERT_CONTENT_SQL);\n // A non-default tokenizer means the tree has chosen its own scheme; a phrase query over\n // grapheme runs would be nonsense against trigram, so the sidecars stay empty.\n const segmenting = contentTokenize(cfg) === undefined;\n for (const doc of parsedDocs) {\n const values = writableColumns.map((col) => {\n if (col === 'path') return doc.relPath;\n if (col === '_mtime') return doc.mtimeMs;\n if (col === '_ctime') return doc.ctimeMs;\n if (col === '_size') return doc.size;\n // Written per parse, unlike _rank, which a feature pass owns and the upsert skips.\n if (col === '_parse_error') return doc.parseError;\n return doc.data[col] ?? null;\n });\n // Frontmatter upsert first: content's rowid lookup below depends on this row existing.\n insert.run(...values);\n // Only for docs that have rows: an unconditional delete made cold crawls quadratic.\n if (existing.has(doc.relPath)) {\n delBody.run(doc.relPath);\n for (const feature of features) feature.remove?.(db, doc.relPath, delta);\n }\n insertContentRow(insertBody, doc, segmenting);\n // A preset edit forces a full rebuild, so an unchanged doc's coverage is already\n // correct; new docs have nothing to clear, which keeps cold builds linear.\n if (existing.has(doc.relPath)) delPresetFiles.run(doc.relPath);\n for (const presetName of doc.presets) insertPresetFile.run(doc.relPath, presetName);\n for (const feature of features) feature.store?.(db, doc.relPath, doc.extracted[feature.name], delta);\n }\n }\n for (const feature of features) feature.afterReconcile?.(db, delta);\n db.exec('COMMIT');\n } catch (err) {\n db.exec('ROLLBACK');\n throw err;\n }\n\n // Reconcile's own write-transaction duration, for open()'s derived busy_timeout (F):\n // keep the observed max so a big watcher reconcile's lock hold is what the next open bounds its wait against.\n const durationMs = Date.now() - txStart;\n const prevRaw = getMeta(db, 'reconcile_max_ms');\n // -1, not 0, so a genuinely 0ms first reconcile (sub-millisecond, common on a tiny tree)\n // still gets recorded instead of losing to the \"nothing recorded yet\" default.\n const prevMax = prevRaw === null ? -1 : Number(prevRaw);\n if (durationMs > prevMax) setMeta(db, 'reconcile_max_ms', String(durationMs));\n\n return { parsed: parsedDocs.length, warnings };\n}\n\n// Segment keys that moved between two feature signatures (see config.featureSignature's\n// format: global features, embed provider, tokenize, then one segment per preset).\nexport function changedSignatureKeys(before: string, after: string): Set<string> {\n const keyOf = (part: string) => (part.startsWith('preset:') ? part.split(':').slice(0, 2).join(':') : part.split(':')[0]);\n const parse = (sig: string) => new Map(sig.split('|').map((part) => [keyOf(part), part]));\n const a = parse(before);\n const b = parse(after);\n const changed = new Set<string>();\n for (const [key, val] of b) if (a.get(key) !== val) changed.add(key);\n for (const key of a.keys()) if (!b.has(key)) changed.add(key);\n return changed;\n}\n\n// Names what moved, for the rebuild notice.\nexport function signatureDiff(before: string, after: string): string {\n const changed = changedSignatureKeys(before, after);\n const label = (key: string) => (key === 'embed' ? 'embed settings' : key === 'tokenize' ? 'content tokenizer' : key.startsWith('preset:') ? `preset \"${key.slice(7)}\"` : 'features');\n return changed.size === 0 ? 'features' : [...changed].map(label).join(', ');\n}\n\n// The tokenize-only rebuild in open(): content is dropped and repopulated from files already\n// listed in frontmatter, which itself is untouched. Frontmatter, links, sections, and\n// embeddings are file-derived and tokenizer-independent, so they survive. No feature extractors\n// run here -- doc.search (title/summary/text) is all content population needs. Returns\n// parseFile's per-file warnings (e.g. a bad date) so open() can surface them -- mtimes are\n// untouched, so reconcile() never reparses these files and would otherwise never emit them again.\nexport function rebuildContentTable(db: DatabaseSync, cfg: Config, baseDir: string): string[] {\n const known = new Set((db.prepare('SELECT \"path\" FROM frontmatter').all() as Array<{ path: string }>).map((r) => r.path));\n const files = listFiles(cfg, baseDir).filter((f) => known.has(f.relPath));\n const segmenting = contentTokenize(cfg) === undefined;\n const insertBody = db.prepare(INSERT_CONTENT_SQL);\n const warnings: string[] = [];\n db.exec('BEGIN');\n try {\n for (const file of files) {\n const { doc, warnings: fileWarnings } = parseFile(file);\n warnings.push(...fileWarnings);\n insertContentRow(insertBody, doc, segmenting);\n }\n db.exec('COMMIT');\n } catch (err) {\n db.exec('ROLLBACK');\n throw err;\n }\n return warnings;\n}\n"],"names":["changedSignatureKeys","rebuildContentTable","reconcile","signatureDiff","CORE_FRONTMATTER_COLUMNS","Set","MAX_FRONTMATTER_COLUMNS","INSERT_CONTENT_SQL","insertContentRow","insertBody","doc","segmenting","run","relPath","search","title","summary","text","segmentField","db","cfg","baseDir","files","listFiles","currentSet","map","f","existingRows","prepare","all","existing","Map","r","path","vanished","filter","has","toReparse","row","get","_mtime","mtimeMs","_size","size","length","parsed","warnings","features","activeFeatures","seenColumns","getColumns","newColumns","parsedDocs","report","progress","parsedCount","file","fileFeatures","feature","enabledForFile","parseFile","fileWarnings","tick","push","Object","keys","data","key","add","finish","allColumns","SenseError","writableColumns","c","RESERVED_COLUMNS","insertSql","quoteIdent","join","added","delta","reparsed","d","txStart","Date","now","exec","col","delBody","delPresetFiles","insertPresetFile","del","remove","insert","contentTokenize","undefined","values","ctimeMs","parseError","presets","presetName","store","extracted","name","afterReconcile","err","durationMs","prevRaw","getMeta","prevMax","Number","setMeta","String","before","after","keyOf","part","startsWith","split","slice","parse","sig","a","b","changed","val","label","known"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
export declare function quoteIdent(name: string): string;
|
|
3
|
+
export declare function getColumns(db: DatabaseSync): Set<string>;
|
|
4
|
+
export declare function getMeta(db: DatabaseSync, key: string): string | null;
|
|
5
|
+
export declare function setMeta(db: DatabaseSync, key: string, value: string | null): void;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
export declare function quoteIdent(name: string): string;
|
|
3
|
+
export declare function getColumns(db: DatabaseSync): Set<string>;
|
|
4
|
+
export declare function getMeta(db: DatabaseSync, key: string): string | null;
|
|
5
|
+
export declare function setMeta(db: DatabaseSync, key: string, value: string | null): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get getColumns () {
|
|
13
|
+
return getColumns;
|
|
14
|
+
},
|
|
15
|
+
get getMeta () {
|
|
16
|
+
return getMeta;
|
|
17
|
+
},
|
|
18
|
+
get quoteIdent () {
|
|
19
|
+
return quoteIdent;
|
|
20
|
+
},
|
|
21
|
+
get setMeta () {
|
|
22
|
+
return setMeta;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
function quoteIdent(name) {
|
|
26
|
+
return '"'.concat(name.split('"').join('""'), '"');
|
|
27
|
+
}
|
|
28
|
+
function getColumns(db) {
|
|
29
|
+
var rows = db.prepare('PRAGMA table_info(frontmatter)').all();
|
|
30
|
+
return new Set(rows.map(function(r) {
|
|
31
|
+
return r.name;
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
function getMeta(db, key) {
|
|
35
|
+
var row = db.prepare('SELECT value FROM meta WHERE key = ?').get(key);
|
|
36
|
+
return row ? row.value : null;
|
|
37
|
+
}
|
|
38
|
+
function setMeta(db, key, value) {
|
|
39
|
+
if (value === null) {
|
|
40
|
+
db.prepare('DELETE FROM meta WHERE key = ?').run(key);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
db.prepare('INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value').run(key, value);
|
|
44
|
+
}
|
|
45
|
+
/* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/db/shared.ts"],"sourcesContent":["import type { DatabaseSync } from 'node:sqlite';\n\n// SQL and meta-table primitives both open() and reconcile() need, kept below both so\n// neither imports the other's module.\n\nexport function quoteIdent(name: string): string {\n return `\"${name.split('\"').join('\"\"')}\"`;\n}\n\nexport function getColumns(db: DatabaseSync): Set<string> {\n const rows = db.prepare('PRAGMA table_info(frontmatter)').all() as Array<{ name: string }>;\n return new Set(rows.map((r) => r.name));\n}\n\nexport function getMeta(db: DatabaseSync, key: string): string | null {\n const row = db.prepare('SELECT value FROM meta WHERE key = ?').get(key) as { value: string } | undefined;\n return row ? row.value : null;\n}\n\nexport function setMeta(db: DatabaseSync, key: string, value: string | null): void {\n if (value === null) {\n db.prepare('DELETE FROM meta WHERE key = ?').run(key);\n return;\n }\n db.prepare('INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value').run(key, value);\n}\n"],"names":["getColumns","getMeta","quoteIdent","setMeta","name","split","join","db","rows","prepare","all","Set","map","r","key","row","get","value","run"],"mappings":";;;;;;;;;;;QASgBA;eAAAA;;QAKAC;eAAAA;;QATAC;eAAAA;;QAcAC;eAAAA;;;AAdT,SAASD,WAAWE,IAAY;IACrC,OAAO,AAAC,IAA8B,OAA3BA,KAAKC,KAAK,CAAC,KAAKC,IAAI,CAAC,OAAM;AACxC;AAEO,SAASN,WAAWO,EAAgB;IACzC,IAAMC,OAAOD,GAAGE,OAAO,CAAC,kCAAkCC,GAAG;IAC7D,OAAO,IAAIC,IAAIH,KAAKI,GAAG,CAAC,SAACC;eAAMA,EAAET,IAAI;;AACvC;AAEO,SAASH,QAAQM,EAAgB,EAAEO,GAAW;IACnD,IAAMC,MAAMR,GAAGE,OAAO,CAAC,wCAAwCO,GAAG,CAACF;IACnE,OAAOC,MAAMA,IAAIE,KAAK,GAAG;AAC3B;AAEO,SAASd,QAAQI,EAAgB,EAAEO,GAAW,EAAEG,KAAoB;IACzE,IAAIA,UAAU,MAAM;QAClBV,GAAGE,OAAO,CAAC,kCAAkCS,GAAG,CAACJ;QACjD;IACF;IACAP,GAAGE,OAAO,CAAC,qGAAqGS,GAAG,CAACJ,KAAKG;AAC3H"}
|
|
@@ -46,7 +46,7 @@ _export(exports, {
|
|
|
46
46
|
var _nodefs = require("node:fs");
|
|
47
47
|
var _nodeos = require("node:os");
|
|
48
48
|
var _nodepath = require("node:path");
|
|
49
|
-
var
|
|
49
|
+
var _indexts = require("../config/index.js");
|
|
50
50
|
var _errorsts = require("../errors.js");
|
|
51
51
|
var _progressts = require("../progress.js");
|
|
52
52
|
var _scants = require("../scan.js");
|
|
@@ -399,7 +399,7 @@ function hasModelFiles(model) {
|
|
|
399
399
|
});
|
|
400
400
|
}
|
|
401
401
|
function modelPresent(cfg) {
|
|
402
|
-
var e = (0,
|
|
402
|
+
var e = (0, _indexts.embedConfig)(cfg);
|
|
403
403
|
if (!e) return false;
|
|
404
404
|
return e.type === 'api' || hasModelFiles(e.model);
|
|
405
405
|
}
|
|
@@ -707,7 +707,7 @@ function apiProvider(model, url, keyEnv) {
|
|
|
707
707
|
var providers = new Map();
|
|
708
708
|
function getProvider(cfg) {
|
|
709
709
|
var _e_url;
|
|
710
|
-
var e = (0,
|
|
710
|
+
var e = (0, _indexts.embedConfig)(cfg);
|
|
711
711
|
if (!e) throw new _errorsts.SenseError('EMBED_DISABLED', 'this tree has no embedding model: add an "embed" block naming one to sense.config.json, then run `sense download`');
|
|
712
712
|
var sig = "".concat(e.type, ":").concat(e.model, ":").concat((_e_url = e.url) !== null && _e_url !== void 0 ? _e_url : '');
|
|
713
713
|
var p = providers.get(sig);
|
|
@@ -823,6 +823,7 @@ function embedPending(db, cfg, baseDir) {
|
|
|
823
823
|
relPath: path,
|
|
824
824
|
absPath: (0, _nodepath.join)(baseDir, path),
|
|
825
825
|
mtimeMs: 0,
|
|
826
|
+
ctimeMs: 0,
|
|
826
827
|
size: 0,
|
|
827
828
|
presets: [],
|
|
828
829
|
embed: true
|