@graphcommerce/docs 3.1.4 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/{content/framework → framework}/deployment.md +10 -6
  3. package/{content/framework → framework}/environment-variables.md +0 -0
  4. package/{content/framework → framework}/favicon.md +3 -1
  5. package/{content/framework → framework}/graphcms.md +10 -4
  6. package/{content/framework → framework}/icons.md +0 -0
  7. package/{content/framework → framework}/readme.md +0 -0
  8. package/{content/framework → framework}/seo.md +0 -0
  9. package/{content/framework → framework}/static-file-serving.md +0 -0
  10. package/{content/framework → framework}/static-generation.md +0 -0
  11. package/{content/framework → framework}/theming.md +1 -1
  12. package/{content/framework → framework}/translations.md +3 -1
  13. package/{content/framework → framework}/troubleshooting.md +0 -0
  14. package/{content/framework → framework}/typography.md +0 -0
  15. package/{content/getting-started → getting-started}/create.md +7 -3
  16. package/{content/getting-started → getting-started}/graphcms-component.md +30 -10
  17. package/{content/getting-started → getting-started}/header.md +17 -7
  18. package/{content/getting-started → getting-started}/pages.md +12 -4
  19. package/{content/getting-started → getting-started}/readme.md +3 -2
  20. package/{content/getting-started → getting-started}/start-building.md +2 -2
  21. package/{content/getting-started → getting-started}/vscode.md +0 -0
  22. package/package.json +6 -51
  23. package/{content/readme.md → readme.md} +1 -1
  24. package/{content/roadmap.md → roadmap.md} +0 -0
  25. package/.babelrc +0 -4
  26. package/components/Layout/LayoutFull.tsx +0 -85
  27. package/components/Layout/Logo.tsx +0 -19
  28. package/components/Layout/graphcommerce.svg +0 -34
  29. package/components/Search.tsx +0 -37
  30. package/components/SearchForm.tsx +0 -110
  31. package/components/SidebarMenu/index.tsx +0 -101
  32. package/components/prism.css +0 -274
  33. package/components/rehype-prism-plus.css +0 -49
  34. package/components/theme.ts +0 -410
  35. package/lib/DocumentIndexer.ts +0 -59
  36. package/lib/files.ts +0 -168
  37. package/lib/instantSearch.ts +0 -26
  38. package/lib/typesense/IndexerHandler.ts +0 -47
  39. package/lib/typesense/Leaves.ts +0 -37
  40. package/lib/typesense/SearchIndexer.ts +0 -64
  41. package/lib/typesense/batchInterable.ts +0 -13
  42. package/lib/typesense/createInstantSearchProps.ts +0 -36
  43. package/lib/typesense/typesenseClientConf.ts +0 -23
  44. package/lib/typesense/typesenseIndexerHandler.ts +0 -23
  45. package/next-env.d.ts +0 -5
  46. package/next.config.js +0 -21
  47. package/pages/[[...url]].tsx +0 -391
  48. package/pages/_app.tsx +0 -26
  49. package/pages/_document.tsx +0 -22
  50. package/pages/api/reindex.ts +0 -4
  51. package/pages/menu/[[...url]].tsx +0 -69
  52. package/public/apple-touch-icon.png +0 -0
  53. package/public/favicon.ico +0 -0
  54. package/public/favicon.svg +0 -12
  55. package/public/link.svg +0 -4
  56. package/public/manifest/favicon-192.png +0 -0
  57. package/public/manifest/favicon-512.png +0 -0
  58. package/public/manifest.webmanifest +0 -20
@@ -1,410 +0,0 @@
1
- /// <reference types="@graphcommerce/next-ui/types" />
2
-
3
- import {
4
- responsiveVal,
5
- breakpointVal,
6
- MuiButtonPill,
7
- MuiButtonResponsive,
8
- themeBaseDefaults,
9
- MuiSnackbar,
10
- MuiFabSizes,
11
- } from '@graphcommerce/next-ui'
12
- import { createTheme, Theme, alpha, darken, lighten } from '@mui/material'
13
- import { Components, PaletteOptions } from '@mui/material/styles'
14
-
15
- const main = '#85FFFD'
16
- const dark = '#CEFF99'
17
-
18
- const lightPalette: PaletteOptions = {
19
- mode: 'light',
20
- primary: {
21
- main: darken(main, 0.175),
22
- contrastText: '#FFFFFF',
23
- dark: darken(dark, 0.175),
24
- },
25
- secondary: {
26
- main: '#006BFF',
27
- light: '#D1E4FF',
28
- contrastText: '#ffffff',
29
- },
30
- background: {
31
- default: '#ffffff',
32
- paper: '#ffffff',
33
- image: '#ffffff',
34
- },
35
- divider: '#00000015',
36
- success: {
37
- main: '#01D26A',
38
- },
39
- action: {
40
- hoverOpacity: 0.16,
41
- },
42
- text: {
43
- primary: '#000000',
44
- secondary: 'hsl(229, 16%, 71%)',
45
- disabled: '#00000030',
46
- },
47
- }
48
-
49
- const darkPalette: PaletteOptions = {
50
- mode: 'dark',
51
- primary: {
52
- main,
53
- contrastText: '#ffffff',
54
- dark,
55
- },
56
- secondary: {
57
- main: '#62C7B0',
58
- light: '#62C7B0',
59
- contrastText: '#ffffff',
60
- },
61
- background: {
62
- default: '#001727',
63
- paper: lighten('#001727', 0.03),
64
- image: '#F8F8F8',
65
- },
66
- divider: '#ffffff30',
67
- success: {
68
- main: '#01D26A',
69
- },
70
- action: {
71
- hoverOpacity: 0.16,
72
- },
73
- text: {
74
- primary: '#ffffff',
75
- secondary: '#ffffff80',
76
- disabled: '#ffffff30',
77
- },
78
- }
79
-
80
- const fontSize = (from: number, to: number) =>
81
- breakpointVal('fontSize', from, to, themeBaseDefaults.breakpoints.values)
82
-
83
- // Create a theme instance.
84
- const createThemeWithPalette = (palette: PaletteOptions) =>
85
- createTheme({
86
- palette,
87
- ...themeBaseDefaults,
88
- shape: { borderRadius: 4 },
89
- typography: {
90
- fontFamily:
91
- '-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji',
92
- // @see docs typography.md
93
- h1: {
94
- ...fontSize(36, 44),
95
- fontWeight: 550,
96
- lineHeight: 1.22,
97
- fontVariationSettings: palette.mode === 'dark' ? "'wght' 550" : "'wght' 610",
98
- },
99
- h2: {
100
- ...fontSize(24, 32),
101
- fontWeight: 530,
102
- lineHeight: 1.6,
103
- fontVariationSettings: palette.mode === 'dark' ? "'wght' 480" : "'wght' 590",
104
- },
105
- h3: {
106
- ...fontSize(18, 22),
107
- fontWeight: 500,
108
- lineHeight: 1.55,
109
- fontVariationSettings: palette.mode === 'dark' ? "'wght' 500" : "'wght' 560",
110
- },
111
- h4: {
112
- ...fontSize(18, 23),
113
- fontWeight: 600,
114
- lineHeight: 1.6,
115
- fontVariationSettings: "'wght' 600",
116
- },
117
- h5: {
118
- ...fontSize(18, 21),
119
- fontWeight: 480,
120
- lineHeight: 1.6,
121
- fontVariationSettings: "'wght' 510",
122
- },
123
- h6: {
124
- ...fontSize(16, 19),
125
- fontWeight: 460,
126
- lineHeight: 1.8,
127
- fontVariationSettings: "'wght' 460",
128
- },
129
- subtitle1: {
130
- ...fontSize(16, 19),
131
- fontWeight: 450,
132
- fontVariationSettings: "'wght' 460",
133
- lineHeight: 1.7,
134
- },
135
- fontWeightBold: 600,
136
- body1: {
137
- ...fontSize(15, 18),
138
- fontWeight: 370,
139
- fontVariationSettings: palette.mode === 'dark' ? "'wght' 450" : "'wght' 370",
140
- lineHeight: 1.7,
141
- },
142
- subtitle2: {
143
- ...fontSize(14, 16),
144
- fontWeight: 500,
145
- fontVariationSettings: "'wght' 450",
146
- lineHeight: 1.7,
147
- },
148
- body2: {
149
- ...fontSize(13, 15),
150
- lineHeight: 1.7,
151
- },
152
- caption: {
153
- // https://web.dev/font-size/#how-the-lighthouse-font-size-audit-fails
154
- ...fontSize(12, 13),
155
- },
156
- button: {},
157
- overline: {
158
- // https://web.dev/font-size/#how-the-lighthouse-font-size-audit-fails
159
- ...fontSize(12, 14),
160
- fontWeight: 500,
161
- letterSpacing: 1,
162
- lineHeight: 1.2,
163
- textTransform: 'uppercase',
164
- },
165
- },
166
- spacings: {
167
- xxs: responsiveVal(10, 16),
168
- xs: responsiveVal(12, 20),
169
- sm: responsiveVal(14, 30),
170
- md: responsiveVal(16, 50),
171
- lg: responsiveVal(24, 80),
172
- xl: responsiveVal(40, 100),
173
- xxl: responsiveVal(80, 160),
174
- },
175
- page: {
176
- horizontal: responsiveVal(10, 30),
177
- vertical: responsiveVal(10, 30),
178
- },
179
- appShell: {
180
- headerHeightSm: '46px',
181
- headerHeightMd: '80px',
182
- appBarHeightMd: '80px',
183
- appBarInnerHeightMd: '46px',
184
- },
185
- })
186
-
187
- // todo: move most of the styles to the graphcommerce library while still allowing for extensibility.
188
- const createOverrides = (theme: Theme): Components => ({
189
- MuiCssBaseline: {
190
- styleOverrides: {
191
- body: {
192
- overflowY: 'scroll',
193
- },
194
- '::selection': { background: alpha(theme.palette.primary.main, 0.6) },
195
- '::-moz-selection': { background: alpha(theme.palette.primary.main, 0.6) },
196
- '#__next': {
197
- position: 'relative',
198
- },
199
- img: {
200
- filter: 'brightness(1.03)',
201
- willChange: 'filter',
202
- },
203
- },
204
- },
205
-
206
- MuiContainer: {
207
- variants: [
208
- {
209
- props: { disableGutters: false },
210
- style: {
211
- paddingLeft: theme.page.horizontal,
212
- paddingRight: theme.page.horizontal,
213
- [theme.breakpoints.up('sm')]: {
214
- paddingLeft: theme.page.horizontal,
215
- paddingRight: theme.page.horizontal,
216
- },
217
- },
218
- },
219
- ],
220
- },
221
-
222
- MuiInputBase: {
223
- styleOverrides: {
224
- root: {
225
- fontSize: '16px', // https://css-tricks.com/16px-or-larger-text-prevents-ios-form-zoom/
226
- },
227
- },
228
- },
229
-
230
- MuiButton: {
231
- defaultProps: { color: 'inherit' },
232
- variants: [
233
- ...MuiButtonResponsive,
234
- ...MuiButtonPill,
235
- {
236
- props: { variant: 'contained', color: 'inherit' },
237
- style: { backgroundColor: theme.palette.background.paper },
238
- },
239
- {
240
- props: { variant: 'outlined' },
241
- style: {
242
- borderRadius: responsiveVal(theme.shape.borderRadius * 2, theme.shape.borderRadius * 3),
243
- },
244
- },
245
- {
246
- props: { variant: 'text' },
247
- style: { borderRadius: '99em' },
248
- },
249
- ],
250
- },
251
-
252
- MuiFab: {
253
- styleOverrides: {
254
- root: {
255
- backgroundColor: theme.palette.background.paper,
256
- '&:hover': {
257
- backgroundColor: theme.palette.background.paper,
258
- },
259
- color: theme.palette.text.primary,
260
- },
261
- colorInherit: {
262
- backgroundColor: 'inherit',
263
- '&:hover, &:focus': {
264
- backgroundColor: 'inherit',
265
- },
266
- boxShadow: 'none',
267
- },
268
- primary: {
269
- color: theme.palette.text.primary,
270
- },
271
- secondary: {
272
- color: theme.palette.text.primary,
273
- },
274
- extended: {
275
- fontWeight: 400,
276
- textTransform: 'none',
277
- },
278
- },
279
- variants: [...MuiFabSizes],
280
- },
281
-
282
- MuiTextField: {
283
- styleOverrides: {
284
- root: {
285
- '& label.Mui-focused': {
286
- color: theme.palette.secondary.main,
287
- },
288
- '& .MuiOutlinedInput-root': {
289
- borderRadius: responsiveVal(theme.shape.borderRadius * 1.5, theme.shape.borderRadius * 2),
290
- '& fieldset': {
291
- borderColor: theme.palette.divider,
292
- },
293
- '&.Mui-focused fieldset': {
294
- borderColor: theme.palette.divider,
295
- borderWidth: 1,
296
- },
297
- },
298
- },
299
- },
300
- },
301
-
302
- MuiListItemIcon: {
303
- styleOverrides: {
304
- root: {
305
- color: theme.palette.text.primary,
306
- },
307
- },
308
- },
309
-
310
- MuiChip: {
311
- styleOverrides: {
312
- root: {
313
- boxShadow: 'unset !important',
314
- borderRadius: '99em',
315
- height: responsiveVal(32, 40),
316
- paddingLeft: responsiveVal(4, 8),
317
- paddingRight: responsiveVal(4, 8),
318
- ...theme.typography.body2,
319
- },
320
- sizeSmall: {
321
- height: responsiveVal(26, 30),
322
- paddingLeft: responsiveVal(3, 6),
323
- paddingRight: responsiveVal(3, 6),
324
- ...theme.typography.caption,
325
- },
326
- outlined: {
327
- borderColor: theme.palette.divider,
328
- },
329
- label: {
330
- paddingLeft: responsiveVal(6, 10),
331
- paddingRight: responsiveVal(6, 10),
332
- },
333
- labelSmall: {
334
- paddingLeft: responsiveVal(6, 8),
335
- paddingRight: responsiveVal(6, 8),
336
- },
337
- deleteIcon: {
338
- color: theme.palette.text.primary,
339
- // display: 'flex',
340
- },
341
- deleteIconOutlinedColorPrimary: {
342
- // color: theme.palette.primary.main,
343
- },
344
- },
345
- },
346
-
347
- MuiCheckbox: {
348
- styleOverrides: {
349
- colorPrimary: {
350
- color: theme.palette.text.disabled,
351
- '&.Mui-checked': {
352
- color: theme.palette.primary.main,
353
- },
354
- },
355
- colorSecondary: {
356
- color: theme.palette.text.disabled,
357
- '&.Mui-checked': {
358
- color: theme.palette.secondary.main,
359
- },
360
- },
361
- },
362
- },
363
-
364
- MuiSwitch: {
365
- styleOverrides: {
366
- track: {
367
- '.Mui-colorPrimary + &': {
368
- backgroundColor: theme.palette.primary,
369
- borderRadius: '30px',
370
- },
371
- '.Mui-checked.Mui-colorPrimary + &': {
372
- opacity: 1,
373
- backgroundColor: theme.palette.primary,
374
- borderRadius: '30px',
375
- },
376
- },
377
- thumb: {
378
- backgroundColor: '#fff',
379
- },
380
- },
381
- },
382
-
383
- MuiSnackbar: { variants: MuiSnackbar },
384
-
385
- MuiAvatar: {
386
- styleOverrides: {
387
- colorDefault: {
388
- backgroundColor: theme.palette.text.disabled,
389
- },
390
- },
391
- },
392
-
393
- MuiSlider: {
394
- styleOverrides: {
395
- rail: {
396
- color: theme.palette.text.disabled,
397
- },
398
- thumb: {
399
- background: theme.palette.background.default,
400
- boxShadow: theme.shadows[6],
401
- },
402
- },
403
- },
404
- })
405
-
406
- export const lightTheme = createThemeWithPalette(lightPalette)
407
- lightTheme.components = createOverrides(lightTheme)
408
-
409
- export const darkTheme = createThemeWithPalette(darkPalette)
410
- darkTheme.components = createOverrides(darkTheme)
@@ -1,59 +0,0 @@
1
- /* eslint-disable class-methods-use-this */
2
- import path from 'path'
3
- import { remark } from 'remark'
4
- import remarkGfm from 'remark-gfm'
5
- import strip from 'strip-markdown'
6
- import { toVFile as vfile } from 'to-vfile'
7
- import { matter } from 'vfile-matter'
8
- import { FileNode, findByUrl, getDirectoryPaths, getDirectoryTree } from './files'
9
- import { indexName } from './instantSearch'
10
- import { BaseDocument, SearchIndexer } from './typesense/SearchIndexer'
11
-
12
- export type DocumentationDocument = BaseDocument & {
13
- url: string
14
- content: string
15
- name: string
16
- }
17
-
18
- export class DocumentIndexer extends SearchIndexer<DocumentationDocument> {
19
- #root: string
20
-
21
- constructor(root: string) {
22
- super({
23
- name: indexName,
24
- fields: {
25
- id: { type: 'string' },
26
- name: { type: 'string' },
27
- url: { type: 'string' },
28
- content: { type: 'string' },
29
- },
30
- })
31
- this.#root = root
32
- }
33
-
34
- // load a single document
35
- async #loadDocument(node?: FileNode | false): Promise<DocumentationDocument> {
36
- if (!node) throw Error('Node not found')
37
-
38
- const file = path.join(process.cwd(), this.#root, node.path)
39
- const res = matter(await vfile.read(file), { strip: true })
40
- const content = (await remark().use(strip).process(res)).value.toString()
41
-
42
- if (!content) throw Error('Can not load file')
43
-
44
- const { name, url } = node
45
- return { id: node.path, content, url, name: node.matter.menu ?? name }
46
- }
47
-
48
- async *all() {
49
- const paths = await getDirectoryPaths(this.#root)
50
- const menuData = await getDirectoryTree(this.#root)
51
- if (!menuData) return false
52
-
53
- for (const p of paths) {
54
- yield this.#loadDocument(findByUrl(p.split('/'), menuData))
55
- }
56
-
57
- return true
58
- }
59
- }
package/lib/files.ts DELETED
@@ -1,168 +0,0 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
- import { toVFile as vfile } from 'to-vfile'
4
- import { matter } from 'vfile-matter'
5
-
6
- export type MatterFields = {
7
- menu?: string
8
- order?: string
9
- metaTitle?: string
10
- metaDescription?: string
11
- }
12
-
13
- type BaseFields = {
14
- type: 'folder' | 'file'
15
- path: string
16
- name: string
17
- childNodes?: FileOrFolderNode[]
18
- matter?: MatterFields
19
- }
20
-
21
- export type FolderNode = BaseFields & { type?: 'folder' }
22
- export type FileNode = BaseFields & { type?: 'file'; url: string; matter: MatterFields }
23
-
24
- export type FileOrFolderNode = FolderNode | FileNode
25
-
26
- function toUrl(p: string) {
27
- let url = p.replace('.mdx', '')
28
- url = url.replace('.md', '')
29
- url = url.endsWith('/') ? url.slice(0, -1) : url
30
- return url
31
- }
32
-
33
- async function dirTree(dir: string, root: string): Promise<FileOrFolderNode> {
34
- const stats = await fs.promises.lstat(dir)
35
-
36
- let name = path.basename(dir)
37
- name = name.replace('.mdx', '')
38
- name = name.replace('.md', '')
39
- name = name.replace(/-/g, ' ').replace(/^./, (x) => x.toUpperCase())
40
-
41
- const filePath = path.relative(root, dir)
42
-
43
- const info: Partial<FileOrFolderNode> = { path: filePath, name }
44
-
45
- if (stats.isDirectory()) {
46
- info.type = 'folder'
47
- info.childNodes = await Promise.all(
48
- (await fs.promises.readdir(dir)).map((child) => dirTree(`${dir}/${child}`, root)),
49
- )
50
- } else {
51
- info.type = 'file'
52
- }
53
-
54
- if (info.type === 'file') {
55
- info.url = toUrl(path.relative(root, dir))
56
- info.matter = matter(await vfile.read(dir)).data.matter as Record<string, string>
57
- }
58
-
59
- return info as FileOrFolderNode
60
- }
61
-
62
- // Replace the path of the parent with the path of the child having index.mdx as name and remove from children.
63
- // Do this recursively for each child.
64
- // Remove type from tree
65
- function hoistIndex(tree: FileOrFolderNode): FileOrFolderNode {
66
- let newTree: FileOrFolderNode = tree
67
-
68
- if (newTree.type === 'folder') {
69
- const index = newTree.childNodes?.find(
70
- (child) =>
71
- child.path.endsWith('readme.mdx') ||
72
- (child.path.endsWith('readme.md') && child.type === 'file'),
73
- ) as FileNode | undefined
74
-
75
- if (index) {
76
- newTree = { ...index, name: tree.name, url: index.url.slice(0, -7) }
77
- newTree.childNodes = tree.childNodes?.filter((child) => child !== index)
78
-
79
- const order = index.matter?.order?.split(',').map((x) => x.trim())
80
- if (order) {
81
- newTree.childNodes = newTree.childNodes?.sort((a, b) => {
82
- const aPath = toUrl(a.path.split('/').pop() as string)
83
- const bPath = toUrl(b.path.split('/').pop() as string)
84
- return order.indexOf(aPath) === -1 ? 1 : order.indexOf(aPath) - order.indexOf(bPath)
85
- })
86
- }
87
-
88
- newTree.childNodes = newTree.childNodes?.map((child) => hoistIndex(child))
89
- }
90
- }
91
- return newTree
92
- }
93
-
94
- export async function getDirectoryTree(dir: string): Promise<false | FileNode> {
95
- const absDir = path.join(process.cwd(), dir)
96
-
97
- const tree = await dirTree(absDir, absDir)
98
-
99
- return hoistIndex(tree) as FileNode
100
- }
101
-
102
- export async function getDirectoryPaths(dir: string) {
103
- const menuData = await getDirectoryTree(dir)
104
-
105
- const paths: string[] = []
106
- const addPathsFromTree = (tree: FileOrFolderNode) => {
107
- if (tree.type === 'file') paths.push(tree.url)
108
-
109
- if (tree.childNodes?.length) {
110
- tree.childNodes.forEach((child) => addPathsFromTree(child))
111
- }
112
- }
113
- if (menuData) addPathsFromTree(menuData)
114
-
115
- return paths
116
- }
117
-
118
- /**
119
- * Recursively traverse the tree and return the aggregated path of of each node.
120
- *
121
- * Each URL segment should reference a path (except for the readme.md/readme.mdx file)
122
- */
123
- export function urlToPath(url: string[], node: FileOrFolderNode): string | false {
124
- if (node.childNodes?.length) {
125
- const child = node.childNodes?.reduce<string | false>((prev, curr) => {
126
- if (prev) return prev
127
- const childPath = urlToPath(url, curr)
128
- return childPath ?? prev
129
- }, false)
130
-
131
- if (child) return child
132
- }
133
-
134
- if (node.type === 'file' && node.url === url.join('/')) return node.path
135
-
136
- return false
137
- }
138
-
139
- /** Get the contens of the requested file. */
140
- export function getFileContents(dir: string, filePath: string) {
141
- const absDir = path.join(process.cwd(), dir, filePath)
142
- try {
143
- return fs.promises.readFile(absDir, 'utf8')
144
- } catch (e) {
145
- return false
146
- }
147
- }
148
-
149
- /**
150
- * Recursively traverse the tree and return the aggregated path of of each node.
151
- *
152
- * Each URL segment should reference a path (except for the readme.md/readme.mdx file)
153
- */
154
- export function findByUrl(url: string[], node: FileOrFolderNode): FileNode | false {
155
- if (node.childNodes?.length) {
156
- const child = node.childNodes?.reduce<FileNode | false>((prev, curr) => {
157
- if (prev) return prev
158
- const childPath = findByUrl(url, curr)
159
- return childPath ?? prev
160
- }, false)
161
-
162
- if (child) return child
163
- }
164
-
165
- if (node.type === 'file' && node.url === url.join('/')) return node
166
-
167
- return false
168
- }
@@ -1,26 +0,0 @@
1
- import type { HitsRenderState } from 'instantsearch.js/es/connectors/hits/connectHits'
2
- import { useHits as useHitsBase } from 'react-instantsearch-hooks'
3
- import { SetReturnType } from 'type-fest'
4
- import type { DocumentationDocument } from './DocumentIndexer'
5
- import { createInstantSearchProps } from './typesense/createInstantSearchProps'
6
-
7
- export const indexName = 'documents'
8
-
9
- export const instantSearchProps = createInstantSearchProps<DocumentationDocument>(indexName, {
10
- query_by: {
11
- name: 2,
12
- content: 1,
13
- },
14
- numTypos: '1',
15
- typoTokensThreshold: 1,
16
- highlight_fields: 'content',
17
- highlight_full_fields: 'name',
18
- include_fields: 'name,url',
19
- // highlight_affix_num_tokens: ,
20
- })
21
-
22
- const useHits: SetReturnType<typeof useHitsBase, HitsRenderState<DocumentationDocument>> = (
23
- ...params
24
- ) => useHitsBase(...params) as HitsRenderState<DocumentationDocument>
25
-
26
- export { useHits }
@@ -1,47 +0,0 @@
1
- import { Client } from 'typesense/lib/Typesense'
2
- import { ConfigurationOptions } from 'typesense/lib/Typesense/Configuration'
3
- import { ObjectNotFound } from 'typesense/lib/Typesense/Errors'
4
- import { BaseDocument, SearchIndexer } from './SearchIndexer'
5
- import { batchIterable } from './batchInterable'
6
-
7
- export class IndexerHandler {
8
- client: Client
9
-
10
- constructor(
11
- clientOptions: ConfigurationOptions,
12
- public indexers: SearchIndexer<BaseDocument>[],
13
- private batchSize: number = 1000,
14
- ) {
15
- this.client = new Client(clientOptions)
16
- }
17
-
18
- async all() {
19
- let count = 0
20
- for await (const indexer of this.indexers) {
21
- const resCount = await this.#reindex(indexer)
22
- count += resCount
23
- }
24
- return count
25
- }
26
-
27
- /** @throws {TypesenseError} */
28
- async #reindex(indexer: SearchIndexer<BaseDocument>) {
29
- const { name } = indexer.schema
30
-
31
- try {
32
- await this.client.collections(name).retrieve()
33
- await this.client.collections(name).delete()
34
- } catch (e) {
35
- if (!(e instanceof ObjectNotFound)) throw e
36
- }
37
- await this.client.collections().create(indexer.schema)
38
-
39
- let count = 0
40
- for await (const documents of batchIterable(indexer.all(), this.batchSize)) {
41
- const result = await this.client.collections(name).documents().import(documents)
42
- count += result.length
43
- }
44
-
45
- return count
46
- }
47
- }