Skip to content

Commit

Permalink
Switch to index segments (#130)
Browse files Browse the repository at this point in the history
* Upgrade @fern-fern/registry-browser

* Add ALGOLIA_SEARCH_INDEX to env vars

* Implement getEnvConfig()

* Implement new useSearchService()

* Include version info in SearchDialog input placeholder

* Try to retrieve index from docs def if not present on search info

* Update mock docs definition

* Add docsDefinition.algoliaSearchIndex to useMemo deps

* Handle the case where search info is not sent

* Remove version from navigateToPath slug argument in SearchHit

* Move validation of `algoliaSearchIndex` env var to useSearchService

* Upgrade @fern-fern/registry-browser

* Update SearchHit onClick handler to use search hit version slug
  • Loading branch information
kafkas authored Sep 19, 2023
1 parent 777bc05 commit c980669
Show file tree
Hide file tree
Showing 14 changed files with 136 additions and 41 deletions.
12 changes: 6 additions & 6 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
2 changes: 1 addition & 1 deletion packages/commons/app-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"depcheck": "depcheck"
},
"dependencies": {
"@fern-fern/registry-browser": "0.17.0-8-g5dfc5af",
"@fern-fern/registry-browser": "0.19.1-10-gf615da5",
"@fern-ui/core-utils": "workspace:*",
"lodash-es": "^4.17.21",
"next-mdx-remote": "^4.4.1",
Expand Down
10 changes: 10 additions & 0 deletions packages/commons/app-utils/src/url-path-resolver/__test__/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,14 @@ export const MOCKS_DOCS_DEFINITION: FernRegistryDocsRead.DocsDefinition = {
],
},
},
search: {
type: "singleAlgoliaIndex",
value: {
type: "unversioned",
indexSegment: {
id: FernRegistryDocsRead.IndexSegmentId("seg_1"),
searchApiKey: "",
},
},
},
};
2 changes: 1 addition & 1 deletion packages/ui/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@blueprintjs/icons": "^4.4.0",
"@blueprintjs/popover2": "^1.8.0",
"@blueprintjs/select": "^4.4.2",
"@fern-fern/registry-browser": "0.17.0-8-g5dfc5af",
"@fern-fern/registry-browser": "0.19.1-10-gf615da5",
"@fern-ui/app-utils": "workspace:*",
"@fern-ui/core-utils": "workspace:*",
"@fern-ui/react-commons": "workspace:*",
Expand Down
10 changes: 8 additions & 2 deletions packages/ui/app/src/docs/Docs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Header } from "./Header";

export const Docs: React.FC = memo(function UnmemoizedDocs() {
const docsContext = useDocsContext();
const { docsDefinition, theme } = docsContext;
const { docsDefinition, docsInfo, theme } = docsContext;
const searchContext = useSearchContext();
const { isSearchDialogOpen, openSearchDialog, closeSearchDialog } = searchContext;
const searchService = useSearchService();
Expand Down Expand Up @@ -43,7 +43,13 @@ export const Docs: React.FC = memo(function UnmemoizedDocs() {
hasSpecifiedBackgroundImage={hasSpecifiedBackgroundImage}
/>
<div className="relative flex min-h-0 flex-1 flex-col">
{searchService.isAvailable && <SearchDialog isOpen={isSearchDialogOpen} onClose={closeSearchDialog} />}
{searchService.isAvailable && (
<SearchDialog
isOpen={isSearchDialogOpen}
onClose={closeSearchDialog}
activeVersion={docsInfo.type === "versioned" ? docsInfo.activeVersionName : undefined}
/>
)}
<div className="border-border-default-light dark:border-border-default-dark bg-background/50 sticky inset-x-0 top-0 z-20 h-16 border-b backdrop-blur-xl">
<Header
className="max-w-8xl mx-auto"
Expand Down
25 changes: 25 additions & 0 deletions packages/ui/app/src/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
type EnvironmentConfig = {
algoliaAppId: string;
/**
* This is used by the legacy search system.
*/
algoliaApiKey: string;

algoliaSearchIndex?: string;
};

export function getEnvConfig(): EnvironmentConfig {
if (process.env.NEXT_PUBLIC_ALGOLIA_APP_ID == null) {
throw new Error('Missing environment variable "NEXT_PUBLIC_ALGOLIA_APP_ID"');
}

if (process.env.NEXT_PUBLIC_ALGOLIA_API_KEY == null) {
throw new Error('Missing environment variable "NEXT_PUBLIC_ALGOLIA_API_KEY"');
}

return {
algoliaAppId: process.env.NEXT_PUBLIC_ALGOLIA_APP_ID,
algoliaApiKey: process.env.NEXT_PUBLIC_ALGOLIA_API_KEY,
algoliaSearchIndex: process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_INDEX,
};
}
9 changes: 7 additions & 2 deletions packages/ui/app/src/search/SearchDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ export declare namespace SearchDialog {
export interface Props {
isOpen: boolean;
onClose: () => void;
activeVersion?: string;
}
}

export const SearchDialog: React.FC<SearchDialog.Props> = (providedProps) => {
const { isOpen, onClose } = providedProps;
const { isOpen, onClose, activeVersion } = providedProps;
const searchService = useSearchService();

if (!searchService.isAvailable) {
Expand All @@ -32,7 +33,11 @@ export const SearchDialog: React.FC<SearchDialog.Props> = (providedProps) => {
<SearchBox
inputMode="text"
autoFocus
placeholder="Find something..."
placeholder={
activeVersion != null
? `Search across version ${activeVersion}`
: "Find something..."
}
classNames={{
root: "w-full",
loadingIcon: "hidden",
Expand Down
16 changes: 11 additions & 5 deletions packages/ui/app/src/search/SearchHit.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Icon } from "@blueprintjs/core";
import { visitDiscriminatedUnion } from "@fern-ui/core-utils";
import Link from "next/link";
import { useCallback } from "react";
import { Snippet } from "react-instantsearch-hooks-web";
import { useDocsContext } from "../docs-context/useDocsContext";
import { useSearchContext } from "../search-context/useSearchContext";
Expand All @@ -16,14 +17,19 @@ export const SearchHit: React.FC<SearchHit.Props> = ({ hit }) => {
const { navigateToPath } = useDocsContext();
const { closeSearchDialog } = useSearchContext();

const handleClick = useCallback(() => {
closeSearchDialog();
navigateToPath(hit.path);
}, [closeSearchDialog, navigateToPath, hit.path]);

const { versionSlug, path } = hit;
const href = `/${versionSlug != null ? `${versionSlug}/` : ""}${path}`;

return (
<Link
className="hover:bg-background-secondary-light hover:dark:bg-background-secondary-dark group flex w-full items-center space-x-4 space-y-1 rounded-md px-3 py-2 hover:no-underline"
onClick={() => {
closeSearchDialog();
navigateToPath(hit.path);
}}
href={`/${hit.path}`}
onClick={handleClick}
href={href}
>
<div className="border-border-default-light dark:border-border-default-dark flex flex-col items-center justify-center rounded-md border p-1">
<Icon
Expand Down
70 changes: 55 additions & 15 deletions packages/ui/app/src/services/useSearchService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { FernRegistry } from "@fern-fern/registry-browser";
import algolia, { type SearchClient } from "algoliasearch/lite";
import { useMemo } from "react";
import { useDocsContext } from "../docs-context/useDocsContext";
import { getEnvConfig } from "../env";

export type SearchService =
| {
Expand All @@ -12,24 +14,62 @@ export type SearchService =
isAvailable: false;
};

if (process.env.NEXT_PUBLIC_ALGOLIA_APP_ID == null || process.env.NEXT_PUBLIC_ALGOLIA_API_KEY == null) {
// TODO: Move this validation elsewhere
throw new Error("Missing Algolia variables.");
}

const client = algolia(process.env.NEXT_PUBLIC_ALGOLIA_APP_ID, process.env.NEXT_PUBLIC_ALGOLIA_API_KEY);

export function useSearchService(): SearchService {
const { docsDefinition } = useDocsContext();
const { algoliaSearchIndex } = docsDefinition;
return useMemo(() => {
if (algoliaSearchIndex) {
const { docsDefinition, docsInfo } = useDocsContext();
const { search: searchInfo } = docsDefinition;

return useMemo<SearchService>(() => {
const envConfig = getEnvConfig();
if (typeof searchInfo !== "object") {
return docsDefinition.algoliaSearchIndex != null
? {
isAvailable: true,
client: algolia(envConfig.algoliaAppId, envConfig.algoliaApiKey),
index: docsDefinition.algoliaSearchIndex,
}
: { isAvailable: false };
} else if (searchInfo.type === "legacyMultiAlgoliaIndex") {
const algoliaIndex = searchInfo.algoliaIndex ?? docsDefinition.algoliaSearchIndex;
return algoliaIndex != null
? {
isAvailable: true,
client: algolia(envConfig.algoliaAppId, envConfig.algoliaApiKey),
index: algoliaIndex,
}
: { isAvailable: false };
} else if (searchInfo.value.type === "unversioned") {
if (docsInfo.type !== "unversioned") {
throw new Error("Inconsistent State: Received search info is unversioned but docs are versioned");
}
if (envConfig.algoliaSearchIndex == null) {
throw new Error('Missing environment variable "NEXT_PUBLIC_ALGOLIA_SEARCH_INDEX"');
}
const { indexSegment } = searchInfo.value;
return {
isAvailable: true,
client: algolia(envConfig.algoliaAppId, indexSegment.searchApiKey),
index: envConfig.algoliaSearchIndex,
};
} else {
if (docsInfo.type !== "versioned") {
throw new Error("Inconsistent State: Received search info is versioned but docs are unversioned");
}
const versionId = FernRegistry.docs.v1.read.VersionId(docsInfo.activeVersionName);
const { indexSegmentsByVersionId } = searchInfo.value;
const indexSegment = indexSegmentsByVersionId[versionId];
if (indexSegment == null) {
throw new Error(
`Inconsistent State: Did not receive index segment for version "${versionId}". This may indicate a backend bug.`
);
}
if (envConfig.algoliaSearchIndex == null) {
throw new Error('Missing environment variable "NEXT_PUBLIC_ALGOLIA_SEARCH_INDEX"');
}
return {
isAvailable: true,
index: algoliaSearchIndex,
client,
client: algolia(envConfig.algoliaAppId, indexSegment.searchApiKey),
index: envConfig.algoliaSearchIndex,
};
}
return { isAvailable: false };
}, [algoliaSearchIndex]);
}, [docsDefinition.algoliaSearchIndex, docsInfo, searchInfo]);
}
2 changes: 2 additions & 0 deletions packages/ui/fe-bundle/.env-cmdrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ module.exports = {
NEXT_PUBLIC_POSTHOG_API_KEY: "",
NEXT_PUBLIC_ALGOLIA_APP_ID: "CQINPZSKS3",
NEXT_PUBLIC_ALGOLIA_API_KEY: "9515d5b15764da73b5cfad85772779fa",
NEXT_PUBLIC_ALGOLIA_SEARCH_INDEX: "search_index_dev",
},
"fern-prod": {
NEXT_PUBLIC_FDR_ORIGIN: "https://registry.buildwithfern.com",
NEXT_PUBLIC_POSTHOG_API_KEY: "phc_yQgAEdJJkVpI24NdSRID2mor1x1leRpDoC9yZ9mfXal",
NEXT_PUBLIC_ALGOLIA_APP_ID: process.env.ALGOLIA_APP_ID,
NEXT_PUBLIC_ALGOLIA_API_KEY: process.env.ALGOLIA_API_KEY,
NEXT_PUBLIC_ALGOLIA_SEARCH_INDEX: process.env.ALGOLIA_SEARCH_INDEX,
},
};
3 changes: 2 additions & 1 deletion packages/ui/fe-bundle/.mrlint.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"NEXT_PUBLIC_FDR_ORIGIN",
"NEXT_PUBLIC_POSTHOG_API_KEY",
"NEXT_PUBLIC_ALGOLIA_APP_ID",
"NEXT_PUBLIC_ALGOLIA_API_KEY"
"NEXT_PUBLIC_ALGOLIA_API_KEY",
"NEXT_PUBLIC_ALGOLIA_SEARCH_INDEX"
]
},
"rules": {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/fe-bundle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"lint:fern-prod": "yarn compile && yarn env:fern-prod next lint"
},
"dependencies": {
"@fern-fern/registry-browser": "0.17.0-8-g5dfc5af",
"@fern-fern/registry-browser": "0.19.1-10-gf615da5",
"@fern-ui/app-utils": "workspace:*",
"@fern-ui/core-utils": "workspace:*",
"@fern-ui/theme": "workspace:*",
Expand Down
14 changes: 7 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1851,24 +1851,24 @@ __metadata:
languageName: node
linkType: hard

"@fern-fern/registry-browser@npm:0.17.0-8-g5dfc5af":
version: 0.17.0-8-g5dfc5af
resolution: "@fern-fern/registry-browser@npm:0.17.0-8-g5dfc5af"
"@fern-fern/registry-browser@npm:0.19.1-10-gf615da5":
version: 0.19.1-10-gf615da5
resolution: "@fern-fern/registry-browser@npm:0.19.1-10-gf615da5"
dependencies:
"@types/url-join": 4.0.1
"@ungap/url-search-params": 0.2.2
axios: 1.4.0
js-base64: 3.7.2
url-join: 4.0.1
checksum: ad2f8a60dda2dd8936f59f0b8388ac65b8e0d9b12fb3d9fe9d4aca5285899432617a2bfd6e522bb73066051850e99fccba3c80cbdf9aecddf861588fc1182d78
checksum: 26d1077db21daa51e5e1a9c56a4dd140f302a90e009aa44d08d547ad0da8fc3f0ff95907f05e972af324695f2f1227246b5340480bd86d57574b1356308620c0
languageName: node
linkType: hard

"@fern-ui/app-utils@workspace:*, @fern-ui/app-utils@workspace:packages/commons/app-utils":
version: 0.0.0-use.local
resolution: "@fern-ui/app-utils@workspace:packages/commons/app-utils"
dependencies:
"@fern-fern/registry-browser": 0.17.0-8-g5dfc5af
"@fern-fern/registry-browser": 0.19.1-10-gf615da5
"@fern-ui/core-utils": "workspace:*"
"@types/jest": ^29.0.3
"@types/lodash-es": 4.17.9
Expand Down Expand Up @@ -1961,7 +1961,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@fern-ui/fe-bundle@workspace:packages/ui/fe-bundle"
dependencies:
"@fern-fern/registry-browser": 0.17.0-8-g5dfc5af
"@fern-fern/registry-browser": 0.19.1-10-gf615da5
"@fern-ui/app-utils": "workspace:*"
"@fern-ui/core-utils": "workspace:*"
"@fern-ui/theme": "workspace:*"
Expand Down Expand Up @@ -2200,7 +2200,7 @@ __metadata:
"@blueprintjs/icons": ^4.4.0
"@blueprintjs/popover2": ^1.8.0
"@blueprintjs/select": ^4.4.2
"@fern-fern/registry-browser": 0.17.0-8-g5dfc5af
"@fern-fern/registry-browser": 0.19.1-10-gf615da5
"@fern-ui/app-utils": "workspace:*"
"@fern-ui/core-utils": "workspace:*"
"@fern-ui/react-commons": "workspace:*"
Expand Down

1 comment on commit c980669

@vercel
Copy link

@vercel vercel bot commented on c980669 Sep 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

fern-dev – ./packages/ui/fe-bundle

app-dev.buildwithfern.com
fern-dev-buildwithfern.vercel.app
devtest.buildwithfern.com
fern-dev-git-main-buildwithfern.vercel.app

Please sign in to comment.