aboutsummaryrefslogtreecommitdiffstats
path: root/packages/shared/search.ts
blob: 8422d79ef59c0d0740d0932d86d126b68efb8db3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { MeiliSearch, Index } from "meilisearch";
import serverConfig from "./config";
import { z } from "zod";

export const zBookmarkIdxSchema = z.object({
  id: z.string(),
  userId: z.string(),
  url: z.string().nullish(),
  title: z.string().nullish(),
  description: z.string().nullish(),
  content: z.string().nullish(),
  createdAt: z.string().nullish(),
  note: z.string().nullish(),
  tags: z.array(z.string()).default([]),
});

export type ZBookmarkIdx = z.infer<typeof zBookmarkIdxSchema>;

let searchClient: MeiliSearch | undefined;

if (serverConfig.meilisearch) {
  searchClient = new MeiliSearch({
    host: serverConfig.meilisearch.address,
    apiKey: serverConfig.meilisearch.key,
  });
}

const BOOKMARKS_IDX_NAME = "bookmarks";

let idxClient: Index<ZBookmarkIdx> | undefined;

export async function getSearchIdxClient(): Promise<Index<ZBookmarkIdx> | null> {
  if (idxClient) {
    return idxClient;
  }
  if (!searchClient) {
    return null;
  }

  const indicies = await searchClient.getIndexes();
  let idxFound = indicies.results.find((i) => i.uid == BOOKMARKS_IDX_NAME);
  if (!idxFound) {
    const idx = await searchClient.createIndex(BOOKMARKS_IDX_NAME, {
      primaryKey: "id",
    });
    await searchClient.waitForTask(idx.taskUid);
    idxFound = await searchClient.getIndex<ZBookmarkIdx>(BOOKMARKS_IDX_NAME);
  }

  const desiredFilterableAttributes = ["id", "userId"].sort();
  const desiredSortableAttributes = ["createdAt"].sort();

  const settings = await idxFound.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 idxFound.updateFilterableAttributes(desiredFilterableAttributes);
    await searchClient.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 idxFound.updateSortableAttributes(desiredSortableAttributes);
    await searchClient.waitForTask(taskId.taskUid);
  }
  idxClient = idxFound;
  return idxFound;
}