swift-skills 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +410 -0
- package/build/cli/auth.d.ts +3 -0
- package/build/cli/auth.d.ts.map +1 -0
- package/build/cli/auth.js +44 -0
- package/build/cli/auth.js.map +1 -0
- package/build/cli/setup.d.ts +2 -0
- package/build/cli/setup.d.ts.map +1 -0
- package/build/cli/setup.js +150 -0
- package/build/cli/setup.js.map +1 -0
- package/build/cli/source-manager.d.ts +3 -0
- package/build/cli/source-manager.d.ts.map +1 -0
- package/build/cli/source-manager.js +117 -0
- package/build/cli/source-manager.js.map +1 -0
- package/build/config/creators.d.ts +11 -0
- package/build/config/creators.d.ts.map +1 -0
- package/build/config/creators.js +32 -0
- package/build/config/creators.js.map +1 -0
- package/build/config/sources.d.ts +91 -0
- package/build/config/sources.d.ts.map +1 -0
- package/build/config/sources.js +231 -0
- package/build/config/sources.js.map +1 -0
- package/build/config/sources.test.d.ts +2 -0
- package/build/config/sources.test.d.ts.map +1 -0
- package/build/config/sources.test.js +199 -0
- package/build/config/sources.test.js.map +1 -0
- package/build/config/swift-keywords.d.ts +29 -0
- package/build/config/swift-keywords.d.ts.map +1 -0
- package/build/config/swift-keywords.js +77 -0
- package/build/config/swift-keywords.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +181 -0
- package/build/index.js.map +1 -0
- package/build/integration/cache-behavior.test.d.ts +2 -0
- package/build/integration/cache-behavior.test.d.ts.map +1 -0
- package/build/integration/cache-behavior.test.js +521 -0
- package/build/integration/cache-behavior.test.js.map +1 -0
- package/build/integration/mcp-client.test.d.ts +2 -0
- package/build/integration/mcp-client.test.d.ts.map +1 -0
- package/build/integration/mcp-client.test.js +82 -0
- package/build/integration/mcp-client.test.js.map +1 -0
- package/build/integration/response-quality.test.d.ts +2 -0
- package/build/integration/response-quality.test.d.ts.map +1 -0
- package/build/integration/response-quality.test.js +230 -0
- package/build/integration/response-quality.test.js.map +1 -0
- package/build/integration/test-client.d.ts +25 -0
- package/build/integration/test-client.d.ts.map +1 -0
- package/build/integration/test-client.js +93 -0
- package/build/integration/test-client.js.map +1 -0
- package/build/sources/free/nilcoalescing.d.ts +8 -0
- package/build/sources/free/nilcoalescing.d.ts.map +1 -0
- package/build/sources/free/nilcoalescing.js +26 -0
- package/build/sources/free/nilcoalescing.js.map +1 -0
- package/build/sources/free/nilcoalescing.test.d.ts +2 -0
- package/build/sources/free/nilcoalescing.test.d.ts.map +1 -0
- package/build/sources/free/nilcoalescing.test.js +63 -0
- package/build/sources/free/nilcoalescing.test.js.map +1 -0
- package/build/sources/free/pointfree.d.ts +15 -0
- package/build/sources/free/pointfree.d.ts.map +1 -0
- package/build/sources/free/pointfree.js +175 -0
- package/build/sources/free/pointfree.js.map +1 -0
- package/build/sources/free/pointfree.test.d.ts +2 -0
- package/build/sources/free/pointfree.test.d.ts.map +1 -0
- package/build/sources/free/pointfree.test.js +86 -0
- package/build/sources/free/pointfree.test.js.map +1 -0
- package/build/sources/free/rssPatternSource.d.ts +42 -0
- package/build/sources/free/rssPatternSource.d.ts.map +1 -0
- package/build/sources/free/rssPatternSource.js +109 -0
- package/build/sources/free/rssPatternSource.js.map +1 -0
- package/build/sources/free/rssPatternSource.test.d.ts +2 -0
- package/build/sources/free/rssPatternSource.test.d.ts.map +1 -0
- package/build/sources/free/rssPatternSource.test.js +89 -0
- package/build/sources/free/rssPatternSource.test.js.map +1 -0
- package/build/sources/free/sundell.d.ts +8 -0
- package/build/sources/free/sundell.d.ts.map +1 -0
- package/build/sources/free/sundell.js +17 -0
- package/build/sources/free/sundell.js.map +1 -0
- package/build/sources/free/sundell.test.d.ts +2 -0
- package/build/sources/free/sundell.test.d.ts.map +1 -0
- package/build/sources/free/sundell.test.js +63 -0
- package/build/sources/free/sundell.test.js.map +1 -0
- package/build/sources/free/vanderlee.d.ts +8 -0
- package/build/sources/free/vanderlee.d.ts.map +1 -0
- package/build/sources/free/vanderlee.js +63 -0
- package/build/sources/free/vanderlee.js.map +1 -0
- package/build/sources/free/vanderlee.test.d.ts +2 -0
- package/build/sources/free/vanderlee.test.d.ts.map +1 -0
- package/build/sources/free/vanderlee.test.js +77 -0
- package/build/sources/free/vanderlee.test.js.map +1 -0
- package/build/sources/premium/patreon-dl.d.ts +45 -0
- package/build/sources/premium/patreon-dl.d.ts.map +1 -0
- package/build/sources/premium/patreon-dl.js +189 -0
- package/build/sources/premium/patreon-dl.js.map +1 -0
- package/build/sources/premium/patreon-fetch.d.ts +3 -0
- package/build/sources/premium/patreon-fetch.d.ts.map +1 -0
- package/build/sources/premium/patreon-fetch.js +18 -0
- package/build/sources/premium/patreon-fetch.js.map +1 -0
- package/build/sources/premium/patreon-oauth.d.ts +24 -0
- package/build/sources/premium/patreon-oauth.d.ts.map +1 -0
- package/build/sources/premium/patreon-oauth.js +208 -0
- package/build/sources/premium/patreon-oauth.js.map +1 -0
- package/build/sources/premium/patreon-zip.d.ts +17 -0
- package/build/sources/premium/patreon-zip.d.ts.map +1 -0
- package/build/sources/premium/patreon-zip.js +127 -0
- package/build/sources/premium/patreon-zip.js.map +1 -0
- package/build/sources/premium/patreon.d.ts +48 -0
- package/build/sources/premium/patreon.d.ts.map +1 -0
- package/build/sources/premium/patreon.js +221 -0
- package/build/sources/premium/patreon.js.map +1 -0
- package/build/sources/premium/youtube.d.ts +14 -0
- package/build/sources/premium/youtube.d.ts.map +1 -0
- package/build/sources/premium/youtube.js +92 -0
- package/build/sources/premium/youtube.js.map +1 -0
- package/build/tools/extract-cookie.d.ts +2 -0
- package/build/tools/extract-cookie.d.ts.map +1 -0
- package/build/tools/extract-cookie.js +40 -0
- package/build/tools/extract-cookie.js.map +1 -0
- package/build/tools/handlers/enableSource.d.ts +3 -0
- package/build/tools/handlers/enableSource.d.ts.map +1 -0
- package/build/tools/handlers/enableSource.js +25 -0
- package/build/tools/handlers/enableSource.js.map +1 -0
- package/build/tools/handlers/getPatreonPatterns.d.ts +3 -0
- package/build/tools/handlers/getPatreonPatterns.d.ts.map +1 -0
- package/build/tools/handlers/getPatreonPatterns.js +43 -0
- package/build/tools/handlers/getPatreonPatterns.js.map +1 -0
- package/build/tools/handlers/getSwiftPattern.d.ts +3 -0
- package/build/tools/handlers/getSwiftPattern.d.ts.map +1 -0
- package/build/tools/handlers/getSwiftPattern.js +72 -0
- package/build/tools/handlers/getSwiftPattern.js.map +1 -0
- package/build/tools/handlers/handlers.test.d.ts +2 -0
- package/build/tools/handlers/handlers.test.d.ts.map +1 -0
- package/build/tools/handlers/handlers.test.js +359 -0
- package/build/tools/handlers/handlers.test.js.map +1 -0
- package/build/tools/handlers/listContentSources.d.ts +3 -0
- package/build/tools/handlers/listContentSources.d.ts.map +1 -0
- package/build/tools/handlers/listContentSources.js +34 -0
- package/build/tools/handlers/listContentSources.js.map +1 -0
- package/build/tools/handlers/searchSwiftContent.d.ts +3 -0
- package/build/tools/handlers/searchSwiftContent.d.ts.map +1 -0
- package/build/tools/handlers/searchSwiftContent.js +121 -0
- package/build/tools/handlers/searchSwiftContent.js.map +1 -0
- package/build/tools/handlers/setupPatreon.d.ts +3 -0
- package/build/tools/handlers/setupPatreon.d.ts.map +1 -0
- package/build/tools/handlers/setupPatreon.js +40 -0
- package/build/tools/handlers/setupPatreon.js.map +1 -0
- package/build/tools/index.d.ts +3 -0
- package/build/tools/index.d.ts.map +1 -0
- package/build/tools/index.js +18 -0
- package/build/tools/index.js.map +1 -0
- package/build/tools/registry.d.ts +14 -0
- package/build/tools/registry.d.ts.map +1 -0
- package/build/tools/registry.js +21 -0
- package/build/tools/registry.js.map +1 -0
- package/build/tools/registry.test.d.ts +2 -0
- package/build/tools/registry.test.d.ts.map +1 -0
- package/build/tools/registry.test.js +54 -0
- package/build/tools/registry.test.js.map +1 -0
- package/build/tools/types.d.ts +67 -0
- package/build/tools/types.d.ts.map +1 -0
- package/build/tools/types.js +3 -0
- package/build/tools/types.js.map +1 -0
- package/build/utils/cache.d.ts +20 -0
- package/build/utils/cache.d.ts.map +1 -0
- package/build/utils/cache.js +186 -0
- package/build/utils/cache.js.map +1 -0
- package/build/utils/concurrency.d.ts +13 -0
- package/build/utils/concurrency.d.ts.map +1 -0
- package/build/utils/concurrency.js +33 -0
- package/build/utils/concurrency.js.map +1 -0
- package/build/utils/errors.d.ts +19 -0
- package/build/utils/errors.d.ts.map +1 -0
- package/build/utils/errors.js +35 -0
- package/build/utils/errors.js.map +1 -0
- package/build/utils/fetch.d.ts +6 -0
- package/build/utils/fetch.d.ts.map +1 -0
- package/build/utils/fetch.js +6 -0
- package/build/utils/fetch.js.map +1 -0
- package/build/utils/http.d.ts +21 -0
- package/build/utils/http.d.ts.map +1 -0
- package/build/utils/http.js +53 -0
- package/build/utils/http.js.map +1 -0
- package/build/utils/intent-cache.d.ts +94 -0
- package/build/utils/intent-cache.d.ts.map +1 -0
- package/build/utils/intent-cache.js +164 -0
- package/build/utils/intent-cache.js.map +1 -0
- package/build/utils/intent-cache.test.d.ts +2 -0
- package/build/utils/intent-cache.test.d.ts.map +1 -0
- package/build/utils/intent-cache.test.js +290 -0
- package/build/utils/intent-cache.test.js.map +1 -0
- package/build/utils/logger.d.ts +4 -0
- package/build/utils/logger.d.ts.map +1 -0
- package/build/utils/logger.js +9 -0
- package/build/utils/logger.js.map +1 -0
- package/build/utils/paths.d.ts +27 -0
- package/build/utils/paths.d.ts.map +1 -0
- package/build/utils/paths.js +43 -0
- package/build/utils/paths.js.map +1 -0
- package/build/utils/pattern-formatter.d.ts +40 -0
- package/build/utils/pattern-formatter.d.ts.map +1 -0
- package/build/utils/pattern-formatter.js +124 -0
- package/build/utils/pattern-formatter.js.map +1 -0
- package/build/utils/response-helpers.d.ts +17 -0
- package/build/utils/response-helpers.d.ts.map +1 -0
- package/build/utils/response-helpers.js +34 -0
- package/build/utils/response-helpers.js.map +1 -0
- package/build/utils/search-terms.d.ts +17 -0
- package/build/utils/search-terms.d.ts.map +1 -0
- package/build/utils/search-terms.js +71 -0
- package/build/utils/search-terms.js.map +1 -0
- package/build/utils/search-terms.test.d.ts +2 -0
- package/build/utils/search-terms.test.d.ts.map +1 -0
- package/build/utils/search-terms.test.js +107 -0
- package/build/utils/search-terms.test.js.map +1 -0
- package/build/utils/search.d.ts +48 -0
- package/build/utils/search.d.ts.map +1 -0
- package/build/utils/search.js +158 -0
- package/build/utils/search.js.map +1 -0
- package/build/utils/search.test.d.ts +2 -0
- package/build/utils/search.test.d.ts.map +1 -0
- package/build/utils/search.test.js +199 -0
- package/build/utils/search.test.js.map +1 -0
- package/build/utils/semantic-recall.d.ts +38 -0
- package/build/utils/semantic-recall.d.ts.map +1 -0
- package/build/utils/semantic-recall.js +134 -0
- package/build/utils/semantic-recall.js.map +1 -0
- package/build/utils/semantic-recall.test.d.ts +2 -0
- package/build/utils/semantic-recall.test.d.ts.map +1 -0
- package/build/utils/semantic-recall.test.js +326 -0
- package/build/utils/semantic-recall.test.js.map +1 -0
- package/build/utils/source-registry.d.ts +45 -0
- package/build/utils/source-registry.d.ts.map +1 -0
- package/build/utils/source-registry.js +113 -0
- package/build/utils/source-registry.js.map +1 -0
- package/build/utils/source-registry.test.d.ts +2 -0
- package/build/utils/source-registry.test.d.ts.map +1 -0
- package/build/utils/source-registry.test.js +206 -0
- package/build/utils/source-registry.test.js.map +1 -0
- package/build/utils/swift-analysis.d.ts +61 -0
- package/build/utils/swift-analysis.d.ts.map +1 -0
- package/build/utils/swift-analysis.js +339 -0
- package/build/utils/swift-analysis.js.map +1 -0
- package/build/utils/swift-analysis.test.d.ts +2 -0
- package/build/utils/swift-analysis.test.d.ts.map +1 -0
- package/build/utils/swift-analysis.test.js +473 -0
- package/build/utils/swift-analysis.test.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared HTTP utilities for making requests with timeouts and error handling
|
|
3
|
+
*/
|
|
4
|
+
import { fetch } from './fetch.js';
|
|
5
|
+
const DEFAULT_TIMEOUT = 10000; // 10 seconds
|
|
6
|
+
/**
|
|
7
|
+
* Build headers with optional authorization token
|
|
8
|
+
*/
|
|
9
|
+
export function buildHeaders(userAgent, authToken) {
|
|
10
|
+
const headers = {
|
|
11
|
+
'User-Agent': userAgent,
|
|
12
|
+
};
|
|
13
|
+
if (authToken) {
|
|
14
|
+
headers.Authorization = `Bearer ${authToken}`;
|
|
15
|
+
}
|
|
16
|
+
return headers;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Fetch with timeout and error handling
|
|
20
|
+
*/
|
|
21
|
+
async function fetchWithTimeout(url, options = {}) {
|
|
22
|
+
const { timeout = DEFAULT_TIMEOUT, headers = {}, signal } = options;
|
|
23
|
+
const controller = new AbortController();
|
|
24
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
25
|
+
try {
|
|
26
|
+
const response = await fetch(url, {
|
|
27
|
+
signal: signal || controller.signal,
|
|
28
|
+
headers,
|
|
29
|
+
});
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
throw new Error(`HTTP ${response.status}`);
|
|
32
|
+
}
|
|
33
|
+
return response;
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
clearTimeout(timeoutId);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Fetch JSON data with timeout
|
|
41
|
+
*/
|
|
42
|
+
export async function fetchJson(url, options = {}) {
|
|
43
|
+
const response = await fetchWithTimeout(url, options);
|
|
44
|
+
return await response.json();
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Fetch text content with timeout
|
|
48
|
+
*/
|
|
49
|
+
export async function fetchText(url, options = {}) {
|
|
50
|
+
const response = await fetchWithTimeout(url, options);
|
|
51
|
+
return await response.text();
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/utils/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAQnC,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,aAAa;AAE5C;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,SAAiB,EAAE,SAAkB;IAChE,MAAM,OAAO,GAA2B;QACtC,YAAY,EAAE,SAAS;KACxB,CAAC;IACF,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,aAAa,GAAG,UAAU,SAAS,EAAE,CAAC;IAChD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAC7B,GAAW,EACX,UAAwB,EAAE;IAE1B,MAAM,EAAE,OAAO,GAAG,eAAe,EAAE,OAAO,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEpE,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;IAEhE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM,IAAI,UAAU,CAAC,MAAM;YACnC,OAAO;SACR,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAW,EACX,UAAwB,EAAE;IAE1B,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtD,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAO,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAW,EACX,UAAwB,EAAE;IAE1B,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtD,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Components used to build a cache key
|
|
3
|
+
*/
|
|
4
|
+
export interface IntentKey {
|
|
5
|
+
tool: string;
|
|
6
|
+
query: string;
|
|
7
|
+
minQuality: number;
|
|
8
|
+
sources: string[];
|
|
9
|
+
requireCode?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Cached search result with all required fields
|
|
13
|
+
*/
|
|
14
|
+
export interface CachedIntentResult {
|
|
15
|
+
patternIds: string[];
|
|
16
|
+
scores: Record<string, number>;
|
|
17
|
+
sourceFingerprint: string;
|
|
18
|
+
timestamp: number;
|
|
19
|
+
totalCount: number;
|
|
20
|
+
patterns?: unknown[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Storable cached search result (without immutable metadata fields)
|
|
24
|
+
* Handlers use this to set cache values with complete type safety
|
|
25
|
+
*/
|
|
26
|
+
export interface StorableCachedSearchResult {
|
|
27
|
+
patternIds: string[];
|
|
28
|
+
scores: Record<string, number>;
|
|
29
|
+
totalCount: number;
|
|
30
|
+
patterns?: unknown[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* IntentCache - Caches tool handler results by normalized query intent
|
|
34
|
+
*
|
|
35
|
+
* Key features:
|
|
36
|
+
* - SHA-256 hashing for cache keys
|
|
37
|
+
* - Query normalization (lowercase, stopwords, sorted)
|
|
38
|
+
* - Source fingerprinting for invalidation
|
|
39
|
+
* - Stores metadata only (IDs + scores), not full patterns
|
|
40
|
+
*/
|
|
41
|
+
export declare class IntentCache {
|
|
42
|
+
private cache;
|
|
43
|
+
private pendingFetches;
|
|
44
|
+
private hits;
|
|
45
|
+
private misses;
|
|
46
|
+
constructor(maxMemoryEntries?: number, namespace?: string);
|
|
47
|
+
/**
|
|
48
|
+
* Normalize a query for consistent cache key generation
|
|
49
|
+
* - Lowercase
|
|
50
|
+
* - Remove stopwords (except Swift terms)
|
|
51
|
+
* - Sort alphabetically (order-independent)
|
|
52
|
+
*/
|
|
53
|
+
normalizeQuery(query: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Generate a fingerprint from enabled source IDs
|
|
56
|
+
* Used to detect when sources change (invalidating cached results)
|
|
57
|
+
*/
|
|
58
|
+
getSourceFingerprint(sources: string[]): string;
|
|
59
|
+
/**
|
|
60
|
+
* Build a cache key from intent components
|
|
61
|
+
* Format: tool::normalizedQuery::qN::fingerprint[::code]
|
|
62
|
+
*/
|
|
63
|
+
buildCacheKey(intent: IntentKey): string;
|
|
64
|
+
/**
|
|
65
|
+
* Get cached result, validating source fingerprint
|
|
66
|
+
* Returns null if no valid cache entry exists
|
|
67
|
+
*/
|
|
68
|
+
get(intent: IntentKey): Promise<CachedIntentResult | null>;
|
|
69
|
+
/**
|
|
70
|
+
* Store result in cache
|
|
71
|
+
* Accepts both basic CachedIntentResult and extended CachedIntentResultWithPatterns
|
|
72
|
+
*/
|
|
73
|
+
set(intent: IntentKey, result: StorableCachedSearchResult, ttl?: number): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* Get cached result or fetch if not cached
|
|
76
|
+
* Includes in-flight deduplication to prevent cache stampede
|
|
77
|
+
*/
|
|
78
|
+
getOrFetch(intent: IntentKey, fetcher: () => Promise<StorableCachedSearchResult>, ttl?: number): Promise<CachedIntentResult>;
|
|
79
|
+
/**
|
|
80
|
+
* Clear all cached intents
|
|
81
|
+
*/
|
|
82
|
+
clear(): void;
|
|
83
|
+
/**
|
|
84
|
+
* Get cache statistics
|
|
85
|
+
*/
|
|
86
|
+
getStats(): {
|
|
87
|
+
hits: number;
|
|
88
|
+
misses: number;
|
|
89
|
+
hitRate: number;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export declare const intentCache: IntentCache;
|
|
93
|
+
export default IntentCache;
|
|
94
|
+
//# sourceMappingURL=intent-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-cache.d.ts","sourceRoot":"","sources":["../../src/utils/intent-cache.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,cAAc,CAA4C;IAGlE,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;gBAGjB,gBAAgB,GAAE,MAAmC,EACrD,SAAS,GAAE,MAAiB;IAK9B;;;;;OAKG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAQrC;;;OAGG;IACH,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM;IAQ/C;;;OAGG;IACH,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM;IAqBxC;;;OAGG;IACG,GAAG,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAoBhE;;;OAGG;IACG,GAAG,CACP,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,0BAA0B,EAClC,GAAG,GAAE,MAA2B,GAC/B,OAAO,CAAC,IAAI,CAAC;IAahB;;;OAGG;IACG,UAAU,CACd,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,MAAM,OAAO,CAAC,0BAA0B,CAAC,EAClD,GAAG,GAAE,MAA2B,GAC/B,OAAO,CAAC,kBAAkB,CAAC;IAuC9B;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,QAAQ,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAQ9D;AAGD,eAAO,MAAM,WAAW,aAAoB,CAAC;AAE7C,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// src/utils/intent-cache.ts
|
|
2
|
+
// Intent-aware response caching for MCP tool handlers
|
|
3
|
+
import { createHash } from 'crypto';
|
|
4
|
+
import { FileCache } from './cache.js';
|
|
5
|
+
import { normalizeTokens } from './search-terms.js';
|
|
6
|
+
// 12 hours in seconds (longer than RSS cache, shorter than article cache)
|
|
7
|
+
const DEFAULT_INTENT_TTL = 43200;
|
|
8
|
+
const DEFAULT_MAX_MEMORY_ENTRIES = 200;
|
|
9
|
+
/**
|
|
10
|
+
* IntentCache - Caches tool handler results by normalized query intent
|
|
11
|
+
*
|
|
12
|
+
* Key features:
|
|
13
|
+
* - SHA-256 hashing for cache keys
|
|
14
|
+
* - Query normalization (lowercase, stopwords, sorted)
|
|
15
|
+
* - Source fingerprinting for invalidation
|
|
16
|
+
* - Stores metadata only (IDs + scores), not full patterns
|
|
17
|
+
*/
|
|
18
|
+
export class IntentCache {
|
|
19
|
+
cache;
|
|
20
|
+
pendingFetches = new Map();
|
|
21
|
+
// Simple metrics
|
|
22
|
+
hits = 0;
|
|
23
|
+
misses = 0;
|
|
24
|
+
constructor(maxMemoryEntries = DEFAULT_MAX_MEMORY_ENTRIES, namespace = 'intent') {
|
|
25
|
+
this.cache = new FileCache(namespace, maxMemoryEntries);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Normalize a query for consistent cache key generation
|
|
29
|
+
* - Lowercase
|
|
30
|
+
* - Remove stopwords (except Swift terms)
|
|
31
|
+
* - Sort alphabetically (order-independent)
|
|
32
|
+
*/
|
|
33
|
+
normalizeQuery(query) {
|
|
34
|
+
// Use shared normalization without stemming (cache keys shouldn't stem)
|
|
35
|
+
const processed = normalizeTokens(query);
|
|
36
|
+
// Sort for order-independent matching
|
|
37
|
+
return processed.sort().join(' ');
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Generate a fingerprint from enabled source IDs
|
|
41
|
+
* Used to detect when sources change (invalidating cached results)
|
|
42
|
+
*/
|
|
43
|
+
getSourceFingerprint(sources) {
|
|
44
|
+
const sorted = [...sources].sort().join(',');
|
|
45
|
+
return createHash('sha256')
|
|
46
|
+
.update(sorted)
|
|
47
|
+
.digest('hex')
|
|
48
|
+
.substring(0, 12); // 12 chars sufficient for source combos
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Build a cache key from intent components
|
|
52
|
+
* Format: tool::normalizedQuery::qN::fingerprint[::code]
|
|
53
|
+
*/
|
|
54
|
+
buildCacheKey(intent) {
|
|
55
|
+
const normalized = this.normalizeQuery(intent.query);
|
|
56
|
+
const fingerprint = this.getSourceFingerprint(intent.sources);
|
|
57
|
+
const parts = [
|
|
58
|
+
intent.tool,
|
|
59
|
+
normalized,
|
|
60
|
+
`q${intent.minQuality}`,
|
|
61
|
+
fingerprint,
|
|
62
|
+
];
|
|
63
|
+
if (intent.requireCode) {
|
|
64
|
+
parts.push('code');
|
|
65
|
+
}
|
|
66
|
+
const key = parts.join('::');
|
|
67
|
+
// Always hash for filesystem safety and consistent length
|
|
68
|
+
return createHash('sha256').update(key).digest('hex');
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get cached result, validating source fingerprint
|
|
72
|
+
* Returns null if no valid cache entry exists
|
|
73
|
+
*/
|
|
74
|
+
async get(intent) {
|
|
75
|
+
const key = this.buildCacheKey(intent);
|
|
76
|
+
const cached = await this.cache.get(key);
|
|
77
|
+
if (!cached) {
|
|
78
|
+
this.misses++;
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
// Validate source fingerprint hasn't changed
|
|
82
|
+
const currentFingerprint = this.getSourceFingerprint(intent.sources);
|
|
83
|
+
if (cached.sourceFingerprint !== currentFingerprint) {
|
|
84
|
+
this.misses++;
|
|
85
|
+
return null; // Sources changed, treat as miss
|
|
86
|
+
}
|
|
87
|
+
this.hits++;
|
|
88
|
+
return cached;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Store result in cache
|
|
92
|
+
* Accepts both basic CachedIntentResult and extended CachedIntentResultWithPatterns
|
|
93
|
+
*/
|
|
94
|
+
async set(intent, result, ttl = DEFAULT_INTENT_TTL) {
|
|
95
|
+
const key = this.buildCacheKey(intent);
|
|
96
|
+
const fingerprint = this.getSourceFingerprint(intent.sources);
|
|
97
|
+
const entry = {
|
|
98
|
+
...result,
|
|
99
|
+
sourceFingerprint: fingerprint,
|
|
100
|
+
timestamp: Date.now(),
|
|
101
|
+
};
|
|
102
|
+
await this.cache.set(key, entry, ttl);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get cached result or fetch if not cached
|
|
106
|
+
* Includes in-flight deduplication to prevent cache stampede
|
|
107
|
+
*/
|
|
108
|
+
async getOrFetch(intent, fetcher, ttl = DEFAULT_INTENT_TTL) {
|
|
109
|
+
// Check cache first
|
|
110
|
+
const cached = await this.get(intent);
|
|
111
|
+
if (cached) {
|
|
112
|
+
return cached;
|
|
113
|
+
}
|
|
114
|
+
// Build key for deduplication
|
|
115
|
+
const key = this.buildCacheKey(intent);
|
|
116
|
+
// Check if fetch already in progress (stampede prevention)
|
|
117
|
+
const pending = this.pendingFetches.get(key);
|
|
118
|
+
if (pending) {
|
|
119
|
+
return pending;
|
|
120
|
+
}
|
|
121
|
+
// Start fetch and track it
|
|
122
|
+
const fetchPromise = (async () => {
|
|
123
|
+
try {
|
|
124
|
+
const result = await fetcher();
|
|
125
|
+
const fingerprint = this.getSourceFingerprint(intent.sources);
|
|
126
|
+
const entry = {
|
|
127
|
+
...result,
|
|
128
|
+
sourceFingerprint: fingerprint,
|
|
129
|
+
timestamp: Date.now(),
|
|
130
|
+
};
|
|
131
|
+
await this.cache.set(key, entry, ttl);
|
|
132
|
+
return entry;
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
this.pendingFetches.delete(key);
|
|
136
|
+
}
|
|
137
|
+
})();
|
|
138
|
+
this.pendingFetches.set(key, fetchPromise);
|
|
139
|
+
return fetchPromise;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Clear all cached intents
|
|
143
|
+
*/
|
|
144
|
+
clear() {
|
|
145
|
+
this.cache.clear();
|
|
146
|
+
this.hits = 0;
|
|
147
|
+
this.misses = 0;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get cache statistics
|
|
151
|
+
*/
|
|
152
|
+
getStats() {
|
|
153
|
+
const total = this.hits + this.misses;
|
|
154
|
+
return {
|
|
155
|
+
hits: this.hits,
|
|
156
|
+
misses: this.misses,
|
|
157
|
+
hitRate: total > 0 ? this.hits / total : 0,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Shared instance for tool handlers
|
|
162
|
+
export const intentCache = new IntentCache();
|
|
163
|
+
export default IntentCache;
|
|
164
|
+
//# sourceMappingURL=intent-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-cache.js","sourceRoot":"","sources":["../../src/utils/intent-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-cache.test.d.ts","sourceRoot":"","sources":["../../src/utils/intent-cache.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
// src/utils/intent-cache.test.ts
|
|
2
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
3
|
+
import { IntentCache } from './intent-cache.js';
|
|
4
|
+
describe('IntentCache', () => {
|
|
5
|
+
let cache;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
// Use test-specific namespace to avoid cache pollution from build/ tests
|
|
8
|
+
cache = new IntentCache(50, `test-${Date.now()}-${Math.random()}`);
|
|
9
|
+
cache.clear();
|
|
10
|
+
});
|
|
11
|
+
describe('normalizeQuery', () => {
|
|
12
|
+
it('should lowercase queries', () => {
|
|
13
|
+
expect(cache.normalizeQuery('SwiftUI Navigation')).toBe('navigation swiftui');
|
|
14
|
+
});
|
|
15
|
+
it('should trim whitespace', () => {
|
|
16
|
+
expect(cache.normalizeQuery(' async await ')).toBe('async await');
|
|
17
|
+
});
|
|
18
|
+
it('should collapse multiple spaces', () => {
|
|
19
|
+
expect(cache.normalizeQuery('async await')).toBe('async await');
|
|
20
|
+
});
|
|
21
|
+
it('should remove stopwords', () => {
|
|
22
|
+
// "how" and "to" are stopwords, but "use" is not
|
|
23
|
+
expect(cache.normalizeQuery('how to use async await')).toBe('async await use');
|
|
24
|
+
});
|
|
25
|
+
it('should preserve Swift technical terms', () => {
|
|
26
|
+
const result = cache.normalizeQuery('swiftui combine async await');
|
|
27
|
+
expect(result).toContain('swiftui');
|
|
28
|
+
expect(result).toContain('combine');
|
|
29
|
+
expect(result).toContain('async');
|
|
30
|
+
expect(result).toContain('await');
|
|
31
|
+
});
|
|
32
|
+
it('should sort tokens alphabetically', () => {
|
|
33
|
+
expect(cache.normalizeQuery('zeta alpha beta')).toBe('alpha beta zeta');
|
|
34
|
+
});
|
|
35
|
+
it('should handle hyphenated terms', () => {
|
|
36
|
+
const result = cache.normalizeQuery('async-await patterns');
|
|
37
|
+
expect(result).toContain('async');
|
|
38
|
+
expect(result).toContain('await');
|
|
39
|
+
expect(result).toContain('pattern');
|
|
40
|
+
});
|
|
41
|
+
it('should produce consistent output for semantically similar queries', () => {
|
|
42
|
+
const q1 = cache.normalizeQuery('How to use SwiftUI navigation');
|
|
43
|
+
const q2 = cache.normalizeQuery('swiftui navigation usage');
|
|
44
|
+
const q3 = cache.normalizeQuery('Navigation in SwiftUI');
|
|
45
|
+
// All should normalize similarly (containing same key terms)
|
|
46
|
+
expect(q1).toContain('navigation');
|
|
47
|
+
expect(q1).toContain('swiftui');
|
|
48
|
+
expect(q2).toContain('navigation');
|
|
49
|
+
expect(q2).toContain('swiftui');
|
|
50
|
+
expect(q3).toContain('navigation');
|
|
51
|
+
expect(q3).toContain('swiftui');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe('getSourceFingerprint', () => {
|
|
55
|
+
it('should produce deterministic fingerprint for same sources', () => {
|
|
56
|
+
const sources = ['sundell', 'vanderlee', 'pointfree'];
|
|
57
|
+
const fp1 = cache.getSourceFingerprint(sources);
|
|
58
|
+
const fp2 = cache.getSourceFingerprint(sources);
|
|
59
|
+
expect(fp1).toBe(fp2);
|
|
60
|
+
});
|
|
61
|
+
it('should produce same fingerprint regardless of source order', () => {
|
|
62
|
+
const fp1 = cache.getSourceFingerprint(['sundell', 'vanderlee']);
|
|
63
|
+
const fp2 = cache.getSourceFingerprint(['vanderlee', 'sundell']);
|
|
64
|
+
expect(fp1).toBe(fp2);
|
|
65
|
+
});
|
|
66
|
+
it('should produce different fingerprint for different sources', () => {
|
|
67
|
+
const fp1 = cache.getSourceFingerprint(['sundell']);
|
|
68
|
+
const fp2 = cache.getSourceFingerprint(['sundell', 'vanderlee']);
|
|
69
|
+
expect(fp1).not.toBe(fp2);
|
|
70
|
+
});
|
|
71
|
+
it('should return 12-character fingerprint', () => {
|
|
72
|
+
const fp = cache.getSourceFingerprint(['sundell', 'vanderlee']);
|
|
73
|
+
expect(fp.length).toBe(12);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
describe('buildCacheKey', () => {
|
|
77
|
+
it('should produce deterministic key for same intent', () => {
|
|
78
|
+
const intent = {
|
|
79
|
+
tool: 'get_swift_pattern',
|
|
80
|
+
query: 'SwiftUI Navigation',
|
|
81
|
+
minQuality: 60,
|
|
82
|
+
sources: ['sundell', 'vanderlee'],
|
|
83
|
+
};
|
|
84
|
+
const key1 = cache.buildCacheKey(intent);
|
|
85
|
+
const key2 = cache.buildCacheKey(intent);
|
|
86
|
+
expect(key1).toBe(key2);
|
|
87
|
+
});
|
|
88
|
+
it('should produce same key for different query orderings', () => {
|
|
89
|
+
const intent1 = {
|
|
90
|
+
tool: 'get_swift_pattern',
|
|
91
|
+
query: 'async await SwiftUI',
|
|
92
|
+
minQuality: 60,
|
|
93
|
+
sources: ['sundell'],
|
|
94
|
+
};
|
|
95
|
+
const intent2 = {
|
|
96
|
+
tool: 'get_swift_pattern',
|
|
97
|
+
query: 'SwiftUI async await',
|
|
98
|
+
minQuality: 60,
|
|
99
|
+
sources: ['sundell'],
|
|
100
|
+
};
|
|
101
|
+
expect(cache.buildCacheKey(intent1)).toBe(cache.buildCacheKey(intent2));
|
|
102
|
+
});
|
|
103
|
+
it('should produce different key for different tools', () => {
|
|
104
|
+
const base = { query: 'testing', minQuality: 60, sources: ['sundell'] };
|
|
105
|
+
const key1 = cache.buildCacheKey({ ...base, tool: 'get_swift_pattern' });
|
|
106
|
+
const key2 = cache.buildCacheKey({ ...base, tool: 'search_swift_content' });
|
|
107
|
+
expect(key1).not.toBe(key2);
|
|
108
|
+
});
|
|
109
|
+
it('should produce different key for different minQuality', () => {
|
|
110
|
+
const base = { tool: 'get_swift_pattern', query: 'testing', sources: ['sundell'] };
|
|
111
|
+
const key1 = cache.buildCacheKey({ ...base, minQuality: 60 });
|
|
112
|
+
const key2 = cache.buildCacheKey({ ...base, minQuality: 80 });
|
|
113
|
+
expect(key1).not.toBe(key2);
|
|
114
|
+
});
|
|
115
|
+
it('should produce different key for different sources', () => {
|
|
116
|
+
const base = { tool: 'get_swift_pattern', query: 'testing', minQuality: 60 };
|
|
117
|
+
const key1 = cache.buildCacheKey({ ...base, sources: ['sundell'] });
|
|
118
|
+
const key2 = cache.buildCacheKey({ ...base, sources: ['sundell', 'vanderlee'] });
|
|
119
|
+
expect(key1).not.toBe(key2);
|
|
120
|
+
});
|
|
121
|
+
it('should produce different key when requireCode differs', () => {
|
|
122
|
+
const base = { tool: 'search_swift_content', query: 'testing', minQuality: 60, sources: ['sundell'] };
|
|
123
|
+
const key1 = cache.buildCacheKey({ ...base, requireCode: false });
|
|
124
|
+
const key2 = cache.buildCacheKey({ ...base, requireCode: true });
|
|
125
|
+
expect(key1).not.toBe(key2);
|
|
126
|
+
});
|
|
127
|
+
it('should return 64-character SHA-256 hash', () => {
|
|
128
|
+
const key = cache.buildCacheKey({
|
|
129
|
+
tool: 'get_swift_pattern',
|
|
130
|
+
query: 'testing',
|
|
131
|
+
minQuality: 60,
|
|
132
|
+
sources: ['sundell'],
|
|
133
|
+
});
|
|
134
|
+
expect(key.length).toBe(64);
|
|
135
|
+
expect(/^[a-f0-9]+$/.test(key)).toBe(true);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
describe('get and set', () => {
|
|
139
|
+
const testIntent = {
|
|
140
|
+
tool: 'get_swift_pattern',
|
|
141
|
+
query: 'SwiftUI navigation',
|
|
142
|
+
minQuality: 60,
|
|
143
|
+
sources: ['sundell', 'vanderlee'],
|
|
144
|
+
};
|
|
145
|
+
const testResult = {
|
|
146
|
+
patternIds: ['pattern-1', 'pattern-2'],
|
|
147
|
+
scores: { 'pattern-1': 95, 'pattern-2': 87 },
|
|
148
|
+
totalCount: 2,
|
|
149
|
+
};
|
|
150
|
+
it('should return null for non-existent key', async () => {
|
|
151
|
+
const result = await cache.get(testIntent);
|
|
152
|
+
expect(result).toBeNull();
|
|
153
|
+
});
|
|
154
|
+
it('should store and retrieve cached result', async () => {
|
|
155
|
+
await cache.set(testIntent, testResult);
|
|
156
|
+
const retrieved = await cache.get(testIntent);
|
|
157
|
+
expect(retrieved).not.toBeNull();
|
|
158
|
+
expect(retrieved?.patternIds).toEqual(testResult.patternIds);
|
|
159
|
+
expect(retrieved?.scores).toEqual(testResult.scores);
|
|
160
|
+
expect(retrieved?.totalCount).toBe(testResult.totalCount);
|
|
161
|
+
});
|
|
162
|
+
it('should include sourceFingerprint in stored result', async () => {
|
|
163
|
+
await cache.set(testIntent, testResult);
|
|
164
|
+
const retrieved = await cache.get(testIntent);
|
|
165
|
+
expect(retrieved?.sourceFingerprint).toBe(cache.getSourceFingerprint(testIntent.sources));
|
|
166
|
+
});
|
|
167
|
+
it('should include timestamp in stored result', async () => {
|
|
168
|
+
const beforeSet = Date.now();
|
|
169
|
+
await cache.set(testIntent, testResult);
|
|
170
|
+
const afterSet = Date.now();
|
|
171
|
+
const retrieved = await cache.get(testIntent);
|
|
172
|
+
expect(retrieved?.timestamp).toBeGreaterThanOrEqual(beforeSet);
|
|
173
|
+
expect(retrieved?.timestamp).toBeLessThanOrEqual(afterSet);
|
|
174
|
+
});
|
|
175
|
+
it('should return null when sources change (fingerprint mismatch)', async () => {
|
|
176
|
+
await cache.set(testIntent, testResult);
|
|
177
|
+
// Query with different sources
|
|
178
|
+
const differentSources = {
|
|
179
|
+
...testIntent,
|
|
180
|
+
sources: ['sundell'], // Different from original
|
|
181
|
+
};
|
|
182
|
+
// Should miss due to fingerprint validation
|
|
183
|
+
const result = await cache.get(differentSources);
|
|
184
|
+
expect(result).toBeNull();
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
describe('getOrFetch', () => {
|
|
188
|
+
const testIntent = {
|
|
189
|
+
tool: 'get_swift_pattern',
|
|
190
|
+
query: 'combine reactive',
|
|
191
|
+
minQuality: 60,
|
|
192
|
+
sources: ['sundell'],
|
|
193
|
+
};
|
|
194
|
+
it('should call fetcher on cache miss', async () => {
|
|
195
|
+
let fetcherCalled = false;
|
|
196
|
+
const fetcher = async () => {
|
|
197
|
+
fetcherCalled = true;
|
|
198
|
+
return {
|
|
199
|
+
patternIds: ['p1'],
|
|
200
|
+
scores: { 'p1': 90 },
|
|
201
|
+
totalCount: 1,
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
await cache.getOrFetch(testIntent, fetcher);
|
|
205
|
+
expect(fetcherCalled).toBe(true);
|
|
206
|
+
});
|
|
207
|
+
it('should not call fetcher on cache hit', async () => {
|
|
208
|
+
// Pre-populate cache
|
|
209
|
+
await cache.set(testIntent, {
|
|
210
|
+
patternIds: ['cached'],
|
|
211
|
+
scores: { 'cached': 80 },
|
|
212
|
+
totalCount: 1,
|
|
213
|
+
});
|
|
214
|
+
let fetcherCalled = false;
|
|
215
|
+
const fetcher = async () => {
|
|
216
|
+
fetcherCalled = true;
|
|
217
|
+
return {
|
|
218
|
+
patternIds: ['fresh'],
|
|
219
|
+
scores: { 'fresh': 90 },
|
|
220
|
+
totalCount: 1,
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
const result = await cache.getOrFetch(testIntent, fetcher);
|
|
224
|
+
expect(fetcherCalled).toBe(false);
|
|
225
|
+
expect(result.patternIds).toEqual(['cached']);
|
|
226
|
+
});
|
|
227
|
+
it('should cache fetched results', async () => {
|
|
228
|
+
const fetcher = async () => ({
|
|
229
|
+
patternIds: ['fetched'],
|
|
230
|
+
scores: { 'fetched': 85 },
|
|
231
|
+
totalCount: 1,
|
|
232
|
+
});
|
|
233
|
+
await cache.getOrFetch(testIntent, fetcher);
|
|
234
|
+
// Second call should hit cache
|
|
235
|
+
const cached = await cache.get(testIntent);
|
|
236
|
+
expect(cached?.patternIds).toEqual(['fetched']);
|
|
237
|
+
});
|
|
238
|
+
// Note: Stampede prevention (concurrent request deduplication) is tested
|
|
239
|
+
// in src/integration/cache-behavior.test.ts with more comprehensive scenarios
|
|
240
|
+
});
|
|
241
|
+
describe('stats', () => {
|
|
242
|
+
const testIntent = {
|
|
243
|
+
tool: 'get_swift_pattern',
|
|
244
|
+
query: 'testing',
|
|
245
|
+
minQuality: 60,
|
|
246
|
+
sources: ['sundell'],
|
|
247
|
+
};
|
|
248
|
+
it('should track cache hits', async () => {
|
|
249
|
+
await cache.set(testIntent, {
|
|
250
|
+
patternIds: ['p1'],
|
|
251
|
+
scores: { 'p1': 90 },
|
|
252
|
+
totalCount: 1,
|
|
253
|
+
});
|
|
254
|
+
await cache.get(testIntent);
|
|
255
|
+
await cache.get(testIntent);
|
|
256
|
+
const stats = cache.getStats();
|
|
257
|
+
expect(stats.hits).toBe(2);
|
|
258
|
+
});
|
|
259
|
+
it('should track cache misses', async () => {
|
|
260
|
+
await cache.get(testIntent);
|
|
261
|
+
await cache.get({ ...testIntent, query: 'different' });
|
|
262
|
+
const stats = cache.getStats();
|
|
263
|
+
expect(stats.misses).toBe(2);
|
|
264
|
+
});
|
|
265
|
+
it('should calculate hit rate correctly', async () => {
|
|
266
|
+
await cache.set(testIntent, {
|
|
267
|
+
patternIds: ['p1'],
|
|
268
|
+
scores: { 'p1': 90 },
|
|
269
|
+
totalCount: 1,
|
|
270
|
+
});
|
|
271
|
+
await cache.get(testIntent); // hit
|
|
272
|
+
await cache.get({ ...testIntent, query: 'miss1' }); // miss
|
|
273
|
+
await cache.get(testIntent); // hit
|
|
274
|
+
await cache.get({ ...testIntent, query: 'miss2' }); // miss
|
|
275
|
+
const stats = cache.getStats();
|
|
276
|
+
expect(stats.hits).toBe(2);
|
|
277
|
+
expect(stats.misses).toBe(2);
|
|
278
|
+
expect(stats.hitRate).toBe(0.5);
|
|
279
|
+
});
|
|
280
|
+
it('should reset stats on clear', async () => {
|
|
281
|
+
await cache.get(testIntent); // miss
|
|
282
|
+
cache.clear();
|
|
283
|
+
const stats = cache.getStats();
|
|
284
|
+
expect(stats.hits).toBe(0);
|
|
285
|
+
expect(stats.misses).toBe(0);
|
|
286
|
+
expect(stats.hitRate).toBe(0);
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
//# sourceMappingURL=intent-cache.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-cache.test.js","sourceRoot":"","sources":["../../src/utils/intent-cache.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,QAAA,MAAM,MAAM,6BAKV,CAAC;AAEH,eAAe,MAAM,CAAC"}
|