Skip to content

Commit

Permalink
refactor: fix type errors & tidy up
Browse files Browse the repository at this point in the history
  • Loading branch information
ghostdevv committed May 20, 2023
1 parent 1d2600e commit b5344e3
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 48 deletions.
48 changes: 25 additions & 23 deletions src/commands/docs/_docs_cache.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
import flexsearch from 'flexsearch';
import fetch from 'node-fetch';
import { Repos, RepositoryDetails } from '../../utils/repositories.js';
import flexsearch, { type Index } from 'flexsearch';
import fetch from 'node-fetch';

const cache = new Map<
Repos,
{
indexes: flexsearch.Index[];
lookup: Map<Block['href'], string>;
}
>();
interface CacheEntry {
indexes: Index[];
lookup: Map<Block['href'], string>;
}

const cache = new Map<Repos, CacheEntry>();

export async function build_cache(repo: Repos) {
let blocks: Block[];

if (repo === Repos.SVELTE) {
const response = await fetch('https://api.svelte.dev/docs/svelte/docs');
blocks = transform_svelte_docs(
(await response.json()) as DocsSection[],
);
const data = (await response.json()) as DocsSection[];

blocks = transform_svelte_docs(data);
} else {
const response = await fetch('https://kit.svelte.dev/content.json');
blocks = ((await response.json()) as { blocks: Block[] }).blocks;
({ blocks } = (await response.json()) as { blocks: Block[] });
}

// Build the index using the same settings as the site
// Adapted from: https://github.com/sveltejs/kit/blob/2ddece81543459f5b2770fafda79e4ac91c9cbbe/sites/kit.svelte.dev/src/lib/search/SearchBox.svelte#L16
const indexes: flexsearch.Index[] = [];
const indexes: Index[] = [];
const lookup = new Map<Block['href'], string>();

for (const block of blocks) {
Expand All @@ -37,8 +36,13 @@ export async function build_cache(repo: Repos) {
})).add(block.href, `${title} ${block.content}`);
}

const cache_entry = { indexes, lookup };
const cache_entry: CacheEntry = {
indexes,
lookup,
};

cache.set(repo, cache_entry);

return cache_entry;
}

Expand All @@ -49,20 +53,19 @@ export async function search_docs(
) {
const { indexes, lookup } = cache.get(repo) ?? (await build_cache(repo));

return (
await Promise.all(
indexes.map((index) => index.searchAsync(query, { limit })),
)
)
const raw_results = await Promise.all(
indexes.map((index) => index.searchAsync(query, { limit })),
);

return raw_results
.flat()
.slice(0, limit)
.map((href) => {
// SAFETY: This link is guaranteed to exist since we built the lookup and index together
const link_text = lookup.get(href.toString())!;

return as_link
? // prettier-ignore
`[${link_text}](${RepositoryDetails[repo].HOMEPAGE}${href})`
? `[${link_text}](${RepositoryDetails[repo].HOMEPAGE}${href})`
: link_text;
});
}
Expand All @@ -82,7 +85,6 @@ type Block = {

/**
* Transform the results of the Svelte docs API into a compatible format
*
* @todo This is a temporary solution until the API is fixed
*/
function transform_svelte_docs(
Expand Down
25 changes: 18 additions & 7 deletions src/commands/docs/_tutorials_cache.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import flexsearch, { type Index } from 'flexsearch';
import fetch from 'node-fetch';
import flexsearch from 'flexsearch';

let cache: {
index: flexsearch.Index;
lookup: Map<Tutorial['slug'], Tutorial['name']>;
};
type CacheLookup = Map<Tutorial['slug'], Tutorial['name']>;

interface Cache {
index: Index;
lookup: CacheLookup;
}

interface Tutorial {
name: string;
Expand All @@ -16,6 +18,8 @@ interface TutorialSection {
tutorials: Tutorial[];
}

let cache: Cache;

export async function build_cache() {
const res = await fetch('https://api.svelte.dev/docs/svelte/tutorial');
if (!res.ok) throw new Error("Couldn't fetch tutorials.");
Expand All @@ -24,7 +28,8 @@ export async function build_cache() {
const index = new flexsearch.Index({
tokenize: 'forward',
});
const lookup: typeof cache['lookup'] = new Map();

const lookup: CacheLookup = new Map();

for (const section of data) {
for (const tutorial of section.tutorials) {
Expand All @@ -34,7 +39,12 @@ export async function build_cache() {
}
}

return (cache = { index, lookup });
cache = {
index,
lookup,
};

return cache;
}

export async function search_tutorials(
Expand All @@ -49,6 +59,7 @@ export async function search_tutorials(

return results.map((slug) => {
const title = lookup.get(slug.toString())!;

return as_link
? `[${title}](https://svelte.dev/tutorial/${slug})`
: title;
Expand Down
25 changes: 9 additions & 16 deletions src/commands/docs/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ import { no_op } from '../../utils/promise.js';
import { Repos, RepositoryDetails } from '../../utils/repositories.js';
import { search_docs } from './_docs_cache.js';

const sc_map = {
svelte: Repos.SVELTE,
sveltekit: Repos.SVELTE_KIT,
};
function get_repo(subcommand: string) {
return subcommand == 'svelte' ? Repos.SVELTE : Repos.SVELTE_KIT;
}

export default command({
name: 'docs',
Expand Down Expand Up @@ -48,12 +47,7 @@ export default command({
],

run: async ({ interaction }) => {
const repo =
sc_map[
interaction.options.getSubcommand(true) as
| 'svelte'
| 'sveltekit'
];
const repo = get_repo(interaction.options.getSubcommand(true));

const repo_details = RepositoryDetails[repo];
const query = interaction.options.getString('query');
Expand All @@ -67,6 +61,7 @@ export default command({
);
return;
}

const results = await search_docs(query, repo);

if (!results.length) {
Expand All @@ -90,23 +85,21 @@ export default command({
});
}
},

autocomplete: async ({ interaction }) => {
const focused = interaction.options.getFocused(true);
if (focused.name !== 'query') return;

const query = focused.value as string;
if (!query) return await interaction.respond([]);
const repo =
sc_map[
interaction.options.getSubcommand(true) as
| 'svelte'
| 'sveltekit'
];

const repo = get_repo(interaction.options.getSubcommand(true));

const results = await search_docs(query, repo, {
limit: 10,
as_link: false,
});

await interaction
.respond(results.map(into_name_value_pair))
.catch(no_op);
Expand Down
6 changes: 5 additions & 1 deletion src/commands/docs/rebuild_cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,24 @@ import { build_cache as build_tutorials_cache } from './_tutorials_cache';
export default command({
name: 'rebuildcache',
description: 'Rebuild the docs and tutorial cache',

defer: {
ephemeral: true,
},

global: true,

run: async ({ interaction }) => {
const member = await get_member(interaction);

if (member && has_any_role_or_id(member, BOT_DEVS))
if (member && has_any_role_or_id(member, BOT_DEVS)) {
await Promise.all([
build_docs_cache(Repos.SVELTE),
build_docs_cache(Repos.SVELTE_KIT),
build_tutorials_cache(),
])
.catch((e) => interaction.followUp(e))
.then(() => interaction.followUp('Success'));
}
},
});
7 changes: 6 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@
"noImplicitAny": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"allowJs": true,
"skipLibCheck": true
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"flexsearch": ["node_modules/@types/flexsearch"]
}
},
"include": ["src/**/*"],
"exclude": ["dist"]
Expand Down

0 comments on commit b5344e3

Please sign in to comment.