Skip to content

Commit 67a346f

Browse files
committed
fixup!
1 parent 073cd74 commit 67a346f

6 files changed

Lines changed: 80 additions & 138 deletions

File tree

apps/site/components/withSearch.tsx

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,30 @@
11
'use client';
22

33
import SearchBox from '@node-core/ui-components/Common/Search';
4-
import useOrama from '@node-core/ui-components/hooks/useOrama';
5-
import { create, insertMultiple, save } from '@orama/orama';
4+
import { create, insertMultiple, search } from '@orama/orama';
65
import { useTranslations } from 'next-intl';
6+
import { useMemo, useRef } from 'react';
77

88
import { ORAMA_DB_URLS } from '#site/next.constants.mjs';
99

10+
import type { OramaCloud } from '@orama/core';
11+
import type { AnyOrama } from '@orama/orama';
1012
import type { FC } from 'react';
1113

12-
/**
13-
* Shape of a single Orama document entry.
14-
* `href` is required (we prefix it); other fields are passthrough.
15-
*/
1614
type OramaDoc = { href: string } & Record<string, unknown>;
1715

18-
/**
19-
* Shape of a serialized Orama database snapshot (from `save()` on the server
20-
* side, fetched as JSON on the client). We only type the parts we touch.
21-
*/
2216
type SerializedOramaDb = {
2317
docs: {
2418
docs: Record<string, OramaDoc>;
2519
};
2620
};
2721

28-
/**
29-
* Each locale/section of the site ships its own prebuilt Orama index, but the
30-
* hrefs inside those indexes are relative to that section's root. When we
31-
* merge multiple indexes into a single client-side DB, we need to re-scope
32-
* those hrefs so clicks route to the correct top-level path.
33-
*/
3422
export const addPrefixToDocs = <T extends SerializedOramaDb>(
3523
db: T,
3624
prefix: string
3725
): T => {
3826
const prefixedDocs: Record<string, OramaDoc> = {};
3927

40-
// Object.entries + Object.fromEntries would also work, but a single pass
41-
// with a plain loop avoids the intermediate array allocations
4228
for (const [id, doc] of Object.entries(db.docs.docs)) {
4329
prefixedDocs[id] = { ...doc, href: `${prefix}${doc.href}` };
4430
}
@@ -49,35 +35,47 @@ export const addPrefixToDocs = <T extends SerializedOramaDb>(
4935
};
5036
};
5137

52-
const loadOrama = async () => {
53-
const db = create({
54-
schema: {
55-
title: 'string',
56-
description: 'string',
57-
href: 'string',
58-
siteSection: 'string',
59-
},
60-
});
61-
38+
const loadOrama = async (db: AnyOrama): Promise<void> => {
6239
const indexes = await Promise.all(
6340
Object.entries(ORAMA_DB_URLS).map(async ([key, url]) => {
6441
const response = await fetch(url);
6542
const fetchedDb = (await response.json()) as SerializedOramaDb;
43+
6644
return addPrefixToDocs(fetchedDb, `/${key}`);
6745
})
6846
);
6947

7048
for (const index of indexes) {
7149
await insertMultiple(db, Object.values(index.docs.docs) as Array<never>);
7250
}
51+
};
7352

74-
return save(db);
53+
export const useOrama = () => {
54+
const loadPromiseRef = useRef<Promise<void> | null>(null);
55+
56+
return useMemo(() => {
57+
const db = create({
58+
schema: {
59+
title: 'string',
60+
description: 'string',
61+
href: 'string',
62+
siteSection: 'string',
63+
},
64+
});
65+
66+
// @ts-expect-error We are overriding a method, an error is expected.
67+
db.search = async options => {
68+
await (loadPromiseRef.current ??= loadOrama(db));
69+
return search(db, options);
70+
};
71+
72+
return db;
73+
}, []) as unknown as OramaCloud;
7574
};
7675

7776
const WithSearch: FC = () => {
7877
const t = useTranslations();
79-
80-
const client = useOrama(loadOrama);
78+
const client = useOrama();
8179

8280
return (
8381
<SearchBox

apps/site/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,15 @@
7878
"vfile-matter": "~5.0.1"
7979
},
8080
"devDependencies": {
81+
"@cloudflare/workers-types": "^4.20260418.1",
8182
"@eslint-react/eslint-plugin": "~3.0.0",
8283
"@flarelabs-net/wrangler-build-time-fs-assets-polyfilling": "^0.0.1",
8384
"@next/eslint-plugin-next": "16.2.1",
8485
"@node-core/remark-lint": "workspace:*",
8586
"@opennextjs/cloudflare": "^1.19.3",
87+
"@orama/core": "^1.2.19",
8688
"@playwright/test": "^1.58.2",
89+
"@sentry/cloudflare": "^10.49.0",
8790
"@testing-library/user-event": "~14.6.1",
8891
"@types/mdast": "^4.0.4",
8992
"@types/mdx": "^2.0.13",
@@ -105,9 +108,7 @@
105108
"typescript": "catalog:",
106109
"typescript-eslint": "~8.57.2",
107110
"user-agent-data-types": "0.4.2",
108-
"wrangler": "^4.77.0",
109-
"@cloudflare/workers-types": "^4.20260418.1",
110-
"@sentry/cloudflare": "^10.49.0"
111+
"wrangler": "^4.77.0"
111112
},
112113
"imports": {
113114
"#site/*": [

packages/ui-components/src/Common/Search/Modal/index.tsx

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { MagnifyingGlassIcon } from '@heroicons/react/24/solid';
2-
import { SearchRoot, ChatRoot, Modal } from '@orama/ui/components';
2+
import { SearchRoot, Modal } from '@orama/ui/components';
33

44
import SearchInput from '#ui/Common/Search/Input';
55

@@ -40,18 +40,13 @@ const SearchModal: FC<PropsWithChildren<SearchModalProps>> = ({
4040
className={styles.modalWrapper}
4141
>
4242
<SearchRoot client={client}>
43-
<ChatRoot client={client} askOptions={{ throttle_delay: 50 }}>
44-
<Modal.Inner className={styles.modalInner}>
45-
<Modal.Content className={styles.modalContent}>
46-
<SearchInput
47-
placeholder={placeholder}
48-
ariaLabel={placeholder}
49-
/>
50-
<Modal.Close className={styles.modalCloseButton} />
51-
{children}
52-
</Modal.Content>
53-
</Modal.Inner>
54-
</ChatRoot>
43+
<Modal.Inner className={styles.modalInner}>
44+
<Modal.Content className={styles.modalContent}>
45+
<SearchInput placeholder={placeholder} ariaLabel={placeholder} />
46+
<Modal.Close className={styles.modalCloseButton} />
47+
{children}
48+
</Modal.Content>
49+
</Modal.Inner>
5550
</SearchRoot>
5651
</Modal.Wrapper>
5752
</Modal.Root>

packages/ui-components/src/Common/Search/index.tsx

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,46 +28,42 @@ const SearchBox: React.FC<SearchBoxProps> = ({
2828
closeShortcutLabel = 'to close',
2929
navigateShortcutLabel = 'to navigate',
3030
selectShortcutLabel = 'to select',
31-
}) => {
32-
return (
33-
<SearchModal client={client} placeholder={placeholder}>
34-
<div className={styles.searchResultsContainer}>
35-
<SearchResults
36-
noResultsTitle={noResultsTitle}
37-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
38-
onHit={hit => <SearchHit document={hit.document as any} />}
39-
/>
40-
</div>
31+
}) => (
32+
<SearchModal client={client} placeholder={placeholder}>
33+
<div className={styles.searchResultsContainer}>
34+
<SearchResults
35+
noResultsTitle={noResultsTitle}
36+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
37+
onHit={hit => <SearchHit document={hit.document as any} />}
38+
/>
39+
</div>
4140

42-
<div className={styles.footer}>
43-
<div className={styles.shortcutWrapper}>
44-
<div className={styles.shortcutItem}>
45-
<kbd className={styles.shortcutKey}>
46-
<ArrowTurnDownLeftIcon />
47-
</kbd>
48-
<span className={styles.shortcutLabel}>{selectShortcutLabel}</span>
49-
</div>
41+
<div className={styles.footer}>
42+
<div className={styles.shortcutWrapper}>
43+
<div className={styles.shortcutItem}>
44+
<kbd className={styles.shortcutKey}>
45+
<ArrowTurnDownLeftIcon />
46+
</kbd>
47+
<span className={styles.shortcutLabel}>{selectShortcutLabel}</span>
48+
</div>
5049

51-
<div className={styles.shortcutItem}>
52-
<kbd className={styles.shortcutKey}>
53-
<ArrowDownIcon />
54-
</kbd>
55-
<kbd className={styles.shortcutKey}>
56-
<ArrowUpIcon />
57-
</kbd>
58-
<span className={styles.shortcutLabel}>
59-
{navigateShortcutLabel}
60-
</span>
61-
</div>
50+
<div className={styles.shortcutItem}>
51+
<kbd className={styles.shortcutKey}>
52+
<ArrowDownIcon />
53+
</kbd>
54+
<kbd className={styles.shortcutKey}>
55+
<ArrowUpIcon />
56+
</kbd>
57+
<span className={styles.shortcutLabel}>{navigateShortcutLabel}</span>
58+
</div>
6259

63-
<div className={styles.shortcutItem}>
64-
<kbd className={styles.shortcutKey}>esc</kbd>
65-
<span className={styles.shortcutLabel}>{closeShortcutLabel}</span>
66-
</div>
60+
<div className={styles.shortcutItem}>
61+
<kbd className={styles.shortcutKey}>esc</kbd>
62+
<span className={styles.shortcutLabel}>{closeShortcutLabel}</span>
6763
</div>
6864
</div>
69-
</SearchModal>
70-
);
71-
};
65+
</div>
66+
</SearchModal>
67+
);
7268

7369
export default SearchBox;

packages/ui-components/src/hooks/useOrama.ts

Lines changed: 0 additions & 48 deletions
This file was deleted.

pnpm-lock.yaml

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)