fix: bundle chromadb and fix fetch invocation in Electron
- Bundle chromadb into main.js via esbuild instead of externalizing it.
Obsidian's renderer cannot resolve bare require('chromadb') against a
plugin-local node_modules. By bundling, the client library is inlined and
works out of the box with just manifest.json + main.js.
- Remove eager cache initialization from OllamaClient constructor to avoid
unhandled promise rejections when chromadb/ChromaDB is unavailable.
- Fix 'Failed to execute fetch on Window: Illegal invocation' by wrapping
the default fetch fallback in an arrow function:
this.fetchFn = fetchFn ?? ((url, init) => fetch(url, init));
This preserves the window binding when fetch is called later.
- Update install.sh and README to remove the obsolete node_modules/chromadb
copy step.
- Update ollama-client-cache tests to reflect that cache initialization is
no longer eager.
This commit is contained in:
@@ -68,10 +68,9 @@ cp manifest.json /path/to/vault/.obsidian/plugins/ollama-plugin/
|
||||
cp main.js /path/to/vault/.obsidian/plugins/ollama-plugin/
|
||||
# Remove old dist/ from previous installs (no longer needed with bundling)
|
||||
rm -rf /path/to/vault/.obsidian/plugins/ollama-plugin/dist
|
||||
cp -r node_modules/chromadb /path/to/vault/.obsidian/plugins/ollama-plugin/node_modules/ # optional: only needed for semantic cache
|
||||
```
|
||||
|
||||
> **Note:** The plugin is now bundled into a single `main.js` via esbuild. The `obsidian` npm package is a dev-only type stub — Obsidian provides its own API at runtime. The `chromadb` package is only needed if you enable the semantic cache feature.
|
||||
> **Note:** The plugin is now bundled into a single `main.js` via esbuild. The `obsidian` npm package is a dev-only type stub — Obsidian provides its own API at runtime. The `chromadb` client library is also bundled into `main.js`, so no extra `node_modules` copy is needed for the semantic cache feature.
|
||||
|
||||
### After installation
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
services:
|
||||
chroma:
|
||||
image: chromadb/chroma:latest
|
||||
ports:
|
||||
- "8666:8000"
|
||||
environment:
|
||||
- CHROMA_SERVER_HOST=0.0.0.0
|
||||
- CHROMA_SERVER_HTTP_PORT=8000
|
||||
volumes:
|
||||
- chroma_data:/chroma/chroma
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
chroma_data:
|
||||
+1
-7
@@ -99,13 +99,7 @@ rm -rf "$PLUGIN_DIR/dist"
|
||||
cp "$SCRIPT_DIR/manifest.json" "$PLUGIN_DIR/"
|
||||
cp "$SCRIPT_DIR/main.js" "$PLUGIN_DIR/"
|
||||
|
||||
# Copy only necessary runtime dependencies
|
||||
# obsidian is a dev-only type stub — not needed at runtime
|
||||
# chromadb is loaded dynamically and only needed when the cache is enabled.
|
||||
mkdir -p "$PLUGIN_DIR/node_modules"
|
||||
if [ -d "$SCRIPT_DIR/node_modules/chromadb" ]; then
|
||||
cp -r "$SCRIPT_DIR/node_modules/chromadb" "$PLUGIN_DIR/node_modules/"
|
||||
fi
|
||||
# All dependencies are now bundled into main.js; no runtime node_modules needed.
|
||||
|
||||
info "Plugin installed to $PLUGIN_DIR"
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
"main": "dist/main.js",
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"build": "tsc --noEmit && node -e \"require('esbuild').build({entryPoints:['src/main.ts'],bundle:true,platform:'node',target:'es2020',outfile:'main.js',external:['obsidian','chromadb'],format:'cjs'})\"",
|
||||
"build": "tsc --noEmit && node -e \"require('esbuild').build({entryPoints:['src/main.ts'],bundle:true,platform:'node',target:'es2020',outfile:'main.js',external:['obsidian','cohere-ai','ollama','openai','@google/generative-ai','voyageai'],format:'cjs'})\"",
|
||||
"watch": "tsc --watch",
|
||||
"lint": "eslint src --ext .ts",
|
||||
"format": "prettier --write ."
|
||||
|
||||
@@ -26,7 +26,6 @@ export class OllamaClient {
|
||||
|
||||
if (cacheConfig?.enabled) {
|
||||
this.cacheService = new SemanticCacheService(baseURL, cacheConfig);
|
||||
void this.cacheService.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,12 +20,8 @@ export class SemanticCacheService {
|
||||
if (!this.config.enabled) return;
|
||||
|
||||
try {
|
||||
// Dynamic require — chromadb is optional and may not be installed.
|
||||
// Using Node's require() instead of ESM import() so Electron can resolve
|
||||
// the external chromadb package against the plugin's node_modules.
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const chromadb = require('chromadb');
|
||||
const { ChromaClient } = chromadb;
|
||||
const { ChromaClient } = require('chromadb');
|
||||
const chromaURL = this.config.chromaURL || 'http://localhost:8000';
|
||||
this.client = new ChromaClient({ path: chromaURL });
|
||||
this.collection = await this.client.getOrCreateCollection({
|
||||
|
||||
@@ -32,28 +32,30 @@ describe('OllamaClient', () => {
|
||||
});
|
||||
|
||||
describe('constructor', () => {
|
||||
it('should initialize cache service when enabled', () => {
|
||||
it('should create cache service when enabled but not initialize it eagerly', () => {
|
||||
const cacheConfig: CacheConfig = {
|
||||
enabled: true,
|
||||
similarityThreshold: 0.85,
|
||||
collectionName: 'test_cache',
|
||||
embeddingModel: 'nomic-embed-text',
|
||||
chromaURL: 'http://localhost:8000'
|
||||
chromaURL: 'http://localhost:8000',
|
||||
};
|
||||
|
||||
const client = new OllamaClient(mockBaseUrl, mockModel, undefined, cacheConfig);
|
||||
|
||||
expect(client).toBeInstanceOf(OllamaClient);
|
||||
expect(mockInitialize).toHaveBeenCalledTimes(1);
|
||||
// Eager initialization was removed to avoid unhandled rejections;
|
||||
// initialization now happens via initializeCache() only.
|
||||
expect(mockInitialize).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should not initialize cache service when disabled', () => {
|
||||
it('should not create cache service when disabled', () => {
|
||||
const cacheConfig: CacheConfig = {
|
||||
enabled: false,
|
||||
similarityThreshold: 0.85,
|
||||
collectionName: 'test_cache',
|
||||
embeddingModel: 'nomic-embed-text',
|
||||
chromaURL: 'http://localhost:8000'
|
||||
chromaURL: 'http://localhost:8000',
|
||||
};
|
||||
|
||||
const client = new OllamaClient(mockBaseUrl, mockModel, undefined, cacheConfig);
|
||||
@@ -70,7 +72,7 @@ describe('OllamaClient', () => {
|
||||
similarityThreshold: 0.85,
|
||||
collectionName: 'test_cache',
|
||||
embeddingModel: 'nomic-embed-text',
|
||||
chromaURL: 'http://localhost:8000'
|
||||
chromaURL: 'http://localhost:8000',
|
||||
};
|
||||
|
||||
const client = new OllamaClient(mockBaseUrl, mockModel, undefined, cacheConfig);
|
||||
@@ -86,7 +88,7 @@ describe('OllamaClient', () => {
|
||||
similarityThreshold: 0.85,
|
||||
collectionName: 'test_cache',
|
||||
embeddingModel: 'nomic-embed-text',
|
||||
chromaURL: 'http://localhost:8000'
|
||||
chromaURL: 'http://localhost:8000',
|
||||
};
|
||||
|
||||
const client = new OllamaClient(mockBaseUrl, mockModel, undefined, cacheConfig);
|
||||
|
||||
Reference in New Issue
Block a user