codesift-mcp 0.15.3 → 0.17.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/cli/auto-prune.d.ts +16 -0
- package/dist/cli/auto-prune.d.ts.map +1 -0
- package/dist/cli/auto-prune.js +87 -0
- package/dist/cli/auto-prune.js.map +1 -0
- package/dist/cli/commands-admin.d.ts.map +1 -1
- package/dist/cli/commands-admin.js +11 -0
- package/dist/cli/commands-admin.js.map +1 -1
- package/dist/cli/commands-daemon.d.ts.map +1 -1
- package/dist/cli/commands-daemon.js +9 -0
- package/dist/cli/commands-daemon.js.map +1 -1
- package/dist/cli/commands-index.d.ts.map +1 -1
- package/dist/cli/commands-index.js +8 -0
- package/dist/cli/commands-index.js.map +1 -1
- package/dist/cli/embed-child.js +5 -1
- package/dist/cli/embed-child.js.map +1 -1
- package/dist/cli/help.js +1 -1
- package/dist/cli/hooks/pre-tool-use.d.ts.map +1 -1
- package/dist/cli/hooks/pre-tool-use.js +11 -5
- package/dist/cli/hooks/pre-tool-use.js.map +1 -1
- package/dist/cli/hooks/shared.d.ts +1 -1
- package/dist/cli/hooks/shared.d.ts.map +1 -1
- package/dist/cli/hooks/shared.js +34 -2
- package/dist/cli/hooks/shared.js.map +1 -1
- package/dist/cli/orphan-guard.d.ts +22 -0
- package/dist/cli/orphan-guard.d.ts.map +1 -1
- package/dist/cli/orphan-guard.js +30 -0
- package/dist/cli/orphan-guard.js.map +1 -1
- package/dist/cli/service.d.ts +43 -0
- package/dist/cli/service.d.ts.map +1 -1
- package/dist/cli/service.js +84 -4
- package/dist/cli/service.js.map +1 -1
- package/dist/cli/setup/codex-project-auto.d.ts +27 -0
- package/dist/cli/setup/codex-project-auto.d.ts.map +1 -0
- package/dist/cli/setup/codex-project-auto.js +98 -0
- package/dist/cli/setup/codex-project-auto.js.map +1 -0
- package/dist/cli/setup/codex.d.ts.map +1 -1
- package/dist/cli/setup/codex.js +101 -6
- package/dist/cli/setup/codex.js.map +1 -1
- package/dist/cli/setup/cursor.d.ts.map +1 -1
- package/dist/cli/setup/cursor.js +9 -1
- package/dist/cli/setup/cursor.js.map +1 -1
- package/dist/cli/setup/gemini.d.ts.map +1 -1
- package/dist/cli/setup/gemini.js +21 -0
- package/dist/cli/setup/gemini.js.map +1 -1
- package/dist/cli/setup/mcp.d.ts +37 -1
- package/dist/cli/setup/mcp.d.ts.map +1 -1
- package/dist/cli/setup/mcp.js +57 -4
- package/dist/cli/setup/mcp.js.map +1 -1
- package/dist/cli/setup/types.d.ts +19 -1
- package/dist/cli/setup/types.d.ts.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +30 -6
- package/dist/config.js.map +1 -1
- package/dist/formatters-core.d.ts +2 -0
- package/dist/formatters-core.d.ts.map +1 -1
- package/dist/formatters-core.js +18 -3
- package/dist/formatters-core.js.map +1 -1
- package/dist/formatters-shortening.d.ts.map +1 -1
- package/dist/formatters-shortening.js +8 -2
- package/dist/formatters-shortening.js.map +1 -1
- package/dist/instructions.d.ts +17 -0
- package/dist/instructions.d.ts.map +1 -1
- package/dist/instructions.js +35 -0
- package/dist/instructions.js.map +1 -1
- package/dist/lsp/lsp-servers.d.ts.map +1 -1
- package/dist/lsp/lsp-servers.js +4 -1
- package/dist/lsp/lsp-servers.js.map +1 -1
- package/dist/parser/parse-cache.d.ts.map +1 -1
- package/dist/parser/parse-cache.js +36 -1
- package/dist/parser/parse-cache.js.map +1 -1
- package/dist/register-tool-groups/analysis.d.ts.map +1 -1
- package/dist/register-tool-groups/analysis.js +10 -1
- package/dist/register-tool-groups/analysis.js.map +1 -1
- package/dist/register-tool-groups/core/index.d.ts.map +1 -1
- package/dist/register-tool-groups/core/index.js +26 -3
- package/dist/register-tool-groups/core/index.js.map +1 -1
- package/dist/register-tool-groups/core/meta.d.ts.map +1 -1
- package/dist/register-tool-groups/core/meta.js +23 -1
- package/dist/register-tool-groups/core/meta.js.map +1 -1
- package/dist/register-tool-groups/core/search.d.ts +15 -0
- package/dist/register-tool-groups/core/search.d.ts.map +1 -1
- package/dist/register-tool-groups/core/search.js +60 -2
- package/dist/register-tool-groups/core/search.js.map +1 -1
- package/dist/register-tool-groups/core/symbols.d.ts.map +1 -1
- package/dist/register-tool-groups/core/symbols.js +13 -2
- package/dist/register-tool-groups/core/symbols.js.map +1 -1
- package/dist/register-tool-groups/meta.d.ts.map +1 -1
- package/dist/register-tool-groups/meta.js +23 -0
- package/dist/register-tool-groups/meta.js.map +1 -1
- package/dist/register-tools/discovery.d.ts +22 -5
- package/dist/register-tools/discovery.d.ts.map +1 -1
- package/dist/register-tools/discovery.js +95 -9
- package/dist/register-tools/discovery.js.map +1 -1
- package/dist/register-tools/runtime.d.ts +9 -1
- package/dist/register-tools/runtime.d.ts.map +1 -1
- package/dist/register-tools/runtime.js +19 -2
- package/dist/register-tools/runtime.js.map +1 -1
- package/dist/register-tools.d.ts +4 -2
- package/dist/register-tools.d.ts.map +1 -1
- package/dist/register-tools.js +20 -8
- package/dist/register-tools.js.map +1 -1
- package/dist/search/bm25-store.d.ts +6 -0
- package/dist/search/bm25-store.d.ts.map +1 -0
- package/dist/search/bm25-store.js +164 -0
- package/dist/search/bm25-store.js.map +1 -0
- package/dist/search/bm25.d.ts +30 -0
- package/dist/search/bm25.d.ts.map +1 -1
- package/dist/search/bm25.js +159 -34
- package/dist/search/bm25.js.map +1 -1
- package/dist/search/embed-gate.d.ts +17 -0
- package/dist/search/embed-gate.d.ts.map +1 -0
- package/dist/search/embed-gate.js +64 -0
- package/dist/search/embed-gate.js.map +1 -0
- package/dist/search/semantic.d.ts.map +1 -1
- package/dist/search/semantic.js +5 -2
- package/dist/search/semantic.js.map +1 -1
- package/dist/server-helpers/health-vitals.d.ts +45 -0
- package/dist/server-helpers/health-vitals.d.ts.map +1 -0
- package/dist/server-helpers/health-vitals.js +77 -0
- package/dist/server-helpers/health-vitals.js.map +1 -0
- package/dist/server-helpers/repo-resolution.d.ts.map +1 -1
- package/dist/server-helpers/repo-resolution.js +23 -3
- package/dist/server-helpers/repo-resolution.js.map +1 -1
- package/dist/server-helpers/request-context.d.ts +34 -4
- package/dist/server-helpers/request-context.d.ts.map +1 -1
- package/dist/server-helpers/request-context.js +4 -0
- package/dist/server-helpers/request-context.js.map +1 -1
- package/dist/server-helpers/response-hints.d.ts +1 -4
- package/dist/server-helpers/response-hints.d.ts.map +1 -1
- package/dist/server-helpers/response-hints.js +44 -1
- package/dist/server-helpers/response-hints.js.map +1 -1
- package/dist/server-helpers.d.ts.map +1 -1
- package/dist/server-helpers.js +20 -0
- package/dist/server-helpers.js.map +1 -1
- package/dist/server.d.ts +10 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +165 -8
- package/dist/server.js.map +1 -1
- package/dist/storage/_shared.d.ts +1 -1
- package/dist/storage/_shared.d.ts.map +1 -1
- package/dist/storage/_shared.js +41 -3
- package/dist/storage/_shared.js.map +1 -1
- package/dist/storage/index-migration.d.ts.map +1 -1
- package/dist/storage/index-migration.js +6 -2
- package/dist/storage/index-migration.js.map +1 -1
- package/dist/storage/index-store.d.ts +29 -0
- package/dist/storage/index-store.d.ts.map +1 -1
- package/dist/storage/index-store.js +112 -0
- package/dist/storage/index-store.js.map +1 -1
- package/dist/storage/registry.d.ts +14 -0
- package/dist/storage/registry.d.ts.map +1 -1
- package/dist/storage/registry.js +46 -7
- package/dist/storage/registry.js.map +1 -1
- package/dist/storage/sqlite/accessors.d.ts +17 -0
- package/dist/storage/sqlite/accessors.d.ts.map +1 -1
- package/dist/storage/sqlite/accessors.js +20 -0
- package/dist/storage/sqlite/accessors.js.map +1 -1
- package/dist/storage/sqlite/connection.d.ts +20 -0
- package/dist/storage/sqlite/connection.d.ts.map +1 -1
- package/dist/storage/sqlite/connection.js +61 -0
- package/dist/storage/sqlite/connection.js.map +1 -1
- package/dist/storage/sqlite/index-io.d.ts +5 -0
- package/dist/storage/sqlite/index-io.d.ts.map +1 -1
- package/dist/storage/sqlite/index-io.js +98 -9
- package/dist/storage/sqlite/index-io.js.map +1 -1
- package/dist/storage/sqlite/meta.d.ts +7 -0
- package/dist/storage/sqlite/meta.d.ts.map +1 -1
- package/dist/storage/sqlite/meta.js.map +1 -1
- package/dist/storage/sqlite/queries.d.ts +66 -0
- package/dist/storage/sqlite/queries.d.ts.map +1 -0
- package/dist/storage/sqlite/queries.js +196 -0
- package/dist/storage/sqlite/queries.js.map +1 -0
- package/dist/storage/sqlite/schema.d.ts +2 -2
- package/dist/storage/sqlite/schema.d.ts.map +1 -1
- package/dist/storage/sqlite/schema.js +36 -0
- package/dist/storage/sqlite/schema.js.map +1 -1
- package/dist/storage/sqlite-index-store.d.ts +3 -1
- package/dist/storage/sqlite-index-store.d.ts.map +1 -1
- package/dist/storage/sqlite-index-store.js +4 -1
- package/dist/storage/sqlite-index-store.js.map +1 -1
- package/dist/storage/telemetry/uploader.js +1 -1
- package/dist/storage/telemetry/uploader.js.map +1 -1
- package/dist/storage/usage-tracker.d.ts.map +1 -1
- package/dist/storage/usage-tracker.js +54 -2
- package/dist/storage/usage-tracker.js.map +1 -1
- package/dist/tools/boundary-tools.js +2 -2
- package/dist/tools/boundary-tools.js.map +1 -1
- package/dist/tools/community-tools.d.ts +7 -0
- package/dist/tools/community-tools.d.ts.map +1 -1
- package/dist/tools/community-tools.js +31 -14
- package/dist/tools/community-tools.js.map +1 -1
- package/dist/tools/complexity-tools.d.ts.map +1 -1
- package/dist/tools/complexity-tools.js +65 -45
- package/dist/tools/complexity-tools.js.map +1 -1
- package/dist/tools/conversation-index-tools.js +2 -2
- package/dist/tools/conversation-index-tools.js.map +1 -1
- package/dist/tools/conversation-search-tools.js +2 -2
- package/dist/tools/conversation-search-tools.js.map +1 -1
- package/dist/tools/coupling-tools.d.ts +2 -2
- package/dist/tools/coupling-tools.d.ts.map +1 -1
- package/dist/tools/coupling-tools.js +8 -13
- package/dist/tools/coupling-tools.js.map +1 -1
- package/dist/tools/diff-tools.d.ts.map +1 -1
- package/dist/tools/diff-tools.js +11 -14
- package/dist/tools/diff-tools.js.map +1 -1
- package/dist/tools/git-exec.d.ts +42 -0
- package/dist/tools/git-exec.d.ts.map +1 -0
- package/dist/tools/git-exec.js +53 -0
- package/dist/tools/git-exec.js.map +1 -0
- package/dist/tools/git-tree-guard.d.ts +23 -0
- package/dist/tools/git-tree-guard.d.ts.map +1 -0
- package/dist/tools/git-tree-guard.js +33 -0
- package/dist/tools/git-tree-guard.js.map +1 -0
- package/dist/tools/graph-tools.d.ts.map +1 -1
- package/dist/tools/graph-tools.js +5 -2
- package/dist/tools/graph-tools.js.map +1 -1
- package/dist/tools/hotspot-tools.d.ts +25 -0
- package/dist/tools/hotspot-tools.d.ts.map +1 -1
- package/dist/tools/hotspot-tools.js +24 -3
- package/dist/tools/hotspot-tools.js.map +1 -1
- package/dist/tools/impact-tools.d.ts.map +1 -1
- package/dist/tools/impact-tools.js +8 -9
- package/dist/tools/impact-tools.js.map +1 -1
- package/dist/tools/index-tools/file-indexer.d.ts +6 -0
- package/dist/tools/index-tools/file-indexer.d.ts.map +1 -1
- package/dist/tools/index-tools/file-indexer.js +184 -18
- package/dist/tools/index-tools/file-indexer.js.map +1 -1
- package/dist/tools/index-tools/folder-indexer.d.ts.map +1 -1
- package/dist/tools/index-tools/folder-indexer.js +59 -7
- package/dist/tools/index-tools/folder-indexer.js.map +1 -1
- package/dist/tools/index-tools/load-gate.d.ts +15 -0
- package/dist/tools/index-tools/load-gate.d.ts.map +1 -0
- package/dist/tools/index-tools/load-gate.js +57 -0
- package/dist/tools/index-tools/load-gate.js.map +1 -0
- package/dist/tools/index-tools/overload-guard.d.ts +16 -0
- package/dist/tools/index-tools/overload-guard.d.ts.map +1 -0
- package/dist/tools/index-tools/overload-guard.js +68 -0
- package/dist/tools/index-tools/overload-guard.js.map +1 -0
- package/dist/tools/index-tools/parse.d.ts +9 -0
- package/dist/tools/index-tools/parse.d.ts.map +1 -1
- package/dist/tools/index-tools/parse.js +9 -2
- package/dist/tools/index-tools/parse.js.map +1 -1
- package/dist/tools/index-tools/registry.d.ts +25 -1
- package/dist/tools/index-tools/registry.d.ts.map +1 -1
- package/dist/tools/index-tools/registry.js +149 -8
- package/dist/tools/index-tools/registry.js.map +1 -1
- package/dist/tools/index-tools/state.d.ts +46 -0
- package/dist/tools/index-tools/state.d.ts.map +1 -1
- package/dist/tools/index-tools/state.js +132 -0
- package/dist/tools/index-tools/state.js.map +1 -1
- package/dist/tools/index-tools/watcher.d.ts.map +1 -1
- package/dist/tools/index-tools/watcher.js +13 -5
- package/dist/tools/index-tools/watcher.js.map +1 -1
- package/dist/tools/index-tools/worktree-seed.d.ts +42 -1
- package/dist/tools/index-tools/worktree-seed.d.ts.map +1 -1
- package/dist/tools/index-tools/worktree-seed.js +165 -24
- package/dist/tools/index-tools/worktree-seed.js.map +1 -1
- package/dist/tools/index-tools.d.ts +2 -2
- package/dist/tools/index-tools.d.ts.map +1 -1
- package/dist/tools/index-tools.js +2 -2
- package/dist/tools/index-tools.js.map +1 -1
- package/dist/tools/journal-generator-helpers.d.ts.map +1 -1
- package/dist/tools/journal-generator-helpers.js +3 -1
- package/dist/tools/journal-generator-helpers.js.map +1 -1
- package/dist/tools/nest-guard-tools.d.ts +8 -0
- package/dist/tools/nest-guard-tools.d.ts.map +1 -1
- package/dist/tools/nest-guard-tools.js +7 -1
- package/dist/tools/nest-guard-tools.js.map +1 -1
- package/dist/tools/nest-pipeline-tools.d.ts.map +1 -1
- package/dist/tools/nest-pipeline-tools.js +5 -1
- package/dist/tools/nest-pipeline-tools.js.map +1 -1
- package/dist/tools/outline-tools.d.ts +4 -1
- package/dist/tools/outline-tools.d.ts.map +1 -1
- package/dist/tools/outline-tools.js +41 -4
- package/dist/tools/outline-tools.js.map +1 -1
- package/dist/tools/patterns/execution.d.ts.map +1 -1
- package/dist/tools/patterns/execution.js +28 -10
- package/dist/tools/patterns/execution.js.map +1 -1
- package/dist/tools/review-diff/checks/coupling.js +1 -1
- package/dist/tools/review-diff/checks/coupling.js.map +1 -1
- package/dist/tools/review-diff/constants.d.ts +9 -0
- package/dist/tools/review-diff/constants.d.ts.map +1 -1
- package/dist/tools/review-diff/constants.js +9 -0
- package/dist/tools/review-diff/constants.js.map +1 -1
- package/dist/tools/review-diff/orchestrator.d.ts.map +1 -1
- package/dist/tools/review-diff/orchestrator.js +35 -2
- package/dist/tools/review-diff/orchestrator.js.map +1 -1
- package/dist/tools/review-diff/types.d.ts +5 -0
- package/dist/tools/review-diff/types.d.ts.map +1 -1
- package/dist/tools/route-tools/file-sources.d.ts.map +1 -1
- package/dist/tools/route-tools/file-sources.js +8 -1
- package/dist/tools/route-tools/file-sources.js.map +1 -1
- package/dist/tools/route-tools/hono.d.ts.map +1 -1
- package/dist/tools/route-tools/hono.js +18 -4
- package/dist/tools/route-tools/hono.js.map +1 -1
- package/dist/tools/route-tools/laravel.js +1 -1
- package/dist/tools/route-tools/laravel.js.map +1 -1
- package/dist/tools/route-tools/mermaid-call-chain.d.ts.map +1 -1
- package/dist/tools/route-tools/mermaid-call-chain.js +9 -1
- package/dist/tools/route-tools/mermaid-call-chain.js.map +1 -1
- package/dist/tools/route-tools/nest.js +2 -2
- package/dist/tools/route-tools/nest.js.map +1 -1
- package/dist/tools/route-tools/next-trace.d.ts.map +1 -1
- package/dist/tools/route-tools/next-trace.js +16 -1
- package/dist/tools/route-tools/next-trace.js.map +1 -1
- package/dist/tools/route-tools/next.d.ts.map +1 -1
- package/dist/tools/route-tools/next.js +10 -3
- package/dist/tools/route-tools/next.js.map +1 -1
- package/dist/tools/route-tools/route-mermaid.d.ts.map +1 -1
- package/dist/tools/route-tools/route-mermaid.js +7 -1
- package/dist/tools/route-tools/route-mermaid.js.map +1 -1
- package/dist/tools/route-tools/spring-kotlin.d.ts.map +1 -1
- package/dist/tools/route-tools/spring-kotlin.js +4 -1
- package/dist/tools/route-tools/spring-kotlin.js.map +1 -1
- package/dist/tools/route-tools/trace-route.d.ts.map +1 -1
- package/dist/tools/route-tools/trace-route.js +12 -4
- package/dist/tools/route-tools/trace-route.js.map +1 -1
- package/dist/tools/route-tools/yii2.d.ts.map +1 -1
- package/dist/tools/route-tools/yii2.js +14 -9
- package/dist/tools/route-tools/yii2.js.map +1 -1
- package/dist/tools/secret-detectors.d.ts +10 -1
- package/dist/tools/secret-detectors.d.ts.map +1 -1
- package/dist/tools/secret-detectors.js +16 -2
- package/dist/tools/secret-detectors.js.map +1 -1
- package/dist/tools/secret-file-scanner.d.ts +3 -1
- package/dist/tools/secret-file-scanner.d.ts.map +1 -1
- package/dist/tools/secret-file-scanner.js +4 -2
- package/dist/tools/secret-file-scanner.js.map +1 -1
- package/dist/tools/secret-tools.d.ts +7 -0
- package/dist/tools/secret-tools.d.ts.map +1 -1
- package/dist/tools/secret-tools.js +62 -5
- package/dist/tools/secret-tools.js.map +1 -1
- package/dist/tools/status-tools.d.ts +20 -0
- package/dist/tools/status-tools.d.ts.map +1 -1
- package/dist/tools/status-tools.js +46 -0
- package/dist/tools/status-tools.js.map +1 -1
- package/dist/tools/symbol-analysis-tools.d.ts.map +1 -1
- package/dist/tools/symbol-analysis-tools.js +27 -2
- package/dist/tools/symbol-analysis-tools.js.map +1 -1
- package/dist/tools/symbol-reference-tools.d.ts +17 -0
- package/dist/tools/symbol-reference-tools.d.ts.map +1 -1
- package/dist/tools/symbol-reference-tools.js +23 -4
- package/dist/tools/symbol-reference-tools.js.map +1 -1
- package/dist/tools/symbol-tool-internals.d.ts +10 -0
- package/dist/tools/symbol-tool-internals.d.ts.map +1 -1
- package/dist/tools/symbol-tool-internals.js +16 -1
- package/dist/tools/symbol-tool-internals.js.map +1 -1
- package/dist/tools/test-impact-tools.d.ts +3 -0
- package/dist/tools/test-impact-tools.d.ts.map +1 -1
- package/dist/tools/test-impact-tools.js +26 -4
- package/dist/tools/test-impact-tools.js.map +1 -1
- package/dist/tools/wiki-overview-sources.d.ts.map +1 -1
- package/dist/tools/wiki-overview-sources.js +3 -0
- package/dist/tools/wiki-overview-sources.js.map +1 -1
- package/dist/utils/import-graph/collect.d.ts +2 -3
- package/dist/utils/import-graph/collect.d.ts.map +1 -1
- package/dist/utils/import-graph/collect.js +73 -8
- package/dist/utils/import-graph/collect.js.map +1 -1
- package/dist/utils/import-graph/edge-accumulator.d.ts.map +1 -1
- package/dist/utils/import-graph/edge-accumulator.js +5 -0
- package/dist/utils/import-graph/edge-accumulator.js.map +1 -1
- package/dist/utils/import-graph/edge-cache.d.ts +15 -0
- package/dist/utils/import-graph/edge-cache.d.ts.map +1 -0
- package/dist/utils/import-graph/edge-cache.js +98 -0
- package/dist/utils/import-graph/edge-cache.js.map +1 -0
- package/dist/utils/import-graph/language-imports.d.ts +2 -2
- package/dist/utils/import-graph/language-imports.d.ts.map +1 -1
- package/dist/utils/import-graph/language-imports.js.map +1 -1
- package/dist/utils/import-graph/path-map.d.ts +2 -2
- package/dist/utils/import-graph/path-map.d.ts.map +1 -1
- package/dist/utils/import-graph/path-map.js.map +1 -1
- package/dist/utils/import-graph/python-php-edge-collectors.d.ts +11 -4
- package/dist/utils/import-graph/python-php-edge-collectors.d.ts.map +1 -1
- package/dist/utils/import-graph/python-php-edge-collectors.js +22 -5
- package/dist/utils/import-graph/python-php-edge-collectors.js.map +1 -1
- package/dist/utils/import-graph/source-edge-collector.d.ts +2 -3
- package/dist/utils/import-graph/source-edge-collector.d.ts.map +1 -1
- package/dist/utils/import-graph/source-edge-collector.js +7 -2
- package/dist/utils/import-graph/source-edge-collector.js.map +1 -1
- package/dist/utils/import-graph/types.d.ts +36 -1
- package/dist/utils/import-graph/types.d.ts.map +1 -1
- package/dist/utils/import-graph/typescript-edge-collector.d.ts +2 -3
- package/dist/utils/import-graph/typescript-edge-collector.d.ts.map +1 -1
- package/dist/utils/import-graph/typescript-edge-collector.js +6 -2
- package/dist/utils/import-graph/typescript-edge-collector.js.map +1 -1
- package/dist/utils/import-graph/workspace-alias.d.ts +2 -2
- package/dist/utils/import-graph/workspace-alias.d.ts.map +1 -1
- package/dist/utils/import-graph/workspace-alias.js.map +1 -1
- package/dist/utils/language-detect.d.ts +2 -4
- package/dist/utils/language-detect.d.ts.map +1 -1
- package/dist/utils/language-detect.js +26 -4
- package/dist/utils/language-detect.js.map +1 -1
- package/dist/utils/python-imports.d.ts +20 -0
- package/dist/utils/python-imports.d.ts.map +1 -1
- package/dist/utils/python-imports.js +52 -0
- package/dist/utils/python-imports.js.map +1 -1
- package/dist/utils/ts-imports.d.ts +16 -0
- package/dist/utils/ts-imports.d.ts.map +1 -1
- package/dist/utils/ts-imports.js +65 -3
- package/dist/utils/ts-imports.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { recordIndexFootprint } from "../index-footprint.js";
|
|
2
|
-
import { openIndexDb, openReadConnection, readMetaValue, rollbackQuietly, writeMetaValue, } from "./connection.js";
|
|
2
|
+
import { openIndexDb, openReadConnection, readMetaValue, rollbackQuietly, writeMetaValue, maybeCheckpointWal, } from "./connection.js";
|
|
3
3
|
import { rethrowOperational } from "./errors.js";
|
|
4
4
|
import { readMetaExtras } from "./meta.js";
|
|
5
5
|
import { INSERT_FILE_SQL, INSERT_SYMBOL_SQL, fileEntryToRow, fileRowBytes, rowToFileEntry, rowToSymbol, symbolRowBytes, symbolToRow, } from "./rows.js";
|
|
@@ -29,11 +29,14 @@ export async function saveIndexSqlite(dbPath, index, opts) {
|
|
|
29
29
|
const db = await openIndexDb(dbPath);
|
|
30
30
|
db.exec("BEGIN");
|
|
31
31
|
try {
|
|
32
|
-
writeIndexRows(db, index);
|
|
32
|
+
await writeIndexRows(db, index);
|
|
33
33
|
if (opts?.sourceComplete === true) {
|
|
34
34
|
db.prepare("DELETE FROM meta WHERE key = ?").run("lossy_v1_migration");
|
|
35
35
|
}
|
|
36
36
|
db.exec("COMMIT");
|
|
37
|
+
// AFTER the commit, never inside the transaction: a checkpoint cannot run in one, and it must
|
|
38
|
+
// not be able to fail a write that already succeeded.
|
|
39
|
+
maybeCheckpointWal(db, dbPath);
|
|
37
40
|
}
|
|
38
41
|
catch (err) {
|
|
39
42
|
rollbackQuietly(db);
|
|
@@ -60,15 +63,64 @@ export async function wasLossilyMigrated(dbPath) {
|
|
|
60
63
|
* as "no index" — so a write killed midway rolls back and the db reads as empty rather than
|
|
61
64
|
* as a partially-populated index that later looks complete.
|
|
62
65
|
*/
|
|
63
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Rows written per turn before the event loop gets a chance to run.
|
|
68
|
+
*
|
|
69
|
+
* `node:sqlite` is entirely synchronous — every `.run()` blocks the thread — and this loop used to
|
|
70
|
+
* hold it for the WHOLE index. Measured on the largest real index here (372,949 symbols, a 732 MB
|
|
71
|
+
* database): **3.2 seconds of uninterrupted main thread** per full save. In a shared daemon that is
|
|
72
|
+
* 3.2 seconds during which no other client gets an answer, `/health` included; sampling a stalled
|
|
73
|
+
* daemon put 41% of main-thread time inside `StatementSync::Run`.
|
|
74
|
+
*
|
|
75
|
+
* Yielding does not make the write faster — the work is the same. It makes the SERVER responsive
|
|
76
|
+
* while the work happens, which is the actual complaint. Measured on that index, longest stall the
|
|
77
|
+
* event loop saw during a full save:
|
|
78
|
+
*
|
|
79
|
+
* no yielding the loop never ran at all (0 timer ticks in 3.8 s)
|
|
80
|
+
* every 5000 42 ms
|
|
81
|
+
* every 500 22 ms
|
|
82
|
+
* every 250 22 ms
|
|
83
|
+
*
|
|
84
|
+
* 500 and 250 are indistinguishable on responsiveness, and total time between them differed by 30%
|
|
85
|
+
* across runs on identical work — i.e. noise, not signal, so it did not decide anything. 500 buys
|
|
86
|
+
* the same 22 ms at half the yields.
|
|
87
|
+
*
|
|
88
|
+
* Note the first row is not "0 ms of stall": the timer never fired, so there was nothing to
|
|
89
|
+
* measure. That is the worst case, not the best.
|
|
90
|
+
*
|
|
91
|
+
* Tuning the database instead was tried and rejected on measurement: `cache_size = 64 MB` plus
|
|
92
|
+
* `synchronous = NORMAL` bought 3% on that same index. The cost is the row count, not the pager.
|
|
93
|
+
*/
|
|
94
|
+
const ROWS_PER_TURN = 500;
|
|
95
|
+
/** Hand the event loop a turn. `setImmediate` runs after I/O callbacks, so pending requests progress. */
|
|
96
|
+
function yieldToEventLoop() {
|
|
97
|
+
return new Promise((resolve) => setImmediate(resolve));
|
|
98
|
+
}
|
|
99
|
+
async function writeIndexRows(db, index) {
|
|
64
100
|
db.exec("DELETE FROM symbols");
|
|
65
101
|
db.exec("DELETE FROM files");
|
|
102
|
+
// The transaction stays OPEN across these yields, which is safe only because writes to one index
|
|
103
|
+
// are serialised (see the per-path write lock in index-json-mutations.ts and the mutex in
|
|
104
|
+
// saveIndexSqlite): a second BEGIN on this shared connection would otherwise fail with
|
|
105
|
+
// "cannot start a transaction within a transaction". Readers are unaffected — they use a private
|
|
106
|
+
// connection whose WAL snapshot is fixed at BEGIN.
|
|
66
107
|
const insSym = db.prepare(INSERT_SYMBOL_SQL);
|
|
67
|
-
|
|
108
|
+
let sinceYield = 0;
|
|
109
|
+
for (const sym of index.symbols) {
|
|
68
110
|
insSym.run(...symbolToRow(sym));
|
|
111
|
+
if (++sinceYield >= ROWS_PER_TURN) {
|
|
112
|
+
sinceYield = 0;
|
|
113
|
+
await yieldToEventLoop();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
69
116
|
const insFile = db.prepare(INSERT_FILE_SQL);
|
|
70
|
-
for (const file of index.files)
|
|
117
|
+
for (const file of index.files) {
|
|
71
118
|
insFile.run(...fileEntryToRow(file));
|
|
119
|
+
if (++sinceYield >= ROWS_PER_TURN) {
|
|
120
|
+
sinceYield = 0;
|
|
121
|
+
await yieldToEventLoop();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
72
124
|
writeMetaValue(db, "repo", index.repo);
|
|
73
125
|
writeMetaValue(db, "root", index.root);
|
|
74
126
|
writeMetaValue(db, "created_at", String(index.created_at));
|
|
@@ -98,7 +150,10 @@ export async function importLegacyIndexIfEmpty(dbPath, index) {
|
|
|
98
150
|
db.exec("ROLLBACK");
|
|
99
151
|
return false; // another process got there first
|
|
100
152
|
}
|
|
101
|
-
|
|
153
|
+
// Yields inside BEGIN IMMEDIATE hold the cross-process write lock a little longer, which is
|
|
154
|
+
// acceptable here: this runs once per index, when migrating a legacy JSON file, and the guard
|
|
155
|
+
// it implements is exactly about not letting a second process write meanwhile.
|
|
156
|
+
await writeIndexRows(db, index);
|
|
102
157
|
db.exec("COMMIT");
|
|
103
158
|
return true;
|
|
104
159
|
}
|
|
@@ -152,13 +207,47 @@ export async function importLegacyIndexIfEmpty(dbPath, index) {
|
|
|
152
207
|
* turning a linear read into a quadratic one exactly on the biggest indexes this exists for.
|
|
153
208
|
*/
|
|
154
209
|
const PAGE_TARGET_MS = 50;
|
|
155
|
-
|
|
210
|
+
/**
|
|
211
|
+
* The floor was 500 — and 500 is a ROW COUNT, which is the one thing the paragraph above says a page
|
|
212
|
+
* must not be sized by.
|
|
213
|
+
*
|
|
214
|
+
* It held while pages were slow for CPU reasons (GC, allocation), because those vary by maybe an
|
|
215
|
+
* order of magnitude. It does not hold when the DISK is the slow part. Measured 2026-09-02 with 21
|
|
216
|
+
* concurrent `npm ci` on this machine: 50,835 IOPS at ~6.9 KB each, the daemon sitting in state `U`
|
|
217
|
+
* (uninterruptible kernel I/O), `initialize` taking 40 s, and clients giving up and running the rest
|
|
218
|
+
* of their session with no CodeSift tools at all.
|
|
219
|
+
*
|
|
220
|
+
* `node:sqlite` is synchronous by design — DatabaseSync and StatementSync are the entire module,
|
|
221
|
+
* there is no async class to switch to — so a page is a blocking syscall for as long as the disk
|
|
222
|
+
* takes. The feedback loop is the right mechanism and was simply not allowed to go low enough:
|
|
223
|
+
* against a disk 100x slower it wanted a page 100x smaller and could not have one.
|
|
224
|
+
*
|
|
225
|
+
* 50 keeps the bulk fetch meaningful — per-ROW yielding was measured to turn the same load into
|
|
226
|
+
* minutes — while giving the loop an order of magnitude more room to shrink.
|
|
227
|
+
*/
|
|
228
|
+
const PAGE_MIN_ROWS = 50;
|
|
156
229
|
const PAGE_MAX_ROWS = 20_000;
|
|
230
|
+
/**
|
|
231
|
+
* The FIRST page is the one nothing has measured yet, so it is the one that can block longest. At
|
|
232
|
+
* 4,000 rows it was a bet that the disk is fast, taken before any evidence — and on a saturated disk
|
|
233
|
+
* that is a multi-second stall in front of every other client's request, the handshake included.
|
|
234
|
+
*
|
|
235
|
+
* Starting at the floor costs two or three extra pages on a fast disk (the loop multiplies back up
|
|
236
|
+
* to 20,000 within a page or two) and bounds the worst case on a slow one.
|
|
237
|
+
*/
|
|
238
|
+
const PAGE_FIRST_ROWS = PAGE_MIN_ROWS;
|
|
239
|
+
/**
|
|
240
|
+
* Row count for the next page, aimed at the time budget. Extracted so the adaptation can be tested
|
|
241
|
+
* directly: a disk-bound stall is not reproducible in a unit test, but the decision it forces is.
|
|
242
|
+
*/
|
|
243
|
+
export function nextPageRows(currentRows, elapsedMs) {
|
|
244
|
+
return Math.max(PAGE_MIN_ROWS, Math.min(PAGE_MAX_ROWS, Math.round(currentRows * (PAGE_TARGET_MS / Math.max(elapsedMs, 1)))));
|
|
245
|
+
}
|
|
157
246
|
async function readTablePaged(db, table, fn) {
|
|
158
247
|
const stmt = db.prepare(`SELECT rowid AS _rid, * FROM ${table} WHERE rowid > ? ORDER BY rowid LIMIT ?`);
|
|
159
248
|
const out = [];
|
|
160
249
|
let cursor = 0;
|
|
161
|
-
let rows =
|
|
250
|
+
let rows = PAGE_FIRST_ROWS;
|
|
162
251
|
for (;;) {
|
|
163
252
|
const started = Date.now();
|
|
164
253
|
const page = stmt.all(cursor, rows);
|
|
@@ -175,7 +264,7 @@ async function readTablePaged(db, table, fn) {
|
|
|
175
264
|
// under a daemon already holding several indexes, because allocating a few thousand
|
|
176
265
|
// objects there lands in incremental marking. A fixed row count is therefore tuned for
|
|
177
266
|
// one heap and wrong for the other; a fixed time budget holds in both.
|
|
178
|
-
rows =
|
|
267
|
+
rows = nextPageRows(rows, elapsed);
|
|
179
268
|
await new Promise((r) => setImmediate(r));
|
|
180
269
|
}
|
|
181
270
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-io.js","sourceRoot":"","sources":["../../../src/storage/sqlite/index-io.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,cAAc,
|
|
1
|
+
{"version":3,"file":"index-io.js","sourceRoot":"","sources":["../../../src/storage/sqlite/index-io.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,13 @@ import type { FileEntry, Workspace } from "../../types.js";
|
|
|
18
18
|
* `symbol_count` is counted in SQL rather than derived from an array, so it stays a real count.
|
|
19
19
|
*/
|
|
20
20
|
export interface IndexSummary {
|
|
21
|
+
/**
|
|
22
|
+
* Where this repo's artifacts live. Set by the tool-layer accessor, which knows it from the
|
|
23
|
+
* registry; absent when a summary is built directly from a database path. Consumers that cache
|
|
24
|
+
* something alongside the index (the parsed-imports cache) need it, and everything else ignores
|
|
25
|
+
* it.
|
|
26
|
+
*/
|
|
27
|
+
indexPath?: string | undefined;
|
|
21
28
|
repo: string;
|
|
22
29
|
root: string;
|
|
23
30
|
files: FileEntry[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/meta.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3D;;;;;;;GAOG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GACxC,IAAI,CAAC,YAAY,EAAE,mBAAmB,GAAG,YAAY,GAAG,iBAAiB,CAAC,CAmB5E"}
|
|
1
|
+
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/meta.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3D;;;;;;;GAOG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GACxC,IAAI,CAAC,YAAY,EAAE,mBAAmB,GAAG,YAAY,GAAG,iBAAiB,CAAC,CAmB5E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../src/storage/sqlite/meta.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../src/storage/sqlite/meta.ts"],"names":[],"mappings":"AAyCA;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAyC;IAEzC,MAAM,GAAG,GAA+E,EAAE,CAAC;IAE3F,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC/C,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAkC,CAAC;QACzE,IAAI,MAAM,KAAK,IAAI;YAAE,GAAG,CAAC,iBAAiB,GAAG,MAAM,CAAC;IACtD,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;IACzC,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAuB,CAAC;QAC/D,IAAI,MAAM,KAAK,IAAI;YAAE,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC;IAC/C,CAAC;IAED,0FAA0F;IAC1F,IAAI,IAAI,CAAC,oBAAoB,CAAC,KAAK,SAAS;QAAE,GAAG,CAAC,eAAe,GAAG,IAAI,CAAC;IAEzE,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { CodeSymbol } from "../../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Ask the database for the rows a tool needs, instead of materialising the whole index.
|
|
4
|
+
*
|
|
5
|
+
* A cold `getCodeIndex` builds 349 MB and ~352,000 objects for the largest repo here, through a
|
|
6
|
+
* synchronous SQLite API, and hands the same object to every caller. Measured against that:
|
|
7
|
+
*
|
|
8
|
+
* WHERE name = ? 9 ms WHERE kind = ? 32 ms (after idx_symbols_kind)
|
|
9
|
+
* WHERE file = ? 10 ms materialise all ~10,000 ms
|
|
10
|
+
*
|
|
11
|
+
* Three orders of magnitude, and the classification of the 159 call sites says 31% of them need no
|
|
12
|
+
* array at all — a metadata read or a single WHERE.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* `withSource` has NO DEFAULT, on purpose.
|
|
16
|
+
*
|
|
17
|
+
* `source` is 45% of the footprint — roughly 650 bytes per symbol — and two thirds of call sites
|
|
18
|
+
* never read it. But omitting the column silently is the dangerous half: `rowToSymbol` does
|
|
19
|
+
* `if (row.source !== null) sym.source = row.source`, so a projected-away column arrives as
|
|
20
|
+
* `undefined` and produces a symbol that is INDISTINGUISHABLE from one whose source is genuinely
|
|
21
|
+
* empty. A caller would read "this function has no body" as a fact about the code.
|
|
22
|
+
*
|
|
23
|
+
* Requiring the flag makes the compiler ask the question at every call site. When it is false the
|
|
24
|
+
* key is omitted entirely rather than set to undefined, so `"source" in symbol` is an honest test.
|
|
25
|
+
*/
|
|
26
|
+
export interface SymbolQuery {
|
|
27
|
+
withSource: boolean;
|
|
28
|
+
file?: string;
|
|
29
|
+
name?: string;
|
|
30
|
+
/** Prefix only. A leading `%` cannot use idx_symbols_name and degrades to a full scan. */
|
|
31
|
+
namePrefix?: string;
|
|
32
|
+
kind?: string;
|
|
33
|
+
parent?: string;
|
|
34
|
+
ids?: readonly string[];
|
|
35
|
+
limit?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface IndexMeta {
|
|
38
|
+
repo: string;
|
|
39
|
+
root: string;
|
|
40
|
+
updatedAt: number;
|
|
41
|
+
symbolCount: number;
|
|
42
|
+
fileCount: number;
|
|
43
|
+
}
|
|
44
|
+
export declare function findSymbolsSqlite(dbPath: string, query: SymbolQuery): Promise<CodeSymbol[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Fold over matching symbols in pages, yielding the event loop between them.
|
|
47
|
+
*
|
|
48
|
+
* For the whole-scan callers (bucket A: 37 of 159 call sites) that genuinely have to see every
|
|
49
|
+
* symbol but never need them all resident at once — regex scanners, adjacency builders, vocabulary
|
|
50
|
+
* collectors. They fold and discard, so holding 352,000 objects was never the requirement.
|
|
51
|
+
*
|
|
52
|
+
* A private read connection, like `loadIndexSqlite`: the pages must come from ONE snapshot, and
|
|
53
|
+
* this yields between them, so a shared connection could observe another process's commit halfway
|
|
54
|
+
* through and return a mixture of two states.
|
|
55
|
+
*/
|
|
56
|
+
export declare function streamSymbolsSqlite(dbPath: string, query: SymbolQuery,
|
|
57
|
+
/** Return `false` to stop early — for callers with a wall-clock budget, which must be able to
|
|
58
|
+
* abandon a scan without reading the rest of the table. */
|
|
59
|
+
onBatch: (batch: CodeSymbol[]) => void | boolean | Promise<void | boolean>): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Root, repo and counts — for the 26 call sites that materialise 349 MB to read `index.root`, and
|
|
62
|
+
* the two that materialise it to check whether the index exists at all
|
|
63
|
+
* (`nest-pipeline-tools.ts:45`, `sql-dml-safety-tools.ts:32`).
|
|
64
|
+
*/
|
|
65
|
+
export declare function getIndexMetaSqlite(dbPath: string): Promise<IndexMeta | null>;
|
|
66
|
+
//# sourceMappingURL=queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAMjD;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0FAA0F;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AA0DD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,UAAU,EAAE,CAAC,CA2BvB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,WAAW;AAClB;4DAC4D;AAC5D,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,GACzE,OAAO,CAAC,IAAI,CAAC,CAqDf;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAkBlF"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { openIndexDb, openReadConnection, readMetaValue } from "./connection.js";
|
|
2
|
+
import { rethrowOperational } from "./errors.js";
|
|
3
|
+
import { rowToSymbol } from "./rows.js";
|
|
4
|
+
import { nextPageRows } from "./index-io.js";
|
|
5
|
+
/** Every column except `source`, so the projection can drop the expensive one by name. */
|
|
6
|
+
const COLUMNS_WITHOUT_SOURCE = "id, file, name, kind, start_line, end_line, start_col, end_col, start_byte, end_byte, " +
|
|
7
|
+
"signature, docstring, parent, is_async, is_exported, extras";
|
|
8
|
+
/**
|
|
9
|
+
* SQLite's default parameter limit is 999. An `ids` list longer than that is a hard error rather
|
|
10
|
+
* than a slow query, so it is chunked — and the chunks are unioned by the caller, not by SQL,
|
|
11
|
+
* because a UNION would have to re-sort.
|
|
12
|
+
*/
|
|
13
|
+
const MAX_BOUND_PARAMS = 900;
|
|
14
|
+
function buildPredicate(query, idChunk) {
|
|
15
|
+
const clauses = [];
|
|
16
|
+
const binds = [];
|
|
17
|
+
if (query.file !== undefined) {
|
|
18
|
+
clauses.push("file = ?");
|
|
19
|
+
binds.push(query.file);
|
|
20
|
+
}
|
|
21
|
+
if (query.name !== undefined) {
|
|
22
|
+
clauses.push("name = ?");
|
|
23
|
+
binds.push(query.name);
|
|
24
|
+
}
|
|
25
|
+
if (query.namePrefix !== undefined) {
|
|
26
|
+
// `LIKE 'x%'` uses idx_symbols_name; the ESCAPE clause keeps a literal % or _ in a symbol name
|
|
27
|
+
// from turning into a wildcard, which would silently widen the query.
|
|
28
|
+
clauses.push("name LIKE ? ESCAPE '\\'");
|
|
29
|
+
binds.push(`${query.namePrefix.replace(/[\\%_]/g, "\\$&")}%`);
|
|
30
|
+
}
|
|
31
|
+
if (query.kind !== undefined) {
|
|
32
|
+
clauses.push("kind = ?");
|
|
33
|
+
binds.push(query.kind);
|
|
34
|
+
}
|
|
35
|
+
if (query.parent !== undefined) {
|
|
36
|
+
clauses.push("parent = ?");
|
|
37
|
+
binds.push(query.parent);
|
|
38
|
+
}
|
|
39
|
+
if (idChunk !== undefined) {
|
|
40
|
+
clauses.push(`id IN (${idChunk.map(() => "?").join(",")})`);
|
|
41
|
+
binds.push(...idChunk);
|
|
42
|
+
}
|
|
43
|
+
return { sql: clauses.length > 0 ? `WHERE ${clauses.join(" AND ")}` : "", binds };
|
|
44
|
+
}
|
|
45
|
+
function chunkIds(ids) {
|
|
46
|
+
if (ids === undefined)
|
|
47
|
+
return [undefined];
|
|
48
|
+
if (ids.length === 0)
|
|
49
|
+
return [];
|
|
50
|
+
const out = [];
|
|
51
|
+
for (let i = 0; i < ids.length; i += MAX_BOUND_PARAMS)
|
|
52
|
+
out.push([...ids.slice(i, i + MAX_BOUND_PARAMS)]);
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Map a row whose `source` column was never selected.
|
|
57
|
+
*
|
|
58
|
+
* Not `rowToSymbol` with a patched row: that mapper tests `row.source !== null`, and `undefined`
|
|
59
|
+
* passes that test. Giving it an explicit null is what keeps the key absent rather than present
|
|
60
|
+
* and undefined — the distinction the whole `withSource` contract rests on.
|
|
61
|
+
*/
|
|
62
|
+
function rowToSymbolNoSource(row, repo) {
|
|
63
|
+
return rowToSymbol({ ...row, source: null }, repo);
|
|
64
|
+
}
|
|
65
|
+
export async function findSymbolsSqlite(dbPath, query) {
|
|
66
|
+
const db = await openIndexDb(dbPath);
|
|
67
|
+
try {
|
|
68
|
+
const repo = readMetaValue(db, "repo");
|
|
69
|
+
if (repo === undefined)
|
|
70
|
+
return [];
|
|
71
|
+
const columns = query.withSource ? "*" : COLUMNS_WITHOUT_SOURCE;
|
|
72
|
+
const out = [];
|
|
73
|
+
for (const idChunk of chunkIds(query.ids)) {
|
|
74
|
+
if (query.limit !== undefined && out.length >= query.limit)
|
|
75
|
+
break;
|
|
76
|
+
const { sql, binds } = buildPredicate(query, idChunk);
|
|
77
|
+
const remaining = query.limit === undefined ? undefined : query.limit - out.length;
|
|
78
|
+
const limitSql = remaining === undefined ? "" : ` LIMIT ${Math.max(0, remaining)}`;
|
|
79
|
+
const rows = db
|
|
80
|
+
.prepare(`SELECT ${columns} FROM symbols ${sql}${limitSql}`)
|
|
81
|
+
.all(...binds);
|
|
82
|
+
for (const row of rows) {
|
|
83
|
+
out.push(query.withSource ? rowToSymbol(row, repo) : rowToSymbolNoSource(row, repo));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return out;
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
// Corruption surfaces on the first page touched, not at open, and callers use
|
|
90
|
+
// `isIndexStorageError` to tell a storage fault from "nothing indexed here". Without this the
|
|
91
|
+
// read falls into the branch that reports an unindexed repo — a fault rendered as an empty
|
|
92
|
+
// answer, which is the worst shape a search result can take.
|
|
93
|
+
rethrowOperational(err, dbPath);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Fold over matching symbols in pages, yielding the event loop between them.
|
|
98
|
+
*
|
|
99
|
+
* For the whole-scan callers (bucket A: 37 of 159 call sites) that genuinely have to see every
|
|
100
|
+
* symbol but never need them all resident at once — regex scanners, adjacency builders, vocabulary
|
|
101
|
+
* collectors. They fold and discard, so holding 352,000 objects was never the requirement.
|
|
102
|
+
*
|
|
103
|
+
* A private read connection, like `loadIndexSqlite`: the pages must come from ONE snapshot, and
|
|
104
|
+
* this yields between them, so a shared connection could observe another process's commit halfway
|
|
105
|
+
* through and return a mixture of two states.
|
|
106
|
+
*/
|
|
107
|
+
export async function streamSymbolsSqlite(dbPath, query,
|
|
108
|
+
/** Return `false` to stop early — for callers with a wall-clock budget, which must be able to
|
|
109
|
+
* abandon a scan without reading the rest of the table. */
|
|
110
|
+
onBatch) {
|
|
111
|
+
const reader = await openReadConnection(dbPath);
|
|
112
|
+
try {
|
|
113
|
+
const repo = readMetaValue(reader, "repo");
|
|
114
|
+
if (repo === undefined)
|
|
115
|
+
return;
|
|
116
|
+
const columns = query.withSource ? "*" : COLUMNS_WITHOUT_SOURCE;
|
|
117
|
+
reader.exec("BEGIN");
|
|
118
|
+
try {
|
|
119
|
+
for (const idChunk of chunkIds(query.ids)) {
|
|
120
|
+
const { sql, binds } = buildPredicate(query, idChunk);
|
|
121
|
+
const where = sql === "" ? "WHERE rowid > ?" : `${sql} AND rowid > ?`;
|
|
122
|
+
const stmt = reader.prepare(`SELECT rowid AS _rid, ${columns} FROM symbols ${where} ORDER BY rowid LIMIT ?`);
|
|
123
|
+
let cursor = 0;
|
|
124
|
+
let rows = 50;
|
|
125
|
+
let seen = 0;
|
|
126
|
+
for (;;) {
|
|
127
|
+
const started = Date.now();
|
|
128
|
+
const page = stmt.all(...binds, cursor, rows);
|
|
129
|
+
// Terminate on EMPTY, not on a short page.
|
|
130
|
+
//
|
|
131
|
+
// With the filter in SQL a short page does in fact mean exhaustion — LIMIT counts
|
|
132
|
+
// MATCHES, not scanned rows — so `page.length < rows` would be correct today. It is not
|
|
133
|
+
// used anyway, for one round-trip: the moment anyone adds a post-fetch filter in JS (the
|
|
134
|
+
// obvious way to express a predicate SQL cannot), the short-page test silently becomes
|
|
135
|
+
// "stop at the first sparsely-matching stretch and report success". Costing one extra
|
|
136
|
+
// query to remove that trap is the right trade in a reader that folds over 352,000 rows.
|
|
137
|
+
if (page.length === 0)
|
|
138
|
+
break;
|
|
139
|
+
cursor = page[page.length - 1]._rid;
|
|
140
|
+
const batch = page.map((row) => query.withSource ? rowToSymbol(row, repo) : rowToSymbolNoSource(row, repo));
|
|
141
|
+
seen += batch.length;
|
|
142
|
+
if (query.limit !== undefined && seen >= query.limit) {
|
|
143
|
+
await onBatch(batch.slice(0, batch.length - (seen - query.limit)));
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
if ((await onBatch(batch)) === false)
|
|
147
|
+
break;
|
|
148
|
+
rows = nextPageRows(rows, Date.now() - started);
|
|
149
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
try {
|
|
155
|
+
reader.exec("COMMIT");
|
|
156
|
+
}
|
|
157
|
+
catch { /* the close below is what matters */ }
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
rethrowOperational(err, dbPath);
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
try {
|
|
165
|
+
reader.close();
|
|
166
|
+
}
|
|
167
|
+
catch { /* already gone */ }
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Root, repo and counts — for the 26 call sites that materialise 349 MB to read `index.root`, and
|
|
172
|
+
* the two that materialise it to check whether the index exists at all
|
|
173
|
+
* (`nest-pipeline-tools.ts:45`, `sql-dml-safety-tools.ts:32`).
|
|
174
|
+
*/
|
|
175
|
+
export async function getIndexMetaSqlite(dbPath) {
|
|
176
|
+
const db = await openIndexDb(dbPath);
|
|
177
|
+
try {
|
|
178
|
+
const repo = readMetaValue(db, "repo");
|
|
179
|
+
const root = readMetaValue(db, "root");
|
|
180
|
+
if (repo === undefined || root === undefined)
|
|
181
|
+
return null;
|
|
182
|
+
const symbolCount = db.prepare("SELECT COUNT(*) AS n FROM symbols").get().n;
|
|
183
|
+
const fileCount = db.prepare("SELECT COUNT(*) AS n FROM files").get().n;
|
|
184
|
+
return {
|
|
185
|
+
repo,
|
|
186
|
+
root,
|
|
187
|
+
updatedAt: Number(readMetaValue(db, "updated_at") ?? 0),
|
|
188
|
+
symbolCount,
|
|
189
|
+
fileCount,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
rethrowOperational(err, dbPath);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../../src/storage/sqlite/queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* id return the first match exactly as the array scan did.
|
|
22
22
|
*/
|
|
23
23
|
export declare const SCHEMA_VERSION = 2;
|
|
24
|
-
export declare const SCHEMA_SQL = "\nCREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS files (\n path TEXT PRIMARY KEY,\n language TEXT NOT NULL,\n symbol_count INTEGER NOT NULL,\n last_modified INTEGER NOT NULL,\n mtime_ms INTEGER,\n stale INTEGER\n);\n\nCREATE TABLE IF NOT EXISTS symbols (\n id TEXT NOT NULL,\n file TEXT NOT NULL,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n start_line INTEGER NOT NULL,\n end_line INTEGER NOT NULL,\n start_col INTEGER,\n end_col INTEGER,\n start_byte INTEGER,\n end_byte INTEGER,\n signature TEXT,\n docstring TEXT,\n source TEXT,\n parent TEXT,\n is_async INTEGER,\n is_exported INTEGER,\n extras TEXT\n);\n\nCREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file);\nCREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);\nCREATE INDEX IF NOT EXISTS idx_symbols_id ON symbols(id);\n";
|
|
24
|
+
export declare const SCHEMA_SQL = "\nCREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS files (\n path TEXT PRIMARY KEY,\n language TEXT NOT NULL,\n symbol_count INTEGER NOT NULL,\n last_modified INTEGER NOT NULL,\n mtime_ms INTEGER,\n stale INTEGER\n);\n\nCREATE TABLE IF NOT EXISTS symbols (\n id TEXT NOT NULL,\n file TEXT NOT NULL,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n start_line INTEGER NOT NULL,\n end_line INTEGER NOT NULL,\n start_col INTEGER,\n end_col INTEGER,\n start_byte INTEGER,\n end_byte INTEGER,\n signature TEXT,\n docstring TEXT,\n source TEXT,\n parent TEXT,\n is_async INTEGER,\n is_exported INTEGER,\n extras TEXT\n);\n\nCREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file);\nCREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);\nCREATE INDEX IF NOT EXISTS idx_symbols_id ON symbols(id);\nCREATE INDEX IF NOT EXISTS idx_symbols_kind ON symbols(kind);\nCREATE INDEX IF NOT EXISTS idx_symbols_parent ON symbols(parent);\n";
|
|
25
25
|
/**
|
|
26
26
|
* v1 -> v2: rebuild `symbols` without the PRIMARY KEY, keeping every row already stored.
|
|
27
27
|
*
|
|
@@ -30,5 +30,5 @@ export declare const SCHEMA_SQL = "\nCREATE TABLE IF NOT EXISTS meta (\n key
|
|
|
30
30
|
* incomplete for no store at all. This recovers nothing on its own; rows lost under v1 come
|
|
31
31
|
* back when the repo is next indexed from source, which now keeps them.
|
|
32
32
|
*/
|
|
33
|
-
export declare const MIGRATE_V1_TO_V2_SQL = "\nALTER TABLE symbols RENAME TO symbols_v1;\nCREATE TABLE symbols (\n id TEXT NOT NULL,\n file TEXT NOT NULL,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n start_line INTEGER NOT NULL,\n end_line INTEGER NOT NULL,\n start_col INTEGER,\n end_col INTEGER,\n start_byte INTEGER,\n end_byte INTEGER,\n signature TEXT,\n docstring TEXT,\n source TEXT,\n parent TEXT,\n is_async INTEGER,\n is_exported INTEGER,\n extras TEXT\n);\nINSERT INTO symbols SELECT * FROM symbols_v1;\nDROP TABLE symbols_v1;\nCREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file);\nCREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);\nCREATE INDEX IF NOT EXISTS idx_symbols_id ON symbols(id);\n";
|
|
33
|
+
export declare const MIGRATE_V1_TO_V2_SQL = "\nALTER TABLE symbols RENAME TO symbols_v1;\nCREATE TABLE symbols (\n id TEXT NOT NULL,\n file TEXT NOT NULL,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n start_line INTEGER NOT NULL,\n end_line INTEGER NOT NULL,\n start_col INTEGER,\n end_col INTEGER,\n start_byte INTEGER,\n end_byte INTEGER,\n signature TEXT,\n docstring TEXT,\n source TEXT,\n parent TEXT,\n is_async INTEGER,\n is_exported INTEGER,\n extras TEXT\n);\nINSERT INTO symbols SELECT * FROM symbols_v1;\nDROP TABLE symbols_v1;\nCREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file);\nCREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);\nCREATE INDEX IF NOT EXISTS idx_symbols_id ON symbols(id);\nCREATE INDEX IF NOT EXISTS idx_symbols_kind ON symbols(kind);\nCREATE INDEX IF NOT EXISTS idx_symbols_parent ON symbols(parent);\n";
|
|
34
34
|
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,eAAO,MAAM,UAAU,imCAwCtB,CAAC;AAmCF;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,k4BA4BhC,CAAC"}
|
|
@@ -59,7 +59,41 @@ CREATE TABLE IF NOT EXISTS symbols (
|
|
|
59
59
|
CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file);
|
|
60
60
|
CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);
|
|
61
61
|
CREATE INDEX IF NOT EXISTS idx_symbols_id ON symbols(id);
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_symbols_kind ON symbols(kind);
|
|
63
|
+
CREATE INDEX IF NOT EXISTS idx_symbols_parent ON symbols(parent);
|
|
62
64
|
`;
|
|
65
|
+
/*
|
|
66
|
+
* Why `kind` and `parent` are indexed, and why that needed no schema version bump.
|
|
67
|
+
*
|
|
68
|
+
* Measured on this machine's largest index (352,166 symbols, 767 MB) BEFORE they existed:
|
|
69
|
+
*
|
|
70
|
+
* WHERE name = ? 9 ms (idx_symbols_name)
|
|
71
|
+
* WHERE file = ? 10 ms (idx_symbols_file)
|
|
72
|
+
* WHERE kind = ? 2128 ms full table scan
|
|
73
|
+
*
|
|
74
|
+
* Every predicate the tool layer filters on is one of those four columns, and `kind` and `parent`
|
|
75
|
+
* are most of them: `sql-schema-tools.ts:94` (`kind === "field" && parent === sym.id`),
|
|
76
|
+
* `react-compiler-tools.ts:61` (`kind === "component"`), `php-god-model-tools.ts:88` (methods per
|
|
77
|
+
* class). Today each runs as a 352k-row scan in JS after materialising the whole index; they are
|
|
78
|
+
* about to become SQL, and a scan in SQLite is no better than a scan in JS.
|
|
79
|
+
*
|
|
80
|
+
* After: kind 32 ms, parent 28 ms — 66x — and the file grew by nothing measurable.
|
|
81
|
+
*
|
|
82
|
+
* NO version bump, deliberately. `SCHEMA_SQL` runs on every open and every statement in it is
|
|
83
|
+
* `IF NOT EXISTS`, so existing databases pick these up by themselves and there is nothing to
|
|
84
|
+
* migrate. Bumping SCHEMA_VERSION would instead make every older CodeSift refuse these databases
|
|
85
|
+
* outright ("written by a newer CodeSift"), trading a backward-compatible addition for a one-way
|
|
86
|
+
* door. An older version simply does not use the new indexes.
|
|
87
|
+
*
|
|
88
|
+
* The one cost: an EXISTING large database builds them once, on its first open after the upgrade —
|
|
89
|
+
* measured 2.26 s + 0.67 s on the 352k-symbol index, inside `openIndexDb`, on the daemon's thread.
|
|
90
|
+
* A new database pays nothing, because the table is empty when the statements run.
|
|
91
|
+
*
|
|
92
|
+
* A composite `(file, kind)` was measured too (0.51 s to build, 26 ms to query) and left out on
|
|
93
|
+
* purpose: `idx_symbols_file` already narrows a per-file query to a handful of rows, and every
|
|
94
|
+
* index is paid again on WRITE — `saveIncrementalSqlite` deletes and re-inserts a file's rows on
|
|
95
|
+
* each edit, and the PostToolUse hook fires that after every agent edit.
|
|
96
|
+
*/
|
|
63
97
|
/**
|
|
64
98
|
* v1 -> v2: rebuild `symbols` without the PRIMARY KEY, keeping every row already stored.
|
|
65
99
|
*
|
|
@@ -94,5 +128,7 @@ DROP TABLE symbols_v1;
|
|
|
94
128
|
CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file);
|
|
95
129
|
CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);
|
|
96
130
|
CREATE INDEX IF NOT EXISTS idx_symbols_id ON symbols(id);
|
|
131
|
+
CREATE INDEX IF NOT EXISTS idx_symbols_kind ON symbols(kind);
|
|
132
|
+
CREATE INDEX IF NOT EXISTS idx_symbols_parent ON symbols(parent);
|
|
97
133
|
`;
|
|
98
134
|
//# sourceMappingURL=schema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/storage/sqlite/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,MAAM,CAAC,MAAM,UAAU,GAAG
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/storage/sqlite/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCzB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BnC,CAAC"}
|
|
@@ -45,5 +45,7 @@ export { SCHEMA_VERSION } from "./sqlite/schema.js";
|
|
|
45
45
|
export { closeAllIndexDbs, closeIndexDb, openIndexDb } from "./sqlite/connection.js";
|
|
46
46
|
export type { IndexSummary } from "./sqlite/meta.js";
|
|
47
47
|
export { importLegacyIndexIfEmpty, loadIndexSqlite, saveIndexSqlite, wasLossilyMigrated, } from "./sqlite/index-io.js";
|
|
48
|
-
export { getDataVersion, getFileEntrySqlite, getFileMtimeSqlite, getSymbolsForFileSqlite, loadIndexSummarySqlite, removeFileFromIndexSqlite, saveIncrementalSqlite, } from "./sqlite/accessors.js";
|
|
48
|
+
export { getDataVersion, getFileEntrySqlite, getFileMtimeSqlite, getSymbolsForFileSqlite, loadIndexSummarySqlite, removeFileFromIndexSqlite, saveIncrementalSqlite, indexDbIsPopulated, } from "./sqlite/accessors.js";
|
|
49
|
+
export { findSymbolsSqlite, streamSymbolsSqlite, getIndexMetaSqlite, } from "./sqlite/queries.js";
|
|
50
|
+
export type { SymbolQuery, IndexMeta } from "./sqlite/queries.js";
|
|
49
51
|
//# sourceMappingURL=sqlite-index-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-index-store.d.ts","sourceRoot":"","sources":["../../src/storage/sqlite-index-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEjG,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAElG,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErF,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EACL,wBAAwB,EACxB,eAAe,EACf,eAAe,EACf,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"sqlite-index-store.d.ts","sourceRoot":"","sources":["../../src/storage/sqlite-index-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEjG,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAElG,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErF,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EACL,wBAAwB,EACxB,eAAe,EACf,eAAe,EACf,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -44,5 +44,8 @@ export { IndexStorageError, classifyStorageError, isIndexStorageError } from "./
|
|
|
44
44
|
export { SCHEMA_VERSION } from "./sqlite/schema.js";
|
|
45
45
|
export { closeAllIndexDbs, closeIndexDb, openIndexDb } from "./sqlite/connection.js";
|
|
46
46
|
export { importLegacyIndexIfEmpty, loadIndexSqlite, saveIndexSqlite, wasLossilyMigrated, } from "./sqlite/index-io.js";
|
|
47
|
-
export { getDataVersion, getFileEntrySqlite, getFileMtimeSqlite, getSymbolsForFileSqlite, loadIndexSummarySqlite, removeFileFromIndexSqlite, saveIncrementalSqlite, } from "./sqlite/accessors.js";
|
|
47
|
+
export { getDataVersion, getFileEntrySqlite, getFileMtimeSqlite, getSymbolsForFileSqlite, loadIndexSummarySqlite, removeFileFromIndexSqlite, saveIncrementalSqlite, indexDbIsPopulated, } from "./sqlite/accessors.js";
|
|
48
|
+
// Narrow reads for ADR-004 stage 2. Listed explicitly, like everything else here: adding an export
|
|
49
|
+
// to a submodule should be a decision about this facade, not a side effect of writing a helper.
|
|
50
|
+
export { findSymbolsSqlite, streamSymbolsSqlite, getIndexMetaSqlite, } from "./sqlite/queries.js";
|
|
48
51
|
//# sourceMappingURL=sqlite-index-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-index-store.js","sourceRoot":"","sources":["../../src/storage/sqlite-index-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEjG,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAElG,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAIrF,OAAO,EACL,wBAAwB,EACxB,eAAe,EACf,eAAe,EACf,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"sqlite-index-store.js","sourceRoot":"","sources":["../../src/storage/sqlite-index-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEjG,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAElG,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAIrF,OAAO,EACL,wBAAwB,EACxB,eAAe,EACf,eAAe,EACf,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,mGAAmG;AACnG,gGAAgG;AAChG,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC"}
|