rag-lite-ts 2.1.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -5
- package/dist/{cli → cjs/cli}/indexer.js +73 -15
- package/dist/cjs/cli/ui-server.d.ts +5 -0
- package/dist/cjs/cli/ui-server.js +152 -0
- package/dist/{cli.js → cjs/cli.js} +25 -6
- package/dist/{core → cjs/core}/binary-index-format.js +6 -3
- package/dist/{core → cjs/core}/db.d.ts +56 -0
- package/dist/{core → cjs/core}/db.js +105 -0
- package/dist/{core → cjs/core}/ingestion.js +3 -0
- package/dist/cjs/core/knowledge-base-manager.d.ts +109 -0
- package/dist/cjs/core/knowledge-base-manager.js +256 -0
- package/dist/{core → cjs/core}/model-validator.js +1 -1
- package/dist/{core → cjs/core}/search-pipeline.js +1 -1
- package/dist/{core → cjs/core}/search.js +1 -1
- package/dist/cjs/core/vector-index-messages.d.ts +52 -0
- package/dist/cjs/core/vector-index-messages.js +5 -0
- package/dist/cjs/core/vector-index-worker.d.ts +6 -0
- package/dist/cjs/core/vector-index-worker.js +304 -0
- package/dist/cjs/core/vector-index.d.ts +107 -0
- package/dist/cjs/core/vector-index.js +344 -0
- package/dist/{factories → cjs/factories}/ingestion-factory.js +3 -7
- package/dist/{factories → cjs/factories}/search-factory.js +11 -0
- package/dist/{index-manager.d.ts → cjs/index-manager.d.ts} +23 -3
- package/dist/{index-manager.js → cjs/index-manager.js} +84 -15
- package/dist/{index.d.ts → cjs/index.d.ts} +2 -1
- package/dist/{index.js → cjs/index.js} +3 -1
- package/dist/esm/api-errors.d.ts +90 -0
- package/dist/esm/api-errors.js +320 -0
- package/dist/esm/cli/indexer.d.ts +11 -0
- package/dist/esm/cli/indexer.js +529 -0
- package/dist/esm/cli/search.d.ts +7 -0
- package/dist/esm/cli/search.js +332 -0
- package/dist/esm/cli/ui-server.d.ts +5 -0
- package/dist/esm/cli/ui-server.js +152 -0
- package/dist/esm/cli.d.ts +3 -0
- package/dist/esm/cli.js +548 -0
- package/dist/esm/config.d.ts +51 -0
- package/dist/esm/config.js +79 -0
- package/dist/esm/core/abstract-embedder.d.ts +125 -0
- package/dist/esm/core/abstract-embedder.js +264 -0
- package/dist/esm/core/actionable-error-messages.d.ts +60 -0
- package/dist/esm/core/actionable-error-messages.js +397 -0
- package/dist/esm/core/adapters.d.ts +93 -0
- package/dist/esm/core/adapters.js +139 -0
- package/dist/esm/core/batch-processing-optimizer.d.ts +155 -0
- package/dist/esm/core/batch-processing-optimizer.js +536 -0
- package/dist/esm/core/binary-index-format.d.ts +78 -0
- package/dist/esm/core/binary-index-format.js +294 -0
- package/dist/esm/core/chunker.d.ts +119 -0
- package/dist/esm/core/chunker.js +73 -0
- package/dist/esm/core/cli-database-utils.d.ts +53 -0
- package/dist/esm/core/cli-database-utils.js +239 -0
- package/dist/esm/core/config.d.ts +102 -0
- package/dist/esm/core/config.js +247 -0
- package/dist/esm/core/content-errors.d.ts +111 -0
- package/dist/esm/core/content-errors.js +362 -0
- package/dist/esm/core/content-manager.d.ts +335 -0
- package/dist/esm/core/content-manager.js +1476 -0
- package/dist/esm/core/content-performance-optimizer.d.ts +150 -0
- package/dist/esm/core/content-performance-optimizer.js +516 -0
- package/dist/esm/core/content-resolver.d.ts +104 -0
- package/dist/esm/core/content-resolver.js +285 -0
- package/dist/esm/core/cross-modal-search.d.ts +164 -0
- package/dist/esm/core/cross-modal-search.js +342 -0
- package/dist/esm/core/database-connection-manager.d.ts +109 -0
- package/dist/esm/core/database-connection-manager.js +310 -0
- package/dist/esm/core/db.d.ts +269 -0
- package/dist/esm/core/db.js +1000 -0
- package/dist/esm/core/embedder-factory.d.ts +154 -0
- package/dist/esm/core/embedder-factory.js +311 -0
- package/dist/esm/core/error-handler.d.ts +112 -0
- package/dist/esm/core/error-handler.js +239 -0
- package/dist/esm/core/index.d.ts +59 -0
- package/dist/esm/core/index.js +69 -0
- package/dist/esm/core/ingestion.d.ts +202 -0
- package/dist/esm/core/ingestion.js +904 -0
- package/dist/esm/core/interfaces.d.ts +408 -0
- package/dist/esm/core/interfaces.js +106 -0
- package/dist/esm/core/knowledge-base-manager.d.ts +109 -0
- package/dist/esm/core/knowledge-base-manager.js +256 -0
- package/dist/esm/core/lazy-dependency-loader.d.ts +147 -0
- package/dist/esm/core/lazy-dependency-loader.js +435 -0
- package/dist/esm/core/mode-detection-service.d.ts +150 -0
- package/dist/esm/core/mode-detection-service.js +565 -0
- package/dist/esm/core/mode-model-validator.d.ts +92 -0
- package/dist/esm/core/mode-model-validator.js +203 -0
- package/dist/esm/core/model-registry.d.ts +116 -0
- package/dist/esm/core/model-registry.js +411 -0
- package/dist/esm/core/model-validator.d.ts +217 -0
- package/dist/esm/core/model-validator.js +782 -0
- package/dist/esm/core/path-manager.d.ts +47 -0
- package/dist/esm/core/path-manager.js +71 -0
- package/dist/esm/core/raglite-paths.d.ts +121 -0
- package/dist/esm/core/raglite-paths.js +145 -0
- package/dist/esm/core/reranking-config.d.ts +42 -0
- package/dist/esm/core/reranking-config.js +147 -0
- package/dist/esm/core/reranking-factory.d.ts +92 -0
- package/dist/esm/core/reranking-factory.js +410 -0
- package/dist/esm/core/reranking-strategies.d.ts +310 -0
- package/dist/esm/core/reranking-strategies.js +650 -0
- package/dist/esm/core/resource-cleanup.d.ts +163 -0
- package/dist/esm/core/resource-cleanup.js +371 -0
- package/dist/esm/core/resource-manager.d.ts +212 -0
- package/dist/esm/core/resource-manager.js +564 -0
- package/dist/esm/core/search-pipeline.d.ts +111 -0
- package/dist/esm/core/search-pipeline.js +287 -0
- package/dist/esm/core/search.d.ts +141 -0
- package/dist/esm/core/search.js +320 -0
- package/dist/esm/core/streaming-operations.d.ts +145 -0
- package/dist/esm/core/streaming-operations.js +409 -0
- package/dist/esm/core/types.d.ts +66 -0
- package/dist/esm/core/types.js +6 -0
- package/dist/esm/core/universal-embedder.d.ts +177 -0
- package/dist/esm/core/universal-embedder.js +139 -0
- package/dist/esm/core/validation-messages.d.ts +99 -0
- package/dist/esm/core/validation-messages.js +334 -0
- package/dist/esm/core/vector-index-messages.d.ts +52 -0
- package/dist/esm/core/vector-index-messages.js +5 -0
- package/dist/esm/core/vector-index-worker.d.ts +6 -0
- package/dist/esm/core/vector-index-worker.js +304 -0
- package/dist/esm/core/vector-index.d.ts +107 -0
- package/dist/esm/core/vector-index.js +344 -0
- package/dist/esm/dom-polyfills.d.ts +6 -0
- package/dist/esm/dom-polyfills.js +37 -0
- package/dist/esm/factories/index.d.ts +27 -0
- package/dist/esm/factories/index.js +29 -0
- package/dist/esm/factories/ingestion-factory.d.ts +200 -0
- package/dist/esm/factories/ingestion-factory.js +473 -0
- package/dist/esm/factories/search-factory.d.ts +154 -0
- package/dist/esm/factories/search-factory.js +355 -0
- package/dist/esm/file-processor.d.ts +147 -0
- package/dist/esm/file-processor.js +963 -0
- package/dist/esm/index-manager.d.ts +136 -0
- package/dist/esm/index-manager.js +667 -0
- package/dist/esm/index.d.ts +76 -0
- package/dist/esm/index.js +112 -0
- package/dist/esm/indexer.d.ts +7 -0
- package/dist/esm/indexer.js +54 -0
- package/dist/esm/ingestion.d.ts +63 -0
- package/dist/esm/ingestion.js +124 -0
- package/dist/esm/mcp-server.d.ts +46 -0
- package/dist/esm/mcp-server.js +1820 -0
- package/dist/esm/multimodal/clip-embedder.d.ts +327 -0
- package/dist/esm/multimodal/clip-embedder.js +996 -0
- package/dist/esm/multimodal/index.d.ts +6 -0
- package/dist/esm/multimodal/index.js +6 -0
- package/dist/esm/preprocess.d.ts +19 -0
- package/dist/esm/preprocess.js +203 -0
- package/dist/esm/preprocessors/index.d.ts +17 -0
- package/dist/esm/preprocessors/index.js +38 -0
- package/dist/esm/preprocessors/mdx.d.ts +25 -0
- package/dist/esm/preprocessors/mdx.js +101 -0
- package/dist/esm/preprocessors/mermaid.d.ts +68 -0
- package/dist/esm/preprocessors/mermaid.js +329 -0
- package/dist/esm/preprocessors/registry.d.ts +56 -0
- package/dist/esm/preprocessors/registry.js +179 -0
- package/dist/esm/run-error-recovery-tests.d.ts +7 -0
- package/dist/esm/run-error-recovery-tests.js +101 -0
- package/dist/esm/search-standalone.d.ts +7 -0
- package/dist/esm/search-standalone.js +117 -0
- package/dist/esm/search.d.ts +99 -0
- package/dist/esm/search.js +177 -0
- package/dist/esm/test-utils.d.ts +18 -0
- package/dist/esm/test-utils.js +27 -0
- package/dist/esm/text/chunker.d.ts +33 -0
- package/dist/esm/text/chunker.js +279 -0
- package/dist/esm/text/embedder.d.ts +111 -0
- package/dist/esm/text/embedder.js +386 -0
- package/dist/esm/text/index.d.ts +8 -0
- package/dist/esm/text/index.js +9 -0
- package/dist/esm/text/preprocessors/index.d.ts +17 -0
- package/dist/esm/text/preprocessors/index.js +38 -0
- package/dist/esm/text/preprocessors/mdx.d.ts +25 -0
- package/dist/esm/text/preprocessors/mdx.js +101 -0
- package/dist/esm/text/preprocessors/mermaid.d.ts +68 -0
- package/dist/esm/text/preprocessors/mermaid.js +330 -0
- package/dist/esm/text/preprocessors/registry.d.ts +56 -0
- package/dist/esm/text/preprocessors/registry.js +180 -0
- package/dist/esm/text/reranker.d.ts +49 -0
- package/dist/esm/text/reranker.js +274 -0
- package/dist/esm/text/sentence-transformer-embedder.d.ts +96 -0
- package/dist/esm/text/sentence-transformer-embedder.js +340 -0
- package/dist/esm/text/tokenizer.d.ts +22 -0
- package/dist/esm/text/tokenizer.js +64 -0
- package/dist/esm/types.d.ts +83 -0
- package/dist/esm/types.js +3 -0
- package/dist/esm/utils/vector-math.d.ts +31 -0
- package/dist/esm/utils/vector-math.js +70 -0
- package/package.json +39 -14
- package/dist/core/vector-index.d.ts +0 -72
- package/dist/core/vector-index.js +0 -331
- /package/dist/{api-errors.d.ts → cjs/api-errors.d.ts} +0 -0
- /package/dist/{api-errors.js → cjs/api-errors.js} +0 -0
- /package/dist/{cli → cjs/cli}/indexer.d.ts +0 -0
- /package/dist/{cli → cjs/cli}/search.d.ts +0 -0
- /package/dist/{cli → cjs/cli}/search.js +0 -0
- /package/dist/{cli.d.ts → cjs/cli.d.ts} +0 -0
- /package/dist/{config.d.ts → cjs/config.d.ts} +0 -0
- /package/dist/{config.js → cjs/config.js} +0 -0
- /package/dist/{core → cjs/core}/abstract-embedder.d.ts +0 -0
- /package/dist/{core → cjs/core}/abstract-embedder.js +0 -0
- /package/dist/{core → cjs/core}/actionable-error-messages.d.ts +0 -0
- /package/dist/{core → cjs/core}/actionable-error-messages.js +0 -0
- /package/dist/{core → cjs/core}/adapters.d.ts +0 -0
- /package/dist/{core → cjs/core}/adapters.js +0 -0
- /package/dist/{core → cjs/core}/batch-processing-optimizer.d.ts +0 -0
- /package/dist/{core → cjs/core}/batch-processing-optimizer.js +0 -0
- /package/dist/{core → cjs/core}/binary-index-format.d.ts +0 -0
- /package/dist/{core → cjs/core}/chunker.d.ts +0 -0
- /package/dist/{core → cjs/core}/chunker.js +0 -0
- /package/dist/{core → cjs/core}/cli-database-utils.d.ts +0 -0
- /package/dist/{core → cjs/core}/cli-database-utils.js +0 -0
- /package/dist/{core → cjs/core}/config.d.ts +0 -0
- /package/dist/{core → cjs/core}/config.js +0 -0
- /package/dist/{core → cjs/core}/content-errors.d.ts +0 -0
- /package/dist/{core → cjs/core}/content-errors.js +0 -0
- /package/dist/{core → cjs/core}/content-manager.d.ts +0 -0
- /package/dist/{core → cjs/core}/content-manager.js +0 -0
- /package/dist/{core → cjs/core}/content-performance-optimizer.d.ts +0 -0
- /package/dist/{core → cjs/core}/content-performance-optimizer.js +0 -0
- /package/dist/{core → cjs/core}/content-resolver.d.ts +0 -0
- /package/dist/{core → cjs/core}/content-resolver.js +0 -0
- /package/dist/{core → cjs/core}/cross-modal-search.d.ts +0 -0
- /package/dist/{core → cjs/core}/cross-modal-search.js +0 -0
- /package/dist/{core → cjs/core}/database-connection-manager.d.ts +0 -0
- /package/dist/{core → cjs/core}/database-connection-manager.js +0 -0
- /package/dist/{core → cjs/core}/embedder-factory.d.ts +0 -0
- /package/dist/{core → cjs/core}/embedder-factory.js +0 -0
- /package/dist/{core → cjs/core}/error-handler.d.ts +0 -0
- /package/dist/{core → cjs/core}/error-handler.js +0 -0
- /package/dist/{core → cjs/core}/index.d.ts +0 -0
- /package/dist/{core → cjs/core}/index.js +0 -0
- /package/dist/{core → cjs/core}/ingestion.d.ts +0 -0
- /package/dist/{core → cjs/core}/interfaces.d.ts +0 -0
- /package/dist/{core → cjs/core}/interfaces.js +0 -0
- /package/dist/{core → cjs/core}/lazy-dependency-loader.d.ts +0 -0
- /package/dist/{core → cjs/core}/lazy-dependency-loader.js +0 -0
- /package/dist/{core → cjs/core}/mode-detection-service.d.ts +0 -0
- /package/dist/{core → cjs/core}/mode-detection-service.js +0 -0
- /package/dist/{core → cjs/core}/mode-model-validator.d.ts +0 -0
- /package/dist/{core → cjs/core}/mode-model-validator.js +0 -0
- /package/dist/{core → cjs/core}/model-registry.d.ts +0 -0
- /package/dist/{core → cjs/core}/model-registry.js +0 -0
- /package/dist/{core → cjs/core}/model-validator.d.ts +0 -0
- /package/dist/{core → cjs/core}/path-manager.d.ts +0 -0
- /package/dist/{core → cjs/core}/path-manager.js +0 -0
- /package/dist/{core → cjs/core}/raglite-paths.d.ts +0 -0
- /package/dist/{core → cjs/core}/raglite-paths.js +0 -0
- /package/dist/{core → cjs/core}/reranking-config.d.ts +0 -0
- /package/dist/{core → cjs/core}/reranking-config.js +0 -0
- /package/dist/{core → cjs/core}/reranking-factory.d.ts +0 -0
- /package/dist/{core → cjs/core}/reranking-factory.js +0 -0
- /package/dist/{core → cjs/core}/reranking-strategies.d.ts +0 -0
- /package/dist/{core → cjs/core}/reranking-strategies.js +0 -0
- /package/dist/{core → cjs/core}/resource-cleanup.d.ts +0 -0
- /package/dist/{core → cjs/core}/resource-cleanup.js +0 -0
- /package/dist/{core → cjs/core}/resource-manager.d.ts +0 -0
- /package/dist/{core → cjs/core}/resource-manager.js +0 -0
- /package/dist/{core → cjs/core}/search-pipeline.d.ts +0 -0
- /package/dist/{core → cjs/core}/search.d.ts +0 -0
- /package/dist/{core → cjs/core}/streaming-operations.d.ts +0 -0
- /package/dist/{core → cjs/core}/streaming-operations.js +0 -0
- /package/dist/{core → cjs/core}/types.d.ts +0 -0
- /package/dist/{core → cjs/core}/types.js +0 -0
- /package/dist/{core → cjs/core}/universal-embedder.d.ts +0 -0
- /package/dist/{core → cjs/core}/universal-embedder.js +0 -0
- /package/dist/{core → cjs/core}/validation-messages.d.ts +0 -0
- /package/dist/{core → cjs/core}/validation-messages.js +0 -0
- /package/dist/{dom-polyfills.d.ts → cjs/dom-polyfills.d.ts} +0 -0
- /package/dist/{dom-polyfills.js → cjs/dom-polyfills.js} +0 -0
- /package/dist/{factories → cjs/factories}/index.d.ts +0 -0
- /package/dist/{factories → cjs/factories}/index.js +0 -0
- /package/dist/{factories → cjs/factories}/ingestion-factory.d.ts +0 -0
- /package/dist/{factories → cjs/factories}/search-factory.d.ts +0 -0
- /package/dist/{file-processor.d.ts → cjs/file-processor.d.ts} +0 -0
- /package/dist/{file-processor.js → cjs/file-processor.js} +0 -0
- /package/dist/{indexer.d.ts → cjs/indexer.d.ts} +0 -0
- /package/dist/{indexer.js → cjs/indexer.js} +0 -0
- /package/dist/{ingestion.d.ts → cjs/ingestion.d.ts} +0 -0
- /package/dist/{ingestion.js → cjs/ingestion.js} +0 -0
- /package/dist/{mcp-server.d.ts → cjs/mcp-server.d.ts} +0 -0
- /package/dist/{mcp-server.js → cjs/mcp-server.js} +0 -0
- /package/dist/{multimodal → cjs/multimodal}/clip-embedder.d.ts +0 -0
- /package/dist/{multimodal → cjs/multimodal}/clip-embedder.js +0 -0
- /package/dist/{multimodal → cjs/multimodal}/index.d.ts +0 -0
- /package/dist/{multimodal → cjs/multimodal}/index.js +0 -0
- /package/dist/{preprocess.d.ts → cjs/preprocess.d.ts} +0 -0
- /package/dist/{preprocess.js → cjs/preprocess.js} +0 -0
- /package/dist/{preprocessors → cjs/preprocessors}/index.d.ts +0 -0
- /package/dist/{preprocessors → cjs/preprocessors}/index.js +0 -0
- /package/dist/{preprocessors → cjs/preprocessors}/mdx.d.ts +0 -0
- /package/dist/{preprocessors → cjs/preprocessors}/mdx.js +0 -0
- /package/dist/{preprocessors → cjs/preprocessors}/mermaid.d.ts +0 -0
- /package/dist/{preprocessors → cjs/preprocessors}/mermaid.js +0 -0
- /package/dist/{preprocessors → cjs/preprocessors}/registry.d.ts +0 -0
- /package/dist/{preprocessors → cjs/preprocessors}/registry.js +0 -0
- /package/dist/{run-error-recovery-tests.d.ts → cjs/run-error-recovery-tests.d.ts} +0 -0
- /package/dist/{run-error-recovery-tests.js → cjs/run-error-recovery-tests.js} +0 -0
- /package/dist/{search-standalone.d.ts → cjs/search-standalone.d.ts} +0 -0
- /package/dist/{search-standalone.js → cjs/search-standalone.js} +0 -0
- /package/dist/{search.d.ts → cjs/search.d.ts} +0 -0
- /package/dist/{search.js → cjs/search.js} +0 -0
- /package/dist/{test-utils.d.ts → cjs/test-utils.d.ts} +0 -0
- /package/dist/{test-utils.js → cjs/test-utils.js} +0 -0
- /package/dist/{text → cjs/text}/chunker.d.ts +0 -0
- /package/dist/{text → cjs/text}/chunker.js +0 -0
- /package/dist/{text → cjs/text}/embedder.d.ts +0 -0
- /package/dist/{text → cjs/text}/embedder.js +0 -0
- /package/dist/{text → cjs/text}/index.d.ts +0 -0
- /package/dist/{text → cjs/text}/index.js +0 -0
- /package/dist/{text → cjs/text}/preprocessors/index.d.ts +0 -0
- /package/dist/{text → cjs/text}/preprocessors/index.js +0 -0
- /package/dist/{text → cjs/text}/preprocessors/mdx.d.ts +0 -0
- /package/dist/{text → cjs/text}/preprocessors/mdx.js +0 -0
- /package/dist/{text → cjs/text}/preprocessors/mermaid.d.ts +0 -0
- /package/dist/{text → cjs/text}/preprocessors/mermaid.js +0 -0
- /package/dist/{text → cjs/text}/preprocessors/registry.d.ts +0 -0
- /package/dist/{text → cjs/text}/preprocessors/registry.js +0 -0
- /package/dist/{text → cjs/text}/reranker.d.ts +0 -0
- /package/dist/{text → cjs/text}/reranker.js +0 -0
- /package/dist/{text → cjs/text}/sentence-transformer-embedder.d.ts +0 -0
- /package/dist/{text → cjs/text}/sentence-transformer-embedder.js +0 -0
- /package/dist/{text → cjs/text}/tokenizer.d.ts +0 -0
- /package/dist/{text → cjs/text}/tokenizer.js +0 -0
- /package/dist/{types.d.ts → cjs/types.d.ts} +0 -0
- /package/dist/{types.js → cjs/types.js} +0 -0
- /package/dist/{utils → cjs/utils}/vector-math.d.ts +0 -0
- /package/dist/{utils → cjs/utils}/vector-math.js +0 -0
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORE MODULE — Resource Manager
|
|
3
|
+
* Implements proper cleanup methods for all embedder implementations
|
|
4
|
+
* Adds automatic resource management for image processing operations
|
|
5
|
+
* Creates memory monitoring and garbage collection optimization
|
|
6
|
+
* Ensures proper disposal of transformers.js model resources
|
|
7
|
+
*
|
|
8
|
+
* Requirements: 9.4, 9.6 - Resource cleanup and memory management
|
|
9
|
+
*/
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// RESOURCE MANAGER
|
|
12
|
+
// =============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Comprehensive resource manager for embedders and models
|
|
15
|
+
* Handles automatic cleanup, memory monitoring, and garbage collection
|
|
16
|
+
*/
|
|
17
|
+
export class ResourceManager {
|
|
18
|
+
static instance;
|
|
19
|
+
resources = new Map();
|
|
20
|
+
memoryThresholdMB = 512; // Default 512MB threshold
|
|
21
|
+
autoCleanupEnabled = true;
|
|
22
|
+
gcEnabled = true;
|
|
23
|
+
cleanupIntervalMs = 30000; // 30 seconds
|
|
24
|
+
cleanupTimer;
|
|
25
|
+
memoryMonitorTimer;
|
|
26
|
+
peakMemoryMB = 0;
|
|
27
|
+
gcCount = 0;
|
|
28
|
+
lastGcAt;
|
|
29
|
+
constructor() {
|
|
30
|
+
this.startAutoCleanup();
|
|
31
|
+
this.setupMemoryMonitoring();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get singleton instance
|
|
35
|
+
*/
|
|
36
|
+
static getInstance() {
|
|
37
|
+
if (!ResourceManager.instance) {
|
|
38
|
+
ResourceManager.instance = new ResourceManager();
|
|
39
|
+
}
|
|
40
|
+
return ResourceManager.instance;
|
|
41
|
+
}
|
|
42
|
+
// =============================================================================
|
|
43
|
+
// RESOURCE REGISTRATION
|
|
44
|
+
// =============================================================================
|
|
45
|
+
/**
|
|
46
|
+
* Register an embedder for resource management
|
|
47
|
+
*/
|
|
48
|
+
registerEmbedder(embedder) {
|
|
49
|
+
const resourceId = this.generateResourceId('embedder', embedder.modelName);
|
|
50
|
+
const resourceInfo = {
|
|
51
|
+
id: resourceId,
|
|
52
|
+
type: 'embedder',
|
|
53
|
+
name: embedder.modelName,
|
|
54
|
+
memoryEstimateMB: this.estimateEmbedderMemory(embedder),
|
|
55
|
+
createdAt: new Date(),
|
|
56
|
+
lastUsedAt: new Date(),
|
|
57
|
+
resource: embedder,
|
|
58
|
+
cleanupFn: async () => {
|
|
59
|
+
// Don't call embedder.cleanup() to avoid circular reference
|
|
60
|
+
// The embedder will handle its own cleanup when explicitly called
|
|
61
|
+
// Just clear the reference here
|
|
62
|
+
console.log(`🧹 Resource manager clearing reference to embedder: ${embedder.modelName}`);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
this.resources.set(resourceId, resourceInfo);
|
|
66
|
+
console.log(`📝 Registered embedder: ${embedder.modelName} (ID: ${resourceId}, Est. Memory: ${resourceInfo.memoryEstimateMB}MB)`);
|
|
67
|
+
return resourceId;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Register a transformers.js model for resource management
|
|
71
|
+
*/
|
|
72
|
+
registerModel(model, modelName, modelType) {
|
|
73
|
+
const resourceId = this.generateResourceId('model', `${modelType}:${modelName}`);
|
|
74
|
+
const resourceInfo = {
|
|
75
|
+
id: resourceId,
|
|
76
|
+
type: 'model',
|
|
77
|
+
name: `${modelType}:${modelName}`,
|
|
78
|
+
memoryEstimateMB: this.estimateModelMemory(modelType),
|
|
79
|
+
createdAt: new Date(),
|
|
80
|
+
lastUsedAt: new Date(),
|
|
81
|
+
resource: model,
|
|
82
|
+
cleanupFn: async () => {
|
|
83
|
+
if (typeof model.dispose === 'function') {
|
|
84
|
+
await model.dispose();
|
|
85
|
+
}
|
|
86
|
+
else if (typeof model.destroy === 'function') {
|
|
87
|
+
await model.destroy();
|
|
88
|
+
}
|
|
89
|
+
else if (typeof model.cleanup === 'function') {
|
|
90
|
+
await model.cleanup();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
this.resources.set(resourceId, resourceInfo);
|
|
95
|
+
console.log(`📝 Registered model: ${modelName} (ID: ${resourceId}, Est. Memory: ${resourceInfo.memoryEstimateMB}MB)`);
|
|
96
|
+
return resourceId;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Register an image processor for resource management
|
|
100
|
+
*/
|
|
101
|
+
registerImageProcessor(processor, processorName) {
|
|
102
|
+
const resourceId = this.generateResourceId('processor', processorName);
|
|
103
|
+
const resourceInfo = {
|
|
104
|
+
id: resourceId,
|
|
105
|
+
type: 'processor',
|
|
106
|
+
name: processorName,
|
|
107
|
+
memoryEstimateMB: this.estimateProcessorMemory(processorName),
|
|
108
|
+
createdAt: new Date(),
|
|
109
|
+
lastUsedAt: new Date(),
|
|
110
|
+
resource: processor,
|
|
111
|
+
cleanupFn: async () => {
|
|
112
|
+
if (typeof processor.dispose === 'function') {
|
|
113
|
+
await processor.dispose();
|
|
114
|
+
}
|
|
115
|
+
else if (typeof processor.cleanup === 'function') {
|
|
116
|
+
await processor.cleanup();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
this.resources.set(resourceId, resourceInfo);
|
|
121
|
+
console.log(`📝 Registered processor: ${processorName} (ID: ${resourceId}, Est. Memory: ${resourceInfo.memoryEstimateMB}MB)`);
|
|
122
|
+
return resourceId;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Update last used timestamp for a resource
|
|
126
|
+
*/
|
|
127
|
+
updateResourceUsage(resourceId) {
|
|
128
|
+
const resource = this.resources.get(resourceId);
|
|
129
|
+
if (resource) {
|
|
130
|
+
resource.lastUsedAt = new Date();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// =============================================================================
|
|
134
|
+
// RESOURCE CLEANUP
|
|
135
|
+
// =============================================================================
|
|
136
|
+
/**
|
|
137
|
+
* Clean up a specific resource by ID
|
|
138
|
+
*/
|
|
139
|
+
async cleanupResource(resourceId) {
|
|
140
|
+
const resource = this.resources.get(resourceId);
|
|
141
|
+
if (!resource) {
|
|
142
|
+
console.warn(`Resource not found for cleanup: ${resourceId}`);
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
console.log(`🧹 Cleaning up resource: ${resource.name} (${resource.type})`);
|
|
147
|
+
if (resource.cleanupFn) {
|
|
148
|
+
await resource.cleanupFn();
|
|
149
|
+
}
|
|
150
|
+
this.resources.delete(resourceId);
|
|
151
|
+
console.log(`✅ Resource cleaned up: ${resource.name}`);
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
console.error(`❌ Failed to cleanup resource ${resource.name}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Clean up all resources of a specific type
|
|
161
|
+
*/
|
|
162
|
+
async cleanupResourcesByType(type) {
|
|
163
|
+
const startTime = Date.now();
|
|
164
|
+
const resourcesOfType = Array.from(this.resources.values()).filter(r => r.type === type);
|
|
165
|
+
let cleanedUp = 0;
|
|
166
|
+
let errors = 0;
|
|
167
|
+
let memoryFreed = 0;
|
|
168
|
+
console.log(`🧹 Cleaning up ${resourcesOfType.length} resources of type: ${type}`);
|
|
169
|
+
for (const resource of resourcesOfType) {
|
|
170
|
+
const success = await this.cleanupResource(resource.id);
|
|
171
|
+
if (success) {
|
|
172
|
+
cleanedUp++;
|
|
173
|
+
memoryFreed += resource.memoryEstimateMB;
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
errors++;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const cleanupTime = Date.now() - startTime;
|
|
180
|
+
const stats = {
|
|
181
|
+
totalResourcesTracked: resourcesOfType.length,
|
|
182
|
+
resourcesCleanedUp: cleanedUp,
|
|
183
|
+
cleanupErrors: errors,
|
|
184
|
+
memoryFreedMB: memoryFreed,
|
|
185
|
+
cleanupTimeMs: cleanupTime
|
|
186
|
+
};
|
|
187
|
+
console.log(`✅ Cleanup complete for ${type}: ${cleanedUp}/${resourcesOfType.length} cleaned, ${memoryFreed}MB freed, ${cleanupTime}ms`);
|
|
188
|
+
return stats;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Clean up all registered resources
|
|
192
|
+
*/
|
|
193
|
+
async cleanupAllResources() {
|
|
194
|
+
const startTime = Date.now();
|
|
195
|
+
const allResources = Array.from(this.resources.values());
|
|
196
|
+
let cleanedUp = 0;
|
|
197
|
+
let errors = 0;
|
|
198
|
+
let memoryFreed = 0;
|
|
199
|
+
console.log(`🧹 Cleaning up all ${allResources.length} registered resources`);
|
|
200
|
+
for (const resource of allResources) {
|
|
201
|
+
const success = await this.cleanupResource(resource.id);
|
|
202
|
+
if (success) {
|
|
203
|
+
cleanedUp++;
|
|
204
|
+
memoryFreed += resource.memoryEstimateMB;
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
errors++;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const cleanupTime = Date.now() - startTime;
|
|
211
|
+
const stats = {
|
|
212
|
+
totalResourcesTracked: allResources.length,
|
|
213
|
+
resourcesCleanedUp: cleanedUp,
|
|
214
|
+
cleanupErrors: errors,
|
|
215
|
+
memoryFreedMB: memoryFreed,
|
|
216
|
+
cleanupTimeMs: cleanupTime
|
|
217
|
+
};
|
|
218
|
+
console.log(`✅ Full cleanup complete: ${cleanedUp}/${allResources.length} cleaned, ${memoryFreed}MB freed, ${cleanupTime}ms`);
|
|
219
|
+
return stats;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Clean up unused resources (not used recently)
|
|
223
|
+
*/
|
|
224
|
+
async cleanupUnusedResources(maxAgeMinutes = 30) {
|
|
225
|
+
const startTime = Date.now();
|
|
226
|
+
const cutoffTime = new Date(Date.now() - maxAgeMinutes * 60 * 1000);
|
|
227
|
+
const unusedResources = Array.from(this.resources.values()).filter(resource => resource.lastUsedAt < cutoffTime);
|
|
228
|
+
let cleanedUp = 0;
|
|
229
|
+
let errors = 0;
|
|
230
|
+
let memoryFreed = 0;
|
|
231
|
+
console.log(`🧹 Cleaning up ${unusedResources.length} unused resources (older than ${maxAgeMinutes} minutes)`);
|
|
232
|
+
for (const resource of unusedResources) {
|
|
233
|
+
const success = await this.cleanupResource(resource.id);
|
|
234
|
+
if (success) {
|
|
235
|
+
cleanedUp++;
|
|
236
|
+
memoryFreed += resource.memoryEstimateMB;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
errors++;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const cleanupTime = Date.now() - startTime;
|
|
243
|
+
const stats = {
|
|
244
|
+
totalResourcesTracked: unusedResources.length,
|
|
245
|
+
resourcesCleanedUp: cleanedUp,
|
|
246
|
+
cleanupErrors: errors,
|
|
247
|
+
memoryFreedMB: memoryFreed,
|
|
248
|
+
cleanupTimeMs: cleanupTime
|
|
249
|
+
};
|
|
250
|
+
console.log(`✅ Unused resource cleanup complete: ${cleanedUp}/${unusedResources.length} cleaned, ${memoryFreed}MB freed`);
|
|
251
|
+
return stats;
|
|
252
|
+
}
|
|
253
|
+
// =============================================================================
|
|
254
|
+
// MEMORY MANAGEMENT
|
|
255
|
+
// =============================================================================
|
|
256
|
+
/**
|
|
257
|
+
* Get current memory statistics
|
|
258
|
+
*/
|
|
259
|
+
getMemoryStats() {
|
|
260
|
+
const memUsage = process.memoryUsage();
|
|
261
|
+
const currentHeapMB = Math.round(memUsage.heapUsed / 1024 / 1024);
|
|
262
|
+
// Update peak memory
|
|
263
|
+
if (currentHeapMB > this.peakMemoryMB) {
|
|
264
|
+
this.peakMemoryMB = currentHeapMB;
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
heapUsedMB: currentHeapMB,
|
|
268
|
+
heapTotalMB: Math.round(memUsage.heapTotal / 1024 / 1024),
|
|
269
|
+
externalMB: Math.round(memUsage.external / 1024 / 1024),
|
|
270
|
+
rssMemoryMB: Math.round(memUsage.rss / 1024 / 1024),
|
|
271
|
+
peakHeapUsedMB: this.peakMemoryMB,
|
|
272
|
+
gcCount: this.gcCount,
|
|
273
|
+
lastGcAt: this.lastGcAt
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Check if memory usage exceeds threshold
|
|
278
|
+
*/
|
|
279
|
+
isMemoryThresholdExceeded() {
|
|
280
|
+
const stats = this.getMemoryStats();
|
|
281
|
+
return stats.heapUsedMB > this.memoryThresholdMB;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Force garbage collection
|
|
285
|
+
*/
|
|
286
|
+
forceGarbageCollection() {
|
|
287
|
+
if (this.gcEnabled && global.gc) {
|
|
288
|
+
try {
|
|
289
|
+
global.gc();
|
|
290
|
+
this.gcCount++;
|
|
291
|
+
this.lastGcAt = new Date();
|
|
292
|
+
console.log(`🗑️ Forced garbage collection (count: ${this.gcCount})`);
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
console.warn(`Failed to force garbage collection: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Perform memory optimization
|
|
304
|
+
*/
|
|
305
|
+
async optimizeMemory() {
|
|
306
|
+
const initialStats = this.getMemoryStats();
|
|
307
|
+
console.log(`🔧 Starting memory optimization (current: ${initialStats.heapUsedMB}MB, threshold: ${this.memoryThresholdMB}MB)`);
|
|
308
|
+
let resourcesCleanedUp = 0;
|
|
309
|
+
// Clean up unused resources if memory threshold exceeded
|
|
310
|
+
if (this.isMemoryThresholdExceeded()) {
|
|
311
|
+
console.log('💾 Memory threshold exceeded, cleaning up unused resources');
|
|
312
|
+
const cleanupStats = await this.cleanupUnusedResources(15); // Clean resources unused for 15+ minutes
|
|
313
|
+
resourcesCleanedUp = cleanupStats.resourcesCleanedUp;
|
|
314
|
+
}
|
|
315
|
+
// Force garbage collection
|
|
316
|
+
const gcPerformed = this.forceGarbageCollection();
|
|
317
|
+
const finalStats = this.getMemoryStats();
|
|
318
|
+
const memoryFreed = Math.max(0, initialStats.heapUsedMB - finalStats.heapUsedMB);
|
|
319
|
+
console.log(`✅ Memory optimization complete: ${initialStats.heapUsedMB}MB → ${finalStats.heapUsedMB}MB (freed: ${memoryFreed}MB)`);
|
|
320
|
+
return {
|
|
321
|
+
initialMemoryMB: initialStats.heapUsedMB,
|
|
322
|
+
finalMemoryMB: finalStats.heapUsedMB,
|
|
323
|
+
memoryFreedMB: memoryFreed,
|
|
324
|
+
resourcesCleanedUp,
|
|
325
|
+
gcPerformed
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
// =============================================================================
|
|
329
|
+
// CONFIGURATION
|
|
330
|
+
// =============================================================================
|
|
331
|
+
/**
|
|
332
|
+
* Configure memory threshold
|
|
333
|
+
*/
|
|
334
|
+
setMemoryThreshold(thresholdMB) {
|
|
335
|
+
if (thresholdMB < 64) {
|
|
336
|
+
throw new Error('Memory threshold must be at least 64MB');
|
|
337
|
+
}
|
|
338
|
+
this.memoryThresholdMB = thresholdMB;
|
|
339
|
+
console.log(`⚙️ Memory threshold set to ${thresholdMB}MB`);
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Enable or disable automatic cleanup
|
|
343
|
+
*/
|
|
344
|
+
setAutoCleanup(enabled) {
|
|
345
|
+
this.autoCleanupEnabled = enabled;
|
|
346
|
+
if (enabled) {
|
|
347
|
+
this.startAutoCleanup();
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
this.stopAutoCleanup();
|
|
351
|
+
}
|
|
352
|
+
console.log(`⚙️ Auto cleanup ${enabled ? 'enabled' : 'disabled'}`);
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Enable or disable garbage collection
|
|
356
|
+
*/
|
|
357
|
+
setGarbageCollection(enabled) {
|
|
358
|
+
this.gcEnabled = enabled;
|
|
359
|
+
console.log(`⚙️ Garbage collection ${enabled ? 'enabled' : 'disabled'}`);
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Set cleanup interval
|
|
363
|
+
*/
|
|
364
|
+
setCleanupInterval(intervalMs) {
|
|
365
|
+
if (intervalMs < 5000) {
|
|
366
|
+
throw new Error('Cleanup interval must be at least 5 seconds');
|
|
367
|
+
}
|
|
368
|
+
this.cleanupIntervalMs = intervalMs;
|
|
369
|
+
// Restart auto cleanup with new interval
|
|
370
|
+
if (this.autoCleanupEnabled) {
|
|
371
|
+
this.stopAutoCleanup();
|
|
372
|
+
this.startAutoCleanup();
|
|
373
|
+
}
|
|
374
|
+
console.log(`⚙️ Cleanup interval set to ${intervalMs}ms`);
|
|
375
|
+
}
|
|
376
|
+
// =============================================================================
|
|
377
|
+
// RESOURCE STATISTICS
|
|
378
|
+
// =============================================================================
|
|
379
|
+
/**
|
|
380
|
+
* Get comprehensive resource statistics
|
|
381
|
+
*/
|
|
382
|
+
getResourceStats() {
|
|
383
|
+
const resources = Array.from(this.resources.values());
|
|
384
|
+
const now = new Date();
|
|
385
|
+
const resourcesByType = resources.reduce((acc, resource) => {
|
|
386
|
+
acc[resource.type] = (acc[resource.type] || 0) + 1;
|
|
387
|
+
return acc;
|
|
388
|
+
}, {});
|
|
389
|
+
const totalEstimatedMemory = resources.reduce((sum, resource) => sum + resource.memoryEstimateMB, 0);
|
|
390
|
+
let oldestResource = null;
|
|
391
|
+
let newestResource = null;
|
|
392
|
+
if (resources.length > 0) {
|
|
393
|
+
const sortedByAge = resources.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
|
394
|
+
const oldest = sortedByAge[0];
|
|
395
|
+
const newest = sortedByAge[sortedByAge.length - 1];
|
|
396
|
+
oldestResource = {
|
|
397
|
+
name: oldest.name,
|
|
398
|
+
ageMinutes: Math.round((now.getTime() - oldest.createdAt.getTime()) / 60000)
|
|
399
|
+
};
|
|
400
|
+
newestResource = {
|
|
401
|
+
name: newest.name,
|
|
402
|
+
ageMinutes: Math.round((now.getTime() - newest.createdAt.getTime()) / 60000)
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
return {
|
|
406
|
+
totalResources: resources.length,
|
|
407
|
+
resourcesByType,
|
|
408
|
+
totalEstimatedMemoryMB: totalEstimatedMemory,
|
|
409
|
+
oldestResource,
|
|
410
|
+
newestResource,
|
|
411
|
+
memoryStats: this.getMemoryStats()
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
// =============================================================================
|
|
415
|
+
// PRIVATE METHODS
|
|
416
|
+
// =============================================================================
|
|
417
|
+
/**
|
|
418
|
+
* Generate unique resource ID
|
|
419
|
+
*/
|
|
420
|
+
generateResourceId(type, name) {
|
|
421
|
+
const timestamp = Date.now();
|
|
422
|
+
const random = Math.random().toString(36).substring(2, 8);
|
|
423
|
+
return `${type}_${name.replace(/[^a-zA-Z0-9]/g, '_')}_${timestamp}_${random}`;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Estimate memory usage for embedder
|
|
427
|
+
*/
|
|
428
|
+
estimateEmbedderMemory(embedder) {
|
|
429
|
+
// Rough estimates based on model type and dimensions
|
|
430
|
+
const dimensions = embedder.dimensions;
|
|
431
|
+
const modelType = embedder.modelType;
|
|
432
|
+
if (modelType === 'clip') {
|
|
433
|
+
// CLIP models are typically larger
|
|
434
|
+
return Math.max(200, dimensions * 0.5); // Minimum 200MB for CLIP
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
// Sentence transformers are typically smaller
|
|
438
|
+
return Math.max(100, dimensions * 0.3); // Minimum 100MB for sentence transformers
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Estimate memory usage for model
|
|
443
|
+
*/
|
|
444
|
+
estimateModelMemory(modelType) {
|
|
445
|
+
const estimates = {
|
|
446
|
+
'clip': 300,
|
|
447
|
+
'sentence-transformer': 150,
|
|
448
|
+
'image-to-text': 250,
|
|
449
|
+
'cross-encoder': 100,
|
|
450
|
+
'default': 100
|
|
451
|
+
};
|
|
452
|
+
return estimates[modelType] || estimates.default;
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Estimate memory usage for processor
|
|
456
|
+
*/
|
|
457
|
+
estimateProcessorMemory(processorName) {
|
|
458
|
+
if (processorName.includes('image')) {
|
|
459
|
+
return 50; // Image processors are relatively lightweight
|
|
460
|
+
}
|
|
461
|
+
return 25; // Default for other processors
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Start automatic cleanup timer
|
|
465
|
+
*/
|
|
466
|
+
startAutoCleanup() {
|
|
467
|
+
if (this.cleanupTimer) {
|
|
468
|
+
clearInterval(this.cleanupTimer);
|
|
469
|
+
}
|
|
470
|
+
this.cleanupTimer = setInterval(async () => {
|
|
471
|
+
if (this.autoCleanupEnabled) {
|
|
472
|
+
try {
|
|
473
|
+
// Check memory and clean up if needed
|
|
474
|
+
if (this.isMemoryThresholdExceeded()) {
|
|
475
|
+
await this.optimizeMemory();
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
catch (error) {
|
|
479
|
+
console.warn(`Auto cleanup error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}, this.cleanupIntervalMs);
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Stop automatic cleanup timer
|
|
486
|
+
*/
|
|
487
|
+
stopAutoCleanup() {
|
|
488
|
+
if (this.cleanupTimer) {
|
|
489
|
+
clearInterval(this.cleanupTimer);
|
|
490
|
+
this.cleanupTimer = undefined;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Setup memory monitoring
|
|
495
|
+
*/
|
|
496
|
+
setupMemoryMonitoring() {
|
|
497
|
+
// Monitor memory usage periodically
|
|
498
|
+
this.memoryMonitorTimer = setInterval(() => {
|
|
499
|
+
const stats = this.getMemoryStats();
|
|
500
|
+
// Log warning if memory usage is high
|
|
501
|
+
if (stats.heapUsedMB > this.memoryThresholdMB * 0.8) {
|
|
502
|
+
console.warn(`⚠️ High memory usage: ${stats.heapUsedMB}MB (threshold: ${this.memoryThresholdMB}MB)`);
|
|
503
|
+
}
|
|
504
|
+
}, 60000); // Check every minute
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Stop memory monitoring
|
|
508
|
+
*/
|
|
509
|
+
stopMemoryMonitoring() {
|
|
510
|
+
if (this.memoryMonitorTimer) {
|
|
511
|
+
clearInterval(this.memoryMonitorTimer);
|
|
512
|
+
this.memoryMonitorTimer = undefined;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Shutdown resource manager
|
|
517
|
+
*/
|
|
518
|
+
async shutdown() {
|
|
519
|
+
console.log('🔄 Shutting down resource manager...');
|
|
520
|
+
this.stopAutoCleanup();
|
|
521
|
+
this.stopMemoryMonitoring();
|
|
522
|
+
const stats = await this.cleanupAllResources();
|
|
523
|
+
console.log(`✅ Resource manager shutdown complete: ${stats.resourcesCleanedUp} resources cleaned up`);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
// =============================================================================
|
|
527
|
+
// CONVENIENCE FUNCTIONS
|
|
528
|
+
// =============================================================================
|
|
529
|
+
/**
|
|
530
|
+
* Get the global resource manager instance
|
|
531
|
+
*/
|
|
532
|
+
export function getResourceManager() {
|
|
533
|
+
return ResourceManager.getInstance();
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Register an embedder for automatic resource management
|
|
537
|
+
*/
|
|
538
|
+
export function registerEmbedder(embedder) {
|
|
539
|
+
return getResourceManager().registerEmbedder(embedder);
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Clean up all resources and optimize memory
|
|
543
|
+
*/
|
|
544
|
+
export async function cleanupAndOptimizeMemory() {
|
|
545
|
+
const manager = getResourceManager();
|
|
546
|
+
await manager.optimizeMemory();
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Force garbage collection if available
|
|
550
|
+
*/
|
|
551
|
+
export function forceGarbageCollection() {
|
|
552
|
+
return getResourceManager().forceGarbageCollection();
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Get current memory statistics
|
|
556
|
+
*/
|
|
557
|
+
export function getMemoryStats() {
|
|
558
|
+
return getResourceManager().getMemoryStats();
|
|
559
|
+
}
|
|
560
|
+
// =============================================================================
|
|
561
|
+
// DEFAULT EXPORT
|
|
562
|
+
// =============================================================================
|
|
563
|
+
export default ResourceManager;
|
|
564
|
+
//# sourceMappingURL=resource-manager.js.map
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORE MODULE — Shared between text-only (rag-lite-ts) and future multimodal (rag-lite-mm)
|
|
3
|
+
* Model-agnostic. No transformer or modality-specific logic.
|
|
4
|
+
*/
|
|
5
|
+
import type { SearchResult, SearchOptions, EmbeddingResult } from './types.js';
|
|
6
|
+
import type { EmbedFunction, RerankFunction, SearchPipelineInterface } from './interfaces.js';
|
|
7
|
+
/**
|
|
8
|
+
* Core search pipeline coordinator
|
|
9
|
+
* Orchestrates the search pipeline: query processing → vector search → metadata retrieval → optional reranking
|
|
10
|
+
* Remains completely independent of specific embedding models or transformer libraries
|
|
11
|
+
*/
|
|
12
|
+
export declare class SearchPipelineCoordinator implements SearchPipelineInterface {
|
|
13
|
+
private embedQueryFn;
|
|
14
|
+
private rerankResultsFn;
|
|
15
|
+
private indexManager;
|
|
16
|
+
private dbConnection;
|
|
17
|
+
private defaultContentType;
|
|
18
|
+
/**
|
|
19
|
+
* Set the embedding function for query processing
|
|
20
|
+
*/
|
|
21
|
+
setEmbedFunction(embedFn: EmbedFunction): void;
|
|
22
|
+
/**
|
|
23
|
+
* Set the reranking function for result reranking
|
|
24
|
+
*/
|
|
25
|
+
setRerankFunction(rerankFn: RerankFunction): void;
|
|
26
|
+
/**
|
|
27
|
+
* Set the index manager for vector search
|
|
28
|
+
*/
|
|
29
|
+
setIndexManager(indexManager: any): void;
|
|
30
|
+
/**
|
|
31
|
+
* Set the database connection for metadata retrieval
|
|
32
|
+
*/
|
|
33
|
+
setDatabaseConnection(dbConnection: any): void;
|
|
34
|
+
/**
|
|
35
|
+
* Set the default content type
|
|
36
|
+
*/
|
|
37
|
+
setDefaultContentType(contentType: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Execute the complete search pipeline
|
|
40
|
+
* Coordinates all steps without knowledge of specific embedding models
|
|
41
|
+
*/
|
|
42
|
+
executeSearchPipeline(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Step 1: Process and embed the query
|
|
45
|
+
* Uses injected embedding function without knowledge of specific models
|
|
46
|
+
*/
|
|
47
|
+
embedQuery(query: string, contentType?: string): Promise<EmbeddingResult>;
|
|
48
|
+
/**
|
|
49
|
+
* Step 2: Perform vector search
|
|
50
|
+
* Uses index manager without knowledge of specific embedding models
|
|
51
|
+
*/
|
|
52
|
+
vectorSearch(queryVector: Float32Array, topK: number): Promise<{
|
|
53
|
+
embeddingIds: string[];
|
|
54
|
+
distances: number[];
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Step 3: Retrieve metadata from database
|
|
58
|
+
* Uses database connection without knowledge of specific data formats
|
|
59
|
+
*/
|
|
60
|
+
retrieveMetadata(embeddingIds: string[]): Promise<any[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Step 4: Format initial results
|
|
63
|
+
* Formats results in core format without knowledge of specific content types
|
|
64
|
+
*/
|
|
65
|
+
formatResults(chunks: any[], distances: number[], embeddingIds: string[]): SearchResult[];
|
|
66
|
+
/**
|
|
67
|
+
* Step 5: Optional reranking
|
|
68
|
+
* Uses injected reranking function without knowledge of specific models
|
|
69
|
+
*/
|
|
70
|
+
rerankResults(query: string, results: SearchResult[], contentType?: string): Promise<SearchResult[]>;
|
|
71
|
+
/**
|
|
72
|
+
* Validate that all required dependencies are set
|
|
73
|
+
*/
|
|
74
|
+
private validateDependencies;
|
|
75
|
+
/**
|
|
76
|
+
* Parse metadata safely
|
|
77
|
+
*/
|
|
78
|
+
private parseMetadata;
|
|
79
|
+
/**
|
|
80
|
+
* Check if the pipeline is ready to execute
|
|
81
|
+
*/
|
|
82
|
+
isReady(): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Get pipeline status information
|
|
85
|
+
*/
|
|
86
|
+
getStatus(): {
|
|
87
|
+
hasEmbedFunction: boolean;
|
|
88
|
+
hasRerankFunction: boolean;
|
|
89
|
+
hasIndexManager: boolean;
|
|
90
|
+
hasDatabaseConnection: boolean;
|
|
91
|
+
isReady: boolean;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Reset all dependencies (useful for testing or reconfiguration)
|
|
95
|
+
*/
|
|
96
|
+
reset(): void;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Factory for creating search pipeline coordinators
|
|
100
|
+
*/
|
|
101
|
+
export declare class SearchPipelineFactory {
|
|
102
|
+
/**
|
|
103
|
+
* Create a search pipeline coordinator with all dependencies
|
|
104
|
+
*/
|
|
105
|
+
static create(embedFn: EmbedFunction, indexManager: any, dbConnection: any, rerankFn?: RerankFunction, defaultContentType?: string): SearchPipelineCoordinator;
|
|
106
|
+
/**
|
|
107
|
+
* Create an empty coordinator for manual configuration
|
|
108
|
+
*/
|
|
109
|
+
static createEmpty(): SearchPipelineCoordinator;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=search-pipeline.d.ts.map
|