aboutsummaryrefslogtreecommitdiffstats
path: root/packages/plugins-search-meilisearch
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2025-11-08 14:50:00 +0000
committerGitHub <noreply@github.com>2025-11-08 14:50:00 +0000
commit99413db0e79a156a1b87eacd3c6a7b83e9df946e (patch)
tree73f0a5fceb507f75f662a109b00beeb3fa6b16fb /packages/plugins-search-meilisearch
parent737b03172c2e063ba311c23d6552418bd2ab1955 (diff)
downloadkarakeep-99413db0e79a156a1b87eacd3c6a7b83e9df946e.tar.zst
refactor: consolidate multiple karakeep plugins into one package (#2101)
* refactor: consolidate plugin packages into single plugins directory - Create new `packages/plugins` directory with consolidated package.json - Move queue-liteque, queue-restate, and search-meilisearch to subdirectories - Update imports in packages/shared-server/src/plugins.ts - Remove individual plugin package directories - Update shared-server dependency to use @karakeep/plugins This reduces overhead of maintaining multiple separate packages for plugins. * refactor: consolidate plugin config files to root level - Move .oxlintrc.json to packages/plugins root - Move vitest.config.ts to packages/plugins root - Update vitest config paths to work from root - Remove individual config files from plugin subdirectories This reduces configuration duplication across plugin subdirectories. --------- Co-authored-by: Claude <noreply@anthropic.com>
Diffstat (limited to 'packages/plugins-search-meilisearch')
-rw-r--r--packages/plugins-search-meilisearch/.oxlintrc.json19
-rw-r--r--packages/plugins-search-meilisearch/index.ts12
-rw-r--r--packages/plugins-search-meilisearch/package.json26
-rw-r--r--packages/plugins-search-meilisearch/src/env.ts8
-rw-r--r--packages/plugins-search-meilisearch/src/index.ts159
-rw-r--r--packages/plugins-search-meilisearch/tsconfig.json9
6 files changed, 0 insertions, 233 deletions
diff --git a/packages/plugins-search-meilisearch/.oxlintrc.json b/packages/plugins-search-meilisearch/.oxlintrc.json
deleted file mode 100644
index 79ba0255..00000000
--- a/packages/plugins-search-meilisearch/.oxlintrc.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "$schema": "../../node_modules/oxlint/configuration_schema.json",
- "extends": [
- "../../tooling/oxlint/oxlint-base.json"
- ],
- "env": {
- "builtin": true,
- "commonjs": true
- },
- "ignorePatterns": [
- "**/*.config.js",
- "**/*.config.cjs",
- "**/.eslintrc.cjs",
- "**/.next",
- "**/dist",
- "**/build",
- "**/pnpm-lock.yaml"
- ]
-}
diff --git a/packages/plugins-search-meilisearch/index.ts b/packages/plugins-search-meilisearch/index.ts
deleted file mode 100644
index 3496d52f..00000000
--- a/packages/plugins-search-meilisearch/index.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-// Auto-register the MeiliSearch provider when this package is imported
-import { PluginManager, PluginType } from "@karakeep/shared/plugins";
-
-import { MeiliSearchProvider } from "./src";
-
-if (MeiliSearchProvider.isConfigured()) {
- PluginManager.register({
- type: PluginType.Search,
- name: "MeiliSearch",
- provider: new MeiliSearchProvider(),
- });
-}
diff --git a/packages/plugins-search-meilisearch/package.json b/packages/plugins-search-meilisearch/package.json
deleted file mode 100644
index c9482731..00000000
--- a/packages/plugins-search-meilisearch/package.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "$schema": "https://json.schemastore.org/package.json",
- "name": "@karakeep/plugins-search-meilisearch",
- "version": "0.1.0",
- "private": true,
- "type": "module",
- "scripts": {
- "typecheck": "tsc --noEmit",
- "format": "prettier . --cache --ignore-path ../../.prettierignore --check",
- "format:fix": "prettier . --cache --ignore-path ../../.prettierignore --write",
- "lint": "oxlint .",
- "lint:fix": "oxlint . --fix",
- "test": "vitest"
- },
- "dependencies": {
- "@karakeep/shared": "workspace:*",
- "meilisearch": "^0.45.0"
- },
- "devDependencies": {
- "@karakeep/prettier-config": "workspace:^0.1.0",
- "@karakeep/tsconfig": "workspace:^0.1.0",
- "vite-tsconfig-paths": "^4.3.1",
- "vitest": "^3.2.4"
- },
- "prettier": "@karakeep/prettier-config"
-}
diff --git a/packages/plugins-search-meilisearch/src/env.ts b/packages/plugins-search-meilisearch/src/env.ts
deleted file mode 100644
index c06fdd55..00000000
--- a/packages/plugins-search-meilisearch/src/env.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { z } from "zod";
-
-export const envConfig = z
- .object({
- MEILI_ADDR: z.string().optional(),
- MEILI_MASTER_KEY: z.string().default(""),
- })
- .parse(process.env);
diff --git a/packages/plugins-search-meilisearch/src/index.ts b/packages/plugins-search-meilisearch/src/index.ts
deleted file mode 100644
index 30da4a64..00000000
--- a/packages/plugins-search-meilisearch/src/index.ts
+++ /dev/null
@@ -1,159 +0,0 @@
-import type { Index } from "meilisearch";
-import { MeiliSearch } from "meilisearch";
-
-import type {
- BookmarkSearchDocument,
- FilterQuery,
- SearchIndexClient,
- SearchOptions,
- SearchResponse,
-} from "@karakeep/shared/search";
-import serverConfig from "@karakeep/shared/config";
-import { PluginProvider } from "@karakeep/shared/plugins";
-
-import { envConfig } from "./env";
-
-function filterToMeiliSearchFilter(filter: FilterQuery): string {
- switch (filter.type) {
- case "eq":
- return `${filter.field} = "${filter.value}"`;
- case "in":
- return `${filter.field} IN [${filter.values.join(",")}]`;
- default: {
- const exhaustiveCheck: never = filter;
- throw new Error(`Unhandled color case: ${exhaustiveCheck}`);
- }
- }
-}
-
-class MeiliSearchIndexClient implements SearchIndexClient {
- constructor(private index: Index<BookmarkSearchDocument>) {}
-
- async addDocuments(documents: BookmarkSearchDocument[]): Promise<void> {
- const task = await this.index.addDocuments(documents, {
- primaryKey: "id",
- });
- await this.ensureTaskSuccess(task.taskUid);
- }
-
- async deleteDocuments(ids: string[]): Promise<void> {
- const task = await this.index.deleteDocuments(ids);
- await this.ensureTaskSuccess(task.taskUid);
- }
-
- async search(options: SearchOptions): Promise<SearchResponse> {
- const result = await this.index.search(options.query, {
- filter: options.filter?.map((f) => filterToMeiliSearchFilter(f)),
- limit: options.limit,
- offset: options.offset,
- sort: options.sort?.map((s) => `${s.field}:${s.order}`),
- attributesToRetrieve: ["id"],
- showRankingScore: true,
- });
-
- return {
- hits: result.hits.map((hit) => ({
- id: hit.id,
- score: hit._rankingScore,
- })),
- totalHits: result.estimatedTotalHits ?? 0,
- processingTimeMs: result.processingTimeMs,
- };
- }
-
- async clearIndex(): Promise<void> {
- const task = await this.index.deleteAllDocuments();
- await this.ensureTaskSuccess(task.taskUid);
- }
-
- private async ensureTaskSuccess(taskUid: number): Promise<void> {
- const task = await this.index.waitForTask(taskUid, {
- intervalMs: 200,
- timeOutMs: serverConfig.search.jobTimeoutSec * 1000 * 0.9,
- });
- if (task.error) {
- throw new Error(`Search task failed: ${task.error.message}`);
- }
- }
-}
-
-export class MeiliSearchProvider implements PluginProvider<SearchIndexClient> {
- private client: MeiliSearch | undefined;
- private indexClient: SearchIndexClient | undefined;
- private readonly indexName = "bookmarks";
-
- constructor() {
- if (MeiliSearchProvider.isConfigured()) {
- this.client = new MeiliSearch({
- host: envConfig.MEILI_ADDR!,
- apiKey: envConfig.MEILI_MASTER_KEY,
- });
- }
- }
-
- static isConfigured(): boolean {
- return !!envConfig.MEILI_ADDR;
- }
-
- async getClient(): Promise<SearchIndexClient | null> {
- if (this.indexClient) {
- return this.indexClient;
- }
-
- if (!this.client) {
- return null;
- }
-
- const indices = await this.client.getIndexes();
- let indexFound = indices.results.find((i) => i.uid === this.indexName);
-
- if (!indexFound) {
- const idx = await this.client.createIndex(this.indexName, {
- primaryKey: "id",
- });
- await this.client.waitForTask(idx.taskUid);
- indexFound = await this.client.getIndex<BookmarkSearchDocument>(
- this.indexName,
- );
- }
-
- await this.configureIndex(indexFound);
- this.indexClient = new MeiliSearchIndexClient(indexFound);
- return this.indexClient;
- }
-
- private async configureIndex(
- index: Index<BookmarkSearchDocument>,
- ): Promise<void> {
- const desiredFilterableAttributes = ["id", "userId"].sort();
- const desiredSortableAttributes = ["createdAt"].sort();
-
- const settings = await index.getSettings();
-
- if (
- JSON.stringify(settings.filterableAttributes?.sort()) !==
- JSON.stringify(desiredFilterableAttributes)
- ) {
- console.log(
- `[meilisearch] Updating desired filterable attributes to ${desiredFilterableAttributes} from ${settings.filterableAttributes}`,
- );
- const taskId = await index.updateFilterableAttributes(
- desiredFilterableAttributes,
- );
- await this.client!.waitForTask(taskId.taskUid);
- }
-
- if (
- JSON.stringify(settings.sortableAttributes?.sort()) !==
- JSON.stringify(desiredSortableAttributes)
- ) {
- console.log(
- `[meilisearch] Updating desired sortable attributes to ${desiredSortableAttributes} from ${settings.sortableAttributes}`,
- );
- const taskId = await index.updateSortableAttributes(
- desiredSortableAttributes,
- );
- await this.client!.waitForTask(taskId.taskUid);
- }
- }
-}
diff --git a/packages/plugins-search-meilisearch/tsconfig.json b/packages/plugins-search-meilisearch/tsconfig.json
deleted file mode 100644
index a795b96a..00000000
--- a/packages/plugins-search-meilisearch/tsconfig.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "$schema": "https://json.schemastore.org/tsconfig",
- "extends": "@karakeep/tsconfig/node.json",
- "include": ["**/*.ts"],
- "exclude": ["node_modules"],
- "compilerOptions": {
- "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json"
- }
-}