sensemaking 0.25.1 → 0.27.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/README.md +48 -12
- package/dist/cjs/cli/index.d.cts +3 -3
- package/dist/cjs/cli/index.d.ts +3 -3
- package/dist/cjs/cli/index.js +3 -3
- package/dist/cjs/cli/index.js.map +1 -1
- package/dist/cjs/cli/path.js +5 -29
- package/dist/cjs/cli/path.js.map +1 -1
- package/dist/cjs/cli/peek.js +43 -2
- package/dist/cjs/cli/peek.js.map +1 -1
- package/dist/cjs/cli/related.js +4 -3
- package/dist/cjs/cli/related.js.map +1 -1
- package/dist/cjs/cli/search.js +38 -6
- package/dist/cjs/cli/search.js.map +1 -1
- package/dist/cjs/commands/index.d.cts +6 -3
- package/dist/cjs/commands/index.d.ts +6 -3
- package/dist/cjs/commands/index.js +4 -0
- package/dist/cjs/commands/index.js.map +1 -1
- package/dist/cjs/commands/map.d.cts +14 -5
- package/dist/cjs/commands/map.d.ts +14 -5
- package/dist/cjs/commands/map.js +42 -35
- package/dist/cjs/commands/map.js.map +1 -1
- package/dist/cjs/commands/path.d.cts +14 -0
- package/dist/cjs/commands/path.d.ts +14 -0
- package/dist/cjs/commands/path.js +209 -0
- package/dist/cjs/commands/path.js.map +1 -0
- package/dist/cjs/commands/peek.d.cts +25 -2
- package/dist/cjs/commands/peek.d.ts +25 -2
- package/dist/cjs/commands/peek.js +131 -50
- package/dist/cjs/commands/peek.js.map +1 -1
- package/dist/cjs/commands/related.d.cts +16 -3
- package/dist/cjs/commands/related.d.ts +16 -3
- package/dist/cjs/commands/related.js +131 -98
- package/dist/cjs/commands/related.js.map +1 -1
- package/dist/cjs/commands/scope.d.cts +1 -0
- package/dist/cjs/commands/scope.d.ts +1 -0
- package/dist/cjs/commands/scope.js +149 -0
- package/dist/cjs/commands/scope.js.map +1 -1
- package/dist/cjs/commands/search.d.cts +30 -3
- package/dist/cjs/commands/search.d.ts +30 -3
- package/dist/cjs/commands/search.js +240 -73
- package/dist/cjs/commands/search.js.map +1 -1
- package/dist/cjs/commands/signals.d.cts +22 -7
- package/dist/cjs/commands/signals.d.ts +22 -7
- package/dist/cjs/commands/signals.js +77 -15
- package/dist/cjs/commands/signals.js.map +1 -1
- package/dist/cjs/commands/snapshot.d.cts +3 -0
- package/dist/cjs/commands/snapshot.d.ts +3 -0
- package/dist/cjs/commands/snapshot.js +180 -0
- package/dist/cjs/commands/snapshot.js.map +1 -0
- package/dist/cjs/config/load.js +6 -0
- package/dist/cjs/config/load.js.map +1 -1
- package/dist/cjs/embed/cohere.js +41 -16
- package/dist/cjs/embed/cohere.js.map +1 -1
- package/dist/cjs/embed/endpoint.d.cts +2 -0
- package/dist/cjs/embed/endpoint.d.ts +2 -0
- package/dist/cjs/embed/endpoint.js +30 -0
- package/dist/cjs/embed/endpoint.js.map +1 -0
- package/dist/cjs/embed/handoff.d.cts +7 -2
- package/dist/cjs/embed/handoff.d.ts +7 -2
- package/dist/cjs/embed/handoff.js +10 -0
- package/dist/cjs/embed/handoff.js.map +1 -1
- package/dist/cjs/embed/http.d.cts +18 -1
- package/dist/cjs/embed/http.d.ts +18 -1
- package/dist/cjs/embed/http.js +239 -40
- package/dist/cjs/embed/http.js.map +1 -1
- package/dist/cjs/embed/openai.js +39 -17
- package/dist/cjs/embed/openai.js.map +1 -1
- package/dist/cjs/embed/query.d.cts +9 -3
- package/dist/cjs/embed/query.d.ts +9 -3
- package/dist/cjs/embed/query.js +257 -90
- package/dist/cjs/embed/query.js.map +1 -1
- package/dist/cjs/embed/registry.d.cts +2 -2
- package/dist/cjs/embed/registry.d.ts +2 -2
- package/dist/cjs/embed/registry.js +36 -4
- package/dist/cjs/embed/registry.js.map +1 -1
- package/dist/cjs/embed/static.js +6 -2
- package/dist/cjs/embed/static.js.map +1 -1
- package/dist/cjs/embed/store.js +42 -77
- package/dist/cjs/embed/store.js.map +1 -1
- package/dist/cjs/embed/types.d.cts +5 -2
- package/dist/cjs/embed/types.d.ts +5 -2
- package/dist/cjs/embed/types.js.map +1 -1
- package/dist/cjs/features/embed.js +290 -43
- package/dist/cjs/features/embed.js.map +1 -1
- package/dist/cjs/graph/traverse.d.cts +2 -2
- package/dist/cjs/graph/traverse.d.ts +2 -2
- package/dist/cjs/graph/traverse.js +15 -5
- package/dist/cjs/graph/traverse.js.map +1 -1
- package/dist/cjs/index.d.cts +2 -2
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/output/output.d.cts +4 -36
- package/dist/cjs/output/output.d.ts +4 -36
- package/dist/cjs/output/output.js +1 -2
- package/dist/cjs/output/output.js.map +1 -1
- package/dist/cjs/scan/pool.d.cts +2 -1
- package/dist/cjs/scan/pool.d.ts +2 -1
- package/dist/cjs/scan/pool.js +116 -27
- package/dist/cjs/scan/pool.js.map +1 -1
- package/dist/cjs/scan/reparse.d.cts +1 -0
- package/dist/cjs/scan/reparse.d.ts +1 -0
- package/dist/cjs/scan/reparse.js +75 -21
- package/dist/cjs/scan/reparse.js.map +1 -1
- package/dist/cjs/store/builder.d.cts +11 -21
- package/dist/cjs/store/builder.d.ts +11 -21
- package/dist/cjs/store/builder.js +1077 -438
- package/dist/cjs/store/builder.js.map +1 -1
- package/dist/cjs/store/duckdb/connection.js +16 -2
- package/dist/cjs/store/duckdb/connection.js.map +1 -1
- package/dist/cjs/store/duckdb/open.d.cts +1 -1
- package/dist/cjs/store/duckdb/open.d.ts +1 -1
- package/dist/cjs/store/duckdb/open.js +73 -65
- package/dist/cjs/store/duckdb/open.js.map +1 -1
- package/dist/cjs/store/duckdb/reconcile.js +533 -15
- package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
- package/dist/cjs/store/embed-scope.js +19 -9
- package/dist/cjs/store/embed-scope.js.map +1 -1
- package/dist/cjs/store/index.d.cts +6 -0
- package/dist/cjs/store/index.d.ts +6 -0
- package/dist/cjs/store/index.js +8 -4
- package/dist/cjs/store/index.js.map +1 -1
- package/dist/cjs/store/open.d.cts +6 -1
- package/dist/cjs/store/open.d.ts +6 -1
- package/dist/cjs/store/open.js +230 -307
- package/dist/cjs/store/open.js.map +1 -1
- package/dist/cjs/store/readiness.d.cts +5 -0
- package/dist/cjs/store/readiness.d.ts +5 -0
- package/dist/cjs/store/readiness.js +39 -0
- package/dist/cjs/store/readiness.js.map +1 -0
- package/dist/cjs/store/reconcile.d.cts +26 -1
- package/dist/cjs/store/reconcile.d.ts +26 -1
- package/dist/cjs/store/reconcile.js +670 -576
- package/dist/cjs/store/reconcile.js.map +1 -1
- package/dist/cjs/store/signature.d.cts +1 -0
- package/dist/cjs/store/signature.d.ts +1 -0
- package/dist/cjs/store/signature.js +9 -0
- package/dist/cjs/store/signature.js.map +1 -1
- package/dist/cjs/store/sqlite/open.d.cts +1 -1
- package/dist/cjs/store/sqlite/open.d.ts +1 -1
- package/dist/cjs/store/sqlite/open.js +84 -90
- package/dist/cjs/store/sqlite/open.js.map +1 -1
- package/dist/cjs/store/sqlite/reconcile.js.map +1 -1
- package/dist/cjs/store/sqlite/store.js +63 -60
- package/dist/cjs/store/sqlite/store.js.map +1 -1
- package/dist/cjs/store/sqlite/vectors.d.cts +2 -2
- package/dist/cjs/store/sqlite/vectors.d.ts +2 -2
- package/dist/cjs/store/sqlite/vectors.js +8 -4
- package/dist/cjs/store/sqlite/vectors.js.map +1 -1
- package/dist/cjs/store/stages.js.map +1 -1
- package/dist/cjs/store/turso/connection.d.cts +1 -0
- package/dist/cjs/store/turso/connection.d.ts +1 -0
- package/dist/cjs/store/turso/connection.js +319 -94
- package/dist/cjs/store/turso/connection.js.map +1 -1
- package/dist/cjs/store/turso/open.d.cts +1 -1
- package/dist/cjs/store/turso/open.d.ts +1 -1
- package/dist/cjs/store/turso/open.js +70 -74
- package/dist/cjs/store/turso/open.js.map +1 -1
- package/dist/cjs/store/turso/store.js +25 -23
- package/dist/cjs/store/turso/store.js.map +1 -1
- package/dist/cjs/store/turso/vectors.d.cts +2 -2
- package/dist/cjs/store/turso/vectors.d.ts +2 -2
- package/dist/cjs/store/turso/vectors.js +26 -16
- package/dist/cjs/store/turso/vectors.js.map +1 -1
- package/dist/cjs/store/types.d.cts +4 -1
- package/dist/cjs/store/types.d.ts +4 -1
- package/dist/cjs/store/types.js.map +1 -1
- package/dist/cjs/store/vectors.d.cts +14 -1
- package/dist/cjs/store/vectors.d.ts +14 -1
- package/dist/cjs/store/vectors.js +61 -0
- package/dist/cjs/store/vectors.js.map +1 -1
- package/dist/cjs/watch.d.cts +6 -0
- package/dist/cjs/watch.d.ts +6 -0
- package/dist/cjs/watch.js +42 -10
- package/dist/cjs/watch.js.map +1 -1
- package/dist/cjs/workers/parse.d.cts +4 -3
- package/dist/cjs/workers/parse.d.ts +4 -3
- package/dist/cjs/workers/parse.js +19 -17
- package/dist/cjs/workers/parse.js.map +1 -1
- package/dist/esm/cli/index.d.ts +3 -3
- package/dist/esm/cli/index.js +3 -3
- package/dist/esm/cli/index.js.map +1 -1
- package/dist/esm/cli/path.js +4 -10
- package/dist/esm/cli/path.js.map +1 -1
- package/dist/esm/cli/peek.js +20 -2
- package/dist/esm/cli/peek.js.map +1 -1
- package/dist/esm/cli/related.js +5 -3
- package/dist/esm/cli/related.js.map +1 -1
- package/dist/esm/cli/search.js +12 -2
- package/dist/esm/cli/search.js.map +1 -1
- package/dist/esm/commands/index.d.ts +6 -3
- package/dist/esm/commands/index.js +1 -0
- package/dist/esm/commands/index.js.map +1 -1
- package/dist/esm/commands/map.d.ts +14 -5
- package/dist/esm/commands/map.js +2 -0
- package/dist/esm/commands/map.js.map +1 -1
- package/dist/esm/commands/path.d.ts +14 -0
- package/dist/esm/commands/path.js +33 -0
- package/dist/esm/commands/path.js.map +1 -0
- package/dist/esm/commands/peek.d.ts +25 -2
- package/dist/esm/commands/peek.js +59 -19
- package/dist/esm/commands/peek.js.map +1 -1
- package/dist/esm/commands/related.d.ts +16 -3
- package/dist/esm/commands/related.js +45 -28
- package/dist/esm/commands/related.js.map +1 -1
- package/dist/esm/commands/scope.d.ts +1 -0
- package/dist/esm/commands/scope.js +58 -0
- package/dist/esm/commands/scope.js.map +1 -1
- package/dist/esm/commands/search.d.ts +30 -3
- package/dist/esm/commands/search.js +95 -20
- package/dist/esm/commands/search.js.map +1 -1
- package/dist/esm/commands/signals.d.ts +22 -7
- package/dist/esm/commands/signals.js +74 -17
- package/dist/esm/commands/signals.js.map +1 -1
- package/dist/esm/commands/snapshot.d.ts +3 -0
- package/dist/esm/commands/snapshot.js +25 -0
- package/dist/esm/commands/snapshot.js.map +1 -0
- package/dist/esm/config/load.js +6 -0
- package/dist/esm/config/load.js.map +1 -1
- package/dist/esm/embed/cohere.js +35 -10
- package/dist/esm/embed/cohere.js.map +1 -1
- package/dist/esm/embed/endpoint.d.ts +2 -0
- package/dist/esm/embed/endpoint.js +11 -0
- package/dist/esm/embed/endpoint.js.map +1 -0
- package/dist/esm/embed/handoff.d.ts +7 -2
- package/dist/esm/embed/handoff.js +7 -0
- package/dist/esm/embed/handoff.js.map +1 -1
- package/dist/esm/embed/http.d.ts +18 -1
- package/dist/esm/embed/http.js +137 -17
- package/dist/esm/embed/http.js.map +1 -1
- package/dist/esm/embed/openai.js +34 -12
- package/dist/esm/embed/openai.js.map +1 -1
- package/dist/esm/embed/query.d.ts +9 -3
- package/dist/esm/embed/query.js +98 -26
- package/dist/esm/embed/query.js.map +1 -1
- package/dist/esm/embed/registry.d.ts +2 -2
- package/dist/esm/embed/registry.js +34 -5
- package/dist/esm/embed/registry.js.map +1 -1
- package/dist/esm/embed/static.js +10 -2
- package/dist/esm/embed/static.js.map +1 -1
- package/dist/esm/embed/store.js +30 -21
- package/dist/esm/embed/store.js.map +1 -1
- package/dist/esm/embed/types.d.ts +5 -2
- package/dist/esm/embed/types.js.map +1 -1
- package/dist/esm/features/embed.js +82 -21
- package/dist/esm/features/embed.js.map +1 -1
- package/dist/esm/graph/traverse.d.ts +2 -2
- package/dist/esm/graph/traverse.js +4 -2
- package/dist/esm/graph/traverse.js.map +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/output/output.d.ts +4 -36
- package/dist/esm/output/output.js +1 -2
- package/dist/esm/output/output.js.map +1 -1
- package/dist/esm/scan/pool.d.ts +2 -1
- package/dist/esm/scan/pool.js +80 -23
- package/dist/esm/scan/pool.js.map +1 -1
- package/dist/esm/scan/reparse.d.ts +1 -0
- package/dist/esm/scan/reparse.js +40 -12
- package/dist/esm/scan/reparse.js.map +1 -1
- package/dist/esm/store/builder.d.ts +11 -21
- package/dist/esm/store/builder.js +337 -133
- package/dist/esm/store/builder.js.map +1 -1
- package/dist/esm/store/duckdb/connection.js +9 -1
- package/dist/esm/store/duckdb/connection.js.map +1 -1
- package/dist/esm/store/duckdb/open.d.ts +1 -1
- package/dist/esm/store/duckdb/open.js +13 -9
- package/dist/esm/store/duckdb/open.js.map +1 -1
- package/dist/esm/store/duckdb/reconcile.js +145 -10
- package/dist/esm/store/duckdb/reconcile.js.map +1 -1
- package/dist/esm/store/embed-scope.js +16 -6
- package/dist/esm/store/embed-scope.js.map +1 -1
- package/dist/esm/store/index.d.ts +6 -0
- package/dist/esm/store/index.js +10 -4
- package/dist/esm/store/index.js.map +1 -1
- package/dist/esm/store/open.d.ts +6 -1
- package/dist/esm/store/open.js +77 -87
- package/dist/esm/store/open.js.map +1 -1
- package/dist/esm/store/readiness.d.ts +5 -0
- package/dist/esm/store/readiness.js +11 -0
- package/dist/esm/store/readiness.js.map +1 -0
- package/dist/esm/store/reconcile.d.ts +26 -1
- package/dist/esm/store/reconcile.js +142 -120
- package/dist/esm/store/reconcile.js.map +1 -1
- package/dist/esm/store/signature.d.ts +1 -0
- package/dist/esm/store/signature.js +8 -0
- package/dist/esm/store/signature.js.map +1 -1
- package/dist/esm/store/sqlite/open.d.ts +1 -1
- package/dist/esm/store/sqlite/open.js +12 -12
- package/dist/esm/store/sqlite/open.js.map +1 -1
- package/dist/esm/store/sqlite/reconcile.js +2 -2
- package/dist/esm/store/sqlite/reconcile.js.map +1 -1
- package/dist/esm/store/sqlite/store.js +21 -18
- package/dist/esm/store/sqlite/store.js.map +1 -1
- package/dist/esm/store/sqlite/vectors.d.ts +2 -2
- package/dist/esm/store/sqlite/vectors.js +7 -5
- package/dist/esm/store/sqlite/vectors.js.map +1 -1
- package/dist/esm/store/stages.js.map +1 -1
- package/dist/esm/store/turso/connection.d.ts +1 -0
- package/dist/esm/store/turso/connection.js +97 -28
- package/dist/esm/store/turso/connection.js.map +1 -1
- package/dist/esm/store/turso/open.d.ts +1 -1
- package/dist/esm/store/turso/open.js +9 -8
- package/dist/esm/store/turso/open.js.map +1 -1
- package/dist/esm/store/turso/store.js +16 -14
- package/dist/esm/store/turso/store.js.map +1 -1
- package/dist/esm/store/turso/vectors.d.ts +2 -2
- package/dist/esm/store/turso/vectors.js +27 -17
- package/dist/esm/store/turso/vectors.js.map +1 -1
- package/dist/esm/store/types.d.ts +4 -1
- package/dist/esm/store/types.js.map +1 -1
- package/dist/esm/store/vectors.d.ts +14 -1
- package/dist/esm/store/vectors.js +55 -0
- package/dist/esm/store/vectors.js.map +1 -1
- package/dist/esm/watch.d.ts +6 -0
- package/dist/esm/watch.js +40 -14
- package/dist/esm/watch.js.map +1 -1
- package/dist/esm/workers/parse.d.ts +4 -3
- package/dist/esm/workers/parse.js +19 -17
- package/dist/esm/workers/parse.js.map +1 -1
- package/package.json +1 -1
- package/skills/sense/EXAMPLES.md +3 -3
- package/skills/sense/SKILL.md +11 -3
- package/skills/sense/references/search.md +17 -1
- package/skills/sense/references/sql.md +1 -1
- package/skills/sense/references/stores/duckdb.md +1 -1
- package/skills/sense/references/terminology.md +32 -0
- package/skills/sense-setup/SKILL.md +2 -2
- package/skills/sense-setup/references/embeddings.md +1 -1
- package/skills/sense-setup/references/store-benchmarks.md +5 -5
- package/skills/sense-setup/references/stores/duckdb.md +1 -1
package/dist/cjs/scan/reparse.js
CHANGED
|
@@ -9,6 +9,9 @@ function _export(target, all) {
|
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
_export(exports, {
|
|
12
|
+
get PARSE_BYTES_PER_WORKER () {
|
|
13
|
+
return PARSE_BYTES_PER_WORKER;
|
|
14
|
+
},
|
|
12
15
|
get featuresForFile () {
|
|
13
16
|
return featuresForFile;
|
|
14
17
|
},
|
|
@@ -171,9 +174,7 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
171
174
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
172
175
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
173
176
|
}
|
|
174
|
-
|
|
175
|
-
// (pool fixed cost ~85-100ms), so 200 keeps margin. 8 workers ties 10 in a 6,566-file sweep; 12+ trends worse.
|
|
176
|
-
var DEFAULT_THRESHOLD = 200;
|
|
177
|
+
var PARSE_BYTES_PER_WORKER = 512 * 1024;
|
|
177
178
|
var DEFAULT_MAX_WORKERS = 8;
|
|
178
179
|
function featuresForFile(features, cfg, file) {
|
|
179
180
|
return features.filter(function(feature) {
|
|
@@ -211,7 +212,7 @@ function reparseSerial(files, features, cfg, onParsed) {
|
|
|
211
212
|
// none given, opens an ephemeral ParsePool for this call alone and always closes it.
|
|
212
213
|
function reparsePooled(files, features, cfg, onParsed, maxWorkers, pool) {
|
|
213
214
|
return _async_to_generator(function() {
|
|
214
|
-
var ephemeral, results, err;
|
|
215
|
+
var ephemeral, results, dispatchError, dispatchFailed, err, closeError;
|
|
215
216
|
return _ts_generator(this, function(_state) {
|
|
216
217
|
switch(_state.label){
|
|
217
218
|
case 0:
|
|
@@ -220,13 +221,14 @@ function reparsePooled(files, features, cfg, onParsed, maxWorkers, pool) {
|
|
|
220
221
|
pool.run(files, features, cfg, onParsed, maxWorkers)
|
|
221
222
|
];
|
|
222
223
|
ephemeral = new _poolts.ParsePool();
|
|
224
|
+
dispatchFailed = false;
|
|
223
225
|
_state.label = 1;
|
|
224
226
|
case 1:
|
|
225
227
|
_state.trys.push([
|
|
226
228
|
1,
|
|
227
|
-
|
|
229
|
+
3,
|
|
228
230
|
,
|
|
229
|
-
|
|
231
|
+
4
|
|
230
232
|
]);
|
|
231
233
|
return [
|
|
232
234
|
4,
|
|
@@ -235,51 +237,103 @@ function reparsePooled(files, features, cfg, onParsed, maxWorkers, pool) {
|
|
|
235
237
|
case 2:
|
|
236
238
|
results = _state.sent();
|
|
237
239
|
return [
|
|
238
|
-
|
|
239
|
-
|
|
240
|
+
3,
|
|
241
|
+
4
|
|
240
242
|
];
|
|
241
243
|
case 3:
|
|
242
|
-
_state.sent();
|
|
244
|
+
err = _state.sent();
|
|
245
|
+
dispatchFailed = true;
|
|
246
|
+
dispatchError = err;
|
|
243
247
|
return [
|
|
244
|
-
|
|
245
|
-
|
|
248
|
+
3,
|
|
249
|
+
4
|
|
246
250
|
];
|
|
247
251
|
case 4:
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
252
|
+
_state.trys.push([
|
|
253
|
+
4,
|
|
254
|
+
6,
|
|
255
|
+
,
|
|
256
|
+
7
|
|
257
|
+
]);
|
|
251
258
|
return [
|
|
252
259
|
4,
|
|
253
|
-
ephemeral.close()
|
|
260
|
+
ephemeral.close()
|
|
254
261
|
];
|
|
255
262
|
case 5:
|
|
256
263
|
_state.sent();
|
|
257
|
-
|
|
264
|
+
return [
|
|
265
|
+
3,
|
|
266
|
+
7
|
|
267
|
+
];
|
|
258
268
|
case 6:
|
|
269
|
+
closeError = _state.sent();
|
|
270
|
+
if (dispatchFailed) throw new AggregateError([
|
|
271
|
+
dispatchError,
|
|
272
|
+
closeError
|
|
273
|
+
], 'parse dispatch and pool close failed');
|
|
274
|
+
throw closeError;
|
|
275
|
+
case 7:
|
|
276
|
+
if (dispatchFailed) throw dispatchError;
|
|
277
|
+
if (results === undefined) throw new Error('parse dispatch finished without results');
|
|
259
278
|
return [
|
|
260
|
-
2
|
|
279
|
+
2,
|
|
280
|
+
results
|
|
261
281
|
];
|
|
262
282
|
}
|
|
263
283
|
});
|
|
264
284
|
})();
|
|
265
285
|
}
|
|
286
|
+
function parseWorkerCount(files, bytesPerWorker, maxWorkers) {
|
|
287
|
+
if (files.length === 0) return 0;
|
|
288
|
+
var available = Math.max(1, Math.min(maxWorkers, files.length));
|
|
289
|
+
if (bytesPerWorker === 0) return available;
|
|
290
|
+
var totalBytes = 0;
|
|
291
|
+
var largestBytes = 0;
|
|
292
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
293
|
+
try {
|
|
294
|
+
for(var _iterator = files[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
295
|
+
var file = _step.value;
|
|
296
|
+
totalBytes += file.size;
|
|
297
|
+
largestBytes = Math.max(largestBytes, file.size);
|
|
298
|
+
}
|
|
299
|
+
} catch (err) {
|
|
300
|
+
_didIteratorError = true;
|
|
301
|
+
_iteratorError = err;
|
|
302
|
+
} finally{
|
|
303
|
+
try {
|
|
304
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
305
|
+
_iterator.return();
|
|
306
|
+
}
|
|
307
|
+
} finally{
|
|
308
|
+
if (_didIteratorError) {
|
|
309
|
+
throw _iteratorError;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
var aggregateWorkers = Math.floor(totalBytes / bytesPerWorker);
|
|
314
|
+
// The largest file is indivisible, so extra workers need full shares among the remainder.
|
|
315
|
+
var companionWorkers = 1 + Math.floor((totalBytes - largestBytes) / bytesPerWorker);
|
|
316
|
+
return Math.min(available, aggregateWorkers, companionWorkers);
|
|
317
|
+
}
|
|
266
318
|
function reparseFiles(_0, _1, _2, _3, _4) {
|
|
267
319
|
return _async_to_generator(function(files, features, cfg, knownColumns, onParsed) {
|
|
268
|
-
var options, _options_threshold, _options_maxWorkers, threshold, maxWorkers, results, _tmp, docs, warnings, newColumns, seen, workerParseMs, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _step_value, doc, fileWarnings, parseMs, _warnings, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, key;
|
|
320
|
+
var options, _options_threshold, _options_maxWorkers, threshold, maxWorkers, workerCount, pooled, results, _tmp, docs, warnings, newColumns, seen, workerParseMs, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _step_value, doc, fileWarnings, parseMs, _warnings, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, key;
|
|
269
321
|
var _arguments = arguments;
|
|
270
322
|
return _ts_generator(this, function(_state) {
|
|
271
323
|
switch(_state.label){
|
|
272
324
|
case 0:
|
|
273
325
|
options = _arguments.length > 5 && _arguments[5] !== void 0 ? _arguments[5] : {};
|
|
274
|
-
threshold = (_options_threshold = options.threshold) !== null && _options_threshold !== void 0 ? _options_threshold :
|
|
326
|
+
threshold = (_options_threshold = options.threshold) !== null && _options_threshold !== void 0 ? _options_threshold : PARSE_BYTES_PER_WORKER;
|
|
275
327
|
maxWorkers = (_options_maxWorkers = options.maxWorkers) !== null && _options_maxWorkers !== void 0 ? _options_maxWorkers : Math.min(DEFAULT_MAX_WORKERS, (0, _nodeos.availableParallelism)());
|
|
276
|
-
|
|
328
|
+
workerCount = parseWorkerCount(files, threshold, maxWorkers);
|
|
329
|
+
pooled = files.length > 0 && (threshold === 0 || workerCount >= 2);
|
|
330
|
+
if (!pooled) return [
|
|
277
331
|
3,
|
|
278
332
|
2
|
|
279
333
|
];
|
|
280
334
|
return [
|
|
281
335
|
4,
|
|
282
|
-
reparsePooled(files, features, cfg, onParsed,
|
|
336
|
+
reparsePooled(files, features, cfg, onParsed, workerCount, options.pool)
|
|
283
337
|
];
|
|
284
338
|
case 1:
|
|
285
339
|
_tmp = _state.sent();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/scan/reparse.ts"],"sourcesContent":["import { availableParallelism } from 'node:os';\nimport type { Config } from '../config/index.ts';\nimport type { Feature } from '../features/types.ts';\nimport type { ParsedDoc } from './index.ts';\nimport { parseFile } from './index.ts';\nimport type { FileStat } from './list.ts';\nimport type { FileResult } from './pool.ts';\nimport { ParsePool } from './pool.ts';\n\n// Store-agnostic per-file parse pass shared by every store's reconcile(). Index-preserving:\n// one pass over `files`, pushed in order.\nexport interface ReparseResult {\n docs: ParsedDoc[];\n warnings: string[];\n // Frontmatter keys not in `knownColumns`, first-seen order -- the order callers ALTER TABLE ADD COLUMN in.\n newColumns: string[];\n // Sum of worker-side parseFile time (workers/parse.ts) across files; 0 on the serial path.\n workerParseMs: number;\n}\n\nexport interface ReparseOptions {\n // Overrides
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/scan/reparse.ts"],"sourcesContent":["import { availableParallelism } from 'node:os';\nimport type { Config } from '../config/index.ts';\nimport type { Feature } from '../features/types.ts';\nimport type { ParsedDoc } from './index.ts';\nimport { parseFile } from './index.ts';\nimport type { FileStat } from './list.ts';\nimport type { FileResult } from './pool.ts';\nimport { ParsePool } from './pool.ts';\n\n// Store-agnostic per-file parse pass shared by every store's reconcile(). Index-preserving:\n// one pass over `files`, pushed in order.\nexport interface ReparseResult {\n docs: ParsedDoc[];\n warnings: string[];\n // Frontmatter keys not in `knownColumns`, first-seen order -- the order callers ALTER TABLE ADD COLUMN in.\n newColumns: string[];\n // Sum of worker-side parseFile time (workers/parse.ts) across files; 0 on the serial path.\n workerParseMs: number;\n}\n\nexport interface ReparseOptions {\n // Overrides PARSE_BYTES_PER_WORKER below. Zero forces worker dispatch in tests.\n // Internal: no caller in src/ passes it.\n threshold?: number;\n // Overrides DEFAULT_MAX_WORKERS below.\n maxWorkers?: number;\n // A builder-owned pool to dispatch through instead of creating and destroying one for this\n // call alone (see store/builder.ts). Absent, reparseFiles manages its own ephemeral pool.\n pool?: ParsePool;\n}\n\n// The 2026-09-26 comparison kept ~326 KiB updates serial and 5.86 MiB work pooled.\n// Companion byte shares prevent one dominant file from selecting workers for a tiny remainder.\nexport const PARSE_BYTES_PER_WORKER = 512 * 1024;\nconst DEFAULT_MAX_WORKERS = 8;\n\n// Per-file feature filtering, shared by the serial loop (reads `features` from the caller) and\n// the worker path (can only pass `cfg` across the thread boundary, so derives `features` itself).\nexport function featuresForFile(features: Feature[], cfg: Config, file: FileStat): Feature[] {\n return features.filter((feature) => !feature.enabledForFile || feature.enabledForFile(cfg, file));\n}\n\nfunction reparseSerial(files: FileStat[], features: Feature[], cfg: Config, onParsed?: (done: number) => void): FileResult[] {\n const results: FileResult[] = [];\n let done = 0;\n for (const file of files) {\n const fileFeatures = featuresForFile(features, cfg, file);\n results.push(parseFile(file, fileFeatures, cfg));\n onParsed?.(++done);\n }\n return results;\n}\n\n// Dispatches through `pool` when the caller owns one (a builder, kept alive across calls); with\n// none given, opens an ephemeral ParsePool for this call alone and always closes it.\nasync function reparsePooled(files: FileStat[], features: Feature[], cfg: Config, onParsed: ((done: number) => void) | undefined, maxWorkers: number, pool: ParsePool | undefined): Promise<FileResult[]> {\n if (pool) return pool.run(files, features, cfg, onParsed, maxWorkers);\n const ephemeral = new ParsePool();\n let results: FileResult[] | undefined;\n let dispatchError: unknown;\n let dispatchFailed = false;\n try {\n results = await ephemeral.run(files, features, cfg, onParsed, maxWorkers);\n } catch (err) {\n dispatchFailed = true;\n dispatchError = err;\n }\n try {\n await ephemeral.close();\n } catch (closeError) {\n if (dispatchFailed) throw new AggregateError([dispatchError, closeError], 'parse dispatch and pool close failed');\n throw closeError;\n }\n if (dispatchFailed) throw dispatchError;\n if (results === undefined) throw new Error('parse dispatch finished without results');\n return results;\n}\n\nfunction parseWorkerCount(files: FileStat[], bytesPerWorker: number, maxWorkers: number): number {\n if (files.length === 0) return 0;\n const available = Math.max(1, Math.min(maxWorkers, files.length));\n if (bytesPerWorker === 0) return available;\n let totalBytes = 0;\n let largestBytes = 0;\n for (const file of files) {\n totalBytes += file.size;\n largestBytes = Math.max(largestBytes, file.size);\n }\n const aggregateWorkers = Math.floor(totalBytes / bytesPerWorker);\n // The largest file is indivisible, so extra workers need full shares among the remainder.\n const companionWorkers = 1 + Math.floor((totalBytes - largestBytes) / bytesPerWorker);\n return Math.min(available, aggregateWorkers, companionWorkers);\n}\n\n// `onParsed` receives the running count (1-based) after each file, mirroring a Progress.tick\n// call; pass one in to keep progress reporting working without this module owning a reporter.\nexport async function reparseFiles(files: FileStat[], features: Feature[], cfg: Config, knownColumns: ReadonlySet<string>, onParsed?: (done: number) => void, options: ReparseOptions = {}): Promise<ReparseResult> {\n const threshold = options.threshold ?? PARSE_BYTES_PER_WORKER;\n const maxWorkers = options.maxWorkers ?? Math.min(DEFAULT_MAX_WORKERS, availableParallelism());\n const workerCount = parseWorkerCount(files, threshold, maxWorkers);\n const pooled = files.length > 0 && (threshold === 0 || workerCount >= 2);\n const results = pooled ? await reparsePooled(files, features, cfg, onParsed, workerCount, options.pool) : reparseSerial(files, features, cfg, onParsed);\n\n const docs: ParsedDoc[] = [];\n const warnings: string[] = [];\n const newColumns: string[] = [];\n const seen = new Set(knownColumns);\n let workerParseMs = 0;\n for (const { doc, warnings: fileWarnings, parseMs } of results) {\n warnings.push(...fileWarnings);\n workerParseMs += parseMs ?? 0;\n for (const key of Object.keys(doc.data)) {\n if (!seen.has(key)) {\n seen.add(key);\n newColumns.push(key);\n }\n }\n docs.push(doc);\n }\n\n return { docs, warnings, newColumns, workerParseMs };\n}\n"],"names":["PARSE_BYTES_PER_WORKER","featuresForFile","reparseFiles","DEFAULT_MAX_WORKERS","features","cfg","file","filter","feature","enabledForFile","reparseSerial","files","onParsed","results","done","fileFeatures","push","parseFile","reparsePooled","maxWorkers","pool","ephemeral","dispatchError","dispatchFailed","err","closeError","run","ParsePool","close","AggregateError","undefined","Error","parseWorkerCount","bytesPerWorker","length","available","Math","max","min","totalBytes","largestBytes","size","aggregateWorkers","floor","companionWorkers","knownColumns","options","threshold","workerCount","pooled","docs","warnings","newColumns","seen","workerParseMs","doc","fileWarnings","parseMs","key","availableParallelism","Set","Object","keys","data","has","add"],"mappings":"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"}
|
|
@@ -1,27 +1,17 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type { EmbedChangeKind } from './embed-scope.js';
|
|
3
|
-
import type { FeatureToggle } from './feature-scope.js';
|
|
4
|
-
import { type ReconcilePaths } from './reconcile.js';
|
|
1
|
+
import { type ResolvedConfig } from '../config/index.js';
|
|
5
2
|
import type { Stages } from './stages.js';
|
|
6
3
|
import type { Connection, ReconcileDialect } from './types.js';
|
|
4
|
+
interface BuildResult {
|
|
5
|
+
parsed: number;
|
|
6
|
+
warnings: string[];
|
|
7
|
+
stages: Stages;
|
|
8
|
+
messages: string[];
|
|
9
|
+
}
|
|
7
10
|
export interface Builder {
|
|
8
|
-
build(
|
|
9
|
-
parsed: number;
|
|
10
|
-
warnings: string[];
|
|
11
|
-
stages: Stages;
|
|
12
|
-
}>;
|
|
13
|
-
recover(): Promise<{
|
|
14
|
-
parsed: number;
|
|
15
|
-
warnings: string[];
|
|
16
|
-
stages: Stages;
|
|
17
|
-
}>;
|
|
18
|
-
invalidate(kind: EmbedChangeKind): Promise<{
|
|
19
|
-
parsed: number;
|
|
20
|
-
}>;
|
|
21
|
-
invalidateFeatures(toggles: FeatureToggle[]): Promise<{
|
|
22
|
-
parsed: number;
|
|
23
|
-
}>;
|
|
11
|
+
build(): Promise<BuildResult>;
|
|
24
12
|
close(): Promise<void>;
|
|
25
13
|
readonly poolsCreated: number;
|
|
26
14
|
}
|
|
27
|
-
|
|
15
|
+
type EnsureFeatureSchema = (cfg: ResolvedConfig) => Promise<void>;
|
|
16
|
+
export declare function createBuilder(conn: Connection, cfg: ResolvedConfig, dialect: ReconcileDialect, ensureFeatureSchema: EnsureFeatureSchema): Builder;
|
|
17
|
+
export {};
|
|
@@ -1,27 +1,17 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type { EmbedChangeKind } from './embed-scope.js';
|
|
3
|
-
import type { FeatureToggle } from './feature-scope.js';
|
|
4
|
-
import { type ReconcilePaths } from './reconcile.js';
|
|
1
|
+
import { type ResolvedConfig } from '../config/index.js';
|
|
5
2
|
import type { Stages } from './stages.js';
|
|
6
3
|
import type { Connection, ReconcileDialect } from './types.js';
|
|
4
|
+
interface BuildResult {
|
|
5
|
+
parsed: number;
|
|
6
|
+
warnings: string[];
|
|
7
|
+
stages: Stages;
|
|
8
|
+
messages: string[];
|
|
9
|
+
}
|
|
7
10
|
export interface Builder {
|
|
8
|
-
build(
|
|
9
|
-
parsed: number;
|
|
10
|
-
warnings: string[];
|
|
11
|
-
stages: Stages;
|
|
12
|
-
}>;
|
|
13
|
-
recover(): Promise<{
|
|
14
|
-
parsed: number;
|
|
15
|
-
warnings: string[];
|
|
16
|
-
stages: Stages;
|
|
17
|
-
}>;
|
|
18
|
-
invalidate(kind: EmbedChangeKind): Promise<{
|
|
19
|
-
parsed: number;
|
|
20
|
-
}>;
|
|
21
|
-
invalidateFeatures(toggles: FeatureToggle[]): Promise<{
|
|
22
|
-
parsed: number;
|
|
23
|
-
}>;
|
|
11
|
+
build(): Promise<BuildResult>;
|
|
24
12
|
close(): Promise<void>;
|
|
25
13
|
readonly poolsCreated: number;
|
|
26
14
|
}
|
|
27
|
-
|
|
15
|
+
type EnsureFeatureSchema = (cfg: ResolvedConfig) => Promise<void>;
|
|
16
|
+
export declare function createBuilder(conn: Connection, cfg: ResolvedConfig, dialect: ReconcileDialect, ensureFeatureSchema: EnsureFeatureSchema): Builder;
|
|
17
|
+
export {};
|