agentdb 2.0.0-alpha.2 → 2.0.0-alpha.2.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/dist/agentdb.min.js +4 -4
- package/dist/simulation/cli.js +0 -0
- package/dist/src/cli/agentdb-cli.d.ts.map +1 -1
- package/dist/src/cli/agentdb-cli.js +78 -0
- package/dist/src/cli/agentdb-cli.js.map +1 -1
- package/package.json +3 -3
- package/src/cli/agentdb-cli.ts +78 -0
- package/dist/agentdb-advanced.js +0 -2110
- package/dist/agentdb-advanced.min.js +0 -1
- package/dist/backends/GraphBackend.d.ts +0 -196
- package/dist/backends/GraphBackend.d.ts.map +0 -1
- package/dist/backends/GraphBackend.js +0 -33
- package/dist/backends/GraphBackend.js.map +0 -1
- package/dist/backends/LearningBackend.d.ts +0 -148
- package/dist/backends/LearningBackend.d.ts.map +0 -1
- package/dist/backends/LearningBackend.js +0 -27
- package/dist/backends/LearningBackend.js.map +0 -1
- package/dist/backends/VectorBackend.d.ts +0 -119
- package/dist/backends/VectorBackend.d.ts.map +0 -1
- package/dist/backends/VectorBackend.js +0 -14
- package/dist/backends/VectorBackend.js.map +0 -1
- package/dist/backends/detector.d.ts +0 -81
- package/dist/backends/detector.d.ts.map +0 -1
- package/dist/backends/detector.js +0 -192
- package/dist/backends/detector.js.map +0 -1
- package/dist/backends/factory.d.ts +0 -50
- package/dist/backends/factory.d.ts.map +0 -1
- package/dist/backends/factory.js +0 -161
- package/dist/backends/factory.js.map +0 -1
- package/dist/backends/graph/GraphDatabaseAdapter.d.ts +0 -139
- package/dist/backends/graph/GraphDatabaseAdapter.d.ts.map +0 -1
- package/dist/backends/graph/GraphDatabaseAdapter.js +0 -194
- package/dist/backends/graph/GraphDatabaseAdapter.js.map +0 -1
- package/dist/backends/hnswlib/HNSWLibBackend.d.ts +0 -92
- package/dist/backends/hnswlib/HNSWLibBackend.d.ts.map +0 -1
- package/dist/backends/hnswlib/HNSWLibBackend.js +0 -316
- package/dist/backends/hnswlib/HNSWLibBackend.js.map +0 -1
- package/dist/backends/hnswlib/index.d.ts +0 -7
- package/dist/backends/hnswlib/index.d.ts.map +0 -1
- package/dist/backends/hnswlib/index.js +0 -7
- package/dist/backends/hnswlib/index.js.map +0 -1
- package/dist/backends/index.d.ts +0 -14
- package/dist/backends/index.d.ts.map +0 -1
- package/dist/backends/index.js +0 -13
- package/dist/backends/index.js.map +0 -1
- package/dist/backends/ruvector/RuVectorBackend.d.ts +0 -75
- package/dist/backends/ruvector/RuVectorBackend.d.ts.map +0 -1
- package/dist/backends/ruvector/RuVectorBackend.js +0 -198
- package/dist/backends/ruvector/RuVectorBackend.js.map +0 -1
- package/dist/backends/ruvector/RuVectorLearning.d.ts +0 -104
- package/dist/backends/ruvector/RuVectorLearning.d.ts.map +0 -1
- package/dist/backends/ruvector/RuVectorLearning.js +0 -177
- package/dist/backends/ruvector/RuVectorLearning.js.map +0 -1
- package/dist/backends/ruvector/index.d.ts +0 -9
- package/dist/backends/ruvector/index.d.ts.map +0 -1
- package/dist/backends/ruvector/index.js +0 -8
- package/dist/backends/ruvector/index.js.map +0 -1
- package/dist/benchmarks/wasm-vector-benchmark.d.ts +0 -10
- package/dist/benchmarks/wasm-vector-benchmark.d.ts.map +0 -1
- package/dist/benchmarks/wasm-vector-benchmark.js +0 -196
- package/dist/benchmarks/wasm-vector-benchmark.js.map +0 -1
- package/dist/browser/AdvancedFeatures.d.ts +0 -144
- package/dist/browser/AdvancedFeatures.d.ts.map +0 -1
- package/dist/browser/AdvancedFeatures.js +0 -430
- package/dist/browser/AdvancedFeatures.js.map +0 -1
- package/dist/browser/HNSWIndex.d.ts +0 -117
- package/dist/browser/HNSWIndex.d.ts.map +0 -1
- package/dist/browser/HNSWIndex.js +0 -402
- package/dist/browser/HNSWIndex.js.map +0 -1
- package/dist/browser/ProductQuantization.d.ts +0 -107
- package/dist/browser/ProductQuantization.d.ts.map +0 -1
- package/dist/browser/ProductQuantization.js +0 -337
- package/dist/browser/ProductQuantization.js.map +0 -1
- package/dist/browser/browser/AdvancedFeatures.d.ts +0 -144
- package/dist/browser/browser/AdvancedFeatures.d.ts.map +0 -1
- package/dist/browser/browser/AdvancedFeatures.js +0 -427
- package/dist/browser/browser/HNSWIndex.d.ts +0 -117
- package/dist/browser/browser/HNSWIndex.d.ts.map +0 -1
- package/dist/browser/browser/HNSWIndex.js +0 -402
- package/dist/browser/browser/ProductQuantization.d.ts +0 -107
- package/dist/browser/browser/ProductQuantization.d.ts.map +0 -1
- package/dist/browser/browser/ProductQuantization.js +0 -348
- package/dist/browser/browser/index.d.ts +0 -223
- package/dist/browser/browser/index.d.ts.map +0 -1
- package/dist/browser/browser/index.js +0 -233
- package/dist/browser/index.d.ts +0 -223
- package/dist/browser/index.d.ts.map +0 -1
- package/dist/browser/index.js +0 -225
- package/dist/browser/index.js.map +0 -1
- package/dist/cli/agentdb-cli.d.ts +0 -154
- package/dist/cli/agentdb-cli.d.ts.map +0 -1
- package/dist/cli/agentdb-cli.js +0 -2273
- package/dist/cli/agentdb-cli.js.map +0 -1
- package/dist/cli/agentdb.db +0 -0
- package/dist/cli/commands/init.d.ts +0 -12
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/init.js +0 -115
- package/dist/cli/commands/init.js.map +0 -1
- package/dist/cli/commands/install-embeddings.d.ts +0 -10
- package/dist/cli/commands/install-embeddings.d.ts.map +0 -1
- package/dist/cli/commands/install-embeddings.js +0 -68
- package/dist/cli/commands/install-embeddings.js.map +0 -1
- package/dist/cli/commands/migrate.d.ts +0 -15
- package/dist/cli/commands/migrate.d.ts.map +0 -1
- package/dist/cli/commands/migrate.js +0 -425
- package/dist/cli/commands/migrate.js.map +0 -1
- package/dist/cli/commands/status.d.ts +0 -10
- package/dist/cli/commands/status.d.ts.map +0 -1
- package/dist/cli/commands/status.js +0 -129
- package/dist/cli/commands/status.js.map +0 -1
- package/dist/controllers/CausalMemoryGraph.d.ts +0 -126
- package/dist/controllers/CausalMemoryGraph.d.ts.map +0 -1
- package/dist/controllers/CausalMemoryGraph.js +0 -323
- package/dist/controllers/CausalMemoryGraph.js.map +0 -1
- package/dist/controllers/CausalRecall.d.ts +0 -139
- package/dist/controllers/CausalRecall.d.ts.map +0 -1
- package/dist/controllers/CausalRecall.js +0 -356
- package/dist/controllers/CausalRecall.js.map +0 -1
- package/dist/controllers/ContextSynthesizer.d.ts +0 -65
- package/dist/controllers/ContextSynthesizer.d.ts.map +0 -1
- package/dist/controllers/ContextSynthesizer.js +0 -208
- package/dist/controllers/ContextSynthesizer.js.map +0 -1
- package/dist/controllers/EmbeddingService.d.ts +0 -37
- package/dist/controllers/EmbeddingService.d.ts.map +0 -1
- package/dist/controllers/EmbeddingService.js +0 -136
- package/dist/controllers/EmbeddingService.js.map +0 -1
- package/dist/controllers/EnhancedEmbeddingService.d.ts +0 -50
- package/dist/controllers/EnhancedEmbeddingService.d.ts.map +0 -1
- package/dist/controllers/EnhancedEmbeddingService.js +0 -119
- package/dist/controllers/EnhancedEmbeddingService.js.map +0 -1
- package/dist/controllers/ExplainableRecall.d.ts +0 -163
- package/dist/controllers/ExplainableRecall.d.ts.map +0 -1
- package/dist/controllers/ExplainableRecall.js +0 -485
- package/dist/controllers/ExplainableRecall.js.map +0 -1
- package/dist/controllers/HNSWIndex.d.ts +0 -128
- package/dist/controllers/HNSWIndex.d.ts.map +0 -1
- package/dist/controllers/HNSWIndex.js +0 -361
- package/dist/controllers/HNSWIndex.js.map +0 -1
- package/dist/controllers/LearningSystem.d.ts +0 -195
- package/dist/controllers/LearningSystem.d.ts.map +0 -1
- package/dist/controllers/LearningSystem.js +0 -929
- package/dist/controllers/LearningSystem.js.map +0 -1
- package/dist/controllers/MMRDiversityRanker.d.ts +0 -50
- package/dist/controllers/MMRDiversityRanker.d.ts.map +0 -1
- package/dist/controllers/MMRDiversityRanker.js +0 -130
- package/dist/controllers/MMRDiversityRanker.js.map +0 -1
- package/dist/controllers/MetadataFilter.d.ts +0 -70
- package/dist/controllers/MetadataFilter.d.ts.map +0 -1
- package/dist/controllers/MetadataFilter.js +0 -243
- package/dist/controllers/MetadataFilter.js.map +0 -1
- package/dist/controllers/NightlyLearner.d.ts +0 -114
- package/dist/controllers/NightlyLearner.d.ts.map +0 -1
- package/dist/controllers/NightlyLearner.js +0 -394
- package/dist/controllers/NightlyLearner.js.map +0 -1
- package/dist/controllers/QUICClient.d.ts +0 -109
- package/dist/controllers/QUICClient.d.ts.map +0 -1
- package/dist/controllers/QUICClient.js +0 -299
- package/dist/controllers/QUICClient.js.map +0 -1
- package/dist/controllers/QUICServer.d.ts +0 -121
- package/dist/controllers/QUICServer.d.ts.map +0 -1
- package/dist/controllers/QUICServer.js +0 -383
- package/dist/controllers/QUICServer.js.map +0 -1
- package/dist/controllers/ReasoningBank.d.ts +0 -196
- package/dist/controllers/ReasoningBank.d.ts.map +0 -1
- package/dist/controllers/ReasoningBank.js +0 -494
- package/dist/controllers/ReasoningBank.js.map +0 -1
- package/dist/controllers/ReflexionMemory.d.ts +0 -125
- package/dist/controllers/ReflexionMemory.d.ts.map +0 -1
- package/dist/controllers/ReflexionMemory.js +0 -521
- package/dist/controllers/ReflexionMemory.js.map +0 -1
- package/dist/controllers/SkillLibrary.d.ts +0 -149
- package/dist/controllers/SkillLibrary.d.ts.map +0 -1
- package/dist/controllers/SkillLibrary.js +0 -547
- package/dist/controllers/SkillLibrary.js.map +0 -1
- package/dist/controllers/SyncCoordinator.d.ts +0 -120
- package/dist/controllers/SyncCoordinator.d.ts.map +0 -1
- package/dist/controllers/SyncCoordinator.js +0 -441
- package/dist/controllers/SyncCoordinator.js.map +0 -1
- package/dist/controllers/WASMVectorSearch.d.ts +0 -89
- package/dist/controllers/WASMVectorSearch.d.ts.map +0 -1
- package/dist/controllers/WASMVectorSearch.js +0 -234
- package/dist/controllers/WASMVectorSearch.js.map +0 -1
- package/dist/controllers/frontier-index.d.ts +0 -14
- package/dist/controllers/frontier-index.d.ts.map +0 -1
- package/dist/controllers/frontier-index.js +0 -10
- package/dist/controllers/frontier-index.js.map +0 -1
- package/dist/controllers/index.d.ts +0 -30
- package/dist/controllers/index.d.ts.map +0 -1
- package/dist/controllers/index.js +0 -18
- package/dist/controllers/index.js.map +0 -1
- package/dist/db-fallback.d.ts +0 -26
- package/dist/db-fallback.d.ts.map +0 -1
- package/dist/db-fallback.js +0 -264
- package/dist/db-fallback.js.map +0 -1
- package/dist/db-test.d.ts +0 -13
- package/dist/db-test.d.ts.map +0 -1
- package/dist/db-test.js +0 -55
- package/dist/db-test.js.map +0 -1
- package/dist/db-unified.d.ts +0 -76
- package/dist/db-unified.d.ts.map +0 -1
- package/dist/db-unified.js +0 -278
- package/dist/db-unified.js.map +0 -1
- package/dist/examples/quic-sync-example.d.ts +0 -9
- package/dist/examples/quic-sync-example.d.ts.map +0 -1
- package/dist/examples/quic-sync-example.js +0 -169
- package/dist/examples/quic-sync-example.js.map +0 -1
- package/dist/examples/wasm-vector-usage.d.ts +0 -12
- package/dist/examples/wasm-vector-usage.d.ts.map +0 -1
- package/dist/examples/wasm-vector-usage.js +0 -190
- package/dist/examples/wasm-vector-usage.js.map +0 -1
- package/dist/index.d.ts +0 -28
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -35
- package/dist/index.js.map +0 -1
- package/dist/malp/core/ccc.d.ts +0 -99
- package/dist/malp/core/ccc.d.ts.map +0 -1
- package/dist/malp/core/ccc.js +0 -181
- package/dist/malp/core/ccc.js.map +0 -1
- package/dist/malp/core/index.d.ts +0 -9
- package/dist/malp/core/index.d.ts.map +0 -1
- package/dist/malp/core/index.js +0 -9
- package/dist/malp/core/index.js.map +0 -1
- package/dist/malp/core/linalg.d.ts +0 -101
- package/dist/malp/core/linalg.d.ts.map +0 -1
- package/dist/malp/core/linalg.js +0 -278
- package/dist/malp/core/linalg.js.map +0 -1
- package/dist/malp/core/optimizer.d.ts +0 -68
- package/dist/malp/core/optimizer.d.ts.map +0 -1
- package/dist/malp/core/optimizer.js +0 -160
- package/dist/malp/core/optimizer.js.map +0 -1
- package/dist/malp/index.d.ts +0 -33
- package/dist/malp/index.d.ts.map +0 -1
- package/dist/malp/index.js +0 -37
- package/dist/malp/index.js.map +0 -1
- package/dist/malp/metrics/agreement.d.ts +0 -106
- package/dist/malp/metrics/agreement.d.ts.map +0 -1
- package/dist/malp/metrics/agreement.js +0 -199
- package/dist/malp/metrics/agreement.js.map +0 -1
- package/dist/malp/metrics/comparison.d.ts +0 -93
- package/dist/malp/metrics/comparison.d.ts.map +0 -1
- package/dist/malp/metrics/comparison.js +0 -256
- package/dist/malp/metrics/comparison.js.map +0 -1
- package/dist/malp/metrics/index.d.ts +0 -8
- package/dist/malp/metrics/index.d.ts.map +0 -1
- package/dist/malp/metrics/index.js +0 -8
- package/dist/malp/metrics/index.js.map +0 -1
- package/dist/malp/metrics/performance.d.ts +0 -61
- package/dist/malp/metrics/performance.d.ts.map +0 -1
- package/dist/malp/metrics/performance.js +0 -190
- package/dist/malp/metrics/performance.js.map +0 -1
- package/dist/malp/models/index.d.ts +0 -7
- package/dist/malp/models/index.d.ts.map +0 -1
- package/dist/malp/models/index.js +0 -7
- package/dist/malp/models/index.js.map +0 -1
- package/dist/malp/models/malp.d.ts +0 -116
- package/dist/malp/models/malp.d.ts.map +0 -1
- package/dist/malp/models/malp.js +0 -206
- package/dist/malp/models/malp.js.map +0 -1
- package/dist/malp/models/regressor.d.ts +0 -80
- package/dist/malp/models/regressor.d.ts.map +0 -1
- package/dist/malp/models/regressor.js +0 -229
- package/dist/malp/models/regressor.js.map +0 -1
- package/dist/malp/reasoningbank_validator.d.ts +0 -187
- package/dist/malp/reasoningbank_validator.d.ts.map +0 -1
- package/dist/malp/reasoningbank_validator.js +0 -246
- package/dist/malp/reasoningbank_validator.js.map +0 -1
- package/dist/malp/wasm_bindings.d.ts +0 -344
- package/dist/malp/wasm_bindings.d.ts.map +0 -1
- package/dist/malp/wasm_bindings.js +0 -9
- package/dist/malp/wasm_bindings.js.map +0 -1
- package/dist/mcp/agentdb-mcp-server.d.ts +0 -8
- package/dist/mcp/agentdb-mcp-server.d.ts.map +0 -1
- package/dist/mcp/agentdb-mcp-server.js +0 -2116
- package/dist/mcp/agentdb-mcp-server.js.map +0 -1
- package/dist/mcp/learning-tools-handlers.d.ts +0 -16
- package/dist/mcp/learning-tools-handlers.d.ts.map +0 -1
- package/dist/mcp/learning-tools-handlers.js +0 -105
- package/dist/mcp/learning-tools-handlers.js.map +0 -1
- package/dist/optimizations/BatchOperations.d.ts +0 -109
- package/dist/optimizations/BatchOperations.d.ts.map +0 -1
- package/dist/optimizations/BatchOperations.js +0 -407
- package/dist/optimizations/BatchOperations.js.map +0 -1
- package/dist/optimizations/QueryOptimizer.d.ts +0 -83
- package/dist/optimizations/QueryOptimizer.d.ts.map +0 -1
- package/dist/optimizations/QueryOptimizer.js +0 -228
- package/dist/optimizations/QueryOptimizer.js.map +0 -1
- package/dist/optimizations/ToolCache.d.ts +0 -137
- package/dist/optimizations/ToolCache.d.ts.map +0 -1
- package/dist/optimizations/ToolCache.js +0 -281
- package/dist/optimizations/ToolCache.js.map +0 -1
- package/dist/optimizations/index.d.ts +0 -10
- package/dist/optimizations/index.d.ts.map +0 -1
- package/dist/optimizations/index.js +0 -8
- package/dist/optimizations/index.js.map +0 -1
- package/dist/security/input-validation.d.ts +0 -109
- package/dist/security/input-validation.d.ts.map +0 -1
- package/dist/security/input-validation.js +0 -398
- package/dist/security/input-validation.js.map +0 -1
- package/dist/security/limits.d.ts +0 -150
- package/dist/security/limits.d.ts.map +0 -1
- package/dist/security/limits.js +0 -288
- package/dist/security/limits.js.map +0 -1
- package/dist/security/path-security.d.ts +0 -100
- package/dist/security/path-security.d.ts.map +0 -1
- package/dist/security/path-security.js +0 -337
- package/dist/security/path-security.js.map +0 -1
- package/dist/security/validation.d.ts +0 -95
- package/dist/security/validation.d.ts.map +0 -1
- package/dist/security/validation.js +0 -315
- package/dist/security/validation.js.map +0 -1
- package/dist/types/quic.d.ts +0 -518
- package/dist/types/quic.d.ts.map +0 -1
- package/dist/types/quic.js +0 -272
- package/dist/types/quic.js.map +0 -1
package/dist/agentdb-advanced.js
DELETED
|
@@ -1,2110 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* AgentDB v2.0.0-alpha.2 - Advanced Browser Bundle
|
|
4
|
-
*
|
|
5
|
-
* Complete feature set for browser environments:
|
|
6
|
-
* - v1 API backward compatible
|
|
7
|
-
* - v2 enhanced API (episodes, skills, causal_edges)
|
|
8
|
-
* - Product Quantization (PQ8/PQ16/PQ32) - 4-32x compression
|
|
9
|
-
* - HNSW Indexing - 10-20x faster search
|
|
10
|
-
* - Graph Neural Networks - Graph attention & message passing
|
|
11
|
-
* - MMR Diversity - Maximal marginal relevance ranking
|
|
12
|
-
* - Tensor Compression - SVD dimension reduction
|
|
13
|
-
* - Batch Operations - Optimized vector processing
|
|
14
|
-
* - IndexedDB persistence
|
|
15
|
-
* - Cross-tab synchronization
|
|
16
|
-
*
|
|
17
|
-
* Bundle Size: ~90 KB raw (~31 KB gzipped)
|
|
18
|
-
* License: MIT
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
(function(global) {
|
|
22
|
-
'use strict';
|
|
23
|
-
|
|
24
|
-
// ============================================================================
|
|
25
|
-
// sql.js WASM Loader
|
|
26
|
-
// ============================================================================
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// We are modularizing this manually because the current modularize setting in Emscripten has some issues:
|
|
30
|
-
// https://github.com/kripken/emscripten/issues/5820
|
|
31
|
-
// In addition, When you use emcc's modularization, it still expects to export a global object called `Module`,
|
|
32
|
-
// which is able to be used/called before the WASM is loaded.
|
|
33
|
-
// The modularization below exports a promise that loads and resolves to the actual sql.js module.
|
|
34
|
-
// That way, this module can't be used before the WASM is finished loading.
|
|
35
|
-
|
|
36
|
-
// We are going to define a function that a user will call to start loading initializing our Sql.js library
|
|
37
|
-
// However, that function might be called multiple times, and on subsequent calls, we don't actually want it to instantiate a new instance of the Module
|
|
38
|
-
// Instead, we want to return the previously loaded module
|
|
39
|
-
|
|
40
|
-
// TODO: Make this not declare a global if used in the browser
|
|
41
|
-
var initSqlJsPromise = undefined;
|
|
42
|
-
|
|
43
|
-
var initSqlJs = function (moduleConfig) {
|
|
44
|
-
|
|
45
|
-
if (initSqlJsPromise){
|
|
46
|
-
return initSqlJsPromise;
|
|
47
|
-
}
|
|
48
|
-
// If we're here, we've never called this function before
|
|
49
|
-
initSqlJsPromise = new Promise(function (resolveModule, reject) {
|
|
50
|
-
|
|
51
|
-
// We are modularizing this manually because the current modularize setting in Emscripten has some issues:
|
|
52
|
-
// https://github.com/kripken/emscripten/issues/5820
|
|
53
|
-
|
|
54
|
-
// The way to affect the loading of emcc compiled modules is to create a variable called `Module` and add
|
|
55
|
-
// properties to it, like `preRun`, `postRun`, etc
|
|
56
|
-
// We are using that to get notified when the WASM has finished loading.
|
|
57
|
-
// Only then will we return our promise
|
|
58
|
-
|
|
59
|
-
// If they passed in a moduleConfig object, use that
|
|
60
|
-
// Otherwise, initialize Module to the empty object
|
|
61
|
-
var Module = typeof moduleConfig !== 'undefined' ? moduleConfig : {};
|
|
62
|
-
|
|
63
|
-
// EMCC only allows for a single onAbort function (not an array of functions)
|
|
64
|
-
// So if the user defined their own onAbort function, we remember it and call it
|
|
65
|
-
var originalOnAbortFunction = Module['onAbort'];
|
|
66
|
-
Module['onAbort'] = function (errorThatCausedAbort) {
|
|
67
|
-
reject(new Error(errorThatCausedAbort));
|
|
68
|
-
if (originalOnAbortFunction){
|
|
69
|
-
originalOnAbortFunction(errorThatCausedAbort);
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
Module['postRun'] = Module['postRun'] || [];
|
|
74
|
-
Module['postRun'].push(function () {
|
|
75
|
-
// When Emscripted calls postRun, this promise resolves with the built Module
|
|
76
|
-
resolveModule(Module);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// There is a section of code in the emcc-generated code below that looks like this:
|
|
80
|
-
// (Note that this is lowercase `module`)
|
|
81
|
-
// if (typeof module !== 'undefined') {
|
|
82
|
-
// module['exports'] = Module;
|
|
83
|
-
// }
|
|
84
|
-
// When that runs, it's going to overwrite our own modularization export efforts in shell-post.js!
|
|
85
|
-
// The only way to tell emcc not to emit it is to pass the MODULARIZE=1 or MODULARIZE_INSTANCE=1 flags,
|
|
86
|
-
// but that carries with it additional unnecessary baggage/bugs we don't want either.
|
|
87
|
-
// So, we have three options:
|
|
88
|
-
// 1) We undefine `module`
|
|
89
|
-
// 2) We remember what `module['exports']` was at the beginning of this function and we restore it later
|
|
90
|
-
// 3) We write a script to remove those lines of code as part of the Make process.
|
|
91
|
-
//
|
|
92
|
-
// Since those are the only lines of code that care about module, we will undefine it. It's the most straightforward
|
|
93
|
-
// of the options, and has the side effect of reducing emcc's efforts to modify the module if its output were to change in the future.
|
|
94
|
-
// That's a nice side effect since we're handling the modularization efforts ourselves
|
|
95
|
-
module = undefined;
|
|
96
|
-
|
|
97
|
-
// The emcc-generated code and shell-post.js code goes below,
|
|
98
|
-
// meaning that all of it runs inside of this promise. If anything throws an exception, our promise will abort
|
|
99
|
-
var f;f||=typeof Module != 'undefined' ? Module : {};var aa="object"==typeof window,ba="undefined"!=typeof WorkerGlobalScope,ca="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node&&"renderer"!=process.type;"use strict";
|
|
100
|
-
f.onRuntimeInitialized=function(){function a(g,l){switch(typeof l){case "boolean":dc(g,l?1:0);break;case "number":ec(g,l);break;case "string":fc(g,l,-1,-1);break;case "object":if(null===l)lb(g);else if(null!=l.length){var n=da(l,ea);gc(g,n,l.length,-1);fa(n)}else va(g,"Wrong API use : tried to return a value of an unknown type ("+l+").",-1);break;default:lb(g)}}function b(g,l){for(var n=[],r=0;r<g;r+=1){var t=m(l+4*r,"i32"),y=hc(t);if(1===y||2===y)t=ic(t);else if(3===y)t=jc(t);else if(4===y){y=t;
|
|
101
|
-
t=kc(y);y=lc(y);for(var L=new Uint8Array(t),J=0;J<t;J+=1)L[J]=p[y+J];t=L}else t=null;n.push(t)}return n}function c(g,l){this.Qa=g;this.db=l;this.Oa=1;this.lb=[]}function d(g,l){this.db=l;l=ha(g)+1;this.eb=ia(l);if(null===this.eb)throw Error("Unable to allocate memory for the SQL string");u(g,x,this.eb,l);this.kb=this.eb;this.Za=this.pb=null}function e(g){this.filename="dbfile_"+(4294967295*Math.random()>>>0);if(null!=g){var l=this.filename,n="/",r=l;n&&(n="string"==typeof n?n:ja(n),r=l?ka(n+"/"+l):
|
|
102
|
-
n);l=la(!0,!0);r=ma(r,l);if(g){if("string"==typeof g){n=Array(g.length);for(var t=0,y=g.length;t<y;++t)n[t]=g.charCodeAt(t);g=n}na(r,l|146);n=oa(r,577);pa(n,g,0,g.length,0);qa(n);na(r,l)}}this.handleError(q(this.filename,h));this.db=m(h,"i32");ob(this.db);this.fb={};this.Sa={}}var h=z(4),k=f.cwrap,q=k("sqlite3_open","number",["string","number"]),w=k("sqlite3_close_v2","number",["number"]),v=k("sqlite3_exec","number",["number","string","number","number","number"]),C=k("sqlite3_changes","number",["number"]),
|
|
103
|
-
G=k("sqlite3_prepare_v2","number",["number","string","number","number","number"]),pb=k("sqlite3_sql","string",["number"]),nc=k("sqlite3_normalized_sql","string",["number"]),qb=k("sqlite3_prepare_v2","number",["number","number","number","number","number"]),oc=k("sqlite3_bind_text","number",["number","number","number","number","number"]),rb=k("sqlite3_bind_blob","number",["number","number","number","number","number"]),pc=k("sqlite3_bind_double","number",["number","number","number"]),qc=k("sqlite3_bind_int",
|
|
104
|
-
"number",["number","number","number"]),rc=k("sqlite3_bind_parameter_index","number",["number","string"]),sc=k("sqlite3_step","number",["number"]),tc=k("sqlite3_errmsg","string",["number"]),uc=k("sqlite3_column_count","number",["number"]),vc=k("sqlite3_data_count","number",["number"]),wc=k("sqlite3_column_double","number",["number","number"]),sb=k("sqlite3_column_text","string",["number","number"]),xc=k("sqlite3_column_blob","number",["number","number"]),yc=k("sqlite3_column_bytes","number",["number",
|
|
105
|
-
"number"]),zc=k("sqlite3_column_type","number",["number","number"]),Ac=k("sqlite3_column_name","string",["number","number"]),Bc=k("sqlite3_reset","number",["number"]),Cc=k("sqlite3_clear_bindings","number",["number"]),Dc=k("sqlite3_finalize","number",["number"]),tb=k("sqlite3_create_function_v2","number","number string number number number number number number number".split(" ")),hc=k("sqlite3_value_type","number",["number"]),kc=k("sqlite3_value_bytes","number",["number"]),jc=k("sqlite3_value_text",
|
|
106
|
-
"string",["number"]),lc=k("sqlite3_value_blob","number",["number"]),ic=k("sqlite3_value_double","number",["number"]),ec=k("sqlite3_result_double","",["number","number"]),lb=k("sqlite3_result_null","",["number"]),fc=k("sqlite3_result_text","",["number","string","number","number"]),gc=k("sqlite3_result_blob","",["number","number","number","number"]),dc=k("sqlite3_result_int","",["number","number"]),va=k("sqlite3_result_error","",["number","string","number"]),ub=k("sqlite3_aggregate_context","number",
|
|
107
|
-
["number","number"]),ob=k("RegisterExtensionFunctions","number",["number"]),vb=k("sqlite3_update_hook","number",["number","number","number"]);c.prototype.bind=function(g){if(!this.Qa)throw"Statement closed";this.reset();return Array.isArray(g)?this.Cb(g):null!=g&&"object"===typeof g?this.Db(g):!0};c.prototype.step=function(){if(!this.Qa)throw"Statement closed";this.Oa=1;var g=sc(this.Qa);switch(g){case 100:return!0;case 101:return!1;default:throw this.db.handleError(g);}};c.prototype.wb=function(g){null==
|
|
108
|
-
g&&(g=this.Oa,this.Oa+=1);return wc(this.Qa,g)};c.prototype.Gb=function(g){null==g&&(g=this.Oa,this.Oa+=1);g=sb(this.Qa,g);if("function"!==typeof BigInt)throw Error("BigInt is not supported");return BigInt(g)};c.prototype.Hb=function(g){null==g&&(g=this.Oa,this.Oa+=1);return sb(this.Qa,g)};c.prototype.getBlob=function(g){null==g&&(g=this.Oa,this.Oa+=1);var l=yc(this.Qa,g);g=xc(this.Qa,g);for(var n=new Uint8Array(l),r=0;r<l;r+=1)n[r]=p[g+r];return n};c.prototype.get=function(g,l){l=l||{};null!=g&&
|
|
109
|
-
this.bind(g)&&this.step();g=[];for(var n=vc(this.Qa),r=0;r<n;r+=1)switch(zc(this.Qa,r)){case 1:var t=l.useBigInt?this.Gb(r):this.wb(r);g.push(t);break;case 2:g.push(this.wb(r));break;case 3:g.push(this.Hb(r));break;case 4:g.push(this.getBlob(r));break;default:g.push(null)}return g};c.prototype.getColumnNames=function(){for(var g=[],l=uc(this.Qa),n=0;n<l;n+=1)g.push(Ac(this.Qa,n));return g};c.prototype.getAsObject=function(g,l){g=this.get(g,l);l=this.getColumnNames();for(var n={},r=0;r<l.length;r+=
|
|
110
|
-
1)n[l[r]]=g[r];return n};c.prototype.getSQL=function(){return pb(this.Qa)};c.prototype.getNormalizedSQL=function(){return nc(this.Qa)};c.prototype.run=function(g){null!=g&&this.bind(g);this.step();return this.reset()};c.prototype.sb=function(g,l){null==l&&(l=this.Oa,this.Oa+=1);g=ra(g);var n=da(g,ea);this.lb.push(n);this.db.handleError(oc(this.Qa,l,n,g.length-1,0))};c.prototype.Bb=function(g,l){null==l&&(l=this.Oa,this.Oa+=1);var n=da(g,ea);this.lb.push(n);this.db.handleError(rb(this.Qa,l,n,g.length,
|
|
111
|
-
0))};c.prototype.rb=function(g,l){null==l&&(l=this.Oa,this.Oa+=1);this.db.handleError((g===(g|0)?qc:pc)(this.Qa,l,g))};c.prototype.Eb=function(g){null==g&&(g=this.Oa,this.Oa+=1);rb(this.Qa,g,0,0,0)};c.prototype.tb=function(g,l){null==l&&(l=this.Oa,this.Oa+=1);switch(typeof g){case "string":this.sb(g,l);return;case "number":this.rb(g,l);return;case "bigint":this.sb(g.toString(),l);return;case "boolean":this.rb(g+0,l);return;case "object":if(null===g){this.Eb(l);return}if(null!=g.length){this.Bb(g,
|
|
112
|
-
l);return}}throw"Wrong API use : tried to bind a value of an unknown type ("+g+").";};c.prototype.Db=function(g){var l=this;Object.keys(g).forEach(function(n){var r=rc(l.Qa,n);0!==r&&l.tb(g[n],r)});return!0};c.prototype.Cb=function(g){for(var l=0;l<g.length;l+=1)this.tb(g[l],l+1);return!0};c.prototype.reset=function(){this.freemem();return 0===Cc(this.Qa)&&0===Bc(this.Qa)};c.prototype.freemem=function(){for(var g;void 0!==(g=this.lb.pop());)fa(g)};c.prototype.free=function(){this.freemem();var g=
|
|
113
|
-
0===Dc(this.Qa);delete this.db.fb[this.Qa];this.Qa=0;return g};d.prototype.next=function(){if(null===this.eb)return{done:!0};null!==this.Za&&(this.Za.free(),this.Za=null);if(!this.db.db)throw this.mb(),Error("Database closed");var g=sa(),l=z(4);ta(h);ta(l);try{this.db.handleError(qb(this.db.db,this.kb,-1,h,l));this.kb=m(l,"i32");var n=m(h,"i32");if(0===n)return this.mb(),{done:!0};this.Za=new c(n,this.db);this.db.fb[n]=this.Za;return{value:this.Za,done:!1}}catch(r){throw this.pb=ua(this.kb),this.mb(),
|
|
114
|
-
r;}finally{wa(g)}};d.prototype.mb=function(){fa(this.eb);this.eb=null};d.prototype.getRemainingSQL=function(){return null!==this.pb?this.pb:ua(this.kb)};"function"===typeof Symbol&&"symbol"===typeof Symbol.iterator&&(d.prototype[Symbol.iterator]=function(){return this});e.prototype.run=function(g,l){if(!this.db)throw"Database closed";if(l){g=this.prepare(g,l);try{g.step()}finally{g.free()}}else this.handleError(v(this.db,g,0,0,h));return this};e.prototype.exec=function(g,l,n){if(!this.db)throw"Database closed";
|
|
115
|
-
var r=sa(),t=null;try{var y=xa(g),L=z(4);for(g=[];0!==m(y,"i8");){ta(h);ta(L);this.handleError(qb(this.db,y,-1,h,L));var J=m(h,"i32");y=m(L,"i32");if(0!==J){var I=null;t=new c(J,this);for(null!=l&&t.bind(l);t.step();)null===I&&(I={columns:t.getColumnNames(),values:[]},g.push(I)),I.values.push(t.get(null,n));t.free()}}return g}catch(M){throw t&&t.free(),M;}finally{wa(r)}};e.prototype.each=function(g,l,n,r,t){"function"===typeof l&&(r=n,n=l,l=void 0);g=this.prepare(g,l);try{for(;g.step();)n(g.getAsObject(null,
|
|
116
|
-
t))}finally{g.free()}if("function"===typeof r)return r()};e.prototype.prepare=function(g,l){ta(h);this.handleError(G(this.db,g,-1,h,0));g=m(h,"i32");if(0===g)throw"Nothing to prepare";var n=new c(g,this);null!=l&&n.bind(l);return this.fb[g]=n};e.prototype.iterateStatements=function(g){return new d(g,this)};e.prototype["export"]=function(){Object.values(this.fb).forEach(function(l){l.free()});Object.values(this.Sa).forEach(A);this.Sa={};this.handleError(w(this.db));var g=ya(this.filename);this.handleError(q(this.filename,
|
|
117
|
-
h));this.db=m(h,"i32");ob(this.db);return g};e.prototype.close=function(){null!==this.db&&(Object.values(this.fb).forEach(function(g){g.free()}),Object.values(this.Sa).forEach(A),this.Sa={},this.Ya&&(A(this.Ya),this.Ya=void 0),this.handleError(w(this.db)),za("/"+this.filename),this.db=null)};e.prototype.handleError=function(g){if(0===g)return null;g=tc(this.db);throw Error(g);};e.prototype.getRowsModified=function(){return C(this.db)};e.prototype.create_function=function(g,l){Object.prototype.hasOwnProperty.call(this.Sa,
|
|
118
|
-
g)&&(A(this.Sa[g]),delete this.Sa[g]);var n=Aa(function(r,t,y){t=b(t,y);try{var L=l.apply(null,t)}catch(J){va(r,J,-1);return}a(r,L)},"viii");this.Sa[g]=n;this.handleError(tb(this.db,g,l.length,1,0,n,0,0,0));return this};e.prototype.create_aggregate=function(g,l){var n=l.init||function(){return null},r=l.finalize||function(I){return I},t=l.step;if(!t)throw"An aggregate function must have a step function in "+g;var y={};Object.hasOwnProperty.call(this.Sa,g)&&(A(this.Sa[g]),delete this.Sa[g]);l=g+"__finalize";
|
|
119
|
-
Object.hasOwnProperty.call(this.Sa,l)&&(A(this.Sa[l]),delete this.Sa[l]);var L=Aa(function(I,M,Ra){var X=ub(I,1);Object.hasOwnProperty.call(y,X)||(y[X]=n());M=b(M,Ra);M=[y[X]].concat(M);try{y[X]=t.apply(null,M)}catch(Fc){delete y[X],va(I,Fc,-1)}},"viii"),J=Aa(function(I){var M=ub(I,1);try{var Ra=r(y[M])}catch(X){delete y[M];va(I,X,-1);return}a(I,Ra);delete y[M]},"vi");this.Sa[g]=L;this.Sa[l]=J;this.handleError(tb(this.db,g,t.length-1,1,0,0,L,J,0));return this};e.prototype.updateHook=function(g){this.Ya&&
|
|
120
|
-
(vb(this.db,0,0),A(this.Ya),this.Ya=void 0);g&&(this.Ya=Aa(function(l,n,r,t,y){switch(n){case 18:l="insert";break;case 23:l="update";break;case 9:l="delete";break;default:throw"unknown operationCode in updateHook callback: "+n;}r=r?B(x,r):"";t=t?B(x,t):"";if(y>Number.MAX_SAFE_INTEGER)throw"rowId too big to fit inside a Number";g(l,r,t,Number(y))},"viiiij"),vb(this.db,this.Ya,0))};f.Database=e};var Ba={...f},Ca="./this.program",Da=(a,b)=>{throw b;},D="",Ea,Fa;
|
|
121
|
-
if(ca){var fs=require("fs");require("path");D=__dirname+"/";Fa=a=>{a=Ga(a)?new URL(a):a;return fs.readFileSync(a)};Ea=async a=>{a=Ga(a)?new URL(a):a;return fs.readFileSync(a,void 0)};!f.thisProgram&&1<process.argv.length&&(Ca=process.argv[1].replace(/\\/g,"/"));process.argv.slice(2);"undefined"!=typeof module&&(module.exports=f);Da=(a,b)=>{process.exitCode=a;throw b;}}else if(aa||ba)ba?D=self.location.href:"undefined"!=typeof document&&document.currentScript&&(D=document.currentScript.src),D=D.startsWith("blob:")?
|
|
122
|
-
"":D.slice(0,D.replace(/[?#].*/,"").lastIndexOf("/")+1),ba&&(Fa=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)}),Ea=async a=>{if(Ga(a))return new Promise((c,d)=>{var e=new XMLHttpRequest;e.open("GET",a,!0);e.responseType="arraybuffer";e.onload=()=>{200==e.status||0==e.status&&e.response?c(e.response):d(e.status)};e.onerror=d;e.send(null)});var b=await fetch(a,{credentials:"same-origin"});if(b.ok)return b.arrayBuffer();throw Error(b.status+
|
|
123
|
-
" : "+b.url);};var Ha=f.print||console.log.bind(console),Ia=f.printErr||console.error.bind(console);Object.assign(f,Ba);Ba=null;f.thisProgram&&(Ca=f.thisProgram);var Ja=f.wasmBinary,Ka,La=!1,Ma,p,x,Na,E,F,Oa,H,Pa,Ga=a=>a.startsWith("file://");
|
|
124
|
-
function Qa(){var a=Ka.buffer;f.HEAP8=p=new Int8Array(a);f.HEAP16=Na=new Int16Array(a);f.HEAPU8=x=new Uint8Array(a);f.HEAPU16=new Uint16Array(a);f.HEAP32=E=new Int32Array(a);f.HEAPU32=F=new Uint32Array(a);f.HEAPF32=Oa=new Float32Array(a);f.HEAPF64=Pa=new Float64Array(a);f.HEAP64=H=new BigInt64Array(a);f.HEAPU64=new BigUint64Array(a)}var K=0,Sa=null;function Ta(a){f.onAbort?.(a);a="Aborted("+a+")";Ia(a);La=!0;throw new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info.");}var Ua;
|
|
125
|
-
async function Va(a){if(!Ja)try{var b=await Ea(a);return new Uint8Array(b)}catch{}if(a==Ua&&Ja)a=new Uint8Array(Ja);else if(Fa)a=Fa(a);else throw"both async and sync fetching of the wasm failed";return a}async function Wa(a,b){try{var c=await Va(a);return await WebAssembly.instantiate(c,b)}catch(d){Ia(`failed to asynchronously prepare wasm: ${d}`),Ta(d)}}
|
|
126
|
-
async function Xa(a){var b=Ua;if(!Ja&&"function"==typeof WebAssembly.instantiateStreaming&&!Ga(b)&&!ca)try{var c=fetch(b,{credentials:"same-origin"});return await WebAssembly.instantiateStreaming(c,a)}catch(d){Ia(`wasm streaming compile failed: ${d}`),Ia("falling back to ArrayBuffer instantiation")}return Wa(b,a)}class Ya{name="ExitStatus";constructor(a){this.message=`Program terminated with exit(${a})`;this.status=a}}
|
|
127
|
-
var Za=a=>{for(;0<a.length;)a.shift()(f)},$a=[],ab=[],bb=()=>{var a=f.preRun.shift();ab.unshift(a)};function m(a,b="i8"){b.endsWith("*")&&(b="*");switch(b){case "i1":return p[a];case "i8":return p[a];case "i16":return Na[a>>1];case "i32":return E[a>>2];case "i64":return H[a>>3];case "float":return Oa[a>>2];case "double":return Pa[a>>3];case "*":return F[a>>2];default:Ta(`invalid type for getValue: ${b}`)}}var cb=f.noExitRuntime||!0;
|
|
128
|
-
function ta(a){var b="i32";b.endsWith("*")&&(b="*");switch(b){case "i1":p[a]=0;break;case "i8":p[a]=0;break;case "i16":Na[a>>1]=0;break;case "i32":E[a>>2]=0;break;case "i64":H[a>>3]=BigInt(0);break;case "float":Oa[a>>2]=0;break;case "double":Pa[a>>3]=0;break;case "*":F[a>>2]=0;break;default:Ta(`invalid type for setValue: ${b}`)}}
|
|
129
|
-
var db="undefined"!=typeof TextDecoder?new TextDecoder:void 0,B=(a,b=0,c=NaN)=>{var d=b+c;for(c=b;a[c]&&!(c>=d);)++c;if(16<c-b&&a.buffer&&db)return db.decode(a.subarray(b,c));for(d="";b<c;){var e=a[b++];if(e&128){var h=a[b++]&63;if(192==(e&224))d+=String.fromCharCode((e&31)<<6|h);else{var k=a[b++]&63;e=224==(e&240)?(e&15)<<12|h<<6|k:(e&7)<<18|h<<12|k<<6|a[b++]&63;65536>e?d+=String.fromCharCode(e):(e-=65536,d+=String.fromCharCode(55296|e>>10,56320|e&1023))}}else d+=String.fromCharCode(e)}return d},
|
|
130
|
-
ua=(a,b)=>a?B(x,a,b):"",eb=(a,b)=>{for(var c=0,d=a.length-1;0<=d;d--){var e=a[d];"."===e?a.splice(d,1):".."===e?(a.splice(d,1),c++):c&&(a.splice(d,1),c--)}if(b)for(;c;c--)a.unshift("..");return a},ka=a=>{var b="/"===a.charAt(0),c="/"===a.slice(-1);(a=eb(a.split("/").filter(d=>!!d),!b).join("/"))||b||(a=".");a&&c&&(a+="/");return(b?"/":"")+a},fb=a=>{var b=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(a).slice(1);a=b[0];b=b[1];if(!a&&!b)return".";b&&=b.slice(0,-1);return a+b},
|
|
131
|
-
gb=a=>a&&a.match(/([^\/]+|\/)\/*$/)[1],hb=()=>{if(ca){var a=require("crypto");return b=>a.randomFillSync(b)}return b=>crypto.getRandomValues(b)},ib=a=>{(ib=hb())(a)},jb=(...a)=>{for(var b="",c=!1,d=a.length-1;-1<=d&&!c;d--){c=0<=d?a[d]:"/";if("string"!=typeof c)throw new TypeError("Arguments to path.resolve must be strings");if(!c)return"";b=c+"/"+b;c="/"===c.charAt(0)}b=eb(b.split("/").filter(e=>!!e),!c).join("/");return(c?"/":"")+b||"."},kb=[],ha=a=>{for(var b=0,c=0;c<a.length;++c){var d=a.charCodeAt(c);
|
|
132
|
-
127>=d?b++:2047>=d?b+=2:55296<=d&&57343>=d?(b+=4,++c):b+=3}return b},u=(a,b,c,d)=>{if(!(0<d))return 0;var e=c;d=c+d-1;for(var h=0;h<a.length;++h){var k=a.charCodeAt(h);if(55296<=k&&57343>=k){var q=a.charCodeAt(++h);k=65536+((k&1023)<<10)|q&1023}if(127>=k){if(c>=d)break;b[c++]=k}else{if(2047>=k){if(c+1>=d)break;b[c++]=192|k>>6}else{if(65535>=k){if(c+2>=d)break;b[c++]=224|k>>12}else{if(c+3>=d)break;b[c++]=240|k>>18;b[c++]=128|k>>12&63}b[c++]=128|k>>6&63}b[c++]=128|k&63}}b[c]=0;return c-e},ra=(a,b)=>
|
|
133
|
-
{var c=Array(ha(a)+1);a=u(a,c,0,c.length);b&&(c.length=a);return c},mb=[];function nb(a,b){mb[a]={input:[],output:[],cb:b};wb(a,xb)}
|
|
134
|
-
var xb={open(a){var b=mb[a.node.rdev];if(!b)throw new N(43);a.tty=b;a.seekable=!1},close(a){a.tty.cb.fsync(a.tty)},fsync(a){a.tty.cb.fsync(a.tty)},read(a,b,c,d){if(!a.tty||!a.tty.cb.xb)throw new N(60);for(var e=0,h=0;h<d;h++){try{var k=a.tty.cb.xb(a.tty)}catch(q){throw new N(29);}if(void 0===k&&0===e)throw new N(6);if(null===k||void 0===k)break;e++;b[c+h]=k}e&&(a.node.atime=Date.now());return e},write(a,b,c,d){if(!a.tty||!a.tty.cb.qb)throw new N(60);try{for(var e=0;e<d;e++)a.tty.cb.qb(a.tty,b[c+e])}catch(h){throw new N(29);
|
|
135
|
-
}d&&(a.node.mtime=a.node.ctime=Date.now());return e}},yb={xb(){a:{if(!kb.length){var a=null;if(ca){var b=Buffer.alloc(256),c=0,d=process.stdin.fd;try{c=fs.readSync(d,b,0,256)}catch(e){if(e.toString().includes("EOF"))c=0;else throw e;}0<c&&(a=b.slice(0,c).toString("utf-8"))}else"undefined"!=typeof window&&"function"==typeof window.prompt&&(a=window.prompt("Input: "),null!==a&&(a+="\n"));if(!a){a=null;break a}kb=ra(a,!0)}a=kb.shift()}return a},qb(a,b){null===b||10===b?(Ha(B(a.output)),a.output=[]):
|
|
136
|
-
0!=b&&a.output.push(b)},fsync(a){0<a.output?.length&&(Ha(B(a.output)),a.output=[])},Tb(){return{Ob:25856,Qb:5,Nb:191,Pb:35387,Mb:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},Ub(){return 0},Vb(){return[24,80]}},zb={qb(a,b){null===b||10===b?(Ia(B(a.output)),a.output=[]):0!=b&&a.output.push(b)},fsync(a){0<a.output?.length&&(Ia(B(a.output)),a.output=[])}},O={Wa:null,Xa(){return O.createNode(null,"/",16895,0)},createNode(a,b,c,d){if(24576===(c&61440)||4096===(c&61440))throw new N(63);
|
|
137
|
-
O.Wa||(O.Wa={dir:{node:{Ta:O.La.Ta,Ua:O.La.Ua,lookup:O.La.lookup,hb:O.La.hb,rename:O.La.rename,unlink:O.La.unlink,rmdir:O.La.rmdir,readdir:O.La.readdir,symlink:O.La.symlink},stream:{Va:O.Ma.Va}},file:{node:{Ta:O.La.Ta,Ua:O.La.Ua},stream:{Va:O.Ma.Va,read:O.Ma.read,write:O.Ma.write,ib:O.Ma.ib,jb:O.Ma.jb}},link:{node:{Ta:O.La.Ta,Ua:O.La.Ua,readlink:O.La.readlink},stream:{}},ub:{node:{Ta:O.La.Ta,Ua:O.La.Ua},stream:Ab}});c=Bb(a,b,c,d);P(c.mode)?(c.La=O.Wa.dir.node,c.Ma=O.Wa.dir.stream,c.Na={}):32768===
|
|
138
|
-
(c.mode&61440)?(c.La=O.Wa.file.node,c.Ma=O.Wa.file.stream,c.Ra=0,c.Na=null):40960===(c.mode&61440)?(c.La=O.Wa.link.node,c.Ma=O.Wa.link.stream):8192===(c.mode&61440)&&(c.La=O.Wa.ub.node,c.Ma=O.Wa.ub.stream);c.atime=c.mtime=c.ctime=Date.now();a&&(a.Na[b]=c,a.atime=a.mtime=a.ctime=c.atime);return c},Sb(a){return a.Na?a.Na.subarray?a.Na.subarray(0,a.Ra):new Uint8Array(a.Na):new Uint8Array(0)},La:{Ta(a){var b={};b.dev=8192===(a.mode&61440)?a.id:1;b.ino=a.id;b.mode=a.mode;b.nlink=1;b.uid=0;b.gid=0;b.rdev=
|
|
139
|
-
a.rdev;P(a.mode)?b.size=4096:32768===(a.mode&61440)?b.size=a.Ra:40960===(a.mode&61440)?b.size=a.link.length:b.size=0;b.atime=new Date(a.atime);b.mtime=new Date(a.mtime);b.ctime=new Date(a.ctime);b.blksize=4096;b.blocks=Math.ceil(b.size/b.blksize);return b},Ua(a,b){for(var c of["mode","atime","mtime","ctime"])null!=b[c]&&(a[c]=b[c]);void 0!==b.size&&(b=b.size,a.Ra!=b&&(0==b?(a.Na=null,a.Ra=0):(c=a.Na,a.Na=new Uint8Array(b),c&&a.Na.set(c.subarray(0,Math.min(b,a.Ra))),a.Ra=b)))},lookup(){throw O.vb;
|
|
140
|
-
},hb(a,b,c,d){return O.createNode(a,b,c,d)},rename(a,b,c){try{var d=Q(b,c)}catch(h){}if(d){if(P(a.mode))for(var e in d.Na)throw new N(55);Cb(d)}delete a.parent.Na[a.name];b.Na[c]=a;a.name=c;b.ctime=b.mtime=a.parent.ctime=a.parent.mtime=Date.now()},unlink(a,b){delete a.Na[b];a.ctime=a.mtime=Date.now()},rmdir(a,b){var c=Q(a,b),d;for(d in c.Na)throw new N(55);delete a.Na[b];a.ctime=a.mtime=Date.now()},readdir(a){return[".","..",...Object.keys(a.Na)]},symlink(a,b,c){a=O.createNode(a,b,41471,0);a.link=
|
|
141
|
-
c;return a},readlink(a){if(40960!==(a.mode&61440))throw new N(28);return a.link}},Ma:{read(a,b,c,d,e){var h=a.node.Na;if(e>=a.node.Ra)return 0;a=Math.min(a.node.Ra-e,d);if(8<a&&h.subarray)b.set(h.subarray(e,e+a),c);else for(d=0;d<a;d++)b[c+d]=h[e+d];return a},write(a,b,c,d,e,h){b.buffer===p.buffer&&(h=!1);if(!d)return 0;a=a.node;a.mtime=a.ctime=Date.now();if(b.subarray&&(!a.Na||a.Na.subarray)){if(h)return a.Na=b.subarray(c,c+d),a.Ra=d;if(0===a.Ra&&0===e)return a.Na=b.slice(c,c+d),a.Ra=d;if(e+d<=a.Ra)return a.Na.set(b.subarray(c,
|
|
142
|
-
c+d),e),d}h=e+d;var k=a.Na?a.Na.length:0;k>=h||(h=Math.max(h,k*(1048576>k?2:1.125)>>>0),0!=k&&(h=Math.max(h,256)),k=a.Na,a.Na=new Uint8Array(h),0<a.Ra&&a.Na.set(k.subarray(0,a.Ra),0));if(a.Na.subarray&&b.subarray)a.Na.set(b.subarray(c,c+d),e);else for(h=0;h<d;h++)a.Na[e+h]=b[c+h];a.Ra=Math.max(a.Ra,e+d);return d},Va(a,b,c){1===c?b+=a.position:2===c&&32768===(a.node.mode&61440)&&(b+=a.node.Ra);if(0>b)throw new N(28);return b},ib(a,b,c,d,e){if(32768!==(a.node.mode&61440))throw new N(43);a=a.node.Na;
|
|
143
|
-
if(e&2||!a||a.buffer!==p.buffer){e=!0;d=65536*Math.ceil(b/65536);var h=Db(65536,d);h&&x.fill(0,h,h+d);d=h;if(!d)throw new N(48);if(a){if(0<c||c+b<a.length)a.subarray?a=a.subarray(c,c+b):a=Array.prototype.slice.call(a,c,c+b);p.set(a,d)}}else e=!1,d=a.byteOffset;return{Kb:d,Ab:e}},jb(a,b,c,d){O.Ma.write(a,b,0,d,c,!1);return 0}}},la=(a,b)=>{var c=0;a&&(c|=365);b&&(c|=146);return c},Eb=null,Fb={},Gb=[],Hb=1,R=null,Ib=!1,Jb=!0,Kb={},N=class{name="ErrnoError";constructor(a){this.Pa=a}},Lb=class{gb={};node=null;get flags(){return this.gb.flags}set flags(a){this.gb.flags=
|
|
144
|
-
a}get position(){return this.gb.position}set position(a){this.gb.position=a}},Mb=class{La={};Ma={};ab=null;constructor(a,b,c,d){a||=this;this.parent=a;this.Xa=a.Xa;this.id=Hb++;this.name=b;this.mode=c;this.rdev=d;this.atime=this.mtime=this.ctime=Date.now()}get read(){return 365===(this.mode&365)}set read(a){a?this.mode|=365:this.mode&=-366}get write(){return 146===(this.mode&146)}set write(a){a?this.mode|=146:this.mode&=-147}};
|
|
145
|
-
function S(a,b={}){if(!a)throw new N(44);b.nb??(b.nb=!0);"/"===a.charAt(0)||(a="//"+a);var c=0;a:for(;40>c;c++){a=a.split("/").filter(q=>!!q);for(var d=Eb,e="/",h=0;h<a.length;h++){var k=h===a.length-1;if(k&&b.parent)break;if("."!==a[h])if(".."===a[h])e=fb(e),d=d.parent;else{e=ka(e+"/"+a[h]);try{d=Q(d,a[h])}catch(q){if(44===q?.Pa&&k&&b.Jb)return{path:e};throw q;}!d.ab||k&&!b.nb||(d=d.ab.root);if(40960===(d.mode&61440)&&(!k||b.$a)){if(!d.La.readlink)throw new N(52);d=d.La.readlink(d);"/"===d.charAt(0)||
|
|
146
|
-
(d=fb(e)+"/"+d);a=d+"/"+a.slice(h+1).join("/");continue a}}}return{path:e,node:d}}throw new N(32);}function ja(a){for(var b;;){if(a===a.parent)return a=a.Xa.zb,b?"/"!==a[a.length-1]?`${a}/${b}`:a+b:a;b=b?`${a.name}/${b}`:a.name;a=a.parent}}function Nb(a,b){for(var c=0,d=0;d<b.length;d++)c=(c<<5)-c+b.charCodeAt(d)|0;return(a+c>>>0)%R.length}function Cb(a){var b=Nb(a.parent.id,a.name);if(R[b]===a)R[b]=a.bb;else for(b=R[b];b;){if(b.bb===a){b.bb=a.bb;break}b=b.bb}}
|
|
147
|
-
function Q(a,b){var c=P(a.mode)?(c=Ob(a,"x"))?c:a.La.lookup?0:2:54;if(c)throw new N(c);for(c=R[Nb(a.id,b)];c;c=c.bb){var d=c.name;if(c.parent.id===a.id&&d===b)return c}return a.La.lookup(a,b)}function Bb(a,b,c,d){a=new Mb(a,b,c,d);b=Nb(a.parent.id,a.name);a.bb=R[b];return R[b]=a}function P(a){return 16384===(a&61440)}function Pb(a){var b=["r","w","rw"][a&3];a&512&&(b+="w");return b}
|
|
148
|
-
function Ob(a,b){if(Jb)return 0;if(!b.includes("r")||a.mode&292){if(b.includes("w")&&!(a.mode&146)||b.includes("x")&&!(a.mode&73))return 2}else return 2;return 0}function Qb(a,b){if(!P(a.mode))return 54;try{return Q(a,b),20}catch(c){}return Ob(a,"wx")}function Rb(a,b,c){try{var d=Q(a,b)}catch(e){return e.Pa}if(a=Ob(a,"wx"))return a;if(c){if(!P(d.mode))return 54;if(d===d.parent||"/"===ja(d))return 10}else if(P(d.mode))return 31;return 0}function Sb(a){if(!a)throw new N(63);return a}
|
|
149
|
-
function T(a){a=Gb[a];if(!a)throw new N(8);return a}function Tb(a,b=-1){a=Object.assign(new Lb,a);if(-1==b)a:{for(b=0;4096>=b;b++)if(!Gb[b])break a;throw new N(33);}a.fd=b;return Gb[b]=a}function Ub(a,b=-1){a=Tb(a,b);a.Ma?.Rb?.(a);return a}function Vb(a,b,c){var d=a?.Ma.Ua;a=d?a:b;d??=b.La.Ua;Sb(d);d(a,c)}var Ab={open(a){a.Ma=Fb[a.node.rdev].Ma;a.Ma.open?.(a)},Va(){throw new N(70);}};function wb(a,b){Fb[a]={Ma:b}}
|
|
150
|
-
function Wb(a,b){var c="/"===b;if(c&&Eb)throw new N(10);if(!c&&b){var d=S(b,{nb:!1});b=d.path;d=d.node;if(d.ab)throw new N(10);if(!P(d.mode))throw new N(54);}b={type:a,Wb:{},zb:b,Ib:[]};a=a.Xa(b);a.Xa=b;b.root=a;c?Eb=a:d&&(d.ab=b,d.Xa&&d.Xa.Ib.push(b))}function Xb(a,b,c){var d=S(a,{parent:!0}).node;a=gb(a);if(!a)throw new N(28);if("."===a||".."===a)throw new N(20);var e=Qb(d,a);if(e)throw new N(e);if(!d.La.hb)throw new N(63);return d.La.hb(d,a,b,c)}
|
|
151
|
-
function ma(a,b=438){return Xb(a,b&4095|32768,0)}function U(a,b=511){return Xb(a,b&1023|16384,0)}function Yb(a,b,c){"undefined"==typeof c&&(c=b,b=438);Xb(a,b|8192,c)}function Zb(a,b){if(!jb(a))throw new N(44);var c=S(b,{parent:!0}).node;if(!c)throw new N(44);b=gb(b);var d=Qb(c,b);if(d)throw new N(d);if(!c.La.symlink)throw new N(63);c.La.symlink(c,b,a)}
|
|
152
|
-
function $b(a){var b=S(a,{parent:!0}).node;a=gb(a);var c=Q(b,a),d=Rb(b,a,!0);if(d)throw new N(d);if(!b.La.rmdir)throw new N(63);if(c.ab)throw new N(10);b.La.rmdir(b,a);Cb(c)}function za(a){var b=S(a,{parent:!0}).node;if(!b)throw new N(44);a=gb(a);var c=Q(b,a),d=Rb(b,a,!1);if(d)throw new N(d);if(!b.La.unlink)throw new N(63);if(c.ab)throw new N(10);b.La.unlink(b,a);Cb(c)}function ac(a,b){a=S(a,{$a:!b}).node;return Sb(a.La.Ta)(a)}
|
|
153
|
-
function bc(a,b,c,d){Vb(a,b,{mode:c&4095|b.mode&-4096,ctime:Date.now(),Fb:d})}function na(a,b){a="string"==typeof a?S(a,{$a:!0}).node:a;bc(null,a,b)}function cc(a,b,c){if(P(b.mode))throw new N(31);if(32768!==(b.mode&61440))throw new N(28);var d=Ob(b,"w");if(d)throw new N(d);Vb(a,b,{size:c,timestamp:Date.now()})}
|
|
154
|
-
function oa(a,b,c=438){if(""===a)throw new N(44);if("string"==typeof b){var d={r:0,"r+":2,w:577,"w+":578,a:1089,"a+":1090}[b];if("undefined"==typeof d)throw Error(`Unknown file open mode: ${b}`);b=d}c=b&64?c&4095|32768:0;if("object"==typeof a)d=a;else{var e=a.endsWith("/");a=S(a,{$a:!(b&131072),Jb:!0});d=a.node;a=a.path}var h=!1;if(b&64)if(d){if(b&128)throw new N(20);}else{if(e)throw new N(31);d=Xb(a,c|511,0);h=!0}if(!d)throw new N(44);8192===(d.mode&61440)&&(b&=-513);if(b&65536&&!P(d.mode))throw new N(54);
|
|
155
|
-
if(!h&&(e=d?40960===(d.mode&61440)?32:P(d.mode)&&("r"!==Pb(b)||b&576)?31:Ob(d,Pb(b)):44))throw new N(e);b&512&&!h&&(e=d,e="string"==typeof e?S(e,{$a:!0}).node:e,cc(null,e,0));b&=-131713;e=Tb({node:d,path:ja(d),flags:b,seekable:!0,position:0,Ma:d.Ma,Lb:[],error:!1});e.Ma.open&&e.Ma.open(e);h&&na(d,c&511);!f.logReadFiles||b&1||a in Kb||(Kb[a]=1);return e}function qa(a){if(null===a.fd)throw new N(8);a.ob&&(a.ob=null);try{a.Ma.close&&a.Ma.close(a)}catch(b){throw b;}finally{Gb[a.fd]=null}a.fd=null}
|
|
156
|
-
function mc(a,b,c){if(null===a.fd)throw new N(8);if(!a.seekable||!a.Ma.Va)throw new N(70);if(0!=c&&1!=c&&2!=c)throw new N(28);a.position=a.Ma.Va(a,b,c);a.Lb=[]}function Ec(a,b,c,d,e){if(0>d||0>e)throw new N(28);if(null===a.fd)throw new N(8);if(1===(a.flags&2097155))throw new N(8);if(P(a.node.mode))throw new N(31);if(!a.Ma.read)throw new N(28);var h="undefined"!=typeof e;if(!h)e=a.position;else if(!a.seekable)throw new N(70);b=a.Ma.read(a,b,c,d,e);h||(a.position+=b);return b}
|
|
157
|
-
function pa(a,b,c,d,e){if(0>d||0>e)throw new N(28);if(null===a.fd)throw new N(8);if(0===(a.flags&2097155))throw new N(8);if(P(a.node.mode))throw new N(31);if(!a.Ma.write)throw new N(28);a.seekable&&a.flags&1024&&mc(a,0,2);var h="undefined"!=typeof e;if(!h)e=a.position;else if(!a.seekable)throw new N(70);b=a.Ma.write(a,b,c,d,e,void 0);h||(a.position+=b);return b}
|
|
158
|
-
function ya(a){var b="binary";if("utf8"!==b&&"binary"!==b)throw Error(`Invalid encoding type "${b}"`);var c;var d=oa(a,d||0);a=ac(a).size;var e=new Uint8Array(a);Ec(d,e,0,a,0);"utf8"===b?c=B(e):"binary"===b&&(c=e);qa(d);return c}
|
|
159
|
-
function V(a,b,c){a=ka("/dev/"+a);var d=la(!!b,!!c);V.yb??(V.yb=64);var e=V.yb++<<8|0;wb(e,{open(h){h.seekable=!1},close(){c?.buffer?.length&&c(10)},read(h,k,q,w){for(var v=0,C=0;C<w;C++){try{var G=b()}catch(pb){throw new N(29);}if(void 0===G&&0===v)throw new N(6);if(null===G||void 0===G)break;v++;k[q+C]=G}v&&(h.node.atime=Date.now());return v},write(h,k,q,w){for(var v=0;v<w;v++)try{c(k[q+v])}catch(C){throw new N(29);}w&&(h.node.mtime=h.node.ctime=Date.now());return v}});Yb(a,d,e)}var W={};
|
|
160
|
-
function Gc(a,b,c){if("/"===b.charAt(0))return b;a=-100===a?"/":T(a).path;if(0==b.length){if(!c)throw new N(44);return a}return a+"/"+b}
|
|
161
|
-
function Hc(a,b){E[a>>2]=b.dev;E[a+4>>2]=b.mode;F[a+8>>2]=b.nlink;E[a+12>>2]=b.uid;E[a+16>>2]=b.gid;E[a+20>>2]=b.rdev;H[a+24>>3]=BigInt(b.size);E[a+32>>2]=4096;E[a+36>>2]=b.blocks;var c=b.atime.getTime(),d=b.mtime.getTime(),e=b.ctime.getTime();H[a+40>>3]=BigInt(Math.floor(c/1E3));F[a+48>>2]=c%1E3*1E6;H[a+56>>3]=BigInt(Math.floor(d/1E3));F[a+64>>2]=d%1E3*1E6;H[a+72>>3]=BigInt(Math.floor(e/1E3));F[a+80>>2]=e%1E3*1E6;H[a+88>>3]=BigInt(b.ino);return 0}
|
|
162
|
-
var Ic=void 0,Jc=()=>{var a=E[+Ic>>2];Ic+=4;return a},Kc=0,Lc=[0,31,60,91,121,152,182,213,244,274,305,335],Mc=[0,31,59,90,120,151,181,212,243,273,304,334],Nc={},Oc=a=>{Ma=a;cb||0<Kc||(f.onExit?.(a),La=!0);Da(a,new Ya(a))},Pc=a=>{if(!La)try{if(a(),!(cb||0<Kc))try{Ma=a=Ma,Oc(a)}catch(b){b instanceof Ya||"unwind"==b||Da(1,b)}}catch(b){b instanceof Ya||"unwind"==b||Da(1,b)}},Qc={},Sc=()=>{if(!Rc){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"==typeof navigator&&
|
|
163
|
-
navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:Ca||"./this.program"},b;for(b in Qc)void 0===Qc[b]?delete a[b]:a[b]=Qc[b];var c=[];for(b in a)c.push(`${b}=${a[b]}`);Rc=c}return Rc},Rc,xa=a=>{var b=ha(a)+1,c=z(b);u(a,x,c,b);return c},Tc=(a,b,c,d)=>{var e={string:v=>{var C=0;null!==v&&void 0!==v&&0!==v&&(C=xa(v));return C},array:v=>{var C=z(v.length);p.set(v,C);return C}};a=f["_"+a];var h=[],k=0;if(d)for(var q=0;q<d.length;q++){var w=e[c[q]];w?(0===k&&(k=sa()),h[q]=w(d[q])):
|
|
164
|
-
h[q]=d[q]}c=a(...h);return c=function(v){0!==k&&wa(k);return"string"===b?v?B(x,v):"":"boolean"===b?!!v:v}(c)},ea=0,da=(a,b)=>{b=1==b?z(a.length):ia(a.length);a.subarray||a.slice||(a=new Uint8Array(a));x.set(a,b);return b},Uc,Vc=[],Y,A=a=>{Uc.delete(Y.get(a));Y.set(a,null);Vc.push(a)},Aa=(a,b)=>{if(!Uc){Uc=new WeakMap;var c=Y.length;if(Uc)for(var d=0;d<0+c;d++){var e=Y.get(d);e&&Uc.set(e,d)}}if(c=Uc.get(a)||0)return c;if(Vc.length)c=Vc.pop();else{try{Y.grow(1)}catch(w){if(!(w instanceof RangeError))throw w;
|
|
165
|
-
throw"Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.";}c=Y.length-1}try{Y.set(c,a)}catch(w){if(!(w instanceof TypeError))throw w;if("function"==typeof WebAssembly.Function){var h=WebAssembly.Function;d={i:"i32",j:"i64",f:"f32",d:"f64",e:"externref",p:"i32"};e={parameters:[],results:"v"==b[0]?[]:[d[b[0]]]};for(var k=1;k<b.length;++k)e.parameters.push(d[b[k]]);b=new h(e,a)}else{d=[1];e=b.slice(0,1);b=b.slice(1);k={i:127,p:127,j:126,f:125,d:124,e:111};d.push(96);var q=b.length;128>q?d.push(q):d.push(q%
|
|
166
|
-
128|128,q>>7);for(h of b)d.push(k[h]);"v"==e?d.push(0):d.push(1,k[e]);b=[0,97,115,109,1,0,0,0,1];h=d.length;128>h?b.push(h):b.push(h%128|128,h>>7);b.push(...d);b.push(2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);b=new WebAssembly.Module(new Uint8Array(b));b=(new WebAssembly.Instance(b,{e:{f:a}})).exports.f}Y.set(c,b)}Uc.set(a,c);return c};R=Array(4096);Wb(O,"/");U("/tmp");U("/home");U("/home/web_user");
|
|
167
|
-
(function(){U("/dev");wb(259,{read:()=>0,write:(d,e,h,k)=>k,Va:()=>0});Yb("/dev/null",259);nb(1280,yb);nb(1536,zb);Yb("/dev/tty",1280);Yb("/dev/tty1",1536);var a=new Uint8Array(1024),b=0,c=()=>{0===b&&(ib(a),b=a.byteLength);return a[--b]};V("random",c);V("urandom",c);U("/dev/shm");U("/dev/shm/tmp")})();
|
|
168
|
-
(function(){U("/proc");var a=U("/proc/self");U("/proc/self/fd");Wb({Xa(){var b=Bb(a,"fd",16895,73);b.Ma={Va:O.Ma.Va};b.La={lookup(c,d){c=+d;var e=T(c);c={parent:null,Xa:{zb:"fake"},La:{readlink:()=>e.path},id:c+1};return c.parent=c},readdir(){return Array.from(Gb.entries()).filter(([,c])=>c).map(([c])=>c.toString())}};return b}},"/proc/self/fd")})();O.vb=new N(44);O.vb.stack="<generic error, no stack>";
|
|
169
|
-
var Xc={a:(a,b,c,d)=>Ta(`Assertion failed: ${a?B(x,a):""}, at: `+[b?b?B(x,b):"":"unknown filename",c,d?d?B(x,d):"":"unknown function"]),i:function(a,b){try{return a=a?B(x,a):"",na(a,b),0}catch(c){if("undefined"==typeof W||"ErrnoError"!==c.name)throw c;return-c.Pa}},L:function(a,b,c){try{b=b?B(x,b):"";b=Gc(a,b);if(c&-8)return-28;var d=S(b,{$a:!0}).node;if(!d)return-44;a="";c&4&&(a+="r");c&2&&(a+="w");c&1&&(a+="x");return a&&Ob(d,a)?-2:0}catch(e){if("undefined"==typeof W||"ErrnoError"!==e.name)throw e;
|
|
170
|
-
return-e.Pa}},j:function(a,b){try{var c=T(a);bc(c,c.node,b,!1);return 0}catch(d){if("undefined"==typeof W||"ErrnoError"!==d.name)throw d;return-d.Pa}},h:function(a){try{var b=T(a);Vb(b,b.node,{timestamp:Date.now(),Fb:!1});return 0}catch(c){if("undefined"==typeof W||"ErrnoError"!==c.name)throw c;return-c.Pa}},b:function(a,b,c){Ic=c;try{var d=T(a);switch(b){case 0:var e=Jc();if(0>e)break;for(;Gb[e];)e++;return Ub(d,e).fd;case 1:case 2:return 0;case 3:return d.flags;case 4:return e=Jc(),d.flags|=e,0;
|
|
171
|
-
case 12:return e=Jc(),Na[e+0>>1]=2,0;case 13:case 14:return 0}return-28}catch(h){if("undefined"==typeof W||"ErrnoError"!==h.name)throw h;return-h.Pa}},g:function(a,b){try{var c=T(a),d=c.node,e=c.Ma.Ta;a=e?c:d;e??=d.La.Ta;Sb(e);var h=e(a);return Hc(b,h)}catch(k){if("undefined"==typeof W||"ErrnoError"!==k.name)throw k;return-k.Pa}},H:function(a,b){b=-9007199254740992>b||9007199254740992<b?NaN:Number(b);try{if(isNaN(b))return 61;var c=T(a);if(0>b||0===(c.flags&2097155))throw new N(28);cc(c,c.node,b);
|
|
172
|
-
return 0}catch(d){if("undefined"==typeof W||"ErrnoError"!==d.name)throw d;return-d.Pa}},G:function(a,b){try{if(0===b)return-28;var c=ha("/")+1;if(b<c)return-68;u("/",x,a,b);return c}catch(d){if("undefined"==typeof W||"ErrnoError"!==d.name)throw d;return-d.Pa}},K:function(a,b){try{return a=a?B(x,a):"",Hc(b,ac(a,!0))}catch(c){if("undefined"==typeof W||"ErrnoError"!==c.name)throw c;return-c.Pa}},C:function(a,b,c){try{return b=b?B(x,b):"",b=Gc(a,b),U(b,c),0}catch(d){if("undefined"==typeof W||"ErrnoError"!==
|
|
173
|
-
d.name)throw d;return-d.Pa}},J:function(a,b,c,d){try{b=b?B(x,b):"";var e=d&256;b=Gc(a,b,d&4096);return Hc(c,e?ac(b,!0):ac(b))}catch(h){if("undefined"==typeof W||"ErrnoError"!==h.name)throw h;return-h.Pa}},x:function(a,b,c,d){Ic=d;try{b=b?B(x,b):"";b=Gc(a,b);var e=d?Jc():0;return oa(b,c,e).fd}catch(h){if("undefined"==typeof W||"ErrnoError"!==h.name)throw h;return-h.Pa}},v:function(a,b,c,d){try{b=b?B(x,b):"";b=Gc(a,b);if(0>=d)return-28;var e=S(b).node;if(!e)throw new N(44);if(!e.La.readlink)throw new N(28);
|
|
174
|
-
var h=e.La.readlink(e);var k=Math.min(d,ha(h)),q=p[c+k];u(h,x,c,d+1);p[c+k]=q;return k}catch(w){if("undefined"==typeof W||"ErrnoError"!==w.name)throw w;return-w.Pa}},u:function(a){try{return a=a?B(x,a):"",$b(a),0}catch(b){if("undefined"==typeof W||"ErrnoError"!==b.name)throw b;return-b.Pa}},f:function(a,b){try{return a=a?B(x,a):"",Hc(b,ac(a))}catch(c){if("undefined"==typeof W||"ErrnoError"!==c.name)throw c;return-c.Pa}},r:function(a,b,c){try{return b=b?B(x,b):"",b=Gc(a,b),0===c?za(b):512===c?$b(b):
|
|
175
|
-
Ta("Invalid flags passed to unlinkat"),0}catch(d){if("undefined"==typeof W||"ErrnoError"!==d.name)throw d;return-d.Pa}},q:function(a,b,c){try{b=b?B(x,b):"";b=Gc(a,b,!0);var d=Date.now(),e,h;if(c){var k=F[c>>2]+4294967296*E[c+4>>2],q=E[c+8>>2];1073741823==q?e=d:1073741822==q?e=null:e=1E3*k+q/1E6;c+=16;k=F[c>>2]+4294967296*E[c+4>>2];q=E[c+8>>2];1073741823==q?h=d:1073741822==q?h=null:h=1E3*k+q/1E6}else h=e=d;if(null!==(h??e)){a=e;var w=S(b,{$a:!0}).node;Sb(w.La.Ua)(w,{atime:a,mtime:h})}return 0}catch(v){if("undefined"==
|
|
176
|
-
typeof W||"ErrnoError"!==v.name)throw v;return-v.Pa}},m:()=>Ta(""),l:()=>{cb=!1;Kc=0},A:function(a,b){a=-9007199254740992>a||9007199254740992<a?NaN:Number(a);a=new Date(1E3*a);E[b>>2]=a.getSeconds();E[b+4>>2]=a.getMinutes();E[b+8>>2]=a.getHours();E[b+12>>2]=a.getDate();E[b+16>>2]=a.getMonth();E[b+20>>2]=a.getFullYear()-1900;E[b+24>>2]=a.getDay();var c=a.getFullYear();E[b+28>>2]=(0!==c%4||0===c%100&&0!==c%400?Mc:Lc)[a.getMonth()]+a.getDate()-1|0;E[b+36>>2]=-(60*a.getTimezoneOffset());c=(new Date(a.getFullYear(),
|
|
177
|
-
6,1)).getTimezoneOffset();var d=(new Date(a.getFullYear(),0,1)).getTimezoneOffset();E[b+32>>2]=(c!=d&&a.getTimezoneOffset()==Math.min(d,c))|0},y:function(a,b,c,d,e,h,k){e=-9007199254740992>e||9007199254740992<e?NaN:Number(e);try{if(isNaN(e))return 61;var q=T(d);if(0!==(b&2)&&0===(c&2)&&2!==(q.flags&2097155))throw new N(2);if(1===(q.flags&2097155))throw new N(2);if(!q.Ma.ib)throw new N(43);if(!a)throw new N(28);var w=q.Ma.ib(q,a,e,b,c);var v=w.Kb;E[h>>2]=w.Ab;F[k>>2]=v;return 0}catch(C){if("undefined"==
|
|
178
|
-
typeof W||"ErrnoError"!==C.name)throw C;return-C.Pa}},z:function(a,b,c,d,e,h){h=-9007199254740992>h||9007199254740992<h?NaN:Number(h);try{var k=T(e);if(c&2){c=h;if(32768!==(k.node.mode&61440))throw new N(43);if(!(d&2)){var q=x.slice(a,a+b);k.Ma.jb&&k.Ma.jb(k,q,c,b,d)}}}catch(w){if("undefined"==typeof W||"ErrnoError"!==w.name)throw w;return-w.Pa}},n:(a,b)=>{Nc[a]&&(clearTimeout(Nc[a].id),delete Nc[a]);if(!b)return 0;var c=setTimeout(()=>{delete Nc[a];Pc(()=>Wc(a,performance.now()))},b);Nc[a]={id:c,
|
|
179
|
-
Xb:b};return 0},B:(a,b,c,d)=>{var e=(new Date).getFullYear(),h=(new Date(e,0,1)).getTimezoneOffset();e=(new Date(e,6,1)).getTimezoneOffset();F[a>>2]=60*Math.max(h,e);E[b>>2]=Number(h!=e);b=k=>{var q=Math.abs(k);return`UTC${0<=k?"-":"+"}${String(Math.floor(q/60)).padStart(2,"0")}${String(q%60).padStart(2,"0")}`};a=b(h);b=b(e);e<h?(u(a,x,c,17),u(b,x,d,17)):(u(a,x,d,17),u(b,x,c,17))},d:()=>Date.now(),s:()=>2147483648,c:()=>performance.now(),o:a=>{var b=x.length;a>>>=0;if(2147483648<a)return!1;for(var c=
|
|
180
|
-
1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,a+100663296);a:{d=(Math.min(2147483648,65536*Math.ceil(Math.max(a,d)/65536))-Ka.buffer.byteLength+65535)/65536|0;try{Ka.grow(d);Qa();var e=1;break a}catch(h){}e=void 0}if(e)return!0}return!1},E:(a,b)=>{var c=0;Sc().forEach((d,e)=>{var h=b+c;e=F[a+4*e>>2]=h;for(h=0;h<d.length;++h)p[e++]=d.charCodeAt(h);p[e]=0;c+=d.length+1});return 0},F:(a,b)=>{var c=Sc();F[a>>2]=c.length;var d=0;c.forEach(e=>d+=e.length+1);F[b>>2]=d;return 0},e:function(a){try{var b=T(a);
|
|
181
|
-
qa(b);return 0}catch(c){if("undefined"==typeof W||"ErrnoError"!==c.name)throw c;return c.Pa}},p:function(a,b){try{var c=T(a);p[b]=c.tty?2:P(c.mode)?3:40960===(c.mode&61440)?7:4;Na[b+2>>1]=0;H[b+8>>3]=BigInt(0);H[b+16>>3]=BigInt(0);return 0}catch(d){if("undefined"==typeof W||"ErrnoError"!==d.name)throw d;return d.Pa}},w:function(a,b,c,d){try{a:{var e=T(a);a=b;for(var h,k=b=0;k<c;k++){var q=F[a>>2],w=F[a+4>>2];a+=8;var v=Ec(e,p,q,w,h);if(0>v){var C=-1;break a}b+=v;if(v<w)break;"undefined"!=typeof h&&
|
|
182
|
-
(h+=v)}C=b}F[d>>2]=C;return 0}catch(G){if("undefined"==typeof W||"ErrnoError"!==G.name)throw G;return G.Pa}},D:function(a,b,c,d){b=-9007199254740992>b||9007199254740992<b?NaN:Number(b);try{if(isNaN(b))return 61;var e=T(a);mc(e,b,c);H[d>>3]=BigInt(e.position);e.ob&&0===b&&0===c&&(e.ob=null);return 0}catch(h){if("undefined"==typeof W||"ErrnoError"!==h.name)throw h;return h.Pa}},I:function(a){try{var b=T(a);return b.Ma?.fsync?b.Ma.fsync(b):0}catch(c){if("undefined"==typeof W||"ErrnoError"!==c.name)throw c;
|
|
183
|
-
return c.Pa}},t:function(a,b,c,d){try{a:{var e=T(a);a=b;for(var h,k=b=0;k<c;k++){var q=F[a>>2],w=F[a+4>>2];a+=8;var v=pa(e,p,q,w,h);if(0>v){var C=-1;break a}b+=v;if(v<w)break;"undefined"!=typeof h&&(h+=v)}C=b}F[d>>2]=C;return 0}catch(G){if("undefined"==typeof W||"ErrnoError"!==G.name)throw G;return G.Pa}},k:Oc},Z;
|
|
184
|
-
(async function(){function a(c){Z=c.exports;Ka=Z.M;Qa();Y=Z.O;K--;f.monitorRunDependencies?.(K);0==K&&Sa&&(c=Sa,Sa=null,c());return Z}K++;f.monitorRunDependencies?.(K);var b={a:Xc};if(f.instantiateWasm)return new Promise(c=>{f.instantiateWasm(b,(d,e)=>{a(d,e);c(d.exports)})});Ua??=f.locateFile?f.locateFile("sql-wasm.wasm",D):D+"sql-wasm.wasm";return a((await Xa(b)).instance)})();f._sqlite3_free=a=>(f._sqlite3_free=Z.P)(a);f._sqlite3_value_text=a=>(f._sqlite3_value_text=Z.Q)(a);
|
|
185
|
-
f._sqlite3_prepare_v2=(a,b,c,d,e)=>(f._sqlite3_prepare_v2=Z.R)(a,b,c,d,e);f._sqlite3_step=a=>(f._sqlite3_step=Z.S)(a);f._sqlite3_reset=a=>(f._sqlite3_reset=Z.T)(a);f._sqlite3_exec=(a,b,c,d,e)=>(f._sqlite3_exec=Z.U)(a,b,c,d,e);f._sqlite3_finalize=a=>(f._sqlite3_finalize=Z.V)(a);f._sqlite3_column_name=(a,b)=>(f._sqlite3_column_name=Z.W)(a,b);f._sqlite3_column_text=(a,b)=>(f._sqlite3_column_text=Z.X)(a,b);f._sqlite3_column_type=(a,b)=>(f._sqlite3_column_type=Z.Y)(a,b);
|
|
186
|
-
f._sqlite3_errmsg=a=>(f._sqlite3_errmsg=Z.Z)(a);f._sqlite3_clear_bindings=a=>(f._sqlite3_clear_bindings=Z._)(a);f._sqlite3_value_blob=a=>(f._sqlite3_value_blob=Z.$)(a);f._sqlite3_value_bytes=a=>(f._sqlite3_value_bytes=Z.aa)(a);f._sqlite3_value_double=a=>(f._sqlite3_value_double=Z.ba)(a);f._sqlite3_value_int=a=>(f._sqlite3_value_int=Z.ca)(a);f._sqlite3_value_type=a=>(f._sqlite3_value_type=Z.da)(a);f._sqlite3_result_blob=(a,b,c,d)=>(f._sqlite3_result_blob=Z.ea)(a,b,c,d);
|
|
187
|
-
f._sqlite3_result_double=(a,b)=>(f._sqlite3_result_double=Z.fa)(a,b);f._sqlite3_result_error=(a,b,c)=>(f._sqlite3_result_error=Z.ga)(a,b,c);f._sqlite3_result_int=(a,b)=>(f._sqlite3_result_int=Z.ha)(a,b);f._sqlite3_result_int64=(a,b)=>(f._sqlite3_result_int64=Z.ia)(a,b);f._sqlite3_result_null=a=>(f._sqlite3_result_null=Z.ja)(a);f._sqlite3_result_text=(a,b,c,d)=>(f._sqlite3_result_text=Z.ka)(a,b,c,d);f._sqlite3_aggregate_context=(a,b)=>(f._sqlite3_aggregate_context=Z.la)(a,b);
|
|
188
|
-
f._sqlite3_column_count=a=>(f._sqlite3_column_count=Z.ma)(a);f._sqlite3_data_count=a=>(f._sqlite3_data_count=Z.na)(a);f._sqlite3_column_blob=(a,b)=>(f._sqlite3_column_blob=Z.oa)(a,b);f._sqlite3_column_bytes=(a,b)=>(f._sqlite3_column_bytes=Z.pa)(a,b);f._sqlite3_column_double=(a,b)=>(f._sqlite3_column_double=Z.qa)(a,b);f._sqlite3_bind_blob=(a,b,c,d,e)=>(f._sqlite3_bind_blob=Z.ra)(a,b,c,d,e);f._sqlite3_bind_double=(a,b,c)=>(f._sqlite3_bind_double=Z.sa)(a,b,c);
|
|
189
|
-
f._sqlite3_bind_int=(a,b,c)=>(f._sqlite3_bind_int=Z.ta)(a,b,c);f._sqlite3_bind_text=(a,b,c,d,e)=>(f._sqlite3_bind_text=Z.ua)(a,b,c,d,e);f._sqlite3_bind_parameter_index=(a,b)=>(f._sqlite3_bind_parameter_index=Z.va)(a,b);f._sqlite3_sql=a=>(f._sqlite3_sql=Z.wa)(a);f._sqlite3_normalized_sql=a=>(f._sqlite3_normalized_sql=Z.xa)(a);f._sqlite3_changes=a=>(f._sqlite3_changes=Z.ya)(a);f._sqlite3_close_v2=a=>(f._sqlite3_close_v2=Z.za)(a);
|
|
190
|
-
f._sqlite3_create_function_v2=(a,b,c,d,e,h,k,q,w)=>(f._sqlite3_create_function_v2=Z.Aa)(a,b,c,d,e,h,k,q,w);f._sqlite3_update_hook=(a,b,c)=>(f._sqlite3_update_hook=Z.Ba)(a,b,c);f._sqlite3_open=(a,b)=>(f._sqlite3_open=Z.Ca)(a,b);var ia=f._malloc=a=>(ia=f._malloc=Z.Da)(a),fa=f._free=a=>(fa=f._free=Z.Ea)(a);f._RegisterExtensionFunctions=a=>(f._RegisterExtensionFunctions=Z.Fa)(a);var Db=(a,b)=>(Db=Z.Ga)(a,b),Wc=(a,b)=>(Wc=Z.Ha)(a,b),wa=a=>(wa=Z.Ia)(a),z=a=>(z=Z.Ja)(a),sa=()=>(sa=Z.Ka)();
|
|
191
|
-
f.stackSave=()=>sa();f.stackRestore=a=>wa(a);f.stackAlloc=a=>z(a);f.cwrap=(a,b,c,d)=>{var e=!c||c.every(h=>"number"===h||"boolean"===h);return"string"!==b&&e&&!d?f["_"+a]:(...h)=>Tc(a,b,c,h)};f.addFunction=Aa;f.removeFunction=A;f.UTF8ToString=ua;f.ALLOC_NORMAL=ea;f.allocate=da;f.allocateUTF8OnStack=xa;
|
|
192
|
-
function Yc(){function a(){f.calledRun=!0;if(!La){if(!f.noFSInit&&!Ib){var b,c;Ib=!0;d??=f.stdin;b??=f.stdout;c??=f.stderr;d?V("stdin",d):Zb("/dev/tty","/dev/stdin");b?V("stdout",null,b):Zb("/dev/tty","/dev/stdout");c?V("stderr",null,c):Zb("/dev/tty1","/dev/stderr");oa("/dev/stdin",0);oa("/dev/stdout",1);oa("/dev/stderr",1)}Z.N();Jb=!1;f.onRuntimeInitialized?.();if(f.postRun)for("function"==typeof f.postRun&&(f.postRun=[f.postRun]);f.postRun.length;){var d=f.postRun.shift();$a.unshift(d)}Za($a)}}
|
|
193
|
-
if(0<K)Sa=Yc;else{if(f.preRun)for("function"==typeof f.preRun&&(f.preRun=[f.preRun]);f.preRun.length;)bb();Za(ab);0<K?Sa=Yc:f.setStatus?(f.setStatus("Running..."),setTimeout(()=>{setTimeout(()=>f.setStatus(""),1);a()},1)):a()}}if(f.preInit)for("function"==typeof f.preInit&&(f.preInit=[f.preInit]);0<f.preInit.length;)f.preInit.pop()();Yc();
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
// The shell-pre.js and emcc-generated code goes above
|
|
197
|
-
return Module;
|
|
198
|
-
}); // The end of the promise being returned
|
|
199
|
-
|
|
200
|
-
return initSqlJsPromise;
|
|
201
|
-
} // The end of our initSqlJs function
|
|
202
|
-
|
|
203
|
-
// This bit below is copied almost exactly from what you get when you use the MODULARIZE=1 flag with emcc
|
|
204
|
-
// However, we don't want to use the emcc modularization. See shell-pre.js
|
|
205
|
-
if (typeof exports === 'object' && typeof module === 'object'){
|
|
206
|
-
module.exports = initSqlJs;
|
|
207
|
-
// This will allow the module to be used in ES6 or CommonJS
|
|
208
|
-
module.exports.default = initSqlJs;
|
|
209
|
-
}
|
|
210
|
-
else if (typeof define === 'function' && define['amd']) {
|
|
211
|
-
define([], function() { return initSqlJs; });
|
|
212
|
-
}
|
|
213
|
-
else if (typeof exports === 'object'){
|
|
214
|
-
exports["Module"] = initSqlJs;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
// ============================================================================
|
|
219
|
-
// Advanced Features
|
|
220
|
-
// ============================================================================
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Product Quantization for Browser
|
|
224
|
-
*
|
|
225
|
-
* Compresses high-dimensional vectors using product quantization.
|
|
226
|
-
* Achieves 4-32x memory reduction with minimal accuracy loss.
|
|
227
|
-
*
|
|
228
|
-
* Features:
|
|
229
|
-
* - PQ8: 8 subvectors, 256 centroids each (4x compression)
|
|
230
|
-
* - PQ16: 16 subvectors, 256 centroids each (8x compression)
|
|
231
|
-
* - Asymmetric distance computation (ADC)
|
|
232
|
-
* - K-means clustering for codebook training
|
|
233
|
-
*
|
|
234
|
-
* Performance:
|
|
235
|
-
* - Memory: Float32 (4 bytes) → uint8 (1 byte) per subvector
|
|
236
|
-
* - Speed: ~1.5x slower search vs uncompressed
|
|
237
|
-
* - Accuracy: 95-99% recall@10
|
|
238
|
-
*/
|
|
239
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
240
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
241
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
242
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
243
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
244
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
245
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
246
|
-
});
|
|
247
|
-
};
|
|
248
|
-
class ProductQuantization {
|
|
249
|
-
constructor(config) {
|
|
250
|
-
this.codebook = null;
|
|
251
|
-
this.trained = false;
|
|
252
|
-
this.config = {
|
|
253
|
-
dimension: config.dimension,
|
|
254
|
-
numSubvectors: config.numSubvectors,
|
|
255
|
-
numCentroids: config.numCentroids,
|
|
256
|
-
maxIterations: config.maxIterations || 50,
|
|
257
|
-
convergenceThreshold: config.convergenceThreshold || 1e-4
|
|
258
|
-
};
|
|
259
|
-
// Validate config
|
|
260
|
-
if (this.config.dimension % this.config.numSubvectors !== 0) {
|
|
261
|
-
throw new Error(`Dimension ${this.config.dimension} must be divisible by numSubvectors ${this.config.numSubvectors}`);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Train codebook using k-means on training vectors
|
|
266
|
-
*/
|
|
267
|
-
train(vectors) {
|
|
268
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
269
|
-
if (vectors.length === 0) {
|
|
270
|
-
throw new Error('Training requires at least one vector');
|
|
271
|
-
}
|
|
272
|
-
const subvectorDim = this.config.dimension / this.config.numSubvectors;
|
|
273
|
-
const centroids = [];
|
|
274
|
-
console.log(`[PQ] Training ${this.config.numSubvectors} subvectors with ${this.config.numCentroids} centroids each...`);
|
|
275
|
-
// Train each subvector independently
|
|
276
|
-
for (let s = 0; s < this.config.numSubvectors; s++) {
|
|
277
|
-
const startDim = s * subvectorDim;
|
|
278
|
-
const endDim = startDim + subvectorDim;
|
|
279
|
-
// Extract subvectors
|
|
280
|
-
const subvectors = vectors.map(v => v.slice(startDim, endDim));
|
|
281
|
-
// Run k-means
|
|
282
|
-
const subCentroids = yield this.kMeans(subvectors, this.config.numCentroids);
|
|
283
|
-
centroids.push(...subCentroids);
|
|
284
|
-
if ((s + 1) % 4 === 0 || s === this.config.numSubvectors - 1) {
|
|
285
|
-
console.log(`[PQ] Trained ${s + 1}/${this.config.numSubvectors} subvectors`);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
this.codebook = {
|
|
289
|
-
subvectorDim,
|
|
290
|
-
numSubvectors: this.config.numSubvectors,
|
|
291
|
-
numCentroids: this.config.numCentroids,
|
|
292
|
-
centroids
|
|
293
|
-
};
|
|
294
|
-
this.trained = true;
|
|
295
|
-
console.log('[PQ] Training complete');
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* K-means clustering for centroids
|
|
300
|
-
*/
|
|
301
|
-
kMeans(vectors, k) {
|
|
302
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
303
|
-
const dim = vectors[0].length;
|
|
304
|
-
const n = vectors.length;
|
|
305
|
-
// Initialize centroids with k-means++
|
|
306
|
-
const centroids = this.kMeansPlusPlus(vectors, k);
|
|
307
|
-
const assignments = new Uint32Array(n);
|
|
308
|
-
let prevInertia = Infinity;
|
|
309
|
-
for (let iter = 0; iter < this.config.maxIterations; iter++) {
|
|
310
|
-
// Assign vectors to nearest centroid
|
|
311
|
-
let inertia = 0;
|
|
312
|
-
for (let i = 0; i < n; i++) {
|
|
313
|
-
let minDist = Infinity;
|
|
314
|
-
let minIdx = 0;
|
|
315
|
-
for (let j = 0; j < k; j++) {
|
|
316
|
-
const dist = this.squaredDistance(vectors[i], centroids[j]);
|
|
317
|
-
if (dist < minDist) {
|
|
318
|
-
minDist = dist;
|
|
319
|
-
minIdx = j;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
assignments[i] = minIdx;
|
|
323
|
-
inertia += minDist;
|
|
324
|
-
}
|
|
325
|
-
// Check convergence
|
|
326
|
-
if (Math.abs(prevInertia - inertia) < this.config.convergenceThreshold) {
|
|
327
|
-
break;
|
|
328
|
-
}
|
|
329
|
-
prevInertia = inertia;
|
|
330
|
-
// Update centroids
|
|
331
|
-
const counts = new Uint32Array(k);
|
|
332
|
-
const sums = Array.from({ length: k }, () => new Float32Array(dim));
|
|
333
|
-
for (let i = 0; i < n; i++) {
|
|
334
|
-
const cluster = assignments[i];
|
|
335
|
-
counts[cluster]++;
|
|
336
|
-
for (let d = 0; d < dim; d++) {
|
|
337
|
-
sums[cluster][d] += vectors[i][d];
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
for (let j = 0; j < k; j++) {
|
|
341
|
-
if (counts[j] > 0) {
|
|
342
|
-
for (let d = 0; d < dim; d++) {
|
|
343
|
-
centroids[j][d] = sums[j][d] / counts[j];
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
return centroids;
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* K-means++ initialization for better centroid selection
|
|
353
|
-
*/
|
|
354
|
-
kMeansPlusPlus(vectors, k) {
|
|
355
|
-
const n = vectors.length;
|
|
356
|
-
const dim = vectors[0].length;
|
|
357
|
-
const centroids = [];
|
|
358
|
-
// Choose first centroid randomly
|
|
359
|
-
const firstIdx = Math.floor(Math.random() * n);
|
|
360
|
-
centroids.push(new Float32Array(vectors[firstIdx]));
|
|
361
|
-
// Choose remaining centroids
|
|
362
|
-
for (let i = 1; i < k; i++) {
|
|
363
|
-
const distances = new Float32Array(n);
|
|
364
|
-
let sumDistances = 0;
|
|
365
|
-
// Calculate distances to nearest centroid
|
|
366
|
-
for (let j = 0; j < n; j++) {
|
|
367
|
-
let minDist = Infinity;
|
|
368
|
-
for (const centroid of centroids) {
|
|
369
|
-
const dist = this.squaredDistance(vectors[j], centroid);
|
|
370
|
-
minDist = Math.min(minDist, dist);
|
|
371
|
-
}
|
|
372
|
-
distances[j] = minDist;
|
|
373
|
-
sumDistances += minDist;
|
|
374
|
-
}
|
|
375
|
-
// Choose next centroid with probability proportional to distance²
|
|
376
|
-
let r = Math.random() * sumDistances;
|
|
377
|
-
for (let j = 0; j < n; j++) {
|
|
378
|
-
r -= distances[j];
|
|
379
|
-
if (r <= 0) {
|
|
380
|
-
centroids.push(new Float32Array(vectors[j]));
|
|
381
|
-
break;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
return centroids;
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Compress a vector using trained codebook
|
|
389
|
-
*/
|
|
390
|
-
compress(vector) {
|
|
391
|
-
if (!this.trained || !this.codebook) {
|
|
392
|
-
throw new Error('Codebook must be trained before compression');
|
|
393
|
-
}
|
|
394
|
-
const codes = new Uint8Array(this.config.numSubvectors);
|
|
395
|
-
const subvectorDim = this.codebook.subvectorDim;
|
|
396
|
-
// Compute norm for later reconstruction
|
|
397
|
-
let norm = 0;
|
|
398
|
-
for (let i = 0; i < vector.length; i++) {
|
|
399
|
-
norm += vector[i] * vector[i];
|
|
400
|
-
}
|
|
401
|
-
norm = Math.sqrt(norm);
|
|
402
|
-
// Encode each subvector
|
|
403
|
-
for (let s = 0; s < this.config.numSubvectors; s++) {
|
|
404
|
-
const startDim = s * subvectorDim;
|
|
405
|
-
const subvector = vector.slice(startDim, startDim + subvectorDim);
|
|
406
|
-
// Find nearest centroid
|
|
407
|
-
let minDist = Infinity;
|
|
408
|
-
let minIdx = 0;
|
|
409
|
-
const centroidOffset = s * this.config.numCentroids;
|
|
410
|
-
for (let c = 0; c < this.config.numCentroids; c++) {
|
|
411
|
-
const centroid = this.codebook.centroids[centroidOffset + c];
|
|
412
|
-
const dist = this.squaredDistance(subvector, centroid);
|
|
413
|
-
if (dist < minDist) {
|
|
414
|
-
minDist = dist;
|
|
415
|
-
minIdx = c;
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
codes[s] = minIdx;
|
|
419
|
-
}
|
|
420
|
-
return { codes, norm };
|
|
421
|
-
}
|
|
422
|
-
/**
|
|
423
|
-
* Decompress a vector (approximate reconstruction)
|
|
424
|
-
*/
|
|
425
|
-
decompress(compressed) {
|
|
426
|
-
if (!this.codebook) {
|
|
427
|
-
throw new Error('Codebook not available');
|
|
428
|
-
}
|
|
429
|
-
const vector = new Float32Array(this.config.dimension);
|
|
430
|
-
const subvectorDim = this.codebook.subvectorDim;
|
|
431
|
-
for (let s = 0; s < this.config.numSubvectors; s++) {
|
|
432
|
-
const code = compressed.codes[s];
|
|
433
|
-
const centroidOffset = s * this.config.numCentroids;
|
|
434
|
-
const centroid = this.codebook.centroids[centroidOffset + code];
|
|
435
|
-
const startDim = s * subvectorDim;
|
|
436
|
-
for (let d = 0; d < subvectorDim; d++) {
|
|
437
|
-
vector[startDim + d] = centroid[d];
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
return vector;
|
|
441
|
-
}
|
|
442
|
-
/**
|
|
443
|
-
* Asymmetric Distance Computation (ADC)
|
|
444
|
-
* Computes distance from query vector to compressed vector
|
|
445
|
-
*/
|
|
446
|
-
asymmetricDistance(query, compressed) {
|
|
447
|
-
if (!this.codebook) {
|
|
448
|
-
throw new Error('Codebook not available');
|
|
449
|
-
}
|
|
450
|
-
let distance = 0;
|
|
451
|
-
const subvectorDim = this.codebook.subvectorDim;
|
|
452
|
-
for (let s = 0; s < this.config.numSubvectors; s++) {
|
|
453
|
-
const code = compressed.codes[s];
|
|
454
|
-
const centroidOffset = s * this.config.numCentroids;
|
|
455
|
-
const centroid = this.codebook.centroids[centroidOffset + code];
|
|
456
|
-
const startDim = s * subvectorDim;
|
|
457
|
-
const querySubvector = query.slice(startDim, startDim + subvectorDim);
|
|
458
|
-
distance += this.squaredDistance(querySubvector, centroid);
|
|
459
|
-
}
|
|
460
|
-
return Math.sqrt(distance);
|
|
461
|
-
}
|
|
462
|
-
/**
|
|
463
|
-
* Batch compression for multiple vectors
|
|
464
|
-
*/
|
|
465
|
-
batchCompress(vectors) {
|
|
466
|
-
return vectors.map(v => this.compress(v));
|
|
467
|
-
}
|
|
468
|
-
/**
|
|
469
|
-
* Get memory savings
|
|
470
|
-
*/
|
|
471
|
-
getCompressionRatio() {
|
|
472
|
-
// Original: dimension * 4 bytes (Float32)
|
|
473
|
-
// Compressed: numSubvectors * 1 byte (Uint8) + 4 bytes (norm)
|
|
474
|
-
const originalBytes = this.config.dimension * 4;
|
|
475
|
-
const compressedBytes = this.config.numSubvectors + 4;
|
|
476
|
-
return originalBytes / compressedBytes;
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* Export codebook for persistence
|
|
480
|
-
*/
|
|
481
|
-
exportCodebook() {
|
|
482
|
-
if (!this.codebook) {
|
|
483
|
-
throw new Error('No codebook to export');
|
|
484
|
-
}
|
|
485
|
-
return JSON.stringify({
|
|
486
|
-
config: this.config,
|
|
487
|
-
codebook: {
|
|
488
|
-
subvectorDim: this.codebook.subvectorDim,
|
|
489
|
-
numSubvectors: this.codebook.numSubvectors,
|
|
490
|
-
numCentroids: this.codebook.numCentroids,
|
|
491
|
-
centroids: this.codebook.centroids.map(c => Array.from(c))
|
|
492
|
-
}
|
|
493
|
-
});
|
|
494
|
-
}
|
|
495
|
-
/**
|
|
496
|
-
* Import codebook
|
|
497
|
-
*/
|
|
498
|
-
importCodebook(json) {
|
|
499
|
-
const data = JSON.parse(json);
|
|
500
|
-
this.config = data.config;
|
|
501
|
-
this.codebook = {
|
|
502
|
-
subvectorDim: data.codebook.subvectorDim,
|
|
503
|
-
numSubvectors: data.codebook.numSubvectors,
|
|
504
|
-
numCentroids: data.codebook.numCentroids,
|
|
505
|
-
centroids: data.codebook.centroids.map((c) => new Float32Array(c))
|
|
506
|
-
};
|
|
507
|
-
this.trained = true;
|
|
508
|
-
}
|
|
509
|
-
/**
|
|
510
|
-
* Utility: Squared Euclidean distance
|
|
511
|
-
*/
|
|
512
|
-
squaredDistance(a, b) {
|
|
513
|
-
let sum = 0;
|
|
514
|
-
for (let i = 0; i < a.length; i++) {
|
|
515
|
-
const diff = a[i] - b[i];
|
|
516
|
-
sum += diff * diff;
|
|
517
|
-
}
|
|
518
|
-
return sum;
|
|
519
|
-
}
|
|
520
|
-
/**
|
|
521
|
-
* Get statistics
|
|
522
|
-
*/
|
|
523
|
-
getStats() {
|
|
524
|
-
const compressionRatio = this.getCompressionRatio();
|
|
525
|
-
const memoryPerVector = this.config.numSubvectors + 4; // codes + norm
|
|
526
|
-
const codebookSize = this.codebook
|
|
527
|
-
? this.config.numSubvectors * this.config.numCentroids * (this.config.dimension / this.config.numSubvectors) * 4
|
|
528
|
-
: 0;
|
|
529
|
-
return {
|
|
530
|
-
trained: this.trained,
|
|
531
|
-
compressionRatio,
|
|
532
|
-
memoryPerVector,
|
|
533
|
-
codebookSize
|
|
534
|
-
};
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
/**
|
|
538
|
-
* Helper function to create PQ8 (8 subvectors, 4x compression)
|
|
539
|
-
*/
|
|
540
|
-
function createPQ8(dimension) {
|
|
541
|
-
return new ProductQuantization({
|
|
542
|
-
dimension,
|
|
543
|
-
numSubvectors: 8,
|
|
544
|
-
numCentroids: 256,
|
|
545
|
-
maxIterations: 50
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
/**
|
|
549
|
-
* Helper function to create PQ16 (16 subvectors, 8x compression)
|
|
550
|
-
*/
|
|
551
|
-
function createPQ16(dimension) {
|
|
552
|
-
return new ProductQuantization({
|
|
553
|
-
dimension,
|
|
554
|
-
numSubvectors: 16,
|
|
555
|
-
numCentroids: 256,
|
|
556
|
-
maxIterations: 50
|
|
557
|
-
});
|
|
558
|
-
}
|
|
559
|
-
/**
|
|
560
|
-
* Helper function to create PQ32 (32 subvectors, 16x compression)
|
|
561
|
-
*/
|
|
562
|
-
function createPQ32(dimension) {
|
|
563
|
-
return new ProductQuantization({
|
|
564
|
-
dimension,
|
|
565
|
-
numSubvectors: 32,
|
|
566
|
-
numCentroids: 256,
|
|
567
|
-
maxIterations: 50
|
|
568
|
-
});
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
/**
|
|
573
|
-
* HNSW (Hierarchical Navigable Small World) Index for Browser
|
|
574
|
-
*
|
|
575
|
-
* JavaScript implementation of HNSW algorithm for fast approximate nearest neighbor search.
|
|
576
|
-
* Achieves O(log n) search complexity vs O(n) for linear scan.
|
|
577
|
-
*
|
|
578
|
-
* Features:
|
|
579
|
-
* - Multi-layer graph structure
|
|
580
|
-
* - Probabilistic layer assignment
|
|
581
|
-
* - Greedy search algorithm
|
|
582
|
-
* - Dynamic insertion
|
|
583
|
-
* - Configurable M (connections per node)
|
|
584
|
-
* - Configurable efConstruction and efSearch
|
|
585
|
-
*
|
|
586
|
-
* Performance:
|
|
587
|
-
* - 10-20x faster than linear scan (vs 150x for native HNSW)
|
|
588
|
-
* - Memory: ~16 bytes per edge + vector storage
|
|
589
|
-
* - Suitable for datasets up to 100K vectors in browser
|
|
590
|
-
*/
|
|
591
|
-
class MinHeap {
|
|
592
|
-
constructor() {
|
|
593
|
-
this.items = [];
|
|
594
|
-
}
|
|
595
|
-
push(item, priority) {
|
|
596
|
-
this.items.push({ item, priority });
|
|
597
|
-
this.bubbleUp(this.items.length - 1);
|
|
598
|
-
}
|
|
599
|
-
pop() {
|
|
600
|
-
if (this.items.length === 0)
|
|
601
|
-
return undefined;
|
|
602
|
-
const result = this.items[0].item;
|
|
603
|
-
const last = this.items.pop();
|
|
604
|
-
if (this.items.length > 0) {
|
|
605
|
-
this.items[0] = last;
|
|
606
|
-
this.bubbleDown(0);
|
|
607
|
-
}
|
|
608
|
-
return result;
|
|
609
|
-
}
|
|
610
|
-
peek() {
|
|
611
|
-
var _a;
|
|
612
|
-
return (_a = this.items[0]) === null || _a === void 0 ? void 0 : _a.item;
|
|
613
|
-
}
|
|
614
|
-
size() {
|
|
615
|
-
return this.items.length;
|
|
616
|
-
}
|
|
617
|
-
bubbleUp(index) {
|
|
618
|
-
while (index > 0) {
|
|
619
|
-
const parentIndex = Math.floor((index - 1) / 2);
|
|
620
|
-
if (this.items[index].priority >= this.items[parentIndex].priority)
|
|
621
|
-
break;
|
|
622
|
-
[this.items[index], this.items[parentIndex]] = [this.items[parentIndex], this.items[index]];
|
|
623
|
-
index = parentIndex;
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
bubbleDown(index) {
|
|
627
|
-
while (true) {
|
|
628
|
-
const leftChild = 2 * index + 1;
|
|
629
|
-
const rightChild = 2 * index + 2;
|
|
630
|
-
let smallest = index;
|
|
631
|
-
if (leftChild < this.items.length && this.items[leftChild].priority < this.items[smallest].priority) {
|
|
632
|
-
smallest = leftChild;
|
|
633
|
-
}
|
|
634
|
-
if (rightChild < this.items.length && this.items[rightChild].priority < this.items[smallest].priority) {
|
|
635
|
-
smallest = rightChild;
|
|
636
|
-
}
|
|
637
|
-
if (smallest === index)
|
|
638
|
-
break;
|
|
639
|
-
[this.items[index], this.items[smallest]] = [this.items[smallest], this.items[index]];
|
|
640
|
-
index = smallest;
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
class HNSWIndex {
|
|
645
|
-
constructor(config = {}) {
|
|
646
|
-
this.nodes = new Map();
|
|
647
|
-
this.entryPoint = null;
|
|
648
|
-
this.currentId = 0;
|
|
649
|
-
this.config = {
|
|
650
|
-
dimension: config.dimension || 384,
|
|
651
|
-
M: config.M || 16,
|
|
652
|
-
efConstruction: config.efConstruction || 200,
|
|
653
|
-
efSearch: config.efSearch || 50,
|
|
654
|
-
ml: config.ml || 1 / Math.log(2),
|
|
655
|
-
maxLayers: config.maxLayers || 16,
|
|
656
|
-
distanceFunction: config.distanceFunction || 'cosine'
|
|
657
|
-
};
|
|
658
|
-
this.ml = this.config.ml;
|
|
659
|
-
}
|
|
660
|
-
/**
|
|
661
|
-
* Add vector to index
|
|
662
|
-
*/
|
|
663
|
-
add(vector, id) {
|
|
664
|
-
const nodeId = id !== undefined ? id : this.currentId++;
|
|
665
|
-
const level = this.randomLevel();
|
|
666
|
-
const node = {
|
|
667
|
-
id: nodeId,
|
|
668
|
-
vector,
|
|
669
|
-
level,
|
|
670
|
-
connections: new Map()
|
|
671
|
-
};
|
|
672
|
-
// Initialize connections for each layer
|
|
673
|
-
for (let l = 0; l <= level; l++) {
|
|
674
|
-
node.connections.set(l, []);
|
|
675
|
-
}
|
|
676
|
-
if (this.entryPoint === null) {
|
|
677
|
-
// First node
|
|
678
|
-
this.entryPoint = nodeId;
|
|
679
|
-
this.nodes.set(nodeId, node);
|
|
680
|
-
return nodeId;
|
|
681
|
-
}
|
|
682
|
-
// Find nearest neighbors at each layer
|
|
683
|
-
const ep = this.entryPoint;
|
|
684
|
-
let nearest = ep;
|
|
685
|
-
// Search from top layer to target layer + 1
|
|
686
|
-
for (let lc = this.nodes.get(ep).level; lc > level; lc--) {
|
|
687
|
-
nearest = this.searchLayer(vector, nearest, 1, lc)[0];
|
|
688
|
-
}
|
|
689
|
-
// Insert node at layers 0 to level
|
|
690
|
-
for (let lc = Math.min(level, this.nodes.get(ep).level); lc >= 0; lc--) {
|
|
691
|
-
const candidates = this.searchLayer(vector, nearest, this.config.efConstruction, lc);
|
|
692
|
-
// Select M neighbors
|
|
693
|
-
const M = lc === 0 ? this.config.M * 2 : this.config.M;
|
|
694
|
-
const neighbors = this.selectNeighbors(vector, candidates, M);
|
|
695
|
-
// Add bidirectional connections
|
|
696
|
-
for (const neighbor of neighbors) {
|
|
697
|
-
this.connect(nodeId, neighbor, lc);
|
|
698
|
-
this.connect(neighbor, nodeId, lc);
|
|
699
|
-
// Prune connections if necessary
|
|
700
|
-
const neighborNode = this.nodes.get(neighbor);
|
|
701
|
-
const neighborConnections = neighborNode.connections.get(lc);
|
|
702
|
-
if (neighborConnections.length > M) {
|
|
703
|
-
const newNeighbors = this.selectNeighbors(neighborNode.vector, neighborConnections, M);
|
|
704
|
-
neighborNode.connections.set(lc, newNeighbors);
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
nearest = candidates[0];
|
|
708
|
-
}
|
|
709
|
-
// Update entry point if necessary
|
|
710
|
-
if (level > this.nodes.get(this.entryPoint).level) {
|
|
711
|
-
this.entryPoint = nodeId;
|
|
712
|
-
}
|
|
713
|
-
this.nodes.set(nodeId, node);
|
|
714
|
-
return nodeId;
|
|
715
|
-
}
|
|
716
|
-
/**
|
|
717
|
-
* Search for k nearest neighbors
|
|
718
|
-
*/
|
|
719
|
-
search(query, k, ef) {
|
|
720
|
-
if (this.entryPoint === null)
|
|
721
|
-
return [];
|
|
722
|
-
ef = ef || Math.max(this.config.efSearch, k);
|
|
723
|
-
let ep = this.entryPoint;
|
|
724
|
-
let nearest = ep;
|
|
725
|
-
// Search from top to layer 1
|
|
726
|
-
for (let lc = this.nodes.get(ep).level; lc > 0; lc--) {
|
|
727
|
-
nearest = this.searchLayer(query, nearest, 1, lc)[0];
|
|
728
|
-
}
|
|
729
|
-
// Search at layer 0
|
|
730
|
-
const candidates = this.searchLayer(query, nearest, ef, 0);
|
|
731
|
-
// Convert to SearchResult and return top k
|
|
732
|
-
return candidates
|
|
733
|
-
.slice(0, k)
|
|
734
|
-
.map(id => ({
|
|
735
|
-
id,
|
|
736
|
-
distance: this.distance(query, this.nodes.get(id).vector),
|
|
737
|
-
vector: this.nodes.get(id).vector
|
|
738
|
-
}));
|
|
739
|
-
}
|
|
740
|
-
/**
|
|
741
|
-
* Search at specific layer
|
|
742
|
-
*/
|
|
743
|
-
searchLayer(query, ep, ef, layer) {
|
|
744
|
-
const visited = new Set();
|
|
745
|
-
const candidates = new MinHeap();
|
|
746
|
-
const w = new MinHeap();
|
|
747
|
-
const dist = this.distance(query, this.nodes.get(ep).vector);
|
|
748
|
-
candidates.push(ep, dist);
|
|
749
|
-
w.push(ep, -dist); // Max heap (negate for min heap)
|
|
750
|
-
visited.add(ep);
|
|
751
|
-
while (candidates.size() > 0) {
|
|
752
|
-
const c = candidates.pop();
|
|
753
|
-
const fDist = -w.peek(); // Furthest point distance
|
|
754
|
-
const cDist = this.distance(query, this.nodes.get(c).vector);
|
|
755
|
-
if (cDist > fDist)
|
|
756
|
-
break;
|
|
757
|
-
const neighbors = this.nodes.get(c).connections.get(layer) || [];
|
|
758
|
-
for (const e of neighbors) {
|
|
759
|
-
if (visited.has(e))
|
|
760
|
-
continue;
|
|
761
|
-
visited.add(e);
|
|
762
|
-
const eDist = this.distance(query, this.nodes.get(e).vector);
|
|
763
|
-
const fDist = -w.peek();
|
|
764
|
-
if (eDist < fDist || w.size() < ef) {
|
|
765
|
-
candidates.push(e, eDist);
|
|
766
|
-
w.push(e, -eDist);
|
|
767
|
-
if (w.size() > ef) {
|
|
768
|
-
w.pop();
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
// Return ef nearest neighbors
|
|
774
|
-
const result = [];
|
|
775
|
-
while (w.size() > 0) {
|
|
776
|
-
result.unshift(w.pop());
|
|
777
|
-
}
|
|
778
|
-
return result;
|
|
779
|
-
}
|
|
780
|
-
/**
|
|
781
|
-
* Select best neighbors using heuristic
|
|
782
|
-
*/
|
|
783
|
-
selectNeighbors(base, candidates, M) {
|
|
784
|
-
if (candidates.length <= M)
|
|
785
|
-
return candidates;
|
|
786
|
-
// Sort by distance
|
|
787
|
-
const sorted = candidates
|
|
788
|
-
.map(id => ({
|
|
789
|
-
id,
|
|
790
|
-
distance: this.distance(base, this.nodes.get(id).vector)
|
|
791
|
-
}))
|
|
792
|
-
.sort((a, b) => a.distance - b.distance);
|
|
793
|
-
return sorted.slice(0, M).map(x => x.id);
|
|
794
|
-
}
|
|
795
|
-
/**
|
|
796
|
-
* Connect two nodes at layer
|
|
797
|
-
*/
|
|
798
|
-
connect(from, to, layer) {
|
|
799
|
-
const node = this.nodes.get(from);
|
|
800
|
-
const connections = node.connections.get(layer);
|
|
801
|
-
if (!connections.includes(to)) {
|
|
802
|
-
connections.push(to);
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
/**
|
|
806
|
-
* Random level assignment
|
|
807
|
-
*/
|
|
808
|
-
randomLevel() {
|
|
809
|
-
let level = 0;
|
|
810
|
-
while (Math.random() < this.ml && level < this.config.maxLayers - 1) {
|
|
811
|
-
level++;
|
|
812
|
-
}
|
|
813
|
-
return level;
|
|
814
|
-
}
|
|
815
|
-
/**
|
|
816
|
-
* Distance function
|
|
817
|
-
*/
|
|
818
|
-
distance(a, b) {
|
|
819
|
-
switch (this.config.distanceFunction) {
|
|
820
|
-
case 'cosine':
|
|
821
|
-
return 1 - this.cosineSimilarity(a, b);
|
|
822
|
-
case 'euclidean':
|
|
823
|
-
return this.euclideanDistance(a, b);
|
|
824
|
-
case 'manhattan':
|
|
825
|
-
return this.manhattanDistance(a, b);
|
|
826
|
-
default:
|
|
827
|
-
return 1 - this.cosineSimilarity(a, b);
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
cosineSimilarity(a, b) {
|
|
831
|
-
let dotProduct = 0;
|
|
832
|
-
let normA = 0;
|
|
833
|
-
let normB = 0;
|
|
834
|
-
for (let i = 0; i < a.length; i++) {
|
|
835
|
-
dotProduct += a[i] * b[i];
|
|
836
|
-
normA += a[i] * a[i];
|
|
837
|
-
normB += b[i] * b[i];
|
|
838
|
-
}
|
|
839
|
-
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
|
|
840
|
-
}
|
|
841
|
-
euclideanDistance(a, b) {
|
|
842
|
-
let sum = 0;
|
|
843
|
-
for (let i = 0; i < a.length; i++) {
|
|
844
|
-
const diff = a[i] - b[i];
|
|
845
|
-
sum += diff * diff;
|
|
846
|
-
}
|
|
847
|
-
return Math.sqrt(sum);
|
|
848
|
-
}
|
|
849
|
-
manhattanDistance(a, b) {
|
|
850
|
-
let sum = 0;
|
|
851
|
-
for (let i = 0; i < a.length; i++) {
|
|
852
|
-
sum += Math.abs(a[i] - b[i]);
|
|
853
|
-
}
|
|
854
|
-
return sum;
|
|
855
|
-
}
|
|
856
|
-
/**
|
|
857
|
-
* Get index statistics
|
|
858
|
-
*/
|
|
859
|
-
getStats() {
|
|
860
|
-
if (this.nodes.size === 0) {
|
|
861
|
-
return {
|
|
862
|
-
numNodes: 0,
|
|
863
|
-
numLayers: 0,
|
|
864
|
-
avgConnections: 0,
|
|
865
|
-
entryPointLevel: 0,
|
|
866
|
-
memoryBytes: 0
|
|
867
|
-
};
|
|
868
|
-
}
|
|
869
|
-
const maxLevel = Math.max(...Array.from(this.nodes.values()).map(n => n.level));
|
|
870
|
-
let totalConnections = 0;
|
|
871
|
-
for (const node of this.nodes.values()) {
|
|
872
|
-
for (const connections of node.connections.values()) {
|
|
873
|
-
totalConnections += connections.length;
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
const avgConnections = totalConnections / this.nodes.size;
|
|
877
|
-
// Estimate memory: vector + connections + metadata
|
|
878
|
-
const vectorBytes = this.config.dimension * 4; // Float32Array
|
|
879
|
-
const connectionBytes = avgConnections * 4; // number array
|
|
880
|
-
const metadataBytes = 100; // rough estimate for node object
|
|
881
|
-
const memoryBytes = this.nodes.size * (vectorBytes + connectionBytes + metadataBytes);
|
|
882
|
-
return {
|
|
883
|
-
numNodes: this.nodes.size,
|
|
884
|
-
numLayers: maxLevel + 1,
|
|
885
|
-
avgConnections,
|
|
886
|
-
entryPointLevel: this.entryPoint ? this.nodes.get(this.entryPoint).level : 0,
|
|
887
|
-
memoryBytes
|
|
888
|
-
};
|
|
889
|
-
}
|
|
890
|
-
/**
|
|
891
|
-
* Export index for persistence
|
|
892
|
-
*/
|
|
893
|
-
export() {
|
|
894
|
-
const data = {
|
|
895
|
-
config: this.config,
|
|
896
|
-
entryPoint: this.entryPoint,
|
|
897
|
-
currentId: this.currentId,
|
|
898
|
-
nodes: Array.from(this.nodes.entries()).map(([id, node]) => ({
|
|
899
|
-
id,
|
|
900
|
-
vector: Array.from(node.vector),
|
|
901
|
-
level: node.level,
|
|
902
|
-
connections: Array.from(node.connections.entries())
|
|
903
|
-
}))
|
|
904
|
-
};
|
|
905
|
-
return JSON.stringify(data);
|
|
906
|
-
}
|
|
907
|
-
/**
|
|
908
|
-
* Import index from JSON
|
|
909
|
-
*/
|
|
910
|
-
import(json) {
|
|
911
|
-
const data = JSON.parse(json);
|
|
912
|
-
this.config = data.config;
|
|
913
|
-
this.entryPoint = data.entryPoint;
|
|
914
|
-
this.currentId = data.currentId;
|
|
915
|
-
this.nodes.clear();
|
|
916
|
-
for (const nodeData of data.nodes) {
|
|
917
|
-
const node = {
|
|
918
|
-
id: nodeData.id,
|
|
919
|
-
vector: new Float32Array(nodeData.vector),
|
|
920
|
-
level: nodeData.level,
|
|
921
|
-
connections: new Map(nodeData.connections)
|
|
922
|
-
};
|
|
923
|
-
this.nodes.set(nodeData.id, node);
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
/**
|
|
927
|
-
* Clear index
|
|
928
|
-
*/
|
|
929
|
-
clear() {
|
|
930
|
-
this.nodes.clear();
|
|
931
|
-
this.entryPoint = null;
|
|
932
|
-
this.currentId = 0;
|
|
933
|
-
}
|
|
934
|
-
/**
|
|
935
|
-
* Get number of nodes
|
|
936
|
-
*/
|
|
937
|
-
size() {
|
|
938
|
-
return this.nodes.size;
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
/**
|
|
942
|
-
* Helper function to create HNSW index with default settings
|
|
943
|
-
*/
|
|
944
|
-
function createHNSW(dimension) {
|
|
945
|
-
return new HNSWIndex({
|
|
946
|
-
dimension,
|
|
947
|
-
M: 16,
|
|
948
|
-
efConstruction: 200,
|
|
949
|
-
efSearch: 50
|
|
950
|
-
});
|
|
951
|
-
}
|
|
952
|
-
/**
|
|
953
|
-
* Helper function to create fast HNSW (lower quality, faster build)
|
|
954
|
-
*/
|
|
955
|
-
function createFastHNSW(dimension) {
|
|
956
|
-
return new HNSWIndex({
|
|
957
|
-
dimension,
|
|
958
|
-
M: 8,
|
|
959
|
-
efConstruction: 100,
|
|
960
|
-
efSearch: 30
|
|
961
|
-
});
|
|
962
|
-
}
|
|
963
|
-
/**
|
|
964
|
-
* Helper function to create accurate HNSW (higher quality, slower build)
|
|
965
|
-
*/
|
|
966
|
-
function createAccurateHNSW(dimension) {
|
|
967
|
-
return new HNSWIndex({
|
|
968
|
-
dimension,
|
|
969
|
-
M: 32,
|
|
970
|
-
efConstruction: 400,
|
|
971
|
-
efSearch: 100
|
|
972
|
-
});
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
/**
|
|
977
|
-
* Advanced Features for AgentDB Browser
|
|
978
|
-
*
|
|
979
|
-
* Includes:
|
|
980
|
-
* - GNN (Graph Neural Networks) - Graph attention and message passing
|
|
981
|
-
* - MMR (Maximal Marginal Relevance) - Diversity ranking
|
|
982
|
-
* - SVD (Singular Value Decomposition) - Tensor compression
|
|
983
|
-
* - Batch operations and utilities
|
|
984
|
-
*/
|
|
985
|
-
/**
|
|
986
|
-
* Graph Neural Network with attention mechanism
|
|
987
|
-
*/
|
|
988
|
-
class GraphNeuralNetwork {
|
|
989
|
-
constructor(config = {}) {
|
|
990
|
-
this.nodes = new Map();
|
|
991
|
-
this.edges = [];
|
|
992
|
-
this.attentionWeights = new Map();
|
|
993
|
-
this.config = {
|
|
994
|
-
hiddenDim: config.hiddenDim || 64,
|
|
995
|
-
numHeads: config.numHeads || 4,
|
|
996
|
-
dropout: config.dropout || 0.1,
|
|
997
|
-
learningRate: config.learningRate || 0.01,
|
|
998
|
-
attentionType: config.attentionType || 'gat'
|
|
999
|
-
};
|
|
1000
|
-
}
|
|
1001
|
-
/**
|
|
1002
|
-
* Add node to graph
|
|
1003
|
-
*/
|
|
1004
|
-
addNode(id, features) {
|
|
1005
|
-
this.nodes.set(id, {
|
|
1006
|
-
id,
|
|
1007
|
-
features,
|
|
1008
|
-
neighbors: []
|
|
1009
|
-
});
|
|
1010
|
-
}
|
|
1011
|
-
/**
|
|
1012
|
-
* Add edge to graph
|
|
1013
|
-
*/
|
|
1014
|
-
addEdge(from, to, weight = 1.0) {
|
|
1015
|
-
this.edges.push({ from, to, weight });
|
|
1016
|
-
// Update neighbor lists
|
|
1017
|
-
const fromNode = this.nodes.get(from);
|
|
1018
|
-
const toNode = this.nodes.get(to);
|
|
1019
|
-
if (fromNode && !fromNode.neighbors.includes(to)) {
|
|
1020
|
-
fromNode.neighbors.push(to);
|
|
1021
|
-
}
|
|
1022
|
-
if (toNode && !toNode.neighbors.includes(from)) {
|
|
1023
|
-
toNode.neighbors.push(from);
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
/**
|
|
1027
|
-
* Graph Attention Network (GAT) message passing
|
|
1028
|
-
*/
|
|
1029
|
-
graphAttention(nodeId) {
|
|
1030
|
-
const node = this.nodes.get(nodeId);
|
|
1031
|
-
if (!node)
|
|
1032
|
-
throw new Error(`Node ${nodeId} not found`);
|
|
1033
|
-
const neighbors = node.neighbors;
|
|
1034
|
-
if (neighbors.length === 0) {
|
|
1035
|
-
return node.features;
|
|
1036
|
-
}
|
|
1037
|
-
// Multi-head attention
|
|
1038
|
-
const headDim = Math.floor(this.config.hiddenDim / this.config.numHeads);
|
|
1039
|
-
const aggregated = new Float32Array(this.config.hiddenDim);
|
|
1040
|
-
for (let h = 0; h < this.config.numHeads; h++) {
|
|
1041
|
-
let attentionSum = 0;
|
|
1042
|
-
const headOutput = new Float32Array(headDim);
|
|
1043
|
-
// Compute attention scores for each neighbor
|
|
1044
|
-
for (const neighborId of neighbors) {
|
|
1045
|
-
const neighbor = this.nodes.get(neighborId);
|
|
1046
|
-
// Attention score: similarity between node and neighbor
|
|
1047
|
-
const score = this.computeAttentionScore(node.features, neighbor.features, h);
|
|
1048
|
-
attentionSum += score;
|
|
1049
|
-
// Aggregate neighbor features weighted by attention
|
|
1050
|
-
for (let i = 0; i < headDim && i < neighbor.features.length; i++) {
|
|
1051
|
-
headOutput[i] += score * neighbor.features[i];
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
|
-
// Normalize by attention sum
|
|
1055
|
-
if (attentionSum > 0) {
|
|
1056
|
-
for (let i = 0; i < headDim; i++) {
|
|
1057
|
-
headOutput[i] /= attentionSum;
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
// Concatenate head outputs
|
|
1061
|
-
const offset = h * headDim;
|
|
1062
|
-
for (let i = 0; i < headDim; i++) {
|
|
1063
|
-
aggregated[offset + i] = headOutput[i];
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
// Apply non-linearity (LeakyReLU)
|
|
1067
|
-
for (let i = 0; i < aggregated.length; i++) {
|
|
1068
|
-
aggregated[i] = aggregated[i] > 0 ? aggregated[i] : 0.01 * aggregated[i];
|
|
1069
|
-
}
|
|
1070
|
-
return aggregated;
|
|
1071
|
-
}
|
|
1072
|
-
/**
|
|
1073
|
-
* Compute attention score between two nodes
|
|
1074
|
-
*/
|
|
1075
|
-
computeAttentionScore(features1, features2, head) {
|
|
1076
|
-
// Simple dot-product attention
|
|
1077
|
-
let score = 0;
|
|
1078
|
-
const len = Math.min(features1.length, features2.length);
|
|
1079
|
-
for (let i = 0; i < len; i++) {
|
|
1080
|
-
score += features1[i] * features2[i];
|
|
1081
|
-
}
|
|
1082
|
-
// Apply softmax-like normalization
|
|
1083
|
-
return Math.exp(score / Math.sqrt(len));
|
|
1084
|
-
}
|
|
1085
|
-
/**
|
|
1086
|
-
* Message passing for all nodes
|
|
1087
|
-
*/
|
|
1088
|
-
messagePass() {
|
|
1089
|
-
const newFeatures = new Map();
|
|
1090
|
-
for (const [nodeId] of this.nodes) {
|
|
1091
|
-
newFeatures.set(nodeId, this.graphAttention(nodeId));
|
|
1092
|
-
}
|
|
1093
|
-
return newFeatures;
|
|
1094
|
-
}
|
|
1095
|
-
/**
|
|
1096
|
-
* Update node features after message passing
|
|
1097
|
-
*/
|
|
1098
|
-
update(newFeatures) {
|
|
1099
|
-
for (const [nodeId, features] of newFeatures) {
|
|
1100
|
-
const node = this.nodes.get(nodeId);
|
|
1101
|
-
if (node) {
|
|
1102
|
-
node.features = features;
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
}
|
|
1106
|
-
/**
|
|
1107
|
-
* Compute graph embeddings for query enhancement
|
|
1108
|
-
*/
|
|
1109
|
-
computeGraphEmbedding(nodeId, hops = 2) {
|
|
1110
|
-
const features = new Map();
|
|
1111
|
-
features.set(nodeId, this.nodes.get(nodeId).features);
|
|
1112
|
-
// Multi-hop message passing
|
|
1113
|
-
for (let h = 0; h < hops; h++) {
|
|
1114
|
-
const newFeatures = this.messagePass();
|
|
1115
|
-
this.update(newFeatures);
|
|
1116
|
-
}
|
|
1117
|
-
return this.nodes.get(nodeId).features;
|
|
1118
|
-
}
|
|
1119
|
-
/**
|
|
1120
|
-
* Get statistics
|
|
1121
|
-
*/
|
|
1122
|
-
getStats() {
|
|
1123
|
-
return {
|
|
1124
|
-
numNodes: this.nodes.size,
|
|
1125
|
-
numEdges: this.edges.length,
|
|
1126
|
-
avgDegree: this.edges.length / Math.max(this.nodes.size, 1),
|
|
1127
|
-
config: this.config
|
|
1128
|
-
};
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
/**
|
|
1132
|
-
* Maximal Marginal Relevance for diversity ranking
|
|
1133
|
-
*/
|
|
1134
|
-
class MaximalMarginalRelevance {
|
|
1135
|
-
constructor(config = {}) {
|
|
1136
|
-
this.config = {
|
|
1137
|
-
lambda: config.lambda || 0.7,
|
|
1138
|
-
metric: config.metric || 'cosine'
|
|
1139
|
-
};
|
|
1140
|
-
}
|
|
1141
|
-
/**
|
|
1142
|
-
* Rerank results for diversity
|
|
1143
|
-
* @param query Query vector
|
|
1144
|
-
* @param candidates Candidate vectors with scores
|
|
1145
|
-
* @param k Number of results to return
|
|
1146
|
-
* @returns Reranked indices
|
|
1147
|
-
*/
|
|
1148
|
-
rerank(query, candidates, k) {
|
|
1149
|
-
if (candidates.length === 0)
|
|
1150
|
-
return [];
|
|
1151
|
-
const selected = [];
|
|
1152
|
-
const remaining = new Set(candidates.map((_, i) => i));
|
|
1153
|
-
// Select first result (highest relevance)
|
|
1154
|
-
let bestIdx = 0;
|
|
1155
|
-
let bestScore = -Infinity;
|
|
1156
|
-
for (let i = 0; i < candidates.length; i++) {
|
|
1157
|
-
if (candidates[i].score > bestScore) {
|
|
1158
|
-
bestScore = candidates[i].score;
|
|
1159
|
-
bestIdx = i;
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
selected.push(candidates[bestIdx].id);
|
|
1163
|
-
remaining.delete(bestIdx);
|
|
1164
|
-
// Iteratively select remaining results
|
|
1165
|
-
while (selected.length < k && remaining.size > 0) {
|
|
1166
|
-
let bestMMR = -Infinity;
|
|
1167
|
-
let bestCandidate = -1;
|
|
1168
|
-
for (const idx of remaining) {
|
|
1169
|
-
const candidate = candidates[idx];
|
|
1170
|
-
// Relevance to query
|
|
1171
|
-
const relevance = this.similarity(query, candidate.vector);
|
|
1172
|
-
// Maximum similarity to already selected
|
|
1173
|
-
let maxSimilarity = -Infinity;
|
|
1174
|
-
for (const selectedId of selected) {
|
|
1175
|
-
const selectedCandidate = candidates.find(c => c.id === selectedId);
|
|
1176
|
-
const sim = this.similarity(candidate.vector, selectedCandidate.vector);
|
|
1177
|
-
maxSimilarity = Math.max(maxSimilarity, sim);
|
|
1178
|
-
}
|
|
1179
|
-
// MMR score
|
|
1180
|
-
const mmr = this.config.lambda * relevance -
|
|
1181
|
-
(1 - this.config.lambda) * maxSimilarity;
|
|
1182
|
-
if (mmr > bestMMR) {
|
|
1183
|
-
bestMMR = mmr;
|
|
1184
|
-
bestCandidate = idx;
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
|
-
if (bestCandidate !== -1) {
|
|
1188
|
-
selected.push(candidates[bestCandidate].id);
|
|
1189
|
-
remaining.delete(bestCandidate);
|
|
1190
|
-
}
|
|
1191
|
-
else {
|
|
1192
|
-
break;
|
|
1193
|
-
}
|
|
1194
|
-
}
|
|
1195
|
-
return selected;
|
|
1196
|
-
}
|
|
1197
|
-
/**
|
|
1198
|
-
* Similarity computation
|
|
1199
|
-
*/
|
|
1200
|
-
similarity(a, b) {
|
|
1201
|
-
if (this.config.metric === 'cosine') {
|
|
1202
|
-
return this.cosineSimilarity(a, b);
|
|
1203
|
-
}
|
|
1204
|
-
else {
|
|
1205
|
-
// Euclidean distance converted to similarity
|
|
1206
|
-
const dist = this.euclideanDistance(a, b);
|
|
1207
|
-
return 1 / (1 + dist);
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1210
|
-
cosineSimilarity(a, b) {
|
|
1211
|
-
let dotProduct = 0;
|
|
1212
|
-
let normA = 0;
|
|
1213
|
-
let normB = 0;
|
|
1214
|
-
for (let i = 0; i < a.length; i++) {
|
|
1215
|
-
dotProduct += a[i] * b[i];
|
|
1216
|
-
normA += a[i] * a[i];
|
|
1217
|
-
normB += b[i] * b[i];
|
|
1218
|
-
}
|
|
1219
|
-
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
|
|
1220
|
-
}
|
|
1221
|
-
euclideanDistance(a, b) {
|
|
1222
|
-
let sum = 0;
|
|
1223
|
-
for (let i = 0; i < a.length; i++) {
|
|
1224
|
-
const diff = a[i] - b[i];
|
|
1225
|
-
sum += diff * diff;
|
|
1226
|
-
}
|
|
1227
|
-
return Math.sqrt(sum);
|
|
1228
|
-
}
|
|
1229
|
-
/**
|
|
1230
|
-
* Set lambda (relevance vs diversity trade-off)
|
|
1231
|
-
*/
|
|
1232
|
-
setLambda(lambda) {
|
|
1233
|
-
this.config.lambda = Math.max(0, Math.min(1, lambda));
|
|
1234
|
-
}
|
|
1235
|
-
}
|
|
1236
|
-
// ============================================================================
|
|
1237
|
-
// SVD (Singular Value Decomposition) for Tensor Compression
|
|
1238
|
-
// ============================================================================
|
|
1239
|
-
/**
|
|
1240
|
-
* Simple SVD implementation for dimension reduction
|
|
1241
|
-
*/
|
|
1242
|
-
class TensorCompression {
|
|
1243
|
-
/**
|
|
1244
|
-
* Reduce dimensionality using truncated SVD
|
|
1245
|
-
* @param vectors Array of vectors to compress
|
|
1246
|
-
* @param targetDim Target dimension
|
|
1247
|
-
* @returns Compressed vectors
|
|
1248
|
-
*/
|
|
1249
|
-
static compress(vectors, targetDim) {
|
|
1250
|
-
if (vectors.length === 0)
|
|
1251
|
-
return [];
|
|
1252
|
-
const originalDim = vectors[0].length;
|
|
1253
|
-
if (targetDim >= originalDim)
|
|
1254
|
-
return vectors;
|
|
1255
|
-
// Create matrix (vectors as rows)
|
|
1256
|
-
const matrix = vectors.map(v => Array.from(v));
|
|
1257
|
-
// Center the data (subtract mean)
|
|
1258
|
-
const mean = this.computeMean(matrix);
|
|
1259
|
-
const centered = matrix.map(row => row.map((val, i) => val - mean[i]));
|
|
1260
|
-
// Compute covariance matrix
|
|
1261
|
-
const cov = this.computeCovariance(centered);
|
|
1262
|
-
// Compute top k eigenvectors using power iteration
|
|
1263
|
-
const eigenvectors = this.powerIteration(cov, targetDim);
|
|
1264
|
-
// Project vectors onto eigenvectors
|
|
1265
|
-
const compressed = centered.map(row => {
|
|
1266
|
-
const projected = new Float32Array(targetDim);
|
|
1267
|
-
for (let i = 0; i < targetDim; i++) {
|
|
1268
|
-
let sum = 0;
|
|
1269
|
-
for (let j = 0; j < originalDim; j++) {
|
|
1270
|
-
sum += row[j] * eigenvectors[i][j];
|
|
1271
|
-
}
|
|
1272
|
-
projected[i] = sum;
|
|
1273
|
-
}
|
|
1274
|
-
return projected;
|
|
1275
|
-
});
|
|
1276
|
-
return compressed;
|
|
1277
|
-
}
|
|
1278
|
-
/**
|
|
1279
|
-
* Compute mean vector
|
|
1280
|
-
*/
|
|
1281
|
-
static computeMean(matrix) {
|
|
1282
|
-
const n = matrix.length;
|
|
1283
|
-
const dim = matrix[0].length;
|
|
1284
|
-
const mean = new Array(dim).fill(0);
|
|
1285
|
-
for (const row of matrix) {
|
|
1286
|
-
for (let i = 0; i < dim; i++) {
|
|
1287
|
-
mean[i] += row[i];
|
|
1288
|
-
}
|
|
1289
|
-
}
|
|
1290
|
-
return mean.map(v => v / n);
|
|
1291
|
-
}
|
|
1292
|
-
/**
|
|
1293
|
-
* Compute covariance matrix
|
|
1294
|
-
*/
|
|
1295
|
-
static computeCovariance(matrix) {
|
|
1296
|
-
const n = matrix.length;
|
|
1297
|
-
const dim = matrix[0].length;
|
|
1298
|
-
const cov = Array.from({ length: dim }, () => new Array(dim).fill(0));
|
|
1299
|
-
for (let i = 0; i < dim; i++) {
|
|
1300
|
-
for (let j = 0; j <= i; j++) {
|
|
1301
|
-
let sum = 0;
|
|
1302
|
-
for (const row of matrix) {
|
|
1303
|
-
sum += row[i] * row[j];
|
|
1304
|
-
}
|
|
1305
|
-
cov[i][j] = cov[j][i] = sum / n;
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
return cov;
|
|
1309
|
-
}
|
|
1310
|
-
/**
|
|
1311
|
-
* Power iteration for computing top eigenvectors
|
|
1312
|
-
*/
|
|
1313
|
-
static powerIteration(matrix, k, iterations = 100) {
|
|
1314
|
-
const dim = matrix.length;
|
|
1315
|
-
const eigenvectors = [];
|
|
1316
|
-
for (let i = 0; i < k; i++) {
|
|
1317
|
-
// Random initialization
|
|
1318
|
-
let v = new Array(dim).fill(0).map(() => Math.random() - 0.5);
|
|
1319
|
-
// Power iteration
|
|
1320
|
-
for (let iter = 0; iter < iterations; iter++) {
|
|
1321
|
-
// Multiply by matrix
|
|
1322
|
-
const newV = new Array(dim).fill(0);
|
|
1323
|
-
for (let r = 0; r < dim; r++) {
|
|
1324
|
-
for (let c = 0; c < dim; c++) {
|
|
1325
|
-
newV[r] += matrix[r][c] * v[c];
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
1328
|
-
// Orthogonalize against previous eigenvectors
|
|
1329
|
-
for (const prev of eigenvectors) {
|
|
1330
|
-
let dot = 0;
|
|
1331
|
-
for (let j = 0; j < dim; j++) {
|
|
1332
|
-
dot += newV[j] * prev[j];
|
|
1333
|
-
}
|
|
1334
|
-
for (let j = 0; j < dim; j++) {
|
|
1335
|
-
newV[j] -= dot * prev[j];
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
|
-
// Normalize
|
|
1339
|
-
let norm = 0;
|
|
1340
|
-
for (const val of newV) {
|
|
1341
|
-
norm += val * val;
|
|
1342
|
-
}
|
|
1343
|
-
norm = Math.sqrt(norm);
|
|
1344
|
-
if (norm < 1e-10)
|
|
1345
|
-
break;
|
|
1346
|
-
v = newV.map(val => val / norm);
|
|
1347
|
-
}
|
|
1348
|
-
eigenvectors.push(v);
|
|
1349
|
-
}
|
|
1350
|
-
return eigenvectors;
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
// ============================================================================
|
|
1354
|
-
// Batch Operations
|
|
1355
|
-
// ============================================================================
|
|
1356
|
-
/**
|
|
1357
|
-
* Efficient batch processing utilities
|
|
1358
|
-
*/
|
|
1359
|
-
class BatchProcessor {
|
|
1360
|
-
/**
|
|
1361
|
-
* Batch cosine similarity computation
|
|
1362
|
-
*/
|
|
1363
|
-
static batchCosineSimilarity(query, vectors) {
|
|
1364
|
-
const similarities = new Float32Array(vectors.length);
|
|
1365
|
-
// Precompute query norm
|
|
1366
|
-
let queryNorm = 0;
|
|
1367
|
-
for (let i = 0; i < query.length; i++) {
|
|
1368
|
-
queryNorm += query[i] * query[i];
|
|
1369
|
-
}
|
|
1370
|
-
queryNorm = Math.sqrt(queryNorm);
|
|
1371
|
-
// Compute similarities
|
|
1372
|
-
for (let v = 0; v < vectors.length; v++) {
|
|
1373
|
-
const vector = vectors[v];
|
|
1374
|
-
let dotProduct = 0;
|
|
1375
|
-
let vectorNorm = 0;
|
|
1376
|
-
for (let i = 0; i < query.length; i++) {
|
|
1377
|
-
dotProduct += query[i] * vector[i];
|
|
1378
|
-
vectorNorm += vector[i] * vector[i];
|
|
1379
|
-
}
|
|
1380
|
-
vectorNorm = Math.sqrt(vectorNorm);
|
|
1381
|
-
similarities[v] = dotProduct / (queryNorm * vectorNorm);
|
|
1382
|
-
}
|
|
1383
|
-
return similarities;
|
|
1384
|
-
}
|
|
1385
|
-
/**
|
|
1386
|
-
* Batch vector normalization
|
|
1387
|
-
*/
|
|
1388
|
-
static batchNormalize(vectors) {
|
|
1389
|
-
return vectors.map(v => {
|
|
1390
|
-
let norm = 0;
|
|
1391
|
-
for (let i = 0; i < v.length; i++) {
|
|
1392
|
-
norm += v[i] * v[i];
|
|
1393
|
-
}
|
|
1394
|
-
norm = Math.sqrt(norm);
|
|
1395
|
-
const normalized = new Float32Array(v.length);
|
|
1396
|
-
for (let i = 0; i < v.length; i++) {
|
|
1397
|
-
normalized[i] = v[i] / norm;
|
|
1398
|
-
}
|
|
1399
|
-
return normalized;
|
|
1400
|
-
});
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
// ============================================================================
|
|
1406
|
-
// Feature Index & Utilities
|
|
1407
|
-
// ============================================================================
|
|
1408
|
-
|
|
1409
|
-
/**
|
|
1410
|
-
* AgentDB Browser Advanced Features
|
|
1411
|
-
*
|
|
1412
|
-
* Unified for all browser-compatible advanced features.
|
|
1413
|
-
*
|
|
1414
|
-
* Features:
|
|
1415
|
-
* - Product Quantization (PQ8/PQ16/PQ32) - 4-32x memory compression
|
|
1416
|
-
* - HNSW Indexing - 10-20x faster approximate search
|
|
1417
|
-
* - Graph Neural Networks - Graph attention and message passing
|
|
1418
|
-
* - MMR Diversity - Maximal marginal relevance ranking
|
|
1419
|
-
* - Tensor Compression - SVD dimension reduction
|
|
1420
|
-
* - Batch Operations - Optimized vector processing
|
|
1421
|
-
*
|
|
1422
|
-
* Bundle Size: ~35 KB minified (~12 KB gzipped)
|
|
1423
|
-
*/
|
|
1424
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
1425
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1426
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1427
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1428
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1429
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1430
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1431
|
-
});
|
|
1432
|
-
};
|
|
1433
|
-
// ============================================================================
|
|
1434
|
-
// Product Quantization
|
|
1435
|
-
// ============================================================================
|
|
1436
|
-
// ============================================================================
|
|
1437
|
-
// HNSW Indexing
|
|
1438
|
-
// ============================================================================
|
|
1439
|
-
// ============================================================================
|
|
1440
|
-
// Advanced Features
|
|
1441
|
-
// ============================================================================
|
|
1442
|
-
// ============================================================================
|
|
1443
|
-
// Feature Detection
|
|
1444
|
-
// ============================================================================
|
|
1445
|
-
/**
|
|
1446
|
-
* Detect available browser features
|
|
1447
|
-
*/
|
|
1448
|
-
function detectFeatures() {
|
|
1449
|
-
return {
|
|
1450
|
-
indexedDB: 'indexedDB' in globalThis,
|
|
1451
|
-
broadcastChannel: 'BroadcastChannel' in globalThis,
|
|
1452
|
-
webWorkers: typeof Worker !== 'undefined',
|
|
1453
|
-
wasmSIMD: detectWasmSIMD(),
|
|
1454
|
-
sharedArrayBuffer: typeof SharedArrayBuffer !== 'undefined'
|
|
1455
|
-
};
|
|
1456
|
-
}
|
|
1457
|
-
/**
|
|
1458
|
-
* Detect WASM SIMD support
|
|
1459
|
-
*/
|
|
1460
|
-
function detectWasmSIMD() {
|
|
1461
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1462
|
-
try {
|
|
1463
|
-
// WASM SIMD detection via feature test
|
|
1464
|
-
const simdTest = new Uint8Array([
|
|
1465
|
-
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,
|
|
1466
|
-
0x01, 0x05, 0x01, 0x60, 0x00, 0x01, 0x7b, 0x03,
|
|
1467
|
-
0x02, 0x01, 0x00, 0x0a, 0x0a, 0x01, 0x08, 0x00,
|
|
1468
|
-
0xfd, 0x0c, 0xfd, 0x0c, 0xfd, 0x54, 0x0b
|
|
1469
|
-
]);
|
|
1470
|
-
const module = yield WebAssembly.instantiate(simdTest);
|
|
1471
|
-
return module instanceof WebAssembly.Instance;
|
|
1472
|
-
}
|
|
1473
|
-
catch (_a) {
|
|
1474
|
-
return false;
|
|
1475
|
-
}
|
|
1476
|
-
});
|
|
1477
|
-
}
|
|
1478
|
-
// ============================================================================
|
|
1479
|
-
// Configuration Presets
|
|
1480
|
-
// ============================================================================
|
|
1481
|
-
/**
|
|
1482
|
-
* Recommended configuration for small datasets (<1K vectors)
|
|
1483
|
-
*/
|
|
1484
|
-
const SMALL_DATASET_CONFIG = {
|
|
1485
|
-
pq: { enabled: false },
|
|
1486
|
-
hnsw: { enabled: false },
|
|
1487
|
-
gnn: { enabled: true, numHeads: 2 },
|
|
1488
|
-
mmr: { enabled: true, lambda: 0.7 },
|
|
1489
|
-
svd: { enabled: false }
|
|
1490
|
-
};
|
|
1491
|
-
/**
|
|
1492
|
-
* Recommended configuration for medium datasets (1K-10K vectors)
|
|
1493
|
-
*/
|
|
1494
|
-
const MEDIUM_DATASET_CONFIG = {
|
|
1495
|
-
pq: { enabled: true, subvectors: 8 },
|
|
1496
|
-
hnsw: { enabled: true, M: 16 },
|
|
1497
|
-
gnn: { enabled: true, numHeads: 4 },
|
|
1498
|
-
mmr: { enabled: true, lambda: 0.7 },
|
|
1499
|
-
svd: { enabled: false }
|
|
1500
|
-
};
|
|
1501
|
-
/**
|
|
1502
|
-
* Recommended configuration for large datasets (10K-100K vectors)
|
|
1503
|
-
*/
|
|
1504
|
-
const LARGE_DATASET_CONFIG = {
|
|
1505
|
-
pq: { enabled: true, subvectors: 16 },
|
|
1506
|
-
hnsw: { enabled: true, M: 32 },
|
|
1507
|
-
gnn: { enabled: true, numHeads: 4 },
|
|
1508
|
-
mmr: { enabled: true, lambda: 0.7 },
|
|
1509
|
-
svd: { enabled: true, targetDim: 128 }
|
|
1510
|
-
};
|
|
1511
|
-
/**
|
|
1512
|
-
* Memory-optimized configuration (minimal memory usage)
|
|
1513
|
-
*/
|
|
1514
|
-
const MEMORY_OPTIMIZED_CONFIG = {
|
|
1515
|
-
pq: { enabled: true, subvectors: 32 }, // 16x compression
|
|
1516
|
-
hnsw: { enabled: true, M: 8 }, // Fewer connections
|
|
1517
|
-
gnn: { enabled: false },
|
|
1518
|
-
mmr: { enabled: false },
|
|
1519
|
-
svd: { enabled: true, targetDim: 64 } // Aggressive dimension reduction
|
|
1520
|
-
};
|
|
1521
|
-
/**
|
|
1522
|
-
* Speed-optimized configuration (fastest search)
|
|
1523
|
-
*/
|
|
1524
|
-
const SPEED_OPTIMIZED_CONFIG = {
|
|
1525
|
-
pq: { enabled: false }, // No compression overhead
|
|
1526
|
-
hnsw: { enabled: true, M: 32, efSearch: 100 }, // Maximum HNSW quality
|
|
1527
|
-
gnn: { enabled: false },
|
|
1528
|
-
mmr: { enabled: false },
|
|
1529
|
-
svd: { enabled: false }
|
|
1530
|
-
};
|
|
1531
|
-
/**
|
|
1532
|
-
* Quality-optimized configuration (best result quality)
|
|
1533
|
-
*/
|
|
1534
|
-
const QUALITY_OPTIMIZED_CONFIG = {
|
|
1535
|
-
pq: { enabled: false }, // No compression
|
|
1536
|
-
hnsw: { enabled: true, M: 48, efConstruction: 400 }, // Highest quality
|
|
1537
|
-
gnn: { enabled: true, numHeads: 8 }, // More attention heads
|
|
1538
|
-
mmr: { enabled: true, lambda: 0.8 }, // More diversity
|
|
1539
|
-
svd: { enabled: false } // No dimension loss
|
|
1540
|
-
};
|
|
1541
|
-
// ============================================================================
|
|
1542
|
-
// Version Information
|
|
1543
|
-
// ============================================================================
|
|
1544
|
-
const VERSION = {
|
|
1545
|
-
major: 2,
|
|
1546
|
-
minor: 0,
|
|
1547
|
-
patch: 0,
|
|
1548
|
-
prerelease: 'alpha.2',
|
|
1549
|
-
features: 'advanced',
|
|
1550
|
-
full: '2.0.0-alpha.2+advanced'
|
|
1551
|
-
};
|
|
1552
|
-
// ============================================================================
|
|
1553
|
-
// Utility Functions
|
|
1554
|
-
// ============================================================================
|
|
1555
|
-
/**
|
|
1556
|
-
* Estimate memory usage for configuration
|
|
1557
|
-
*/
|
|
1558
|
-
function estimateMemoryUsage(numVectors, dimension, config) {
|
|
1559
|
-
var _a, _b, _c;
|
|
1560
|
-
let vectorBytes = numVectors * dimension * 4; // Float32Array
|
|
1561
|
-
// Apply PQ compression
|
|
1562
|
-
if ((_a = config.pq) === null || _a === void 0 ? void 0 : _a.enabled) {
|
|
1563
|
-
const subvectors = config.pq.subvectors || 8;
|
|
1564
|
-
vectorBytes = numVectors * (subvectors + 4); // codes + norm
|
|
1565
|
-
}
|
|
1566
|
-
// Apply SVD compression
|
|
1567
|
-
if ((_b = config.svd) === null || _b === void 0 ? void 0 : _b.enabled) {
|
|
1568
|
-
const targetDim = config.svd.targetDim || dimension / 2;
|
|
1569
|
-
vectorBytes = numVectors * targetDim * 4;
|
|
1570
|
-
}
|
|
1571
|
-
// HNSW index overhead
|
|
1572
|
-
let indexBytes = 0;
|
|
1573
|
-
if ((_c = config.hnsw) === null || _c === void 0 ? void 0 : _c.enabled) {
|
|
1574
|
-
const M = config.hnsw.M || 16;
|
|
1575
|
-
const avgConnections = M * 1.5; // Estimate
|
|
1576
|
-
indexBytes = numVectors * avgConnections * 4; // Connection IDs
|
|
1577
|
-
}
|
|
1578
|
-
const total = vectorBytes + indexBytes;
|
|
1579
|
-
return {
|
|
1580
|
-
vectors: vectorBytes,
|
|
1581
|
-
index: indexBytes,
|
|
1582
|
-
total,
|
|
1583
|
-
totalMB: total / (1024 * 1024)
|
|
1584
|
-
};
|
|
1585
|
-
}
|
|
1586
|
-
/**
|
|
1587
|
-
* Recommend configuration based on dataset size
|
|
1588
|
-
*/
|
|
1589
|
-
function recommendConfig(numVectors, dimension) {
|
|
1590
|
-
if (numVectors < 1000) {
|
|
1591
|
-
return {
|
|
1592
|
-
name: 'SMALL_DATASET',
|
|
1593
|
-
config: SMALL_DATASET_CONFIG,
|
|
1594
|
-
reason: 'Small dataset, linear search is fast enough'
|
|
1595
|
-
};
|
|
1596
|
-
}
|
|
1597
|
-
else if (numVectors < 10000) {
|
|
1598
|
-
return {
|
|
1599
|
-
name: 'MEDIUM_DATASET',
|
|
1600
|
-
config: MEDIUM_DATASET_CONFIG,
|
|
1601
|
-
reason: 'Medium dataset, HNSW + PQ8 recommended'
|
|
1602
|
-
};
|
|
1603
|
-
}
|
|
1604
|
-
else {
|
|
1605
|
-
return {
|
|
1606
|
-
name: 'LARGE_DATASET',
|
|
1607
|
-
config: LARGE_DATASET_CONFIG,
|
|
1608
|
-
reason: 'Large dataset, aggressive compression + HNSW recommended'
|
|
1609
|
-
};
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
/**
|
|
1613
|
-
* Benchmark search performance
|
|
1614
|
-
*/
|
|
1615
|
-
function benchmarkSearch(searchFn_1) {
|
|
1616
|
-
return __awaiter(this, arguments, void 0, function* (searchFn, numQueries = 100, k = 10, dimension = 384) {
|
|
1617
|
-
const times = [];
|
|
1618
|
-
for (let i = 0; i < numQueries; i++) {
|
|
1619
|
-
const query = new Float32Array(dimension);
|
|
1620
|
-
for (let d = 0; d < dimension; d++) {
|
|
1621
|
-
query[d] = Math.random() - 0.5;
|
|
1622
|
-
}
|
|
1623
|
-
const start = performance.now();
|
|
1624
|
-
searchFn(query, k);
|
|
1625
|
-
const end = performance.now();
|
|
1626
|
-
times.push(end - start);
|
|
1627
|
-
}
|
|
1628
|
-
times.sort((a, b) => a - b);
|
|
1629
|
-
return {
|
|
1630
|
-
avgTimeMs: times.reduce((a, b) => a + b, 0) / times.length,
|
|
1631
|
-
minTimeMs: times[0],
|
|
1632
|
-
maxTimeMs: times[times.length - 1],
|
|
1633
|
-
p50Ms: times[Math.floor(times.length * 0.5)],
|
|
1634
|
-
p95Ms: times[Math.floor(times.length * 0.95)],
|
|
1635
|
-
p99Ms: times[Math.floor(times.length * 0.99)]
|
|
1636
|
-
};
|
|
1637
|
-
});
|
|
1638
|
-
}
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
// ============================================================================
|
|
1642
|
-
// Create Advanced Features Namespace
|
|
1643
|
-
// ============================================================================
|
|
1644
|
-
|
|
1645
|
-
// Create global namespace for advanced features
|
|
1646
|
-
const AgentDBAdvanced = {
|
|
1647
|
-
// Product Quantization
|
|
1648
|
-
ProductQuantization: ProductQuantization,
|
|
1649
|
-
createPQ8: createPQ8,
|
|
1650
|
-
createPQ16: createPQ16,
|
|
1651
|
-
createPQ32: createPQ32,
|
|
1652
|
-
|
|
1653
|
-
// HNSW Index
|
|
1654
|
-
HNSWIndex: HNSWIndex,
|
|
1655
|
-
createHNSW: createHNSW,
|
|
1656
|
-
createFastHNSW: createFastHNSW,
|
|
1657
|
-
createAccurateHNSW: createAccurateHNSW,
|
|
1658
|
-
|
|
1659
|
-
// Advanced Features
|
|
1660
|
-
GraphNeuralNetwork: GraphNeuralNetwork,
|
|
1661
|
-
MaximalMarginalRelevance: MaximalMarginalRelevance,
|
|
1662
|
-
TensorCompression: TensorCompression,
|
|
1663
|
-
BatchProcessor: BatchProcessor,
|
|
1664
|
-
|
|
1665
|
-
// Utilities
|
|
1666
|
-
detectFeatures: detectFeatures,
|
|
1667
|
-
estimateMemoryUsage: estimateMemoryUsage,
|
|
1668
|
-
recommendConfig: recommendConfig,
|
|
1669
|
-
benchmarkSearch: benchmarkSearch,
|
|
1670
|
-
|
|
1671
|
-
// Configuration Presets
|
|
1672
|
-
SMALL_DATASET_CONFIG: SMALL_DATASET_CONFIG,
|
|
1673
|
-
MEDIUM_DATASET_CONFIG: MEDIUM_DATASET_CONFIG,
|
|
1674
|
-
LARGE_DATASET_CONFIG: LARGE_DATASET_CONFIG,
|
|
1675
|
-
MEMORY_OPTIMIZED_CONFIG: MEMORY_OPTIMIZED_CONFIG,
|
|
1676
|
-
SPEED_OPTIMIZED_CONFIG: SPEED_OPTIMIZED_CONFIG,
|
|
1677
|
-
QUALITY_OPTIMIZED_CONFIG: QUALITY_OPTIMIZED_CONFIG,
|
|
1678
|
-
|
|
1679
|
-
// Version
|
|
1680
|
-
VERSION: VERSION
|
|
1681
|
-
};
|
|
1682
|
-
|
|
1683
|
-
// Expose to global for use in AgentDB initialization
|
|
1684
|
-
global.AgentDBAdvanced = AgentDBAdvanced;
|
|
1685
|
-
|
|
1686
|
-
// ============================================================================
|
|
1687
|
-
// AgentDB v2 API with Advanced Features
|
|
1688
|
-
// ============================================================================
|
|
1689
|
-
|
|
1690
|
-
const AgentDB = {};
|
|
1691
|
-
|
|
1692
|
-
// SQL.js database wrapper with advanced features
|
|
1693
|
-
AgentDB.SQLiteVectorDB = function(config) {
|
|
1694
|
-
config = config || {};
|
|
1695
|
-
const self = this;
|
|
1696
|
-
|
|
1697
|
-
// Configuration
|
|
1698
|
-
const enablePQ = config.enablePQ !== false;
|
|
1699
|
-
const enableHNSW = config.enableHNSW !== false;
|
|
1700
|
-
const enableGNN = config.enableGNN !== false;
|
|
1701
|
-
const enableMMR = config.enableMMR !== false;
|
|
1702
|
-
const enableSVD = config.enableSVD || false;
|
|
1703
|
-
const enableIndexedDB = config.enableIndexedDB !== false && ('indexedDB' in global);
|
|
1704
|
-
const enableCrossTab = config.enableCrossTab !== false && ('BroadcastChannel' in global);
|
|
1705
|
-
|
|
1706
|
-
// Initialize sql.js
|
|
1707
|
-
let db = null;
|
|
1708
|
-
|
|
1709
|
-
// Advanced feature instances
|
|
1710
|
-
let pqInstance = null;
|
|
1711
|
-
let hnswInstance = null;
|
|
1712
|
-
let gnnInstance = null;
|
|
1713
|
-
let mmrInstance = null;
|
|
1714
|
-
|
|
1715
|
-
// Mock embeddings function (deterministic hash)
|
|
1716
|
-
function mockEmbed(text) {
|
|
1717
|
-
const embedding = new Float32Array(384);
|
|
1718
|
-
let hash = 0;
|
|
1719
|
-
for (let i = 0; i < text.length; i++) {
|
|
1720
|
-
hash = ((hash << 5) - hash) + text.charCodeAt(i);
|
|
1721
|
-
hash = hash & hash;
|
|
1722
|
-
}
|
|
1723
|
-
for (let i = 0; i < 384; i++) {
|
|
1724
|
-
const seed = hash + i * 997;
|
|
1725
|
-
embedding[i] = (Math.sin(seed) + Math.cos(seed * 1.618)) * 0.5;
|
|
1726
|
-
}
|
|
1727
|
-
const norm = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
|
|
1728
|
-
for (let i = 0; i < 384; i++) {
|
|
1729
|
-
embedding[i] /= norm;
|
|
1730
|
-
}
|
|
1731
|
-
return embedding;
|
|
1732
|
-
}
|
|
1733
|
-
|
|
1734
|
-
// Initialize database
|
|
1735
|
-
this.initializeAsync = function() {
|
|
1736
|
-
return new Promise(function(resolve, reject) {
|
|
1737
|
-
global.initSqlJs().then(function(SQL) {
|
|
1738
|
-
db = new SQL.Database();
|
|
1739
|
-
|
|
1740
|
-
// Create v2 schema
|
|
1741
|
-
db.run(`CREATE TABLE IF NOT EXISTS episodes (
|
|
1742
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1743
|
-
session_id TEXT NOT NULL,
|
|
1744
|
-
task TEXT NOT NULL,
|
|
1745
|
-
input TEXT,
|
|
1746
|
-
output TEXT,
|
|
1747
|
-
critique TEXT,
|
|
1748
|
-
reward REAL NOT NULL,
|
|
1749
|
-
tokens_used INTEGER,
|
|
1750
|
-
latency_ms REAL,
|
|
1751
|
-
success BOOLEAN NOT NULL,
|
|
1752
|
-
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
1753
|
-
)`);
|
|
1754
|
-
|
|
1755
|
-
db.run(`CREATE TABLE IF NOT EXISTS episode_embeddings (
|
|
1756
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1757
|
-
episode_id INTEGER NOT NULL,
|
|
1758
|
-
embedding BLOB NOT NULL,
|
|
1759
|
-
FOREIGN KEY (episode_id) REFERENCES episodes(id) ON DELETE CASCADE
|
|
1760
|
-
)`);
|
|
1761
|
-
|
|
1762
|
-
db.run(`CREATE TABLE IF NOT EXISTS skills (
|
|
1763
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1764
|
-
name TEXT UNIQUE NOT NULL,
|
|
1765
|
-
code TEXT NOT NULL,
|
|
1766
|
-
signature TEXT NOT NULL,
|
|
1767
|
-
success_rate REAL DEFAULT 0.0,
|
|
1768
|
-
uses INTEGER DEFAULT 0,
|
|
1769
|
-
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
1770
|
-
)`);
|
|
1771
|
-
|
|
1772
|
-
db.run(`CREATE TABLE IF NOT EXISTS skill_embeddings (
|
|
1773
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1774
|
-
skill_id INTEGER NOT NULL,
|
|
1775
|
-
embedding BLOB NOT NULL,
|
|
1776
|
-
FOREIGN KEY (skill_id) REFERENCES skills(id) ON DELETE CASCADE
|
|
1777
|
-
)`);
|
|
1778
|
-
|
|
1779
|
-
db.run(`CREATE TABLE IF NOT EXISTS causal_edges (
|
|
1780
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1781
|
-
from_memory_id INTEGER NOT NULL,
|
|
1782
|
-
to_memory_id INTEGER NOT NULL,
|
|
1783
|
-
similarity REAL NOT NULL,
|
|
1784
|
-
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
1785
|
-
FOREIGN KEY (from_memory_id) REFERENCES episodes(id) ON DELETE CASCADE,
|
|
1786
|
-
FOREIGN KEY (to_memory_id) REFERENCES episodes(id) ON DELETE CASCADE
|
|
1787
|
-
)`);
|
|
1788
|
-
|
|
1789
|
-
// Legacy v1 tables
|
|
1790
|
-
db.run(`CREATE TABLE IF NOT EXISTS vectors (
|
|
1791
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1792
|
-
content TEXT,
|
|
1793
|
-
embedding BLOB
|
|
1794
|
-
)`);
|
|
1795
|
-
|
|
1796
|
-
db.run(`CREATE TABLE IF NOT EXISTS patterns (
|
|
1797
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1798
|
-
pattern TEXT,
|
|
1799
|
-
metadata TEXT
|
|
1800
|
-
)`);
|
|
1801
|
-
|
|
1802
|
-
// Initialize advanced features
|
|
1803
|
-
if (enablePQ) {
|
|
1804
|
-
pqInstance = global.AgentDBAdvanced.createPQ8(384);
|
|
1805
|
-
console.log('[AgentDB] Product Quantization (PQ8) enabled');
|
|
1806
|
-
}
|
|
1807
|
-
|
|
1808
|
-
if (enableHNSW) {
|
|
1809
|
-
hnswInstance = global.AgentDBAdvanced.createHNSW(384);
|
|
1810
|
-
console.log('[AgentDB] HNSW Indexing enabled');
|
|
1811
|
-
}
|
|
1812
|
-
|
|
1813
|
-
if (enableGNN) {
|
|
1814
|
-
gnnInstance = new global.AgentDBAdvanced.GraphNeuralNetwork({ numHeads: 4 });
|
|
1815
|
-
console.log('[AgentDB] Graph Neural Networks enabled');
|
|
1816
|
-
}
|
|
1817
|
-
|
|
1818
|
-
if (enableMMR) {
|
|
1819
|
-
mmrInstance = new global.AgentDBAdvanced.MaximalMarginalRelevance({ lambda: 0.7 });
|
|
1820
|
-
console.log('[AgentDB] MMR Diversity enabled');
|
|
1821
|
-
}
|
|
1822
|
-
|
|
1823
|
-
console.log('[AgentDB] Initialized with advanced features');
|
|
1824
|
-
resolve(self);
|
|
1825
|
-
}).catch(reject);
|
|
1826
|
-
});
|
|
1827
|
-
};
|
|
1828
|
-
|
|
1829
|
-
// v2 Episodes API
|
|
1830
|
-
this.episodes = {
|
|
1831
|
-
store: async function(episodeData) {
|
|
1832
|
-
const stmt = db.prepare(`
|
|
1833
|
-
INSERT INTO episodes (session_id, task, input, output, critique, reward, tokens_used, latency_ms, success)
|
|
1834
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1835
|
-
`);
|
|
1836
|
-
stmt.run([
|
|
1837
|
-
episodeData.sessionId || 'default',
|
|
1838
|
-
episodeData.task,
|
|
1839
|
-
episodeData.input || '',
|
|
1840
|
-
episodeData.output || '',
|
|
1841
|
-
episodeData.critique || '',
|
|
1842
|
-
episodeData.reward,
|
|
1843
|
-
episodeData.tokensUsed || 0,
|
|
1844
|
-
episodeData.latencyMs || 0,
|
|
1845
|
-
episodeData.success ? 1 : 0
|
|
1846
|
-
]);
|
|
1847
|
-
const id = db.exec('SELECT last_insert_rowid()')[0].values[0][0];
|
|
1848
|
-
|
|
1849
|
-
const embedding = mockEmbed(episodeData.task);
|
|
1850
|
-
const embeddingBlob = new Uint8Array(embedding.buffer);
|
|
1851
|
-
|
|
1852
|
-
const embStmt = db.prepare('INSERT INTO episode_embeddings (episode_id, embedding) VALUES (?, ?)');
|
|
1853
|
-
embStmt.run([id, embeddingBlob]);
|
|
1854
|
-
|
|
1855
|
-
// Add to HNSW index if enabled
|
|
1856
|
-
if (enableHNSW && hnswInstance) {
|
|
1857
|
-
hnswInstance.add(embedding, id);
|
|
1858
|
-
}
|
|
1859
|
-
|
|
1860
|
-
// Add to GNN if enabled
|
|
1861
|
-
if (enableGNN && gnnInstance) {
|
|
1862
|
-
gnnInstance.addNode(id, embedding);
|
|
1863
|
-
}
|
|
1864
|
-
|
|
1865
|
-
return id;
|
|
1866
|
-
},
|
|
1867
|
-
|
|
1868
|
-
search: async function(options) {
|
|
1869
|
-
const query = options.task;
|
|
1870
|
-
const k = options.k || 10;
|
|
1871
|
-
const minReward = options.minReward;
|
|
1872
|
-
const onlySuccesses = options.onlySuccesses;
|
|
1873
|
-
const diversify = options.diversify && enableMMR;
|
|
1874
|
-
|
|
1875
|
-
const queryEmbedding = mockEmbed(query);
|
|
1876
|
-
|
|
1877
|
-
let results;
|
|
1878
|
-
|
|
1879
|
-
if (enableHNSW && hnswInstance && hnswInstance.size() > 0) {
|
|
1880
|
-
// Use HNSW for fast search
|
|
1881
|
-
results = hnswInstance.search(queryEmbedding, k * 2); // Get more for filtering
|
|
1882
|
-
} else {
|
|
1883
|
-
// Fallback to linear scan
|
|
1884
|
-
results = self._linearSearch(queryEmbedding, k * 2, 'episodes');
|
|
1885
|
-
}
|
|
1886
|
-
|
|
1887
|
-
// Filter by criteria
|
|
1888
|
-
let filtered = results.map(r => {
|
|
1889
|
-
const episode = db.exec(`SELECT * FROM episodes WHERE id = ${r.id}`)[0];
|
|
1890
|
-
if (!episode || !episode.values.length) return null;
|
|
1891
|
-
|
|
1892
|
-
const row = episode.values[0];
|
|
1893
|
-
const episodeObj = {
|
|
1894
|
-
id: row[0],
|
|
1895
|
-
session_id: row[1],
|
|
1896
|
-
task: row[2],
|
|
1897
|
-
reward: row[5],
|
|
1898
|
-
success: row[8] === 1,
|
|
1899
|
-
distance: r.distance,
|
|
1900
|
-
similarity: 1 - r.distance
|
|
1901
|
-
};
|
|
1902
|
-
|
|
1903
|
-
// Apply filters
|
|
1904
|
-
if (minReward && episodeObj.reward < minReward) return null;
|
|
1905
|
-
if (onlySuccesses && !episodeObj.success) return null;
|
|
1906
|
-
|
|
1907
|
-
return episodeObj;
|
|
1908
|
-
}).filter(e => e !== null);
|
|
1909
|
-
|
|
1910
|
-
// Apply MMR diversity if enabled
|
|
1911
|
-
if (diversify && mmrInstance && filtered.length > k) {
|
|
1912
|
-
const candidates = filtered.map(e => ({
|
|
1913
|
-
id: e.id,
|
|
1914
|
-
vector: results.find(r => r.id === e.id).vector,
|
|
1915
|
-
score: e.similarity
|
|
1916
|
-
}));
|
|
1917
|
-
const diverseIds = mmrInstance.rerank(queryEmbedding, candidates, k);
|
|
1918
|
-
filtered = diverseIds.map(id => filtered.find(e => e.id === id));
|
|
1919
|
-
} else {
|
|
1920
|
-
filtered = filtered.slice(0, k);
|
|
1921
|
-
}
|
|
1922
|
-
|
|
1923
|
-
return filtered;
|
|
1924
|
-
}
|
|
1925
|
-
};
|
|
1926
|
-
|
|
1927
|
-
// v2 Skills API
|
|
1928
|
-
this.skills = {
|
|
1929
|
-
store: async function(skillData) {
|
|
1930
|
-
const stmt = db.prepare(`
|
|
1931
|
-
INSERT INTO skills (name, code, signature, success_rate, uses)
|
|
1932
|
-
VALUES (?, ?, ?, ?, ?)
|
|
1933
|
-
ON CONFLICT(name) DO UPDATE SET
|
|
1934
|
-
code = excluded.code,
|
|
1935
|
-
signature = excluded.signature,
|
|
1936
|
-
success_rate = excluded.success_rate,
|
|
1937
|
-
uses = excluded.uses
|
|
1938
|
-
`);
|
|
1939
|
-
stmt.run([
|
|
1940
|
-
skillData.name,
|
|
1941
|
-
skillData.code,
|
|
1942
|
-
skillData.signature,
|
|
1943
|
-
skillData.successRate || 0.0,
|
|
1944
|
-
skillData.uses || 0
|
|
1945
|
-
]);
|
|
1946
|
-
const id = db.exec('SELECT last_insert_rowid()')[0].values[0][0];
|
|
1947
|
-
|
|
1948
|
-
const embedding = mockEmbed(skillData.name + ' ' + skillData.signature);
|
|
1949
|
-
const embeddingBlob = new Uint8Array(embedding.buffer);
|
|
1950
|
-
|
|
1951
|
-
const embStmt = db.prepare('INSERT INTO skill_embeddings (skill_id, embedding) VALUES (?, ?)');
|
|
1952
|
-
embStmt.run([id, embeddingBlob]);
|
|
1953
|
-
|
|
1954
|
-
return id;
|
|
1955
|
-
},
|
|
1956
|
-
|
|
1957
|
-
search: async function(options) {
|
|
1958
|
-
const query = options.query;
|
|
1959
|
-
const k = options.k || 10;
|
|
1960
|
-
|
|
1961
|
-
const queryEmbedding = mockEmbed(query);
|
|
1962
|
-
const results = self._linearSearch(queryEmbedding, k, 'skills');
|
|
1963
|
-
|
|
1964
|
-
return results.map(r => {
|
|
1965
|
-
const skill = db.exec(`SELECT * FROM skills WHERE id = ${r.id}`)[0];
|
|
1966
|
-
if (!skill || !skill.values.length) return null;
|
|
1967
|
-
|
|
1968
|
-
const row = skill.values[0];
|
|
1969
|
-
return {
|
|
1970
|
-
id: row[0],
|
|
1971
|
-
name: row[1],
|
|
1972
|
-
code: row[2],
|
|
1973
|
-
signature: row[3],
|
|
1974
|
-
success_rate: row[4],
|
|
1975
|
-
uses: row[5],
|
|
1976
|
-
similarity: 1 - r.distance
|
|
1977
|
-
};
|
|
1978
|
-
}).filter(s => s !== null);
|
|
1979
|
-
}
|
|
1980
|
-
};
|
|
1981
|
-
|
|
1982
|
-
// v2 Causal Edges API
|
|
1983
|
-
this.causal_edges = {
|
|
1984
|
-
add: async function(edge) {
|
|
1985
|
-
const stmt = db.prepare(`
|
|
1986
|
-
INSERT INTO causal_edges (from_memory_id, to_memory_id, similarity)
|
|
1987
|
-
VALUES (?, ?, ?)
|
|
1988
|
-
`);
|
|
1989
|
-
stmt.run([edge.fromMemoryId, edge.toMemoryId, edge.similarity]);
|
|
1990
|
-
|
|
1991
|
-
// Add edge to GNN if enabled
|
|
1992
|
-
if (enableGNN && gnnInstance) {
|
|
1993
|
-
gnnInstance.addEdge(edge.fromMemoryId, edge.toMemoryId, edge.similarity);
|
|
1994
|
-
}
|
|
1995
|
-
|
|
1996
|
-
return db.exec('SELECT last_insert_rowid()')[0].values[0][0];
|
|
1997
|
-
},
|
|
1998
|
-
|
|
1999
|
-
get: async function(memoryId) {
|
|
2000
|
-
const results = db.exec(`
|
|
2001
|
-
SELECT * FROM causal_edges
|
|
2002
|
-
WHERE from_memory_id = ${memoryId} OR to_memory_id = ${memoryId}
|
|
2003
|
-
`);
|
|
2004
|
-
|
|
2005
|
-
if (!results.length || !results[0].values.length) return [];
|
|
2006
|
-
|
|
2007
|
-
return results[0].values.map(row => ({
|
|
2008
|
-
id: row[0],
|
|
2009
|
-
from_memory_id: row[1],
|
|
2010
|
-
to_memory_id: row[2],
|
|
2011
|
-
similarity: row[3]
|
|
2012
|
-
}));
|
|
2013
|
-
}
|
|
2014
|
-
};
|
|
2015
|
-
|
|
2016
|
-
// Linear search fallback
|
|
2017
|
-
this._linearSearch = function(queryEmbedding, k, table) {
|
|
2018
|
-
const embeddingTable = table === 'episodes' ? 'episode_embeddings' : 'skill_embeddings';
|
|
2019
|
-
const idColumn = table === 'episodes' ? 'episode_id' : 'skill_id';
|
|
2020
|
-
|
|
2021
|
-
const results = db.exec(`SELECT id, ${idColumn}, embedding FROM ${embeddingTable}`);
|
|
2022
|
-
if (!results.length || !results[0].values.length) return [];
|
|
2023
|
-
|
|
2024
|
-
const distances = results[0].values.map(row => {
|
|
2025
|
-
const id = row[1];
|
|
2026
|
-
const embeddingBlob = row[2];
|
|
2027
|
-
const embedding = new Float32Array(embeddingBlob.buffer);
|
|
2028
|
-
|
|
2029
|
-
let distance = 0;
|
|
2030
|
-
for (let i = 0; i < queryEmbedding.length; i++) {
|
|
2031
|
-
const diff = queryEmbedding[i] - embedding[i];
|
|
2032
|
-
distance += diff * diff;
|
|
2033
|
-
}
|
|
2034
|
-
distance = Math.sqrt(distance);
|
|
2035
|
-
|
|
2036
|
-
return { id, distance, vector: embedding };
|
|
2037
|
-
});
|
|
2038
|
-
|
|
2039
|
-
distances.sort((a, b) => a.distance - b.distance);
|
|
2040
|
-
return distances.slice(0, k);
|
|
2041
|
-
};
|
|
2042
|
-
|
|
2043
|
-
// v1 API (backward compatible)
|
|
2044
|
-
this.storeVector = function(content, embedding) {
|
|
2045
|
-
const embeddingBlob = new Uint8Array(embedding.buffer);
|
|
2046
|
-
const stmt = db.prepare('INSERT INTO vectors (content, embedding) VALUES (?, ?)');
|
|
2047
|
-
stmt.run([content, embeddingBlob]);
|
|
2048
|
-
return db.exec('SELECT last_insert_rowid()')[0].values[0][0];
|
|
2049
|
-
};
|
|
2050
|
-
|
|
2051
|
-
this.storePattern = function(pattern, metadata) {
|
|
2052
|
-
const stmt = db.prepare('INSERT INTO patterns (pattern, metadata) VALUES (?, ?)');
|
|
2053
|
-
stmt.run([pattern, JSON.stringify(metadata)]);
|
|
2054
|
-
return db.exec('SELECT last_insert_rowid()')[0].values[0][0];
|
|
2055
|
-
};
|
|
2056
|
-
|
|
2057
|
-
this.searchVectors = function(queryEmbedding, k) {
|
|
2058
|
-
return self._linearSearch(queryEmbedding, k, 'vectors');
|
|
2059
|
-
};
|
|
2060
|
-
|
|
2061
|
-
// Advanced Features API
|
|
2062
|
-
this.advanced = {
|
|
2063
|
-
getPQ: () => pqInstance,
|
|
2064
|
-
getHNSW: () => hnswInstance,
|
|
2065
|
-
getGNN: () => gnnInstance,
|
|
2066
|
-
getMMR: () => mmrInstance,
|
|
2067
|
-
|
|
2068
|
-
stats: function() {
|
|
2069
|
-
return {
|
|
2070
|
-
pq: pqInstance ? pqInstance.getStats() : null,
|
|
2071
|
-
hnsw: hnswInstance ? hnswInstance.getStats() : null,
|
|
2072
|
-
gnn: gnnInstance ? gnnInstance.getStats() : null
|
|
2073
|
-
};
|
|
2074
|
-
}
|
|
2075
|
-
};
|
|
2076
|
-
|
|
2077
|
-
// Export database
|
|
2078
|
-
this.export = function() {
|
|
2079
|
-
return db.export();
|
|
2080
|
-
};
|
|
2081
|
-
|
|
2082
|
-
// Close database
|
|
2083
|
-
this.close = function() {
|
|
2084
|
-
if (db) {
|
|
2085
|
-
db.close();
|
|
2086
|
-
db = null;
|
|
2087
|
-
}
|
|
2088
|
-
};
|
|
2089
|
-
|
|
2090
|
-
// Run SQL
|
|
2091
|
-
this.run = function(sql, params) {
|
|
2092
|
-
return db.run(sql, params);
|
|
2093
|
-
};
|
|
2094
|
-
|
|
2095
|
-
this.exec = function(sql) {
|
|
2096
|
-
return db.exec(sql);
|
|
2097
|
-
};
|
|
2098
|
-
};
|
|
2099
|
-
|
|
2100
|
-
// Export advanced features namespace
|
|
2101
|
-
AgentDB.Advanced = global.AgentDBAdvanced;
|
|
2102
|
-
|
|
2103
|
-
// Export to global
|
|
2104
|
-
if (typeof module !== 'undefined' && module.exports) {
|
|
2105
|
-
module.exports = AgentDB;
|
|
2106
|
-
} else {
|
|
2107
|
-
global.AgentDB = AgentDB;
|
|
2108
|
-
}
|
|
2109
|
-
|
|
2110
|
-
})(typeof window !== 'undefined' ? window : global);
|