@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.
@@ -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,7 @@
1
+ /**
2
+ * Registry integration module.
3
+ *
4
+ * @module @hyperfixi/patterns-reference/registry
5
+ */
6
+
7
+ export * from './patterns-provider';
@@ -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
+ }