@crashbytes/semantic-text-toolkit 1.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/DEPLOYMENT.md +203 -0
- package/README.md +300 -0
- package/dist/SemanticEngine-3EGZZHKU.mjs +7 -0
- package/dist/SemanticSearch-CQZQEKEG.mjs +7 -0
- package/dist/chunk-ENOBULOJ.mjs +93 -0
- package/dist/chunk-TPAL6DKL.mjs +149 -0
- package/dist/chunk-XJ4PTDH6.mjs +176 -0
- package/dist/index.d.mts +148 -0
- package/dist/index.d.ts +148 -0
- package/dist/index.js +506 -0
- package/dist/index.mjs +55 -0
- package/package.json +56 -0
- package/src/engine/SemanticEngine.ts +225 -0
- package/src/index.ts +31 -0
- package/src/search/SemanticSearch.ts +154 -0
- package/src/types.ts +73 -0
- package/src/utils/vector.ts +158 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
var SemanticErrorCode = /* @__PURE__ */ ((SemanticErrorCode2) => {
|
|
3
|
+
SemanticErrorCode2["MODEL_NOT_LOADED"] = "MODEL_NOT_LOADED";
|
|
4
|
+
SemanticErrorCode2["INVALID_INPUT"] = "INVALID_INPUT";
|
|
5
|
+
SemanticErrorCode2["EMBEDDING_FAILED"] = "EMBEDDING_FAILED";
|
|
6
|
+
SemanticErrorCode2["COMPUTATION_FAILED"] = "COMPUTATION_FAILED";
|
|
7
|
+
SemanticErrorCode2["DIMENSION_MISMATCH"] = "DIMENSION_MISMATCH";
|
|
8
|
+
return SemanticErrorCode2;
|
|
9
|
+
})(SemanticErrorCode || {});
|
|
10
|
+
var SemanticError = class extends Error {
|
|
11
|
+
constructor(code, message, details) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.details = details;
|
|
15
|
+
this.name = "SemanticError";
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// src/utils/vector.ts
|
|
20
|
+
function validateDimensions(a, b) {
|
|
21
|
+
if (a.length !== b.length) {
|
|
22
|
+
throw new SemanticError(
|
|
23
|
+
"DIMENSION_MISMATCH" /* DIMENSION_MISMATCH */,
|
|
24
|
+
`Embedding dimensions must match. Got ${a.length} and ${b.length}`,
|
|
25
|
+
{ dimensions: [a.length, b.length] }
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function validateEmbedding(embedding, name = "embedding") {
|
|
30
|
+
if (!embedding || embedding.length === 0) {
|
|
31
|
+
throw new SemanticError(
|
|
32
|
+
"INVALID_INPUT" /* INVALID_INPUT */,
|
|
33
|
+
`${name} must be a non-empty array`,
|
|
34
|
+
{ length: embedding?.length }
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function dotProduct(a, b) {
|
|
39
|
+
validateEmbedding(a, "first embedding");
|
|
40
|
+
validateEmbedding(b, "second embedding");
|
|
41
|
+
validateDimensions(a, b);
|
|
42
|
+
let sum = 0;
|
|
43
|
+
for (let i = 0; i < a.length; i++) {
|
|
44
|
+
sum += a[i] * b[i];
|
|
45
|
+
}
|
|
46
|
+
return sum;
|
|
47
|
+
}
|
|
48
|
+
function magnitude(vector) {
|
|
49
|
+
validateEmbedding(vector);
|
|
50
|
+
let sum = 0;
|
|
51
|
+
for (let i = 0; i < vector.length; i++) {
|
|
52
|
+
sum += vector[i] * vector[i];
|
|
53
|
+
}
|
|
54
|
+
return Math.sqrt(sum);
|
|
55
|
+
}
|
|
56
|
+
function cosineSimilarity(a, b) {
|
|
57
|
+
validateEmbedding(a, "first embedding");
|
|
58
|
+
validateEmbedding(b, "second embedding");
|
|
59
|
+
validateDimensions(a, b);
|
|
60
|
+
const dot = dotProduct(a, b);
|
|
61
|
+
const magA = magnitude(a);
|
|
62
|
+
const magB = magnitude(b);
|
|
63
|
+
if (magA === 0 || magB === 0) {
|
|
64
|
+
throw new SemanticError(
|
|
65
|
+
"COMPUTATION_FAILED" /* COMPUTATION_FAILED */,
|
|
66
|
+
"Cannot compute cosine similarity with zero-magnitude vector",
|
|
67
|
+
{ magnitudes: [magA, magB] }
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
return dot / (magA * magB);
|
|
71
|
+
}
|
|
72
|
+
function euclideanDistance(a, b) {
|
|
73
|
+
validateEmbedding(a, "first embedding");
|
|
74
|
+
validateEmbedding(b, "second embedding");
|
|
75
|
+
validateDimensions(a, b);
|
|
76
|
+
let sum = 0;
|
|
77
|
+
for (let i = 0; i < a.length; i++) {
|
|
78
|
+
const diff = a[i] - b[i];
|
|
79
|
+
sum += diff * diff;
|
|
80
|
+
}
|
|
81
|
+
return Math.sqrt(sum);
|
|
82
|
+
}
|
|
83
|
+
function normalize(vector) {
|
|
84
|
+
validateEmbedding(vector);
|
|
85
|
+
const mag = magnitude(vector);
|
|
86
|
+
if (mag === 0) {
|
|
87
|
+
throw new SemanticError(
|
|
88
|
+
"COMPUTATION_FAILED" /* COMPUTATION_FAILED */,
|
|
89
|
+
"Cannot normalize zero-magnitude vector"
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
return vector.map((v) => v / mag);
|
|
93
|
+
}
|
|
94
|
+
function centroid(embeddings) {
|
|
95
|
+
if (!embeddings || embeddings.length === 0) {
|
|
96
|
+
throw new SemanticError(
|
|
97
|
+
"INVALID_INPUT" /* INVALID_INPUT */,
|
|
98
|
+
"Cannot compute centroid of empty array"
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
const dim = embeddings[0].length;
|
|
102
|
+
const result = new Array(dim).fill(0);
|
|
103
|
+
for (const embedding of embeddings) {
|
|
104
|
+
if (embedding.length !== dim) {
|
|
105
|
+
throw new SemanticError(
|
|
106
|
+
"DIMENSION_MISMATCH" /* DIMENSION_MISMATCH */,
|
|
107
|
+
"All embeddings must have same dimensions"
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
for (let i = 0; i < dim; i++) {
|
|
111
|
+
result[i] += embedding[i];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return result.map((v) => v / embeddings.length);
|
|
115
|
+
}
|
|
116
|
+
function topKSimilar(query, candidates, k = 10) {
|
|
117
|
+
validateEmbedding(query, "query");
|
|
118
|
+
if (!candidates || candidates.length === 0) {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
if (k <= 0) {
|
|
122
|
+
throw new SemanticError(
|
|
123
|
+
"INVALID_INPUT" /* INVALID_INPUT */,
|
|
124
|
+
"k must be positive",
|
|
125
|
+
{ k }
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
const similarities = candidates.map((candidate, idx) => {
|
|
129
|
+
try {
|
|
130
|
+
return [idx, cosineSimilarity(query, candidate)];
|
|
131
|
+
} catch (error) {
|
|
132
|
+
return [idx, -Infinity];
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
similarities.sort((a, b) => b[1] - a[1]);
|
|
136
|
+
return similarities.slice(0, Math.min(k, similarities.length));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export {
|
|
140
|
+
SemanticErrorCode,
|
|
141
|
+
SemanticError,
|
|
142
|
+
dotProduct,
|
|
143
|
+
magnitude,
|
|
144
|
+
cosineSimilarity,
|
|
145
|
+
euclideanDistance,
|
|
146
|
+
normalize,
|
|
147
|
+
centroid,
|
|
148
|
+
topKSimilar
|
|
149
|
+
};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SemanticError,
|
|
3
|
+
cosineSimilarity,
|
|
4
|
+
dotProduct,
|
|
5
|
+
euclideanDistance
|
|
6
|
+
} from "./chunk-TPAL6DKL.mjs";
|
|
7
|
+
|
|
8
|
+
// src/engine/SemanticEngine.ts
|
|
9
|
+
import { pipeline } from "@xenova/transformers";
|
|
10
|
+
var DEFAULT_CONFIG = {
|
|
11
|
+
modelName: "Xenova/all-MiniLM-L6-v2",
|
|
12
|
+
maxLength: 512,
|
|
13
|
+
quantized: true,
|
|
14
|
+
onProgress: () => {
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var SemanticEngine = class {
|
|
18
|
+
constructor(config = {}) {
|
|
19
|
+
this.model = null;
|
|
20
|
+
this.initializationPromise = null;
|
|
21
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
22
|
+
}
|
|
23
|
+
async initialize() {
|
|
24
|
+
if (this.initializationPromise) {
|
|
25
|
+
return this.initializationPromise;
|
|
26
|
+
}
|
|
27
|
+
if (this.model) {
|
|
28
|
+
return Promise.resolve();
|
|
29
|
+
}
|
|
30
|
+
this.initializationPromise = this._performInitialization();
|
|
31
|
+
try {
|
|
32
|
+
await this.initializationPromise;
|
|
33
|
+
} finally {
|
|
34
|
+
this.initializationPromise = null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async _performInitialization() {
|
|
38
|
+
try {
|
|
39
|
+
this.config.onProgress({
|
|
40
|
+
status: "downloading",
|
|
41
|
+
progress: 0
|
|
42
|
+
});
|
|
43
|
+
this.model = await pipeline(
|
|
44
|
+
"feature-extraction",
|
|
45
|
+
this.config.modelName,
|
|
46
|
+
{
|
|
47
|
+
quantized: this.config.quantized
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
this.config.onProgress({
|
|
51
|
+
status: "ready",
|
|
52
|
+
progress: 100
|
|
53
|
+
});
|
|
54
|
+
} catch (error) {
|
|
55
|
+
throw new SemanticError(
|
|
56
|
+
"MODEL_NOT_LOADED" /* MODEL_NOT_LOADED */,
|
|
57
|
+
`Failed to initialize model: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
58
|
+
{ modelName: this.config.modelName, error }
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
assertInitialized() {
|
|
63
|
+
if (!this.model) {
|
|
64
|
+
throw new SemanticError(
|
|
65
|
+
"MODEL_NOT_LOADED" /* MODEL_NOT_LOADED */,
|
|
66
|
+
"Model not initialized. Call initialize() first."
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async embed(text) {
|
|
71
|
+
this.assertInitialized();
|
|
72
|
+
if (!text || typeof text !== "string") {
|
|
73
|
+
throw new SemanticError(
|
|
74
|
+
"INVALID_INPUT" /* INVALID_INPUT */,
|
|
75
|
+
"Text must be a non-empty string",
|
|
76
|
+
{ text }
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
const startTime = performance.now();
|
|
80
|
+
try {
|
|
81
|
+
const output = await this.model(text, {
|
|
82
|
+
pooling: "mean",
|
|
83
|
+
normalize: true
|
|
84
|
+
});
|
|
85
|
+
const embedding = Array.from(output.data);
|
|
86
|
+
const processingTime = performance.now() - startTime;
|
|
87
|
+
return {
|
|
88
|
+
embedding,
|
|
89
|
+
text,
|
|
90
|
+
metadata: {
|
|
91
|
+
dimensions: embedding.length,
|
|
92
|
+
modelName: this.config.modelName,
|
|
93
|
+
processingTime
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
} catch (error) {
|
|
97
|
+
throw new SemanticError(
|
|
98
|
+
"EMBEDDING_FAILED" /* EMBEDDING_FAILED */,
|
|
99
|
+
`Failed to generate embedding: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
100
|
+
{ text: text.substring(0, 100), error }
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async embedBatch(texts, options = {}) {
|
|
105
|
+
this.assertInitialized();
|
|
106
|
+
const { batchSize = 32, onProgress } = options;
|
|
107
|
+
if (!Array.isArray(texts) || texts.length === 0) {
|
|
108
|
+
throw new SemanticError(
|
|
109
|
+
"INVALID_INPUT" /* INVALID_INPUT */,
|
|
110
|
+
"Texts must be a non-empty array"
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
const results = [];
|
|
114
|
+
const batches = Math.ceil(texts.length / batchSize);
|
|
115
|
+
for (let i = 0; i < batches; i++) {
|
|
116
|
+
const start = i * batchSize;
|
|
117
|
+
const end = Math.min(start + batchSize, texts.length);
|
|
118
|
+
const batch = texts.slice(start, end);
|
|
119
|
+
const batchResults = await Promise.all(
|
|
120
|
+
batch.map((text) => this.embed(text))
|
|
121
|
+
);
|
|
122
|
+
results.push(...batchResults);
|
|
123
|
+
if (onProgress) {
|
|
124
|
+
onProgress(end, texts.length);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return results;
|
|
128
|
+
}
|
|
129
|
+
async similarity(textA, textB, method = "cosine") {
|
|
130
|
+
const startTime = performance.now();
|
|
131
|
+
const [resultA, resultB] = await Promise.all([
|
|
132
|
+
this.embed(textA),
|
|
133
|
+
this.embed(textB)
|
|
134
|
+
]);
|
|
135
|
+
let score;
|
|
136
|
+
switch (method) {
|
|
137
|
+
case "cosine":
|
|
138
|
+
score = cosineSimilarity(resultA.embedding, resultB.embedding);
|
|
139
|
+
break;
|
|
140
|
+
case "euclidean":
|
|
141
|
+
score = -euclideanDistance(resultA.embedding, resultB.embedding);
|
|
142
|
+
break;
|
|
143
|
+
case "dot":
|
|
144
|
+
score = dotProduct(resultA.embedding, resultB.embedding);
|
|
145
|
+
break;
|
|
146
|
+
default:
|
|
147
|
+
throw new SemanticError(
|
|
148
|
+
"INVALID_INPUT" /* INVALID_INPUT */,
|
|
149
|
+
`Unknown similarity method: ${method}`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
const processingTime = performance.now() - startTime;
|
|
153
|
+
return {
|
|
154
|
+
score,
|
|
155
|
+
texts: [textA, textB],
|
|
156
|
+
metadata: {
|
|
157
|
+
method,
|
|
158
|
+
processingTime
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
dispose() {
|
|
163
|
+
this.model = null;
|
|
164
|
+
this.initializationPromise = null;
|
|
165
|
+
}
|
|
166
|
+
isReady() {
|
|
167
|
+
return this.model !== null;
|
|
168
|
+
}
|
|
169
|
+
getConfig() {
|
|
170
|
+
return { ...this.config };
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export {
|
|
175
|
+
SemanticEngine
|
|
176
|
+
};
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Design Philosophy:
|
|
5
|
+
* - Type safety prevents runtime failures
|
|
6
|
+
* - Semantic error codes enable precise debugging
|
|
7
|
+
* - Generic types provide flexibility without sacrificing safety
|
|
8
|
+
*/
|
|
9
|
+
type Embedding = number[];
|
|
10
|
+
interface ModelConfig {
|
|
11
|
+
modelName?: string;
|
|
12
|
+
maxLength?: number;
|
|
13
|
+
quantized?: boolean;
|
|
14
|
+
onProgress?: (progress: ModelLoadProgress) => void;
|
|
15
|
+
}
|
|
16
|
+
interface ModelLoadProgress {
|
|
17
|
+
status: 'downloading' | 'loading' | 'ready';
|
|
18
|
+
progress: number;
|
|
19
|
+
file?: string;
|
|
20
|
+
}
|
|
21
|
+
interface EmbeddingResult {
|
|
22
|
+
embedding: Embedding;
|
|
23
|
+
text: string;
|
|
24
|
+
metadata: {
|
|
25
|
+
dimensions: number;
|
|
26
|
+
modelName: string;
|
|
27
|
+
processingTime: number;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
interface SimilarityResult {
|
|
31
|
+
score: number;
|
|
32
|
+
texts: [string, string];
|
|
33
|
+
metadata: {
|
|
34
|
+
method: 'cosine' | 'euclidean' | 'dot';
|
|
35
|
+
processingTime: number;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
interface SearchResult<T = string> {
|
|
39
|
+
item: T;
|
|
40
|
+
score: number;
|
|
41
|
+
rank: number;
|
|
42
|
+
}
|
|
43
|
+
interface BatchOptions {
|
|
44
|
+
batchSize?: number;
|
|
45
|
+
parallel?: boolean;
|
|
46
|
+
onProgress?: (completed: number, total: number) => void;
|
|
47
|
+
}
|
|
48
|
+
declare enum SemanticErrorCode {
|
|
49
|
+
MODEL_NOT_LOADED = "MODEL_NOT_LOADED",
|
|
50
|
+
INVALID_INPUT = "INVALID_INPUT",
|
|
51
|
+
EMBEDDING_FAILED = "EMBEDDING_FAILED",
|
|
52
|
+
COMPUTATION_FAILED = "COMPUTATION_FAILED",
|
|
53
|
+
DIMENSION_MISMATCH = "DIMENSION_MISMATCH"
|
|
54
|
+
}
|
|
55
|
+
declare class SemanticError extends Error {
|
|
56
|
+
code: SemanticErrorCode;
|
|
57
|
+
details?: Record<string, unknown> | undefined;
|
|
58
|
+
constructor(code: SemanticErrorCode, message: string, details?: Record<string, unknown> | undefined);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Semantic Engine - Core Embedding Generation
|
|
63
|
+
*
|
|
64
|
+
* Architectural Principles:
|
|
65
|
+
* - Lazy initialization minimizes startup overhead
|
|
66
|
+
* - Singleton pattern prevents redundant model loading
|
|
67
|
+
* - Resource management through explicit lifecycle control
|
|
68
|
+
* - Defensive error handling with semantic codes
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
declare class SemanticEngine {
|
|
72
|
+
private model;
|
|
73
|
+
private config;
|
|
74
|
+
private initializationPromise;
|
|
75
|
+
constructor(config?: ModelConfig);
|
|
76
|
+
initialize(): Promise<void>;
|
|
77
|
+
private _performInitialization;
|
|
78
|
+
private assertInitialized;
|
|
79
|
+
embed(text: string): Promise<EmbeddingResult>;
|
|
80
|
+
embedBatch(texts: string[], options?: BatchOptions): Promise<EmbeddingResult[]>;
|
|
81
|
+
similarity(textA: string, textB: string, method?: 'cosine' | 'euclidean' | 'dot'): Promise<SimilarityResult>;
|
|
82
|
+
dispose(): void;
|
|
83
|
+
isReady(): boolean;
|
|
84
|
+
getConfig(): Required<ModelConfig>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Semantic Search - Vector-Based Document Retrieval
|
|
89
|
+
*
|
|
90
|
+
* Architectural Principles:
|
|
91
|
+
* - Pre-computed embeddings optimize retrieval latency
|
|
92
|
+
* - Configurable ranking strategies enable domain customization
|
|
93
|
+
* - Metadata filtering supports complex queries
|
|
94
|
+
* - O(n log k) complexity for top-k selection
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
interface SearchConfig<T = string> {
|
|
98
|
+
topK?: number;
|
|
99
|
+
threshold?: number;
|
|
100
|
+
textExtractor?: (item: T) => string;
|
|
101
|
+
metadataExtractor?: (item: T) => Record<string, unknown>;
|
|
102
|
+
}
|
|
103
|
+
interface IndexedItem<T = string> {
|
|
104
|
+
item: T;
|
|
105
|
+
embedding: Embedding;
|
|
106
|
+
metadata?: Record<string, unknown>;
|
|
107
|
+
}
|
|
108
|
+
declare class SemanticSearch<T = string> {
|
|
109
|
+
private engine;
|
|
110
|
+
private indexedItems;
|
|
111
|
+
private config;
|
|
112
|
+
constructor(engine: SemanticEngine, config?: SearchConfig<T>);
|
|
113
|
+
index(items: T[], replace?: boolean): Promise<void>;
|
|
114
|
+
search(query: string, overrideConfig?: Partial<SearchConfig<T>>): Promise<SearchResult<T>[]>;
|
|
115
|
+
searchWithFilter(query: string, filter: (metadata: Record<string, unknown>) => boolean, config?: Partial<SearchConfig<T>>): Promise<SearchResult<T>[]>;
|
|
116
|
+
findSimilar(item: T, config?: Partial<SearchConfig<T>>): Promise<SearchResult<T>[]>;
|
|
117
|
+
getStats(): {
|
|
118
|
+
itemCount: number;
|
|
119
|
+
dimensions: number;
|
|
120
|
+
memoryEstimate: string;
|
|
121
|
+
};
|
|
122
|
+
clear(): void;
|
|
123
|
+
exportIndex(): IndexedItem<T>[];
|
|
124
|
+
importIndex(index: IndexedItem<T>[]): void;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Vector Mathematics - Performance-Optimized Operations
|
|
129
|
+
*
|
|
130
|
+
* Architectural Principles:
|
|
131
|
+
* - Pure functions ensure predictability
|
|
132
|
+
* - O(n) time complexity for scalability
|
|
133
|
+
* - Defensive validation at boundaries
|
|
134
|
+
* - Zero external dependencies
|
|
135
|
+
*/
|
|
136
|
+
|
|
137
|
+
declare function dotProduct(a: Embedding, b: Embedding): number;
|
|
138
|
+
declare function magnitude(vector: Embedding): number;
|
|
139
|
+
declare function cosineSimilarity(a: Embedding, b: Embedding): number;
|
|
140
|
+
declare function euclideanDistance(a: Embedding, b: Embedding): number;
|
|
141
|
+
declare function normalize(vector: Embedding): Embedding;
|
|
142
|
+
declare function centroid(embeddings: Embedding[]): Embedding;
|
|
143
|
+
declare function topKSimilar(query: Embedding, candidates: Embedding[], k?: number): Array<[number, number]>;
|
|
144
|
+
|
|
145
|
+
declare function createSemanticEngine(config?: ModelConfig): Promise<SemanticEngine>;
|
|
146
|
+
declare function createSemanticSearch<T = string>(items: T[], config?: SearchConfig<T>): Promise<SemanticSearch<T>>;
|
|
147
|
+
|
|
148
|
+
export { type BatchOptions, type Embedding, type EmbeddingResult, type IndexedItem, type ModelConfig, type ModelLoadProgress, type SearchConfig, type SearchResult, SemanticEngine, SemanticError, SemanticErrorCode, SemanticSearch, type SimilarityResult, centroid, cosineSimilarity, createSemanticEngine, createSemanticSearch, dotProduct, euclideanDistance, magnitude, normalize, topKSimilar };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Design Philosophy:
|
|
5
|
+
* - Type safety prevents runtime failures
|
|
6
|
+
* - Semantic error codes enable precise debugging
|
|
7
|
+
* - Generic types provide flexibility without sacrificing safety
|
|
8
|
+
*/
|
|
9
|
+
type Embedding = number[];
|
|
10
|
+
interface ModelConfig {
|
|
11
|
+
modelName?: string;
|
|
12
|
+
maxLength?: number;
|
|
13
|
+
quantized?: boolean;
|
|
14
|
+
onProgress?: (progress: ModelLoadProgress) => void;
|
|
15
|
+
}
|
|
16
|
+
interface ModelLoadProgress {
|
|
17
|
+
status: 'downloading' | 'loading' | 'ready';
|
|
18
|
+
progress: number;
|
|
19
|
+
file?: string;
|
|
20
|
+
}
|
|
21
|
+
interface EmbeddingResult {
|
|
22
|
+
embedding: Embedding;
|
|
23
|
+
text: string;
|
|
24
|
+
metadata: {
|
|
25
|
+
dimensions: number;
|
|
26
|
+
modelName: string;
|
|
27
|
+
processingTime: number;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
interface SimilarityResult {
|
|
31
|
+
score: number;
|
|
32
|
+
texts: [string, string];
|
|
33
|
+
metadata: {
|
|
34
|
+
method: 'cosine' | 'euclidean' | 'dot';
|
|
35
|
+
processingTime: number;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
interface SearchResult<T = string> {
|
|
39
|
+
item: T;
|
|
40
|
+
score: number;
|
|
41
|
+
rank: number;
|
|
42
|
+
}
|
|
43
|
+
interface BatchOptions {
|
|
44
|
+
batchSize?: number;
|
|
45
|
+
parallel?: boolean;
|
|
46
|
+
onProgress?: (completed: number, total: number) => void;
|
|
47
|
+
}
|
|
48
|
+
declare enum SemanticErrorCode {
|
|
49
|
+
MODEL_NOT_LOADED = "MODEL_NOT_LOADED",
|
|
50
|
+
INVALID_INPUT = "INVALID_INPUT",
|
|
51
|
+
EMBEDDING_FAILED = "EMBEDDING_FAILED",
|
|
52
|
+
COMPUTATION_FAILED = "COMPUTATION_FAILED",
|
|
53
|
+
DIMENSION_MISMATCH = "DIMENSION_MISMATCH"
|
|
54
|
+
}
|
|
55
|
+
declare class SemanticError extends Error {
|
|
56
|
+
code: SemanticErrorCode;
|
|
57
|
+
details?: Record<string, unknown> | undefined;
|
|
58
|
+
constructor(code: SemanticErrorCode, message: string, details?: Record<string, unknown> | undefined);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Semantic Engine - Core Embedding Generation
|
|
63
|
+
*
|
|
64
|
+
* Architectural Principles:
|
|
65
|
+
* - Lazy initialization minimizes startup overhead
|
|
66
|
+
* - Singleton pattern prevents redundant model loading
|
|
67
|
+
* - Resource management through explicit lifecycle control
|
|
68
|
+
* - Defensive error handling with semantic codes
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
declare class SemanticEngine {
|
|
72
|
+
private model;
|
|
73
|
+
private config;
|
|
74
|
+
private initializationPromise;
|
|
75
|
+
constructor(config?: ModelConfig);
|
|
76
|
+
initialize(): Promise<void>;
|
|
77
|
+
private _performInitialization;
|
|
78
|
+
private assertInitialized;
|
|
79
|
+
embed(text: string): Promise<EmbeddingResult>;
|
|
80
|
+
embedBatch(texts: string[], options?: BatchOptions): Promise<EmbeddingResult[]>;
|
|
81
|
+
similarity(textA: string, textB: string, method?: 'cosine' | 'euclidean' | 'dot'): Promise<SimilarityResult>;
|
|
82
|
+
dispose(): void;
|
|
83
|
+
isReady(): boolean;
|
|
84
|
+
getConfig(): Required<ModelConfig>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Semantic Search - Vector-Based Document Retrieval
|
|
89
|
+
*
|
|
90
|
+
* Architectural Principles:
|
|
91
|
+
* - Pre-computed embeddings optimize retrieval latency
|
|
92
|
+
* - Configurable ranking strategies enable domain customization
|
|
93
|
+
* - Metadata filtering supports complex queries
|
|
94
|
+
* - O(n log k) complexity for top-k selection
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
interface SearchConfig<T = string> {
|
|
98
|
+
topK?: number;
|
|
99
|
+
threshold?: number;
|
|
100
|
+
textExtractor?: (item: T) => string;
|
|
101
|
+
metadataExtractor?: (item: T) => Record<string, unknown>;
|
|
102
|
+
}
|
|
103
|
+
interface IndexedItem<T = string> {
|
|
104
|
+
item: T;
|
|
105
|
+
embedding: Embedding;
|
|
106
|
+
metadata?: Record<string, unknown>;
|
|
107
|
+
}
|
|
108
|
+
declare class SemanticSearch<T = string> {
|
|
109
|
+
private engine;
|
|
110
|
+
private indexedItems;
|
|
111
|
+
private config;
|
|
112
|
+
constructor(engine: SemanticEngine, config?: SearchConfig<T>);
|
|
113
|
+
index(items: T[], replace?: boolean): Promise<void>;
|
|
114
|
+
search(query: string, overrideConfig?: Partial<SearchConfig<T>>): Promise<SearchResult<T>[]>;
|
|
115
|
+
searchWithFilter(query: string, filter: (metadata: Record<string, unknown>) => boolean, config?: Partial<SearchConfig<T>>): Promise<SearchResult<T>[]>;
|
|
116
|
+
findSimilar(item: T, config?: Partial<SearchConfig<T>>): Promise<SearchResult<T>[]>;
|
|
117
|
+
getStats(): {
|
|
118
|
+
itemCount: number;
|
|
119
|
+
dimensions: number;
|
|
120
|
+
memoryEstimate: string;
|
|
121
|
+
};
|
|
122
|
+
clear(): void;
|
|
123
|
+
exportIndex(): IndexedItem<T>[];
|
|
124
|
+
importIndex(index: IndexedItem<T>[]): void;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Vector Mathematics - Performance-Optimized Operations
|
|
129
|
+
*
|
|
130
|
+
* Architectural Principles:
|
|
131
|
+
* - Pure functions ensure predictability
|
|
132
|
+
* - O(n) time complexity for scalability
|
|
133
|
+
* - Defensive validation at boundaries
|
|
134
|
+
* - Zero external dependencies
|
|
135
|
+
*/
|
|
136
|
+
|
|
137
|
+
declare function dotProduct(a: Embedding, b: Embedding): number;
|
|
138
|
+
declare function magnitude(vector: Embedding): number;
|
|
139
|
+
declare function cosineSimilarity(a: Embedding, b: Embedding): number;
|
|
140
|
+
declare function euclideanDistance(a: Embedding, b: Embedding): number;
|
|
141
|
+
declare function normalize(vector: Embedding): Embedding;
|
|
142
|
+
declare function centroid(embeddings: Embedding[]): Embedding;
|
|
143
|
+
declare function topKSimilar(query: Embedding, candidates: Embedding[], k?: number): Array<[number, number]>;
|
|
144
|
+
|
|
145
|
+
declare function createSemanticEngine(config?: ModelConfig): Promise<SemanticEngine>;
|
|
146
|
+
declare function createSemanticSearch<T = string>(items: T[], config?: SearchConfig<T>): Promise<SemanticSearch<T>>;
|
|
147
|
+
|
|
148
|
+
export { type BatchOptions, type Embedding, type EmbeddingResult, type IndexedItem, type ModelConfig, type ModelLoadProgress, type SearchConfig, type SearchResult, SemanticEngine, SemanticError, SemanticErrorCode, SemanticSearch, type SimilarityResult, centroid, cosineSimilarity, createSemanticEngine, createSemanticSearch, dotProduct, euclideanDistance, magnitude, normalize, topKSimilar };
|