From 798b854daa7bf07a9c063e2412905e4c41aad72f Mon Sep 17 00:00:00 2001 From: Elure Date: Mon, 18 May 2026 14:50:27 +0300 Subject: [PATCH 1/8] Update withSearch.tsx Signed-off-by: Elure --- apps/site/components/withSearch.tsx | 67 ++++++++++++++++++----------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/apps/site/components/withSearch.tsx b/apps/site/components/withSearch.tsx index a8c0a620affda..6e9b7d7771b87 100644 --- a/apps/site/components/withSearch.tsx +++ b/apps/site/components/withSearch.tsx @@ -3,7 +3,7 @@ import SearchBox from '@node-core/ui-components/Common/Search'; import { create, insertMultiple, search } from '@orama/orama'; import { useTranslations } from 'next-intl'; -import { useMemo, useRef } from 'react'; +import { useMemo } from 'react'; import { ORAMA_DB_URLS } from '#site/next.constants.mjs'; @@ -19,6 +19,13 @@ type SerializedOramaDb = { }; }; +type OramaUrls = typeof ORAMA_DB_URLS; + +type OramaClient = { + client: OramaCloud; + warmup: () => Promise; +}; + export const addPrefixToDocs = ( db: T, prefix: string @@ -35,9 +42,12 @@ export const addPrefixToDocs = ( }; }; -const loadOrama = async (db: AnyOrama): Promise => { +const loadOrama = async ( + db: AnyOrama, + urls: OramaUrls = ORAMA_DB_URLS +): Promise => { const indexes = await Promise.all( - Object.entries(ORAMA_DB_URLS).map(async ([key, url]) => { + Object.entries(urls).map(async ([key, url]) => { const response = await fetch(url); const fetchedDb = (await response.json()) as SerializedOramaDb; @@ -50,36 +60,43 @@ const loadOrama = async (db: AnyOrama): Promise => { } }; -export const useOrama = () => { - const loadPromiseRef = useRef | null>(null); - - return useMemo(() => { - const db = create({ - schema: { - title: 'string', - description: 'string', - href: 'string', - siteSection: 'string', - }, - }); - - // @ts-expect-error We are overriding a method, an error is expected. - db.search = async options => { - await (loadPromiseRef.current ??= loadOrama(db)); - return search(db, options); - }; - - return db; - }, []) as unknown as OramaCloud; +export const createOramaClient = ( + urls: OramaUrls = ORAMA_DB_URLS +): OramaClient => { + const db = create({ + schema: { + title: 'string', + description: 'string', + href: 'string', + siteSection: 'string', + }, + }); + + let loadPromise: Promise | null = null; + const warmup = () => (loadPromise ??= loadOrama(db, urls)); + + // @ts-expect-error We are overriding a method, an error is expected. + db.search = async options => { + await warmup(); + return search(db, options); + }; + + return { + client: db as unknown as OramaCloud, + warmup, + }; }; +export const useOrama = () => useMemo(() => createOramaClient(), []); + const WithSearch: FC = () => { const t = useTranslations(); - const client = useOrama(); + const { client, warmup } = useOrama(); return ( Date: Mon, 18 May 2026 14:52:50 +0300 Subject: [PATCH 2/8] Create index.test.jsx Signed-off-by: Elure --- .../Search/Modal/__tests__/index.test.jsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 packages/ui-components/src/Common/Search/Modal/__tests__/index.test.jsx diff --git a/packages/ui-components/src/Common/Search/Modal/__tests__/index.test.jsx b/packages/ui-components/src/Common/Search/Modal/__tests__/index.test.jsx new file mode 100644 index 0000000000000..8d894208432ee --- /dev/null +++ b/packages/ui-components/src/Common/Search/Modal/__tests__/index.test.jsx @@ -0,0 +1,46 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { fireEvent, render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import SearchModal from '..'; + +describe('SearchModal', () => { + it('warms search when the trigger receives hover or focus intent', async t => { + const warmup = t.mock.fn(); + + render( + +
Results
+
+ ); + + const trigger = screen.getByRole('button', { name: /search docs/i }); + + await userEvent.hover(trigger); + fireEvent.focus(trigger); + + assert.equal(warmup.mock.callCount(), 2); + }); + + it('warms search when the keyboard shortcut is pressed', () => { + let warmupCalls = 0; + + render( + { + warmupCalls += 1; + }} + > +
Results
+
+ ); + + fireEvent.keyDown(document, { key: 'k', ctrlKey: true }); + + assert.equal(warmupCalls, 1); + }); +}); From 58c8e45dfbdca7b90945adc46bac910b81ca0be5 Mon Sep 17 00:00:00 2001 From: Elure Date: Mon, 18 May 2026 14:53:22 +0300 Subject: [PATCH 3/8] Update index.tsx Signed-off-by: Elure --- .../src/Common/Search/Modal/index.tsx | 101 ++++++++++++------ 1 file changed, 66 insertions(+), 35 deletions(-) diff --git a/packages/ui-components/src/Common/Search/Modal/index.tsx b/packages/ui-components/src/Common/Search/Modal/index.tsx index 95769eb15adb9..5692932a429a7 100644 --- a/packages/ui-components/src/Common/Search/Modal/index.tsx +++ b/packages/ui-components/src/Common/Search/Modal/index.tsx @@ -1,5 +1,6 @@ import { MagnifyingGlassIcon } from '@heroicons/react/24/solid'; import { SearchRoot, Modal } from '@orama/ui/components'; +import { useCallback, useEffect } from 'react'; import SearchInput from '#ui/Common/Search/Input'; @@ -10,47 +11,77 @@ import styles from './index.module.css'; type SearchModalProps = { client: OramaCloud | null; + onWarmup?: () => Promise | void; placeholder: string; } & ComponentProps; const SearchModal: FC> = ({ children, client, + onWarmup, placeholder, -}) => ( -
- - -
- - {placeholder} -
- - ⌘ K -
- - - - - - - - {children} - - - - -
-
-); +}) => { + const warmup = useCallback(() => { + onWarmup?.(); + }, [onWarmup]); + + useEffect(() => { + if (!onWarmup) { + return; + } + + const handleGlobalKeyDown = (event: KeyboardEvent) => { + if ((event.metaKey || event.ctrlKey) && event.key === 'k') { + warmup(); + } + }; + + document.addEventListener('keydown', handleGlobalKeyDown); + + return () => document.removeEventListener('keydown', handleGlobalKeyDown); + }, [onWarmup, warmup]); + + return ( +
+ + +
+ + {placeholder} +
+ + ⌘ K +
+ + + + + + + + {children} + + + + +
+
+ ); +}; export default SearchModal; From a6a6c2c0e76231d4b36612c156acb31a3b5dac6f Mon Sep 17 00:00:00 2001 From: Elure Date: Mon, 18 May 2026 14:53:47 +0300 Subject: [PATCH 4/8] Update index.tsx Signed-off-by: Elure --- packages/ui-components/src/Common/Search/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/ui-components/src/Common/Search/index.tsx b/packages/ui-components/src/Common/Search/index.tsx index 9b33f1a2b9b37..9b780e614636a 100644 --- a/packages/ui-components/src/Common/Search/index.tsx +++ b/packages/ui-components/src/Common/Search/index.tsx @@ -17,6 +17,7 @@ type SearchBoxProps = { closeShortcutLabel?: string; navigateShortcutLabel?: string; noResultsTitle?: string; + onWarmup?: () => Promise | void; placeholder?: string; selectShortcutLabel?: string; }; @@ -27,9 +28,10 @@ const SearchBox: React.FC = ({ noResultsTitle = 'No results found for', closeShortcutLabel = 'to close', navigateShortcutLabel = 'to navigate', + onWarmup, selectShortcutLabel = 'to select', }) => ( - +
Date: Mon, 18 May 2026 14:54:39 +0300 Subject: [PATCH 5/8] Create __tests__ Signed-off-by: Elure --- apps/site/components/__tests__ | 67 ++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 apps/site/components/__tests__ diff --git a/apps/site/components/__tests__ b/apps/site/components/__tests__ new file mode 100644 index 0000000000000..ad2109c30be00 --- /dev/null +++ b/apps/site/components/__tests__ @@ -0,0 +1,67 @@ +import assert from 'node:assert/strict'; +import { describe, it, mock } from 'node:test'; + +const fakeDb = {}; +const createMock = mock.fn(() => fakeDb); +const insertMultipleMock = mock.fn(async () => {}); +const searchMock = mock.fn(async (_db, options) => ({ options })); + +mock.module('@orama/orama', { + namedExports: { + create: createMock, + insertMultiple: insertMultipleMock, + search: searchMock, + }, +}); + +const { addPrefixToDocs, createOramaClient } = await import( + '#site/components/withSearch' +); + +describe('withSearch', () => { + it('adds the locale prefix to indexed document URLs', () => { + const db = { + docs: { + docs: { + one: { href: '/docs', title: 'Docs' }, + }, + }, + }; + + assert.deepEqual(addPrefixToDocs(db, '/en'), { + docs: { + docs: { + one: { href: '/en/docs', title: 'Docs' }, + }, + }, + }); + }); + + it('warms the Orama indexes only once before searching', async () => { + createMock.mock.resetCalls(); + insertMultipleMock.mock.resetCalls(); + searchMock.mock.resetCalls(); + + global.fetch = mock.fn(async url => ({ + json: async () => ({ + docs: { + docs: { + [String(url)]: { href: '/result', title: 'Node.js' }, + }, + }, + }), + })); + + const { client, warmup } = createOramaClient({ + '/docs': 'https://example.com/docs.json', + '/learn': 'https://example.com/learn.json', + }); + + await Promise.all([warmup(), warmup()]); + await client.search({ term: 'node' }); + + assert.equal(global.fetch.mock.callCount(), 2); + assert.equal(insertMultipleMock.mock.callCount(), 2); + assert.equal(searchMock.mock.callCount(), 1); + }); +}); From 50251f5481f32841152ea0353510e3c7c37aaa61 Mon Sep 17 00:00:00 2001 From: Elure Date: Mon, 18 May 2026 14:56:36 +0300 Subject: [PATCH 6/8] Delete apps/site/components/__tests__ Signed-off-by: Elure --- apps/site/components/__tests__ | 67 ---------------------------------- 1 file changed, 67 deletions(-) delete mode 100644 apps/site/components/__tests__ diff --git a/apps/site/components/__tests__ b/apps/site/components/__tests__ deleted file mode 100644 index ad2109c30be00..0000000000000 --- a/apps/site/components/__tests__ +++ /dev/null @@ -1,67 +0,0 @@ -import assert from 'node:assert/strict'; -import { describe, it, mock } from 'node:test'; - -const fakeDb = {}; -const createMock = mock.fn(() => fakeDb); -const insertMultipleMock = mock.fn(async () => {}); -const searchMock = mock.fn(async (_db, options) => ({ options })); - -mock.module('@orama/orama', { - namedExports: { - create: createMock, - insertMultiple: insertMultipleMock, - search: searchMock, - }, -}); - -const { addPrefixToDocs, createOramaClient } = await import( - '#site/components/withSearch' -); - -describe('withSearch', () => { - it('adds the locale prefix to indexed document URLs', () => { - const db = { - docs: { - docs: { - one: { href: '/docs', title: 'Docs' }, - }, - }, - }; - - assert.deepEqual(addPrefixToDocs(db, '/en'), { - docs: { - docs: { - one: { href: '/en/docs', title: 'Docs' }, - }, - }, - }); - }); - - it('warms the Orama indexes only once before searching', async () => { - createMock.mock.resetCalls(); - insertMultipleMock.mock.resetCalls(); - searchMock.mock.resetCalls(); - - global.fetch = mock.fn(async url => ({ - json: async () => ({ - docs: { - docs: { - [String(url)]: { href: '/result', title: 'Node.js' }, - }, - }, - }), - })); - - const { client, warmup } = createOramaClient({ - '/docs': 'https://example.com/docs.json', - '/learn': 'https://example.com/learn.json', - }); - - await Promise.all([warmup(), warmup()]); - await client.search({ term: 'node' }); - - assert.equal(global.fetch.mock.callCount(), 2); - assert.equal(insertMultipleMock.mock.callCount(), 2); - assert.equal(searchMock.mock.callCount(), 1); - }); -}); From 03dd0be146ea46dfba6a7cffd5603816036071b0 Mon Sep 17 00:00:00 2001 From: Elure Date: Mon, 18 May 2026 14:57:00 +0300 Subject: [PATCH 7/8] Create withSearch.test.jsx Signed-off-by: Elure --- .../components/__tests__/withSearch.test.jsx | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 apps/site/components/__tests__/withSearch.test.jsx diff --git a/apps/site/components/__tests__/withSearch.test.jsx b/apps/site/components/__tests__/withSearch.test.jsx new file mode 100644 index 0000000000000..ad2109c30be00 --- /dev/null +++ b/apps/site/components/__tests__/withSearch.test.jsx @@ -0,0 +1,67 @@ +import assert from 'node:assert/strict'; +import { describe, it, mock } from 'node:test'; + +const fakeDb = {}; +const createMock = mock.fn(() => fakeDb); +const insertMultipleMock = mock.fn(async () => {}); +const searchMock = mock.fn(async (_db, options) => ({ options })); + +mock.module('@orama/orama', { + namedExports: { + create: createMock, + insertMultiple: insertMultipleMock, + search: searchMock, + }, +}); + +const { addPrefixToDocs, createOramaClient } = await import( + '#site/components/withSearch' +); + +describe('withSearch', () => { + it('adds the locale prefix to indexed document URLs', () => { + const db = { + docs: { + docs: { + one: { href: '/docs', title: 'Docs' }, + }, + }, + }; + + assert.deepEqual(addPrefixToDocs(db, '/en'), { + docs: { + docs: { + one: { href: '/en/docs', title: 'Docs' }, + }, + }, + }); + }); + + it('warms the Orama indexes only once before searching', async () => { + createMock.mock.resetCalls(); + insertMultipleMock.mock.resetCalls(); + searchMock.mock.resetCalls(); + + global.fetch = mock.fn(async url => ({ + json: async () => ({ + docs: { + docs: { + [String(url)]: { href: '/result', title: 'Node.js' }, + }, + }, + }), + })); + + const { client, warmup } = createOramaClient({ + '/docs': 'https://example.com/docs.json', + '/learn': 'https://example.com/learn.json', + }); + + await Promise.all([warmup(), warmup()]); + await client.search({ term: 'node' }); + + assert.equal(global.fetch.mock.callCount(), 2); + assert.equal(insertMultipleMock.mock.callCount(), 2); + assert.equal(searchMock.mock.callCount(), 1); + }); +}); From c2080fa42f27c74fe8a5fe0d1e9e259825bac68a Mon Sep 17 00:00:00 2001 From: Elure Date: Mon, 18 May 2026 15:22:03 +0300 Subject: [PATCH 8/8] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Elure --- .../ui-components/src/Common/Search/Modal/index.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/ui-components/src/Common/Search/Modal/index.tsx b/packages/ui-components/src/Common/Search/Modal/index.tsx index 5692932a429a7..edc5e8a14a7ce 100644 --- a/packages/ui-components/src/Common/Search/Modal/index.tsx +++ b/packages/ui-components/src/Common/Search/Modal/index.tsx @@ -22,7 +22,18 @@ const SearchModal: FC> = ({ placeholder, }) => { const warmup = useCallback(() => { - onWarmup?.(); + if (!onWarmup) { + return; + } + + try { + const result = onWarmup(); + Promise.resolve(result).catch((error) => { + console.error('Search warmup failed', error); + }); + } catch (error) { + console.error('Search warmup failed', error); + } }, [onWarmup]); useEffect(() => {