diff --git a/packages/core/__tests__/lookup.test.js b/packages/core/__tests__/lookup.test.js
index 86dec39a2..49d10e335 100644
--- a/packages/core/__tests__/lookup.test.js
+++ b/packages/core/__tests__/lookup.test.js
@@ -14,7 +14,10 @@ beforeEach(async () => {
StorageInterface.clear();
});
-const content = { ...TEST_NOTE.content, data: "
5
" };
+const content = {
+ ...TEST_NOTE.content,
+ data: "hello i am a note of the world
",
+};
//TODO
test("search notes", () =>
@@ -22,7 +25,7 @@ test("search notes", () =>
content: content,
}).then(async ({ db }) => {
await db.notes.add(TEST_NOTE);
- let filtered = await db.lookup.notes(db.notes.all, "5");
+ let filtered = await db.lookup.notes(db.notes.all, "note of the world");
expect(filtered.length).toBe(1);
}));
@@ -33,7 +36,7 @@ test("search notes with a locked note", () =>
const noteId = await db.notes.add(TEST_NOTE);
await db.vault.create("password");
await db.vault.add(noteId);
- let filtered = await db.lookup.notes(db.notes.all, "5");
+ let filtered = await db.lookup.notes(db.notes.all, "note of the world");
expect(filtered.length).toBe(1);
}));
@@ -42,10 +45,10 @@ test("search notes with an empty note", () =>
content: content,
}).then(async ({ db }) => {
await db.notes.add({
- title: "hello world",
+ title: "world is a heavy tune",
content: { type: "tiny", data: "
" },
});
- let filtered = await db.lookup.notes(db.notes.all, "hello world");
+ let filtered = await db.lookup.notes(db.notes.all, "heavy tune");
expect(filtered.length).toBe(1);
}));
diff --git a/packages/core/api/lookup.js b/packages/core/api/lookup.js
index df831b6fd..43f6a97ea 100644
--- a/packages/core/api/lookup.js
+++ b/packages/core/api/lookup.js
@@ -1,5 +1,4 @@
-import { qclone } from "qclone";
-import { getContentFromData } from "../content-types";
+import { Fzf } from "fzf";
export default class Lookup {
/**
@@ -11,28 +10,37 @@ export default class Lookup {
}
async notes(notes, query) {
- notes = qclone(notes);
const contents = await this._db.content.multi(
notes.map((note) => note.contentId || "")
);
- return notes.filter((note) => {
- let content = "";
- if (!note.locked) {
- content = contents.find(
- (content) => !!content && content.id === note.contentId
- );
- if (!content) return false;
- content = getContentFromData(content.type, content.data);
- content = content.toHTML();
- }
- return search(query, note.title) || search(query, content);
- });
+
+ const items = [];
+ for (let i = 0; i < notes.length; ++i) {
+ const note = notes[i];
+ const item = { note, text: note.title };
+ items.push(item);
+ if (
+ !note.locked &&
+ !!note.contentId &&
+ contents.hasOwnProperty(note.contentId)
+ )
+ item.text += " " + contents[note.contentId]["data"];
+ }
+
+ return new Fzf(items, {
+ selector: (v) => v.text,
+ normalize: false,
+ })
+ .find(query)
+ .map((v) => v.item.note);
}
notebooks(array, query) {
- return array.filter(
- (item) => search(query, item.title) || search(query, item.description)
- );
+ return new Fzf(array, {
+ selector: (n) => `${n.title} ${n.description}`,
+ })
+ .find(query)
+ .map((v) => v.item);
}
topics(array, query) {
@@ -48,11 +56,10 @@ export default class Lookup {
}
_byTitle(array, query) {
- return array.filter((item) => search(query, item.title));
+ return new Fzf(array, {
+ selector: (n) => n.title,
+ })
+ .find(query)
+ .map((v) => v.item);
}
}
-
-function search(query, string) {
- const words = query.toLowerCase().split(" ");
- return words.some((word) => string.toLowerCase().indexOf(word) > -1);
-}
diff --git a/packages/core/package-lock.json b/packages/core/package-lock.json
index 27fd3ef77..d0da3515a 100644
--- a/packages/core/package-lock.json
+++ b/packages/core/package-lock.json
@@ -1,17 +1,18 @@
{
"name": "notes-core",
- "version": "6.13.1",
+ "version": "6.14.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "notes-core",
- "version": "6.13.1",
+ "version": "6.14.0",
"dependencies": {
"@stablelib/blake2s": "^1.0.1",
"async-mutex": "^0.3.2",
"dayjs": "^1.10.6",
"fast-sort": "^2.0.1",
+ "fzf": "^0.4.1",
"node-html-parser": "github:thecodrr/node-html-parser",
"qclone": "^1.0.4",
"showdown": "github:thecodrr/showdown",
@@ -4174,6 +4175,11 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
+ "node_modules/fzf": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/fzf/-/fzf-0.4.1.tgz",
+ "integrity": "sha512-ZKnxeZqxkJlnHXE37yfqyGez45Wan99eqns5B9xzVTvF4MazXlLsOYWeyiofdCEexgzuOmYGs3g7gtlz9lGxiQ=="
+ },
"node_modules/gensync": {
"version": "1.0.0-beta.1",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
@@ -11785,6 +11791,11 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
+ "fzf": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/fzf/-/fzf-0.4.1.tgz",
+ "integrity": "sha512-ZKnxeZqxkJlnHXE37yfqyGez45Wan99eqns5B9xzVTvF4MazXlLsOYWeyiofdCEexgzuOmYGs3g7gtlz9lGxiQ=="
+ },
"gensync": {
"version": "1.0.0-beta.1",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
diff --git a/packages/core/package.json b/packages/core/package.json
index 9b7a96918..597c875fa 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -27,6 +27,7 @@
"async-mutex": "^0.3.2",
"dayjs": "^1.10.6",
"fast-sort": "^2.0.1",
+ "fzf": "^0.4.1",
"node-html-parser": "github:thecodrr/node-html-parser",
"qclone": "^1.0.4",
"showdown": "github:thecodrr/showdown",