@hyperfixi/patterns-reference 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +311 -0
- package/data/hyperfixi-extensions.json +106 -0
- package/dist/api/index.d.mts +59 -0
- package/dist/api/index.d.ts +59 -0
- package/dist/api/index.js +769 -0
- package/dist/api/index.mjs +731 -0
- package/dist/index-CBoczxz7.d.mts +296 -0
- package/dist/index-CBoczxz7.d.ts +296 -0
- package/dist/index.d.mts +403 -0
- package/dist/index.d.ts +403 -0
- package/dist/index.js +1312 -0
- package/dist/index.mjs +1240 -0
- package/dist/llm-DMR6tmkM.d.ts +123 -0
- package/dist/llm-UOOBXwj3.d.mts +123 -0
- package/dist/sync/index.d.mts +42 -0
- package/dist/sync/index.d.ts +42 -0
- package/dist/sync/index.js +28 -0
- package/dist/sync/index.mjs +23 -0
- package/package.json +92 -0
- package/src/adapters/index.ts +7 -0
- package/src/adapters/llm-adapter.ts +394 -0
- package/src/api/index.ts +52 -0
- package/src/api/language-docs.ts +529 -0
- package/src/api/llm.ts +357 -0
- package/src/api/patterns.ts +276 -0
- package/src/api/roles.ts +401 -0
- package/src/api/translations.ts +283 -0
- package/src/database/connection.ts +85 -0
- package/src/index.ts +266 -0
- package/src/registry/index.ts +7 -0
- package/src/registry/patterns-provider.ts +250 -0
- package/src/semantic-bridge.ts +204 -0
- package/src/sync/index.ts +70 -0
- package/src/types/better-sqlite3.d.ts +44 -0
- package/src/types/index.ts +434 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Connection Management
|
|
3
|
+
*
|
|
4
|
+
* Provides singleton connection to the patterns-reference SQLite database.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Database from 'better-sqlite3';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
import { dirname, join } from 'path';
|
|
10
|
+
import type { ConnectionOptions } from '../types';
|
|
11
|
+
|
|
12
|
+
// Resolve __dirname for ESM
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = dirname(__filename);
|
|
15
|
+
|
|
16
|
+
// Default path resolved from the dist directory after bundling
|
|
17
|
+
// When bundled by tsup, __dirname will be the dist/ folder
|
|
18
|
+
// So we need to go up one level to reach the package root, then into data/
|
|
19
|
+
const DEFAULT_DB_PATH =
|
|
20
|
+
process.env.LSP_DB_PATH ||
|
|
21
|
+
process.env.HYPERSCRIPT_LSP_DB ||
|
|
22
|
+
join(__dirname, '../data/patterns.db');
|
|
23
|
+
|
|
24
|
+
let dbInstance: InstanceType<typeof Database> | null = null;
|
|
25
|
+
let currentDbPath: string | null = null;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get database connection (lazy singleton).
|
|
29
|
+
*/
|
|
30
|
+
export function getDatabase(options: ConnectionOptions = {}): InstanceType<typeof Database> {
|
|
31
|
+
const dbPath = options.dbPath ?? DEFAULT_DB_PATH;
|
|
32
|
+
|
|
33
|
+
// Return existing connection if same path
|
|
34
|
+
if (dbInstance !== null && currentDbPath === dbPath) {
|
|
35
|
+
return dbInstance;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Close existing connection if path changed
|
|
39
|
+
if (dbInstance !== null) {
|
|
40
|
+
dbInstance.close();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
dbInstance = new Database(dbPath, {
|
|
44
|
+
readonly: options.readonly ?? false,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Enable foreign keys
|
|
48
|
+
dbInstance.pragma('foreign_keys = ON');
|
|
49
|
+
|
|
50
|
+
currentDbPath = dbPath;
|
|
51
|
+
return dbInstance;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Close database connection.
|
|
56
|
+
*/
|
|
57
|
+
export function closeDatabase(): void {
|
|
58
|
+
if (dbInstance) {
|
|
59
|
+
dbInstance.close();
|
|
60
|
+
dbInstance = null;
|
|
61
|
+
currentDbPath = null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* For testing: reset the database connection.
|
|
67
|
+
*/
|
|
68
|
+
export function resetConnection(): void {
|
|
69
|
+
dbInstance = null;
|
|
70
|
+
currentDbPath = null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Check if database is connected.
|
|
75
|
+
*/
|
|
76
|
+
export function isConnected(): boolean {
|
|
77
|
+
return dbInstance !== null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get the current database path.
|
|
82
|
+
*/
|
|
83
|
+
export function getCurrentDbPath(): string | null {
|
|
84
|
+
return currentDbPath;
|
|
85
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hyperfixi/patterns-reference
|
|
3
|
+
*
|
|
4
|
+
* Queryable patterns database for hyperscript with multilingual translations
|
|
5
|
+
* and LLM support for few-shot learning.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { createPatternsReference } from '@hyperfixi/patterns-reference';
|
|
10
|
+
*
|
|
11
|
+
* const ref = createPatternsReference();
|
|
12
|
+
*
|
|
13
|
+
* // Query patterns
|
|
14
|
+
* const pattern = await ref.getPatternById('toggle-class-basic');
|
|
15
|
+
* const patterns = await ref.searchPatterns('toggle');
|
|
16
|
+
*
|
|
17
|
+
* // Get translations
|
|
18
|
+
* const translation = await ref.getTranslation('toggle-class-basic', 'ja');
|
|
19
|
+
*
|
|
20
|
+
* // Get LLM examples
|
|
21
|
+
* const examples = await ref.getLLMExamples('toggle a class on click');
|
|
22
|
+
*
|
|
23
|
+
* // Clean up
|
|
24
|
+
* ref.close();
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// Types
|
|
30
|
+
// =============================================================================
|
|
31
|
+
|
|
32
|
+
export type {
|
|
33
|
+
// Pattern types
|
|
34
|
+
Pattern,
|
|
35
|
+
ClassifiedPattern,
|
|
36
|
+
ComplexityLevel,
|
|
37
|
+
EngineCompat,
|
|
38
|
+
|
|
39
|
+
// Translation types
|
|
40
|
+
Translation,
|
|
41
|
+
VerificationResult,
|
|
42
|
+
WordOrder,
|
|
43
|
+
TranslationMethod,
|
|
44
|
+
|
|
45
|
+
// LLM types
|
|
46
|
+
LLMExample,
|
|
47
|
+
|
|
48
|
+
// Language documentation types
|
|
49
|
+
Command,
|
|
50
|
+
Expression,
|
|
51
|
+
ExpressionOperator,
|
|
52
|
+
Keyword,
|
|
53
|
+
Feature,
|
|
54
|
+
SpecialSymbol,
|
|
55
|
+
LanguageElement,
|
|
56
|
+
LanguageElementType,
|
|
57
|
+
LanguageDocsStats,
|
|
58
|
+
|
|
59
|
+
// API types
|
|
60
|
+
PatternsReference,
|
|
61
|
+
SearchOptions,
|
|
62
|
+
TestOptions,
|
|
63
|
+
PatternStats,
|
|
64
|
+
|
|
65
|
+
// Sync types
|
|
66
|
+
SyncOptions,
|
|
67
|
+
SyncResult,
|
|
68
|
+
ValidationOptions,
|
|
69
|
+
ValidationResult,
|
|
70
|
+
DiscoveryResult,
|
|
71
|
+
|
|
72
|
+
// Connection types
|
|
73
|
+
ConnectionOptions,
|
|
74
|
+
} from './types';
|
|
75
|
+
|
|
76
|
+
// =============================================================================
|
|
77
|
+
// Database
|
|
78
|
+
// =============================================================================
|
|
79
|
+
|
|
80
|
+
export {
|
|
81
|
+
getDatabase,
|
|
82
|
+
closeDatabase,
|
|
83
|
+
resetConnection,
|
|
84
|
+
isConnected,
|
|
85
|
+
getCurrentDbPath,
|
|
86
|
+
} from './database/connection';
|
|
87
|
+
|
|
88
|
+
// =============================================================================
|
|
89
|
+
// API
|
|
90
|
+
// =============================================================================
|
|
91
|
+
|
|
92
|
+
// Patterns
|
|
93
|
+
export {
|
|
94
|
+
getPatternById,
|
|
95
|
+
getPatternsByCategory,
|
|
96
|
+
getPatternsByCommand,
|
|
97
|
+
searchPatterns,
|
|
98
|
+
getAllPatterns,
|
|
99
|
+
getPatternStats,
|
|
100
|
+
} from './api/patterns';
|
|
101
|
+
|
|
102
|
+
// Translations
|
|
103
|
+
export {
|
|
104
|
+
getTranslation,
|
|
105
|
+
getAllTranslations,
|
|
106
|
+
getTranslationsByLanguage,
|
|
107
|
+
getVerifiedTranslations,
|
|
108
|
+
getHighConfidenceTranslations,
|
|
109
|
+
verifyTranslation,
|
|
110
|
+
getTranslationStats,
|
|
111
|
+
getWordOrder,
|
|
112
|
+
} from './api/translations';
|
|
113
|
+
|
|
114
|
+
// LLM
|
|
115
|
+
export {
|
|
116
|
+
getLLMExamples,
|
|
117
|
+
getExamplesByCommand,
|
|
118
|
+
getHighQualityExamples,
|
|
119
|
+
getMostUsedExamples,
|
|
120
|
+
buildFewShotContext,
|
|
121
|
+
addLLMExample,
|
|
122
|
+
updateQualityScore,
|
|
123
|
+
getLLMStats,
|
|
124
|
+
} from './api/llm';
|
|
125
|
+
|
|
126
|
+
// Language Documentation
|
|
127
|
+
export {
|
|
128
|
+
// Commands
|
|
129
|
+
getCommandByName,
|
|
130
|
+
getAllCommands,
|
|
131
|
+
searchCommands,
|
|
132
|
+
// Expressions
|
|
133
|
+
getExpressionByName,
|
|
134
|
+
getAllExpressions,
|
|
135
|
+
getExpressionsByCategory,
|
|
136
|
+
// Keywords
|
|
137
|
+
getKeywordByName,
|
|
138
|
+
getAllKeywords,
|
|
139
|
+
// Features
|
|
140
|
+
getFeatureByName,
|
|
141
|
+
getAllFeatures,
|
|
142
|
+
// Special Symbols
|
|
143
|
+
getSpecialSymbolByName,
|
|
144
|
+
getAllSpecialSymbols,
|
|
145
|
+
// Unified search
|
|
146
|
+
searchLanguageElements,
|
|
147
|
+
// Statistics
|
|
148
|
+
getLanguageDocsStats,
|
|
149
|
+
} from './api/language-docs';
|
|
150
|
+
|
|
151
|
+
// =============================================================================
|
|
152
|
+
// Sync (placeholders - run via CLI scripts)
|
|
153
|
+
// =============================================================================
|
|
154
|
+
|
|
155
|
+
export {
|
|
156
|
+
syncTranslations,
|
|
157
|
+
validateAllTranslations,
|
|
158
|
+
discoverPatterns,
|
|
159
|
+
seedLLMExamples,
|
|
160
|
+
} from './sync';
|
|
161
|
+
|
|
162
|
+
// =============================================================================
|
|
163
|
+
// Adapters (for cross-package integration)
|
|
164
|
+
// =============================================================================
|
|
165
|
+
|
|
166
|
+
export {
|
|
167
|
+
// Unified adapter factory
|
|
168
|
+
createLLMAdapter,
|
|
169
|
+
// Sync interface (backward compat with packages/core/src/context/llm-examples-query.ts)
|
|
170
|
+
findRelevantExamples,
|
|
171
|
+
findExamplesByCommand,
|
|
172
|
+
buildFewShotContextSync,
|
|
173
|
+
trackExampleUsage,
|
|
174
|
+
getLLMExampleStats,
|
|
175
|
+
isDatabaseAvailable,
|
|
176
|
+
// Types
|
|
177
|
+
type LLMExampleRecord,
|
|
178
|
+
} from './adapters/llm-adapter';
|
|
179
|
+
|
|
180
|
+
// =============================================================================
|
|
181
|
+
// Registry Integration (for @lokascript/semantic)
|
|
182
|
+
// =============================================================================
|
|
183
|
+
|
|
184
|
+
export {
|
|
185
|
+
// Patterns provider
|
|
186
|
+
DatabasePatternsProvider,
|
|
187
|
+
createPatternsProvider,
|
|
188
|
+
getDefaultProvider,
|
|
189
|
+
resetDefaultProvider,
|
|
190
|
+
// Types
|
|
191
|
+
type PatternsSource,
|
|
192
|
+
type PatternEntry,
|
|
193
|
+
} from './registry/patterns-provider';
|
|
194
|
+
|
|
195
|
+
// =============================================================================
|
|
196
|
+
// Semantic Bridge
|
|
197
|
+
// =============================================================================
|
|
198
|
+
|
|
199
|
+
export {
|
|
200
|
+
// Initialization
|
|
201
|
+
initializeSemanticIntegration,
|
|
202
|
+
uninitializeSemanticIntegration,
|
|
203
|
+
isSemanticIntegrationInitialized,
|
|
204
|
+
getBridgeProvider,
|
|
205
|
+
// Query helpers
|
|
206
|
+
queryPatterns,
|
|
207
|
+
queryPatternsForCommand,
|
|
208
|
+
getSupportedLanguages,
|
|
209
|
+
// Types
|
|
210
|
+
type SemanticIntegrationOptions,
|
|
211
|
+
type IntegrationResult,
|
|
212
|
+
} from './semantic-bridge';
|
|
213
|
+
|
|
214
|
+
// =============================================================================
|
|
215
|
+
// Factory
|
|
216
|
+
// =============================================================================
|
|
217
|
+
|
|
218
|
+
import type { PatternsReference, ConnectionOptions } from './types';
|
|
219
|
+
import * as patterns from './api/patterns';
|
|
220
|
+
import * as translations from './api/translations';
|
|
221
|
+
import * as llm from './api/llm';
|
|
222
|
+
import { getDatabase, closeDatabase } from './database/connection';
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Create a PatternsReference instance.
|
|
226
|
+
*
|
|
227
|
+
* This provides a unified API for querying patterns, translations,
|
|
228
|
+
* and LLM examples from the hyperscript-lsp database.
|
|
229
|
+
*
|
|
230
|
+
* @param options - Connection options (dbPath, readonly)
|
|
231
|
+
* @returns PatternsReference instance
|
|
232
|
+
*/
|
|
233
|
+
export function createPatternsReference(options?: ConnectionOptions): PatternsReference {
|
|
234
|
+
// Initialize database connection
|
|
235
|
+
getDatabase(options);
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
// Patterns
|
|
239
|
+
getPatternById: id => patterns.getPatternById(id, options),
|
|
240
|
+
getPatternsByCategory: category => patterns.getPatternsByCategory(category, options),
|
|
241
|
+
getPatternsByCommand: command => patterns.getPatternsByCommand(command, options),
|
|
242
|
+
searchPatterns: (query, searchOptions) =>
|
|
243
|
+
patterns.searchPatterns(query, searchOptions, options),
|
|
244
|
+
|
|
245
|
+
// Translations
|
|
246
|
+
getTranslation: (patternId, language) =>
|
|
247
|
+
translations.getTranslation(patternId, language, options),
|
|
248
|
+
getAllTranslations: patternId => translations.getAllTranslations(patternId, options),
|
|
249
|
+
verifyTranslation: translation => translations.verifyTranslation(translation, options),
|
|
250
|
+
|
|
251
|
+
// LLM
|
|
252
|
+
getLLMExamples: (prompt, language, limit) =>
|
|
253
|
+
llm.getLLMExamples(prompt, language, limit, options),
|
|
254
|
+
|
|
255
|
+
// Stats
|
|
256
|
+
getStats: () => patterns.getPatternStats(options),
|
|
257
|
+
|
|
258
|
+
// Connection
|
|
259
|
+
close: closeDatabase,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Version of the package.
|
|
265
|
+
*/
|
|
266
|
+
export const VERSION = '0.1.0';
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Patterns Provider
|
|
3
|
+
*
|
|
4
|
+
* Provides patterns from the patterns-reference database to the semantic registry.
|
|
5
|
+
* This enables runtime pattern matching using database-backed patterns.
|
|
6
|
+
*
|
|
7
|
+
* @module @hyperfixi/patterns-reference/registry
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { getDatabase } from '../database/connection';
|
|
11
|
+
import type { Pattern, Translation, ConnectionOptions } from '../types';
|
|
12
|
+
import { getPatternsByCommand, getAllPatterns } from '../api/patterns';
|
|
13
|
+
import { getTranslationsByLanguage, getVerifiedTranslations } from '../api/translations';
|
|
14
|
+
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Types
|
|
17
|
+
// =============================================================================
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Pattern source interface for external pattern providers.
|
|
21
|
+
*/
|
|
22
|
+
export interface PatternsSource {
|
|
23
|
+
/** Unique identifier for the source */
|
|
24
|
+
id: string;
|
|
25
|
+
/** Human-readable name */
|
|
26
|
+
name: string;
|
|
27
|
+
/** Get patterns for a specific language */
|
|
28
|
+
getPatternsForLanguage(language: string): Promise<PatternEntry[]>;
|
|
29
|
+
/** Get patterns for a specific command */
|
|
30
|
+
getPatternsForCommand(command: string, language?: string): Promise<PatternEntry[]>;
|
|
31
|
+
/** Check if source has patterns for a language */
|
|
32
|
+
hasPatterns(language: string): Promise<boolean>;
|
|
33
|
+
/** Get all supported languages */
|
|
34
|
+
getSupportedLanguages(): Promise<string[]>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Pattern entry from the database.
|
|
39
|
+
*/
|
|
40
|
+
export interface PatternEntry {
|
|
41
|
+
/** Pattern ID */
|
|
42
|
+
id: string;
|
|
43
|
+
/** The hyperscript code */
|
|
44
|
+
code: string;
|
|
45
|
+
/** Primary command (toggle, add, remove, etc.) */
|
|
46
|
+
command: string | null;
|
|
47
|
+
/** Language code */
|
|
48
|
+
language: string;
|
|
49
|
+
/** Confidence score (0-1) */
|
|
50
|
+
confidence: number;
|
|
51
|
+
/** Whether the pattern has been verified to parse correctly */
|
|
52
|
+
verified: boolean;
|
|
53
|
+
/** Pattern title/description */
|
|
54
|
+
title?: string;
|
|
55
|
+
/** Pattern category */
|
|
56
|
+
category?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// =============================================================================
|
|
60
|
+
// Patterns Provider Implementation
|
|
61
|
+
// =============================================================================
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Database-backed patterns provider.
|
|
65
|
+
*/
|
|
66
|
+
export class DatabasePatternsProvider implements PatternsSource {
|
|
67
|
+
public readonly id = 'patterns-reference-db';
|
|
68
|
+
public readonly name = 'Patterns Reference Database';
|
|
69
|
+
|
|
70
|
+
private options: ConnectionOptions;
|
|
71
|
+
private languageCache: Map<string, PatternEntry[]> = new Map();
|
|
72
|
+
private supportedLanguagesCache: string[] | null = null;
|
|
73
|
+
|
|
74
|
+
constructor(options?: ConnectionOptions) {
|
|
75
|
+
this.options = options || {};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get patterns for a specific language.
|
|
80
|
+
*/
|
|
81
|
+
async getPatternsForLanguage(language: string): Promise<PatternEntry[]> {
|
|
82
|
+
// Check cache
|
|
83
|
+
const cached = this.languageCache.get(language);
|
|
84
|
+
if (cached) {
|
|
85
|
+
return cached;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
// Get verified translations for this language
|
|
90
|
+
const translations = await getVerifiedTranslations(language, 1000, this.options);
|
|
91
|
+
|
|
92
|
+
const patterns: PatternEntry[] = translations.map(t => ({
|
|
93
|
+
id: t.codeExampleId,
|
|
94
|
+
code: t.hyperscript,
|
|
95
|
+
command: this.extractCommand(t.hyperscript),
|
|
96
|
+
language: t.language,
|
|
97
|
+
confidence: t.confidence,
|
|
98
|
+
verified: t.verifiedParses,
|
|
99
|
+
}));
|
|
100
|
+
|
|
101
|
+
this.languageCache.set(language, patterns);
|
|
102
|
+
return patterns;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.warn(
|
|
105
|
+
`[PatternsProvider] Failed to get patterns for ${language}:`,
|
|
106
|
+
error instanceof Error ? error.message : String(error)
|
|
107
|
+
);
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Get patterns for a specific command.
|
|
114
|
+
*/
|
|
115
|
+
async getPatternsForCommand(command: string, language?: string): Promise<PatternEntry[]> {
|
|
116
|
+
try {
|
|
117
|
+
const patterns = await getPatternsByCommand(command, this.options);
|
|
118
|
+
|
|
119
|
+
const entries: PatternEntry[] = patterns.map(p => ({
|
|
120
|
+
id: p.id,
|
|
121
|
+
code: p.rawCode,
|
|
122
|
+
command: p.primaryCommand,
|
|
123
|
+
language: language || 'en',
|
|
124
|
+
confidence: 1.0,
|
|
125
|
+
verified: true,
|
|
126
|
+
title: p.title,
|
|
127
|
+
category: p.category || undefined,
|
|
128
|
+
}));
|
|
129
|
+
|
|
130
|
+
return entries;
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.warn(
|
|
133
|
+
`[PatternsProvider] Failed to get patterns for command ${command}:`,
|
|
134
|
+
error instanceof Error ? error.message : String(error)
|
|
135
|
+
);
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Check if source has patterns for a language.
|
|
142
|
+
*/
|
|
143
|
+
async hasPatterns(language: string): Promise<boolean> {
|
|
144
|
+
const patterns = await this.getPatternsForLanguage(language);
|
|
145
|
+
return patterns.length > 0;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Get all supported languages.
|
|
150
|
+
*/
|
|
151
|
+
async getSupportedLanguages(): Promise<string[]> {
|
|
152
|
+
if (this.supportedLanguagesCache) {
|
|
153
|
+
return this.supportedLanguagesCache;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
const db = getDatabase({ ...this.options, readonly: true });
|
|
158
|
+
const result = db
|
|
159
|
+
.prepare(
|
|
160
|
+
`
|
|
161
|
+
SELECT DISTINCT language FROM pattern_translations
|
|
162
|
+
WHERE verified_parses = 1
|
|
163
|
+
`
|
|
164
|
+
)
|
|
165
|
+
.all() as { language: string }[];
|
|
166
|
+
|
|
167
|
+
this.supportedLanguagesCache = result.map(r => r.language);
|
|
168
|
+
return this.supportedLanguagesCache;
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.warn(
|
|
171
|
+
'[PatternsProvider] Failed to get supported languages:',
|
|
172
|
+
error instanceof Error ? error.message : String(error)
|
|
173
|
+
);
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Clear the pattern cache.
|
|
180
|
+
*/
|
|
181
|
+
clearCache(): void {
|
|
182
|
+
this.languageCache.clear();
|
|
183
|
+
this.supportedLanguagesCache = null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Extract primary command from hyperscript code.
|
|
188
|
+
*/
|
|
189
|
+
private extractCommand(code: string): string | null {
|
|
190
|
+
const match = code.match(/^(?:on\s+\w+\s+)?(\w+)/i);
|
|
191
|
+
if (match) {
|
|
192
|
+
const keyword = match[1].toLowerCase();
|
|
193
|
+
const commands = [
|
|
194
|
+
'toggle',
|
|
195
|
+
'add',
|
|
196
|
+
'remove',
|
|
197
|
+
'put',
|
|
198
|
+
'set',
|
|
199
|
+
'show',
|
|
200
|
+
'hide',
|
|
201
|
+
'wait',
|
|
202
|
+
'log',
|
|
203
|
+
'send',
|
|
204
|
+
'fetch',
|
|
205
|
+
'call',
|
|
206
|
+
'trigger',
|
|
207
|
+
'transition',
|
|
208
|
+
'increment',
|
|
209
|
+
'decrement',
|
|
210
|
+
];
|
|
211
|
+
if (commands.includes(keyword)) {
|
|
212
|
+
return keyword;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// =============================================================================
|
|
220
|
+
// Factory Functions
|
|
221
|
+
// =============================================================================
|
|
222
|
+
|
|
223
|
+
let defaultProvider: DatabasePatternsProvider | null = null;
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Get the default patterns provider instance.
|
|
227
|
+
*/
|
|
228
|
+
export function getDefaultProvider(options?: ConnectionOptions): DatabasePatternsProvider {
|
|
229
|
+
if (!defaultProvider) {
|
|
230
|
+
defaultProvider = new DatabasePatternsProvider(options);
|
|
231
|
+
}
|
|
232
|
+
return defaultProvider;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Create a new patterns provider instance.
|
|
237
|
+
*/
|
|
238
|
+
export function createPatternsProvider(options?: ConnectionOptions): DatabasePatternsProvider {
|
|
239
|
+
return new DatabasePatternsProvider(options);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Reset the default provider (for testing).
|
|
244
|
+
*/
|
|
245
|
+
export function resetDefaultProvider(): void {
|
|
246
|
+
if (defaultProvider) {
|
|
247
|
+
defaultProvider.clearCache();
|
|
248
|
+
defaultProvider = null;
|
|
249
|
+
}
|
|
250
|
+
}
|