autosnippet 3.0.0 → 3.0.2
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 +230 -324
- package/bin/api-server.js +1 -1
- package/bin/cli.js +204 -244
- package/bin/mcp-server.js +5 -3
- package/config/knowledge-base.config.js +132 -132
- package/dashboard/dist/assets/{icons-CEfgGaZi.js → icons-Cdq22n2i.js} +95 -100
- package/dashboard/dist/assets/index-ClkyPkDX.js +133 -0
- package/dashboard/dist/assets/index-t4QrJwv1.css +1 -0
- package/dashboard/dist/index.html +3 -3
- package/lib/bootstrap.js +8 -8
- package/lib/cli/AiScanService.js +86 -40
- package/lib/cli/KnowledgeSyncService.js +113 -74
- package/lib/cli/SetupService.js +439 -277
- package/lib/cli/UpgradeService.js +63 -100
- package/lib/core/AstAnalyzer.js +276 -597
- package/lib/core/ast/ProjectGraph.js +101 -40
- package/lib/core/ast/ensure-grammars.js +232 -0
- package/lib/core/ast/index.js +115 -0
- package/lib/core/ast/lang-dart.js +661 -0
- package/lib/core/ast/lang-go.js +530 -0
- package/lib/core/ast/lang-java.js +435 -0
- package/lib/core/ast/lang-javascript.js +272 -0
- package/lib/core/ast/lang-kotlin.js +423 -0
- package/lib/core/ast/lang-objc.js +388 -0
- package/lib/core/ast/lang-python.js +371 -0
- package/lib/core/ast/lang-swift.js +337 -0
- package/lib/core/ast/lang-typescript.js +503 -0
- package/lib/core/capability/CapabilityProbe.js +18 -9
- package/lib/core/constitution/Constitution.js +2 -3
- package/lib/core/constitution/ConstitutionValidator.js +65 -24
- package/lib/core/discovery/DartDiscoverer.js +534 -0
- package/lib/core/discovery/DiscovererRegistry.js +83 -0
- package/lib/core/discovery/GenericDiscoverer.js +225 -0
- package/lib/core/discovery/GoDiscoverer.js +541 -0
- package/lib/core/discovery/JvmDiscoverer.js +506 -0
- package/lib/core/discovery/NodeDiscoverer.js +466 -0
- package/lib/core/discovery/ProjectDiscoverer.js +93 -0
- package/lib/core/discovery/PythonDiscoverer.js +338 -0
- package/lib/core/discovery/SpmDiscoverer.js +5 -0
- package/lib/core/discovery/index.js +53 -0
- package/lib/core/enhancement/EnhancementPack.js +71 -0
- package/lib/core/enhancement/EnhancementRegistry.js +47 -0
- package/lib/core/enhancement/android-enhancement.js +102 -0
- package/lib/core/enhancement/django-enhancement.js +70 -0
- package/lib/core/enhancement/fastapi-enhancement.js +63 -0
- package/lib/core/enhancement/go-grpc-enhancement.js +152 -0
- package/lib/core/enhancement/go-web-enhancement.js +201 -0
- package/lib/core/enhancement/index.js +65 -0
- package/lib/core/enhancement/node-server-enhancement.js +88 -0
- package/lib/core/enhancement/react-enhancement.js +86 -0
- package/lib/core/enhancement/spring-enhancement.js +112 -0
- package/lib/core/enhancement/vue-enhancement.js +96 -0
- package/lib/core/gateway/Gateway.js +8 -9
- package/lib/core/gateway/GatewayActionRegistry.js +1 -1
- package/lib/core/permission/PermissionManager.js +12 -8
- package/lib/domain/index.js +13 -9
- package/lib/domain/knowledge/KnowledgeEntry.js +111 -101
- package/lib/domain/knowledge/KnowledgeRepository.js +0 -1
- package/lib/domain/knowledge/Lifecycle.js +22 -22
- package/lib/domain/knowledge/index.js +9 -12
- package/lib/domain/knowledge/values/Constraints.js +31 -21
- package/lib/domain/knowledge/values/Content.js +21 -13
- package/lib/domain/knowledge/values/Quality.js +31 -18
- package/lib/domain/knowledge/values/Reasoning.js +20 -12
- package/lib/domain/knowledge/values/Relations.js +37 -25
- package/lib/domain/knowledge/values/Stats.js +18 -12
- package/lib/domain/knowledge/values/index.js +4 -3
- package/lib/domain/snippet/Snippet.js +35 -10
- package/lib/external/ai/AiFactory.js +48 -16
- package/lib/external/ai/AiProvider.js +184 -90
- package/lib/external/ai/providers/ClaudeProvider.js +25 -12
- package/lib/external/ai/providers/GoogleGeminiProvider.js +59 -30
- package/lib/external/ai/providers/MockProvider.js +9 -3
- package/lib/external/ai/providers/OpenAiProvider.js +51 -29
- package/lib/external/mcp/McpServer.js +66 -36
- package/lib/external/mcp/errorHandler.js +23 -11
- package/lib/external/mcp/handlers/LanguageExtensions.js +138 -53
- package/lib/external/mcp/handlers/TargetClassifier.js +52 -16
- package/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +81 -20
- package/lib/external/mcp/handlers/bootstrap/pipeline/EpisodicMemory.js +71 -42
- package/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +9 -17
- package/lib/external/mcp/handlers/bootstrap/pipeline/ToolResultCache.js +14 -9
- package/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +15 -7
- package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +352 -153
- package/lib/external/mcp/handlers/bootstrap/pipeline/tier-scheduler.js +52 -12
- package/lib/external/mcp/handlers/bootstrap/skills.js +143 -39
- package/lib/external/mcp/handlers/bootstrap.js +691 -168
- package/lib/external/mcp/handlers/browse.js +66 -22
- package/lib/external/mcp/handlers/candidate.js +118 -35
- package/lib/external/mcp/handlers/consolidated.js +49 -17
- package/lib/external/mcp/handlers/guard.js +104 -39
- package/lib/external/mcp/handlers/knowledge.js +60 -36
- package/lib/external/mcp/handlers/search.js +43 -14
- package/lib/external/mcp/handlers/skill.js +120 -45
- package/lib/external/mcp/handlers/structure.js +240 -86
- package/lib/external/mcp/handlers/system.js +42 -12
- package/lib/external/mcp/handlers/wiki.js +58 -33
- package/lib/external/mcp/tools.js +306 -123
- package/lib/http/HttpServer.js +72 -47
- package/lib/http/middleware/RateLimiter.js +5 -3
- package/lib/http/middleware/errorHandler.js +6 -1
- package/lib/http/middleware/requestLogger.js +14 -3
- package/lib/http/middleware/roleResolver.js +30 -23
- package/lib/http/routes/ai.js +387 -265
- package/lib/http/routes/auth.js +81 -61
- package/lib/http/routes/candidates.js +430 -320
- package/lib/http/routes/commands.js +289 -189
- package/lib/http/routes/extract.js +158 -125
- package/lib/http/routes/guardRules.js +309 -217
- package/lib/http/routes/knowledge.js +213 -154
- package/lib/http/routes/modules.js +578 -0
- package/lib/http/routes/monitoring.js +6 -6
- package/lib/http/routes/recipes.js +104 -93
- package/lib/http/routes/search.js +361 -305
- package/lib/http/routes/skills.js +145 -98
- package/lib/http/routes/snippets.js +42 -30
- package/lib/http/routes/spm.js +3 -405
- package/lib/http/routes/violations.js +113 -93
- package/lib/http/routes/wiki.js +211 -170
- package/lib/http/utils/routeHelpers.js +3 -1
- package/lib/http/utils/sse-sessions.js +16 -6
- package/lib/http/utils/sse.js +15 -5
- package/lib/infrastructure/audit/AuditLogger.js +5 -2
- package/lib/infrastructure/audit/AuditStore.js +10 -7
- package/lib/infrastructure/cache/CacheService.js +3 -1
- package/lib/infrastructure/cache/GraphCache.js +8 -4
- package/lib/infrastructure/cache/UnifiedCacheAdapter.js +1 -1
- package/lib/infrastructure/config/ConfigLoader.js +9 -5
- package/lib/infrastructure/config/Defaults.js +30 -10
- package/lib/infrastructure/config/Paths.js +28 -8
- package/lib/infrastructure/config/TriggerSymbol.js +22 -10
- package/lib/infrastructure/database/DatabaseConnection.js +15 -10
- package/lib/infrastructure/database/migrations/001_initial_schema.js +0 -1
- package/lib/infrastructure/external/ClipboardManager.js +6 -2
- package/lib/infrastructure/external/NativeUi.js +50 -43
- package/lib/infrastructure/external/OpenBrowser.js +14 -17
- package/lib/infrastructure/external/XcodeAutomation.js +14 -258
- package/lib/infrastructure/logging/Logger.js +46 -30
- package/lib/infrastructure/monitoring/ErrorTracker.js +7 -5
- package/lib/infrastructure/monitoring/PerformanceMonitor.js +12 -4
- package/lib/infrastructure/paths/HeaderResolver.js +25 -9
- package/lib/infrastructure/paths/PathFinder.js +34 -12
- package/lib/infrastructure/plugin/PluginManager.js +26 -8
- package/lib/infrastructure/realtime/RealtimeService.js +2 -2
- package/lib/infrastructure/vector/Chunker.js +22 -7
- package/lib/infrastructure/vector/IndexingPipeline.js +46 -22
- package/lib/infrastructure/vector/JsonVectorAdapter.js +90 -53
- package/lib/infrastructure/vector/VectorStore.js +28 -10
- package/lib/injection/ServiceContainer.js +247 -93
- package/lib/platform/ios/index.js +63 -0
- package/lib/platform/ios/routes/spm.js +437 -0
- package/lib/platform/ios/snippet/PlaceholderConverter.js +55 -0
- package/lib/platform/ios/snippet/XcodeCodec.js +112 -0
- package/lib/{service → platform/ios}/spm/DependencyGraph.js +41 -17
- package/lib/{service → platform/ios}/spm/PackageSwiftParser.js +41 -14
- package/lib/{service → platform/ios}/spm/PolicyEngine.js +9 -4
- package/lib/platform/ios/spm/SpmDiscoverer.js +122 -0
- package/lib/{service → platform/ios}/spm/SpmService.js +385 -127
- package/lib/{service/automation → platform/ios/xcode}/SaveEventFilter.js +8 -7
- package/lib/platform/ios/xcode/XcodeAutomation.js +350 -0
- package/lib/{service/automation → platform/ios/xcode}/XcodeIntegration.js +325 -145
- package/lib/repository/base/BaseRepository.js +7 -9
- package/lib/repository/knowledge/KnowledgeRepository.impl.js +98 -75
- package/lib/repository/token/TokenUsageStore.js +4 -2
- package/lib/service/automation/ActionPipeline.js +1 -1
- package/lib/service/automation/AutomationOrchestrator.js +8 -4
- package/lib/service/automation/ContextCollector.js +7 -5
- package/lib/service/automation/DirectiveDetector.js +23 -16
- package/lib/service/automation/FileWatcher.js +112 -56
- package/lib/service/automation/TriggerResolver.js +6 -4
- package/lib/service/automation/handlers/AlinkHandler.js +24 -12
- package/lib/service/automation/handlers/CreateHandler.js +19 -20
- package/lib/service/automation/handlers/DraftHandler.js +14 -8
- package/lib/service/automation/handlers/GuardHandler.js +93 -63
- package/lib/service/automation/handlers/HeaderHandler.js +1 -6
- package/lib/service/automation/handlers/SearchHandler.js +155 -88
- package/lib/service/bootstrap/BootstrapTaskManager.js +77 -35
- package/lib/service/candidate/SimilarityService.js +25 -9
- package/lib/service/chat/AnalystAgent.js +50 -24
- package/lib/service/chat/CandidateGuardrail.js +143 -17
- package/lib/service/chat/ChatAgent.js +759 -243
- package/lib/service/chat/ContextWindow.js +116 -71
- package/lib/service/chat/ConversationStore.js +77 -36
- package/lib/service/chat/EpisodicConsolidator.js +47 -23
- package/lib/service/chat/HandoffProtocol.js +98 -22
- package/lib/service/chat/Memory.js +34 -14
- package/lib/service/chat/ProducerAgent.js +40 -20
- package/lib/service/chat/ProjectSemanticMemory.js +109 -78
- package/lib/service/chat/ReasoningLayer.js +148 -70
- package/lib/service/chat/ReasoningTrace.js +44 -32
- package/lib/service/chat/TaskPipeline.js +39 -19
- package/lib/service/chat/ToolRegistry.js +48 -29
- package/lib/service/chat/WorkingMemory.js +44 -18
- package/lib/service/chat/tools.js +1096 -494
- package/lib/service/context/RecipeExtractor.js +132 -51
- package/lib/service/cursor/CursorDeliveryPipeline.js +82 -37
- package/lib/service/cursor/KnowledgeCompressor.js +25 -22
- package/lib/service/cursor/RulesGenerator.js +13 -7
- package/lib/service/cursor/SkillsSyncer.js +77 -27
- package/lib/service/cursor/TokenBudget.js +2 -2
- package/lib/service/cursor/TopicClassifier.js +54 -20
- package/lib/service/guard/ComplianceReporter.js +55 -43
- package/lib/service/guard/ExclusionManager.js +67 -29
- package/lib/service/guard/GuardCheckEngine.js +381 -86
- package/lib/service/guard/GuardFeedbackLoop.js +22 -10
- package/lib/service/guard/GuardService.js +29 -19
- package/lib/service/guard/RuleLearner.js +55 -23
- package/lib/service/guard/SourceFileCollector.js +27 -20
- package/lib/service/guard/ViolationsStore.js +43 -38
- package/lib/service/knowledge/CodeEntityGraph.js +147 -82
- package/lib/service/knowledge/ConfidenceRouter.js +12 -10
- package/lib/service/knowledge/KnowledgeFileWriter.js +147 -56
- package/lib/service/knowledge/KnowledgeGraphService.js +81 -34
- package/lib/service/knowledge/KnowledgeService.js +222 -112
- package/lib/service/module/ModuleService.js +969 -0
- package/lib/service/quality/FeedbackCollector.js +27 -15
- package/lib/service/quality/QualityScorer.js +78 -24
- package/lib/service/recipe/RecipeCandidateValidator.js +110 -44
- package/lib/service/recipe/RecipeParser.js +78 -45
- package/lib/service/search/CoarseRanker.js +43 -28
- package/lib/service/search/CrossEncoderReranker.js +32 -21
- package/lib/service/search/InvertedIndex.js +21 -7
- package/lib/service/search/MultiSignalRanker.js +90 -28
- package/lib/service/search/RetrievalFunnel.js +45 -24
- package/lib/service/search/SearchEngine.js +255 -103
- package/lib/service/skills/EventAggregator.js +32 -15
- package/lib/service/skills/SignalCollector.js +140 -64
- package/lib/service/skills/SkillAdvisor.js +79 -42
- package/lib/service/skills/SkillHooks.js +16 -14
- package/lib/service/snippet/PlaceholderConverter.js +5 -0
- package/lib/service/snippet/SnippetFactory.js +116 -99
- package/lib/service/snippet/SnippetInstaller.js +234 -62
- package/lib/service/snippet/codecs/SnippetCodec.js +67 -0
- package/lib/service/snippet/codecs/VSCodeCodec.js +102 -0
- package/lib/service/snippet/codecs/XcodeCodec.js +5 -0
- package/lib/service/wiki/WikiGenerator.js +637 -263
- package/lib/shared/DimensionCopyRegistry.js +472 -0
- package/lib/shared/LanguageService.js +399 -0
- package/lib/shared/PathGuard.js +45 -28
- package/lib/shared/RecipeReadinessChecker.js +72 -12
- package/lib/shared/constants.js +41 -41
- package/lib/shared/errors/BaseError.js +2 -2
- package/lib/shared/errors/index.js +4 -4
- package/lib/shared/similarity.js +25 -8
- package/lib/shared/token-utils.js +6 -2
- package/lib/shared/utils/common.js +12 -4
- package/package.json +49 -13
- package/scripts/bench-real-projects.mjs +256 -0
- package/scripts/build-native-ui.js +30 -30
- package/scripts/clear-old-vector-index.js +5 -35
- package/scripts/clear-vector-cache.js +7 -37
- package/scripts/collect-test-project-stats.mjs +160 -0
- package/scripts/diagnose-mcp.js +41 -32
- package/scripts/ensure-parse-package.js +6 -9
- package/scripts/generate-recipe-drafts.js +116 -77
- package/scripts/init-db.js +3 -20
- package/scripts/init-snippets.js +305 -0
- package/scripts/init-vector-db.js +173 -170
- package/scripts/install-cursor-skill.js +148 -104
- package/scripts/install-full.js +8 -21
- package/scripts/install-vscode-copilot.js +146 -145
- package/scripts/migrate-md-to-knowledge.mjs +139 -151
- package/scripts/postinstall-safe.js +5 -17
- package/scripts/recipe-audit.js +106 -82
- package/scripts/release.js +283 -323
- package/scripts/setup-mcp-config.js +60 -52
- package/scripts/verify-context-api.js +20 -20
- package/skills/autosnippet-analysis/SKILL.md +10 -6
- package/skills/autosnippet-candidates/SKILL.md +27 -26
- package/skills/autosnippet-coldstart/SKILL.md +555 -38
- package/skills/autosnippet-concepts/SKILL.md +349 -337
- package/skills/autosnippet-create/SKILL.md +5 -5
- package/skills/autosnippet-reference-dart/SKILL.md +543 -0
- package/skills/autosnippet-reference-go/SKILL.md +539 -0
- package/skills/autosnippet-reference-java/SKILL.md +534 -0
- package/skills/autosnippet-reference-jsts/SKILL.md +41 -9
- package/skills/autosnippet-reference-kotlin/SKILL.md +526 -0
- package/skills/autosnippet-reference-objc/SKILL.md +29 -6
- package/skills/autosnippet-reference-python/SKILL.md +800 -0
- package/skills/autosnippet-reference-swift/SKILL.md +70 -14
- package/skills/autosnippet-structure/SKILL.md +4 -4
- package/templates/cursor-rules/autosnippet-conventions.mdc +2 -2
- package/templates/recipes-setup/README.md +2 -2
- package/templates/recipes-setup/_template.md +1 -1
- package/dashboard/dist/assets/index-Bun3ld_J.css +0 -1
- package/dashboard/dist/assets/index-_Sk_Dmg3.js +0 -143
- package/resources/asd-entry/main.swift +0 -159
- package/scripts/build-asd-entry.js +0 -51
- package/scripts/init-xcode-snippets.js +0 -311
- package/template.json +0 -39
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import Logger from '../logging/Logger.js';
|
|
7
7
|
|
|
8
8
|
export class PluginManager {
|
|
9
|
-
#plugins;
|
|
9
|
+
#plugins; // Map<name, { plugin, enabled, priority, meta }>
|
|
10
10
|
#logger;
|
|
11
11
|
|
|
12
12
|
constructor() {
|
|
@@ -37,7 +37,11 @@ export class PluginManager {
|
|
|
37
37
|
unregister(name) {
|
|
38
38
|
const entry = this.#plugins.get(name);
|
|
39
39
|
if (entry?.plugin?.destroy) {
|
|
40
|
-
try {
|
|
40
|
+
try {
|
|
41
|
+
entry.plugin.destroy();
|
|
42
|
+
} catch {
|
|
43
|
+
/* silent */
|
|
44
|
+
}
|
|
41
45
|
}
|
|
42
46
|
this.#plugins.delete(name);
|
|
43
47
|
}
|
|
@@ -47,7 +51,9 @@ export class PluginManager {
|
|
|
47
51
|
*/
|
|
48
52
|
setEnabled(name, enabled) {
|
|
49
53
|
const entry = this.#plugins.get(name);
|
|
50
|
-
if (entry)
|
|
54
|
+
if (entry) {
|
|
55
|
+
entry.enabled = enabled;
|
|
56
|
+
}
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
/**
|
|
@@ -56,7 +62,9 @@ export class PluginManager {
|
|
|
56
62
|
async initAll(context = {}) {
|
|
57
63
|
const sorted = this.#getSorted();
|
|
58
64
|
for (const { name, entry } of sorted) {
|
|
59
|
-
if (!entry.enabled || !entry.plugin.init)
|
|
65
|
+
if (!entry.enabled || !entry.plugin.init) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
60
68
|
try {
|
|
61
69
|
await entry.plugin.init(context);
|
|
62
70
|
this.#logger.debug(`[PluginManager] 初始化: ${name}`);
|
|
@@ -70,9 +78,13 @@ export class PluginManager {
|
|
|
70
78
|
* 销毁所有插件
|
|
71
79
|
*/
|
|
72
80
|
async destroyAll() {
|
|
73
|
-
for (const [
|
|
81
|
+
for (const [_name, entry] of this.#plugins) {
|
|
74
82
|
if (entry.plugin.destroy) {
|
|
75
|
-
try {
|
|
83
|
+
try {
|
|
84
|
+
await entry.plugin.destroy();
|
|
85
|
+
} catch {
|
|
86
|
+
/* silent */
|
|
87
|
+
}
|
|
76
88
|
}
|
|
77
89
|
}
|
|
78
90
|
this.#plugins.clear();
|
|
@@ -84,7 +96,11 @@ export class PluginManager {
|
|
|
84
96
|
getEnabled() {
|
|
85
97
|
return this.#getSorted()
|
|
86
98
|
.filter(({ entry }) => entry.enabled)
|
|
87
|
-
.map(({ name, entry }) => ({
|
|
99
|
+
.map(({ name, entry }) => ({
|
|
100
|
+
name,
|
|
101
|
+
priority: entry.priority,
|
|
102
|
+
description: entry.description,
|
|
103
|
+
}));
|
|
88
104
|
}
|
|
89
105
|
|
|
90
106
|
/**
|
|
@@ -102,7 +118,9 @@ export class PluginManager {
|
|
|
102
118
|
async callHook(hookName, ...args) {
|
|
103
119
|
const results = [];
|
|
104
120
|
for (const { name, entry } of this.#getSorted()) {
|
|
105
|
-
if (!entry.enabled || !entry.plugin[hookName])
|
|
121
|
+
if (!entry.enabled || !entry.plugin[hookName]) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
106
124
|
try {
|
|
107
125
|
const result = await entry.plugin[hookName](...args);
|
|
108
126
|
results.push({ name, result });
|
|
@@ -17,8 +17,8 @@ export class RealtimeService {
|
|
|
17
17
|
methods: ['GET', 'POST'],
|
|
18
18
|
},
|
|
19
19
|
transports: ['websocket', 'polling'],
|
|
20
|
-
pingInterval: 25000,
|
|
21
|
-
pingTimeout: 20000,
|
|
20
|
+
pingInterval: 25000, // 25s 心跳间隔(默认值,显式声明)
|
|
21
|
+
pingTimeout: 20000, // 20s 超时(默认值)
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
this.setupEventHandlers();
|
|
@@ -23,7 +23,9 @@ export function chunk(content, metadata = {}, options = {}) {
|
|
|
23
23
|
overlapTokens = DEFAULT_OVERLAP_TOKENS,
|
|
24
24
|
} = options;
|
|
25
25
|
|
|
26
|
-
if (!content || content.trim().length === 0)
|
|
26
|
+
if (!content || content.trim().length === 0) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
27
29
|
|
|
28
30
|
const tokens = estimateTokens(content);
|
|
29
31
|
|
|
@@ -86,7 +88,7 @@ function chunkBySection(content, metadata, maxChunkTokens) {
|
|
|
86
88
|
buffer = section;
|
|
87
89
|
continue;
|
|
88
90
|
}
|
|
89
|
-
const combined = buffer.content
|
|
91
|
+
const combined = `${buffer.content}\n${section.content}`;
|
|
90
92
|
if (estimateTokens(combined) <= maxChunkTokens) {
|
|
91
93
|
buffer = { title: buffer.title, content: combined };
|
|
92
94
|
} else {
|
|
@@ -94,7 +96,9 @@ function chunkBySection(content, metadata, maxChunkTokens) {
|
|
|
94
96
|
buffer = section;
|
|
95
97
|
}
|
|
96
98
|
}
|
|
97
|
-
if (buffer)
|
|
99
|
+
if (buffer) {
|
|
100
|
+
merged.push(buffer);
|
|
101
|
+
}
|
|
98
102
|
|
|
99
103
|
// 对超大段落做 fixed 分割
|
|
100
104
|
const results = [];
|
|
@@ -105,7 +109,12 @@ function chunkBySection(content, metadata, maxChunkTokens) {
|
|
|
105
109
|
for (const sub of subChunks) {
|
|
106
110
|
results.push({
|
|
107
111
|
content: sub.content,
|
|
108
|
-
metadata: {
|
|
112
|
+
metadata: {
|
|
113
|
+
...metadata,
|
|
114
|
+
...sub.metadata,
|
|
115
|
+
sectionTitle: section.title,
|
|
116
|
+
chunkIndex: results.length,
|
|
117
|
+
},
|
|
109
118
|
});
|
|
110
119
|
}
|
|
111
120
|
} else {
|
|
@@ -117,7 +126,9 @@ function chunkBySection(content, metadata, maxChunkTokens) {
|
|
|
117
126
|
}
|
|
118
127
|
|
|
119
128
|
// 设置 totalChunks
|
|
120
|
-
for (const chunk of results)
|
|
129
|
+
for (const chunk of results) {
|
|
130
|
+
chunk.metadata.totalChunks = results.length;
|
|
131
|
+
}
|
|
121
132
|
return results;
|
|
122
133
|
}
|
|
123
134
|
|
|
@@ -152,10 +163,14 @@ function chunkFixed(content, metadata, maxChunkTokens, overlapTokens) {
|
|
|
152
163
|
const nextStart = end - overlapChars;
|
|
153
164
|
// 确保至少前进 1 字符,防止 overlap >= maxChars 时无限循环
|
|
154
165
|
start = nextStart > start ? nextStart : end;
|
|
155
|
-
if (start >= content.length)
|
|
166
|
+
if (start >= content.length) {
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
156
169
|
}
|
|
157
170
|
|
|
158
|
-
for (const chunk of results)
|
|
171
|
+
for (const chunk of results) {
|
|
172
|
+
chunk.metadata.totalChunks = results.length;
|
|
173
|
+
}
|
|
159
174
|
return results;
|
|
160
175
|
}
|
|
161
176
|
|
|
@@ -3,17 +3,26 @@
|
|
|
3
3
|
* scan → chunk → detect incremental changes (sourceHash) → embed via AI → batch upsert
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { readdirSync, readFileSync, statSync, existsSync } from 'node:fs';
|
|
7
|
-
import { join, relative, extname } from 'node:path';
|
|
8
6
|
import { createHash } from 'node:crypto';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
8
|
+
import { extname, join, relative } from 'node:path';
|
|
9
|
+
import { LanguageService } from '../../shared/LanguageService.js';
|
|
10
|
+
import { chunk } from './Chunker.js';
|
|
11
|
+
|
|
12
|
+
const SCANNABLE_EXTENSIONS = new Set([
|
|
13
|
+
'.md', '.markdown', '.txt',
|
|
14
|
+
'.swift', '.m', '.h',
|
|
15
|
+
'.js', '.ts', '.jsx', '.tsx',
|
|
16
|
+
'.py',
|
|
17
|
+
'.java', '.kt',
|
|
18
|
+
'.go',
|
|
19
|
+
'.rs', '.rb',
|
|
20
|
+
]);
|
|
12
21
|
|
|
13
22
|
export class IndexingPipeline {
|
|
14
|
-
#vectorStore;
|
|
15
|
-
#aiProvider;
|
|
16
|
-
#scanDirs;
|
|
23
|
+
#vectorStore; // VectorStore 实例
|
|
24
|
+
#aiProvider; // AiProvider 实例 (可选, 用于 embedding)
|
|
25
|
+
#scanDirs; // 要扫描的目录
|
|
17
26
|
#projectRoot;
|
|
18
27
|
|
|
19
28
|
constructor(options = {}) {
|
|
@@ -23,8 +32,12 @@ export class IndexingPipeline {
|
|
|
23
32
|
this.#projectRoot = options.projectRoot || process.cwd();
|
|
24
33
|
}
|
|
25
34
|
|
|
26
|
-
setVectorStore(store) {
|
|
27
|
-
|
|
35
|
+
setVectorStore(store) {
|
|
36
|
+
this.#vectorStore = store;
|
|
37
|
+
}
|
|
38
|
+
setAiProvider(provider) {
|
|
39
|
+
this.#aiProvider = provider;
|
|
40
|
+
}
|
|
28
41
|
|
|
29
42
|
/**
|
|
30
43
|
* 运行完整索引管线
|
|
@@ -35,7 +48,9 @@ export class IndexingPipeline {
|
|
|
35
48
|
const { force = false, dryRun = false } = options;
|
|
36
49
|
const stats = { scanned: 0, chunked: 0, embedded: 0, upserted: 0, skipped: 0, errors: 0 };
|
|
37
50
|
|
|
38
|
-
if (!this.#vectorStore)
|
|
51
|
+
if (!this.#vectorStore) {
|
|
52
|
+
throw new Error('VectorStore not set');
|
|
53
|
+
}
|
|
39
54
|
|
|
40
55
|
// 1. 扫描文件
|
|
41
56
|
const files = this.scan();
|
|
@@ -53,7 +68,7 @@ export class IndexingPipeline {
|
|
|
53
68
|
|
|
54
69
|
// 增量检测:hash 未变时跳过
|
|
55
70
|
if (!force) {
|
|
56
|
-
const existing = await this.#vectorStore.getById(baseId
|
|
71
|
+
const existing = await this.#vectorStore.getById(`${baseId}_0`);
|
|
57
72
|
if (existing?.metadata?.sourceHash === hash) {
|
|
58
73
|
stats.skipped++;
|
|
59
74
|
continue;
|
|
@@ -79,7 +94,9 @@ export class IndexingPipeline {
|
|
|
79
94
|
try {
|
|
80
95
|
vector = await this.#aiProvider.embed(chunkItem.content);
|
|
81
96
|
stats.embedded++;
|
|
82
|
-
} catch {
|
|
97
|
+
} catch {
|
|
98
|
+
/* embed optional */
|
|
99
|
+
}
|
|
83
100
|
}
|
|
84
101
|
|
|
85
102
|
batch.push({
|
|
@@ -92,14 +109,16 @@ export class IndexingPipeline {
|
|
|
92
109
|
|
|
93
110
|
// 清理旧 chunk (如果文件 chunk 数减少)
|
|
94
111
|
for (const existId of existingIds) {
|
|
95
|
-
if (existId.startsWith(baseId
|
|
112
|
+
if (existId.startsWith(`${baseId}_`)) {
|
|
96
113
|
const idx = parseInt(existId.split('_').pop(), 10);
|
|
97
114
|
if (idx >= chunks.length) {
|
|
98
|
-
if (!dryRun)
|
|
115
|
+
if (!dryRun) {
|
|
116
|
+
await this.#vectorStore.remove(existId);
|
|
117
|
+
}
|
|
99
118
|
}
|
|
100
119
|
}
|
|
101
120
|
}
|
|
102
|
-
} catch (
|
|
121
|
+
} catch (_error) {
|
|
103
122
|
stats.errors++;
|
|
104
123
|
}
|
|
105
124
|
}
|
|
@@ -122,7 +141,9 @@ export class IndexingPipeline {
|
|
|
122
141
|
|
|
123
142
|
for (const dir of this.#scanDirs) {
|
|
124
143
|
const absDir = join(this.#projectRoot, dir);
|
|
125
|
-
if (!existsSync(absDir))
|
|
144
|
+
if (!existsSync(absDir)) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
126
147
|
this.#walkDir(absDir, files);
|
|
127
148
|
}
|
|
128
149
|
|
|
@@ -152,7 +173,9 @@ export class IndexingPipeline {
|
|
|
152
173
|
for (const entry of entries) {
|
|
153
174
|
const fullPath = join(dir, entry.name);
|
|
154
175
|
if (entry.isDirectory()) {
|
|
155
|
-
if (entry.name.startsWith('.') || entry.name === 'node_modules')
|
|
176
|
+
if (entry.name.startsWith('.') || entry.name === 'node_modules') {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
156
179
|
this.#walkDir(fullPath, files);
|
|
157
180
|
} else if (entry.isFile()) {
|
|
158
181
|
const ext = extname(entry.name).toLowerCase();
|
|
@@ -165,12 +188,13 @@ export class IndexingPipeline {
|
|
|
165
188
|
}
|
|
166
189
|
}
|
|
167
190
|
}
|
|
168
|
-
} catch {
|
|
191
|
+
} catch {
|
|
192
|
+
/* skip unreadable dirs */
|
|
193
|
+
}
|
|
169
194
|
}
|
|
170
195
|
|
|
171
196
|
#detectLanguage(filePath) {
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
return map[ext] || 'text';
|
|
197
|
+
const lang = LanguageService.inferLang(filePath);
|
|
198
|
+
return lang === 'unknown' ? 'text' : lang;
|
|
175
199
|
}
|
|
176
200
|
}
|
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
* 支持余弦相似度搜索、混合搜索(向量 70% + 关键词 30%)
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { join, dirname } from 'node:path';
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { dirname, join } from 'node:path';
|
|
10
9
|
import pathGuard from '../../shared/PathGuard.js';
|
|
11
10
|
import { cosineSimilarity } from '../../shared/similarity.js';
|
|
11
|
+
import { VectorStore } from './VectorStore.js';
|
|
12
12
|
|
|
13
13
|
export class JsonVectorAdapter extends VectorStore {
|
|
14
14
|
#indexPath;
|
|
15
|
-
#data;
|
|
15
|
+
#data; // Map<id, { id, content, vector, metadata }>
|
|
16
16
|
#dirty;
|
|
17
17
|
|
|
18
18
|
constructor(projectRoot, options = {}) {
|
|
@@ -36,7 +36,9 @@ export class JsonVectorAdapter extends VectorStore {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
async upsert(item) {
|
|
39
|
-
if (!item?.id)
|
|
39
|
+
if (!item?.id) {
|
|
40
|
+
throw new Error('Item must have an id');
|
|
41
|
+
}
|
|
40
42
|
this.#data.set(item.id, {
|
|
41
43
|
id: item.id,
|
|
42
44
|
content: item.content || '',
|
|
@@ -50,7 +52,9 @@ export class JsonVectorAdapter extends VectorStore {
|
|
|
50
52
|
|
|
51
53
|
async batchUpsert(items) {
|
|
52
54
|
for (const item of items) {
|
|
53
|
-
if (!item?.id)
|
|
55
|
+
if (!item?.id) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
54
58
|
this.#data.set(item.id, {
|
|
55
59
|
id: item.id,
|
|
56
60
|
content: item.content || '',
|
|
@@ -79,7 +83,9 @@ export class JsonVectorAdapter extends VectorStore {
|
|
|
79
83
|
async searchVector(queryVector, options = {}) {
|
|
80
84
|
const { topK = 10, filter = null, minScore = 0 } = options;
|
|
81
85
|
|
|
82
|
-
if (!queryVector || queryVector.length === 0)
|
|
86
|
+
if (!queryVector || queryVector.length === 0) {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
83
89
|
|
|
84
90
|
let candidates = [...this.#data.values()];
|
|
85
91
|
|
|
@@ -90,12 +96,12 @@ export class JsonVectorAdapter extends VectorStore {
|
|
|
90
96
|
|
|
91
97
|
// 计算余弦相似度
|
|
92
98
|
const scored = candidates
|
|
93
|
-
.filter(item => item.vector && item.vector.length > 0)
|
|
94
|
-
.map(item => ({
|
|
99
|
+
.filter((item) => item.vector && item.vector.length > 0)
|
|
100
|
+
.map((item) => ({
|
|
95
101
|
item,
|
|
96
102
|
score: this.#cosineSimilarity(queryVector, item.vector),
|
|
97
103
|
}))
|
|
98
|
-
.filter(result => result.score >= minScore)
|
|
104
|
+
.filter((result) => result.score >= minScore)
|
|
99
105
|
.sort((a, b) => b.score - a.score)
|
|
100
106
|
.slice(0, topK);
|
|
101
107
|
|
|
@@ -109,35 +115,38 @@ export class JsonVectorAdapter extends VectorStore {
|
|
|
109
115
|
const { topK = 10, filter = null } = options;
|
|
110
116
|
|
|
111
117
|
let candidates = [...this.#data.values()];
|
|
112
|
-
if (filter)
|
|
118
|
+
if (filter) {
|
|
119
|
+
candidates = this.#applyFilter(candidates, filter);
|
|
120
|
+
}
|
|
113
121
|
|
|
114
|
-
const scored = candidates
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
122
|
+
const scored = candidates
|
|
123
|
+
.map((item) => {
|
|
124
|
+
// 向量分数
|
|
125
|
+
let vectorScore = 0;
|
|
126
|
+
if (queryVector && queryVector.length > 0 && item.vector && item.vector.length > 0) {
|
|
127
|
+
vectorScore = this.#cosineSimilarity(queryVector, item.vector);
|
|
128
|
+
}
|
|
120
129
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
+
// 关键词分数
|
|
131
|
+
let keywordScore = 0;
|
|
132
|
+
if (queryText) {
|
|
133
|
+
const text = (item.content || '').toLowerCase();
|
|
134
|
+
const query = queryText.toLowerCase();
|
|
135
|
+
const words = query.split(/\s+/);
|
|
136
|
+
const hits = words.filter((w) => text.includes(w)).length;
|
|
137
|
+
keywordScore = words.length > 0 ? hits / words.length : 0;
|
|
138
|
+
}
|
|
130
139
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
140
|
+
return {
|
|
141
|
+
item,
|
|
142
|
+
score: vectorScore * 0.7 + keywordScore * 0.3,
|
|
143
|
+
vectorScore,
|
|
144
|
+
keywordScore,
|
|
145
|
+
};
|
|
146
|
+
})
|
|
147
|
+
.filter((r) => r.score > 0)
|
|
148
|
+
.sort((a, b) => b.score - a.score)
|
|
149
|
+
.slice(0, topK);
|
|
141
150
|
|
|
142
151
|
return scored;
|
|
143
152
|
}
|
|
@@ -148,7 +157,7 @@ export class JsonVectorAdapter extends VectorStore {
|
|
|
148
157
|
*/
|
|
149
158
|
async query(queryVector, topK = 10) {
|
|
150
159
|
const results = await this.searchVector(queryVector, { topK });
|
|
151
|
-
return results.map(r => ({
|
|
160
|
+
return results.map((r) => ({
|
|
152
161
|
id: r.item.id,
|
|
153
162
|
similarity: r.score,
|
|
154
163
|
score: r.score,
|
|
@@ -177,31 +186,47 @@ export class JsonVectorAdapter extends VectorStore {
|
|
|
177
186
|
if (existsSync(this.#indexPath)) {
|
|
178
187
|
indexSize = statSync(this.#indexPath).size;
|
|
179
188
|
}
|
|
180
|
-
} catch {
|
|
189
|
+
} catch {
|
|
190
|
+
/* ignore */
|
|
191
|
+
}
|
|
181
192
|
|
|
182
193
|
return {
|
|
183
194
|
count: this.#data.size,
|
|
184
195
|
indexSize,
|
|
185
196
|
indexPath: this.#indexPath,
|
|
186
|
-
hasVectors: [...this.#data.values()].filter(d => d.vector?.length > 0).length,
|
|
197
|
+
hasVectors: [...this.#data.values()].filter((d) => d.vector?.length > 0).length,
|
|
187
198
|
};
|
|
188
199
|
}
|
|
189
200
|
|
|
190
201
|
// --- 私有方法 ---
|
|
191
202
|
|
|
192
203
|
#applyFilter(items, filter) {
|
|
193
|
-
return items.filter(item => {
|
|
204
|
+
return items.filter((item) => {
|
|
194
205
|
const meta = item.metadata || {};
|
|
195
|
-
if (filter.type && meta.type !== filter.type)
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
if (filter.
|
|
199
|
-
|
|
206
|
+
if (filter.type && meta.type !== filter.type) {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
if (filter.category && meta.category !== filter.category) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
if (filter.language && meta.language !== filter.language) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
if (filter.sourcePath && !meta.sourcePath?.includes(filter.sourcePath)) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
if (filter.module && meta.module !== filter.module) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
200
221
|
if (filter.tags && Array.isArray(filter.tags)) {
|
|
201
222
|
const itemTags = meta.tags || [];
|
|
202
|
-
if (!filter.tags.some(t => itemTags.includes(t)))
|
|
223
|
+
if (!filter.tags.some((t) => itemTags.includes(t))) {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (filter.deprecated === false && meta.deprecated) {
|
|
228
|
+
return false;
|
|
203
229
|
}
|
|
204
|
-
if (filter.deprecated === false && meta.deprecated) return false;
|
|
205
230
|
return true;
|
|
206
231
|
});
|
|
207
232
|
}
|
|
@@ -212,12 +237,16 @@ export class JsonVectorAdapter extends VectorStore {
|
|
|
212
237
|
|
|
213
238
|
#load() {
|
|
214
239
|
try {
|
|
215
|
-
if (!existsSync(this.#indexPath))
|
|
240
|
+
if (!existsSync(this.#indexPath)) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
216
243
|
const raw = readFileSync(this.#indexPath, 'utf-8');
|
|
217
244
|
const items = JSON.parse(raw);
|
|
218
245
|
if (Array.isArray(items)) {
|
|
219
246
|
for (const item of items) {
|
|
220
|
-
if (item?.id)
|
|
247
|
+
if (item?.id) {
|
|
248
|
+
this.#data.set(item.id, item);
|
|
249
|
+
}
|
|
221
250
|
}
|
|
222
251
|
} else if (typeof items === 'object') {
|
|
223
252
|
// 兼容旧格式 { id: item }
|
|
@@ -225,18 +254,26 @@ export class JsonVectorAdapter extends VectorStore {
|
|
|
225
254
|
this.#data.set(id, { ...item, id });
|
|
226
255
|
}
|
|
227
256
|
}
|
|
228
|
-
} catch {
|
|
257
|
+
} catch {
|
|
258
|
+
/* silent: start empty */
|
|
259
|
+
}
|
|
229
260
|
}
|
|
230
261
|
|
|
231
262
|
#autoSave() {
|
|
232
|
-
if (!this.#dirty)
|
|
263
|
+
if (!this.#dirty) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
233
266
|
try {
|
|
234
267
|
const dir = dirname(this.#indexPath);
|
|
235
268
|
pathGuard.assertProjectWriteSafe(dir);
|
|
236
|
-
if (!existsSync(dir))
|
|
269
|
+
if (!existsSync(dir)) {
|
|
270
|
+
mkdirSync(dir, { recursive: true });
|
|
271
|
+
}
|
|
237
272
|
const items = [...this.#data.values()];
|
|
238
273
|
writeFileSync(this.#indexPath, JSON.stringify(items, null, 2));
|
|
239
274
|
this.#dirty = false;
|
|
240
|
-
} catch {
|
|
275
|
+
} catch {
|
|
276
|
+
/* silent */
|
|
277
|
+
}
|
|
241
278
|
}
|
|
242
279
|
}
|
|
@@ -8,13 +8,17 @@ export class VectorStore {
|
|
|
8
8
|
* 初始化存储
|
|
9
9
|
* @returns {Promise<void>}
|
|
10
10
|
*/
|
|
11
|
-
async init() {
|
|
11
|
+
async init() {
|
|
12
|
+
throw new Error('Not implemented: init()');
|
|
13
|
+
}
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* 插入或更新文档
|
|
15
17
|
* @param {{ id: string, content: string, vector: number[], metadata: object }} item
|
|
16
18
|
*/
|
|
17
|
-
async upsert(item) {
|
|
19
|
+
async upsert(item) {
|
|
20
|
+
throw new Error('Not implemented: upsert()');
|
|
21
|
+
}
|
|
18
22
|
|
|
19
23
|
/**
|
|
20
24
|
* 批量 upsert
|
|
@@ -25,7 +29,7 @@ export class VectorStore {
|
|
|
25
29
|
const BATCH_SIZE = 50;
|
|
26
30
|
for (let i = 0; i < items.length; i += BATCH_SIZE) {
|
|
27
31
|
const batch = items.slice(i, i + BATCH_SIZE);
|
|
28
|
-
await Promise.all(batch.map(item => this.upsert(item)));
|
|
32
|
+
await Promise.all(batch.map((item) => this.upsert(item)));
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
35
|
|
|
@@ -33,14 +37,18 @@ export class VectorStore {
|
|
|
33
37
|
* 删除文档
|
|
34
38
|
* @param {string} id
|
|
35
39
|
*/
|
|
36
|
-
async remove(id) {
|
|
40
|
+
async remove(id) {
|
|
41
|
+
throw new Error('Not implemented: remove()');
|
|
42
|
+
}
|
|
37
43
|
|
|
38
44
|
/**
|
|
39
45
|
* 按 ID 获取
|
|
40
46
|
* @param {string} id
|
|
41
47
|
* @returns {object|null}
|
|
42
48
|
*/
|
|
43
|
-
async getById(id) {
|
|
49
|
+
async getById(id) {
|
|
50
|
+
throw new Error('Not implemented: getById()');
|
|
51
|
+
}
|
|
44
52
|
|
|
45
53
|
/**
|
|
46
54
|
* 向量相似度搜索
|
|
@@ -48,29 +56,39 @@ export class VectorStore {
|
|
|
48
56
|
* @param {object} options — { topK, filter, minScore }
|
|
49
57
|
* @returns {Array<{ item: object, score: number }>}
|
|
50
58
|
*/
|
|
51
|
-
async searchVector(queryVector, options = {}) {
|
|
59
|
+
async searchVector(queryVector, options = {}) {
|
|
60
|
+
throw new Error('Not implemented: searchVector()');
|
|
61
|
+
}
|
|
52
62
|
|
|
53
63
|
/**
|
|
54
64
|
* 按过滤条件搜索
|
|
55
65
|
* @param {object} filter — { type, category, language, tags, ... }
|
|
56
66
|
* @returns {Array}
|
|
57
67
|
*/
|
|
58
|
-
async searchByFilter(filter) {
|
|
68
|
+
async searchByFilter(filter) {
|
|
69
|
+
throw new Error('Not implemented: searchByFilter()');
|
|
70
|
+
}
|
|
59
71
|
|
|
60
72
|
/**
|
|
61
73
|
* 列出所有 ID
|
|
62
74
|
* @returns {string[]}
|
|
63
75
|
*/
|
|
64
|
-
async listIds() {
|
|
76
|
+
async listIds() {
|
|
77
|
+
throw new Error('Not implemented: listIds()');
|
|
78
|
+
}
|
|
65
79
|
|
|
66
80
|
/**
|
|
67
81
|
* 清空存储
|
|
68
82
|
*/
|
|
69
|
-
async clear() {
|
|
83
|
+
async clear() {
|
|
84
|
+
throw new Error('Not implemented: clear()');
|
|
85
|
+
}
|
|
70
86
|
|
|
71
87
|
/**
|
|
72
88
|
* 获取统计信息
|
|
73
89
|
* @returns {{ count: number, indexSize: number }}
|
|
74
90
|
*/
|
|
75
|
-
async getStats() {
|
|
91
|
+
async getStats() {
|
|
92
|
+
throw new Error('Not implemented: getStats()');
|
|
93
|
+
}
|
|
76
94
|
}
|