@raystack/chronicle 0.5.3 → 0.6.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.
- package/dist/cli/index.js +260 -81
- package/package.json +8 -6
- package/src/cli/commands/build.ts +5 -8
- package/src/cli/commands/dev.ts +5 -6
- package/src/cli/commands/init.test.ts +77 -0
- package/src/cli/commands/init.ts +73 -40
- package/src/cli/commands/serve.ts +6 -9
- package/src/cli/commands/start.ts +5 -5
- package/src/cli/utils/config.ts +6 -12
- package/src/cli/utils/scaffold.test.ts +179 -0
- package/src/cli/utils/scaffold.ts +70 -9
- package/src/components/api/field-row.tsx +1 -1
- package/src/components/api/field-section.tsx +2 -2
- package/src/components/mdx/index.tsx +1 -1
- package/src/components/mdx/mermaid.tsx +24 -21
- package/src/components/ui/breadcrumbs.tsx +4 -2
- package/src/components/ui/client-theme-switcher.tsx +21 -4
- package/src/components/ui/search.module.css +16 -41
- package/src/components/ui/search.tsx +30 -41
- package/src/lib/config.test.ts +493 -0
- package/src/lib/config.ts +123 -22
- package/src/lib/head.tsx +23 -5
- package/src/lib/llms.test.ts +94 -0
- package/src/lib/llms.ts +41 -0
- package/src/lib/navigation.test.ts +94 -0
- package/src/lib/navigation.ts +51 -0
- package/src/lib/page-context.tsx +79 -32
- package/src/lib/route-resolver.test.ts +173 -0
- package/src/lib/route-resolver.ts +73 -0
- package/src/lib/source.ts +94 -1
- package/src/lib/version-source.test.ts +163 -0
- package/src/lib/version-source.ts +101 -0
- package/src/pages/ApiPage.tsx +1 -1
- package/src/pages/DocsLayout.tsx +24 -3
- package/src/pages/DocsPage.tsx +7 -7
- package/src/pages/LandingPage.module.css +56 -0
- package/src/pages/LandingPage.tsx +39 -0
- package/src/pages/NotFound.module.css +3 -0
- package/src/pages/NotFound.tsx +9 -12
- package/src/server/App.tsx +21 -23
- package/src/server/api/{page/[...slug].ts → page.ts} +7 -3
- package/src/server/api/search.ts +51 -24
- package/src/server/api/specs.ts +17 -5
- package/src/server/entry-client.tsx +42 -14
- package/src/server/entry-server.tsx +35 -13
- package/src/server/plugins/telemetry.ts +47 -7
- package/src/server/routes/[...slug].md.ts +0 -6
- package/src/server/routes/[version]/llms.txt.ts +26 -0
- package/src/server/routes/llms.txt.ts +10 -13
- package/src/server/routes/og.tsx +2 -2
- package/src/server/routes/sitemap.xml.ts +14 -6
- package/src/server/vite-config.ts +5 -5
- package/src/themes/default/ContentDirButtons.tsx +66 -0
- package/src/themes/default/Layout.module.css +187 -40
- package/src/themes/default/Layout.tsx +166 -65
- package/src/themes/default/OpenInAI.tsx +112 -0
- package/src/themes/default/Page.module.css +30 -0
- package/src/themes/default/Page.tsx +1 -3
- package/src/themes/default/SidebarLogo.tsx +26 -0
- package/src/themes/default/Toc.module.css +102 -25
- package/src/themes/default/Toc.tsx +56 -10
- package/src/themes/default/VersionSwitcher.tsx +59 -0
- package/src/themes/paper/ContentDirDropdown.tsx +47 -0
- package/src/themes/paper/Layout.module.css +7 -0
- package/src/themes/paper/Layout.tsx +20 -13
- package/src/themes/paper/VersionSwitcher.tsx +60 -0
- package/src/types/config.ts +146 -23
- package/src/types/content.ts +11 -1
- package/src/types/theme.ts +1 -0
- package/src/components/ui/footer.module.css +0 -27
- package/src/components/ui/footer.tsx +0 -30
- package/src/server/api/metrics.ts +0 -23
- package/src/server/api/page/index.ts +0 -1
- package/src/server/telemetry.ts +0 -49
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { useEffect, useId, useState } from 'react'
|
|
1
|
+
import { renderMermaidSVG } from 'beautiful-mermaid'
|
|
2
|
+
import { useMemo } from 'react'
|
|
4
3
|
import styles from './mermaid.module.css'
|
|
5
4
|
|
|
6
5
|
interface MermaidProps {
|
|
@@ -8,30 +7,34 @@ interface MermaidProps {
|
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
export function Mermaid({ chart }: MermaidProps) {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
10
|
+
const { svg, error } = useMemo(() => {
|
|
11
|
+
try {
|
|
12
|
+
return {
|
|
13
|
+
svg: renderMermaidSVG(chart, {
|
|
14
|
+
bg: 'var(--rs-color-background-base-primary)',
|
|
15
|
+
fg: 'var(--rs-color-foreground-base-primary)',
|
|
16
|
+
line: 'var(--rs-color-border-base-focus)',
|
|
17
|
+
accent: 'var(--rs-color-foreground-accent-primary)',
|
|
18
|
+
muted: 'var(--rs-color-foreground-base-secondary)',
|
|
19
|
+
surface: 'var(--rs-color-background-neutral-secondary)',
|
|
20
|
+
border: 'var(--rs-color-border-base-tertiary)',
|
|
21
|
+
transparent: true,
|
|
22
|
+
}),
|
|
23
|
+
error: null,
|
|
24
|
+
}
|
|
25
|
+
} catch (err) {
|
|
26
|
+
return {
|
|
27
|
+
svg: null,
|
|
28
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
29
|
+
}
|
|
25
30
|
}
|
|
26
|
-
|
|
27
|
-
render()
|
|
28
|
-
return () => { cancelled = true }
|
|
29
31
|
}, [chart])
|
|
30
32
|
|
|
33
|
+
if (error) return <pre className={styles.error}>{error.message}</pre>
|
|
31
34
|
return (
|
|
32
35
|
<div
|
|
33
36
|
className={styles.mermaid}
|
|
34
|
-
dangerouslySetInnerHTML={{ __html: svg }}
|
|
37
|
+
dangerouslySetInnerHTML={{ __html: svg! }}
|
|
35
38
|
/>
|
|
36
39
|
)
|
|
37
40
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { Breadcrumb } from '@raystack/apsara'
|
|
4
4
|
import { getBreadcrumbItems } from 'fumadocs-core/breadcrumb'
|
|
5
5
|
import type { Root } from 'fumadocs-core/page-tree'
|
|
6
|
+
import { Link as RouterLink } from 'react-router'
|
|
6
7
|
|
|
7
8
|
interface BreadcrumbsProps {
|
|
8
9
|
slug: string[]
|
|
@@ -18,11 +19,12 @@ export function Breadcrumbs({ slug, tree }: BreadcrumbsProps) {
|
|
|
18
19
|
return (
|
|
19
20
|
<Breadcrumb size="small">
|
|
20
21
|
{items.flatMap((item, index) => {
|
|
22
|
+
const isCurrent = index === items.length - 1
|
|
21
23
|
const breadcrumbItem = (
|
|
22
24
|
<Breadcrumb.Item
|
|
23
25
|
key={`item-${index}`}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
current={isCurrent}
|
|
27
|
+
render={isCurrent ? undefined : <RouterLink to={item.url} />}
|
|
26
28
|
>
|
|
27
29
|
{item.name}
|
|
28
30
|
</Breadcrumb.Item>
|
|
@@ -1,18 +1,35 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { MoonIcon, SunIcon } from '@heroicons/react/24/outline'
|
|
4
|
+
import { IconButton, useTheme } from '@raystack/apsara'
|
|
5
|
+
import { useEffect, useState } from 'react'
|
|
5
6
|
|
|
6
7
|
interface ClientThemeSwitcherProps {
|
|
7
8
|
size?: number
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
export function ClientThemeSwitcher({ size }: ClientThemeSwitcherProps) {
|
|
11
|
+
export function ClientThemeSwitcher({ size = 16 }: ClientThemeSwitcherProps) {
|
|
11
12
|
const [isClient, setIsClient] = useState(false)
|
|
13
|
+
const { resolvedTheme, setTheme } = useTheme()
|
|
12
14
|
|
|
13
15
|
useEffect(() => {
|
|
14
16
|
setIsClient(true)
|
|
15
17
|
}, [])
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
if (!isClient) return null
|
|
20
|
+
|
|
21
|
+
const isDark = resolvedTheme === 'dark'
|
|
22
|
+
return (
|
|
23
|
+
<IconButton
|
|
24
|
+
size={3}
|
|
25
|
+
aria-label={isDark ? 'Switch to light theme' : 'Switch to dark theme'}
|
|
26
|
+
onClick={() => setTheme(isDark ? 'light' : 'dark')}
|
|
27
|
+
>
|
|
28
|
+
{isDark ? (
|
|
29
|
+
<SunIcon width={size} height={size} />
|
|
30
|
+
) : (
|
|
31
|
+
<MoonIcon width={size} height={size} />
|
|
32
|
+
)}
|
|
33
|
+
</IconButton>
|
|
34
|
+
)
|
|
18
35
|
}
|
|
@@ -1,63 +1,38 @@
|
|
|
1
|
-
.trigger {
|
|
2
|
-
gap: 8px;
|
|
3
|
-
color: var(--rs-color-foreground-base-secondary);
|
|
4
|
-
cursor: pointer;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
.kbd {
|
|
8
|
-
padding: 2px 6px;
|
|
9
|
-
border-radius: 4px;
|
|
10
|
-
border: 1px solid var(--rs-color-border-base-primary);
|
|
11
|
-
font-size: 12px;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
1
|
.dialogContent {
|
|
2
|
+
border-radius: var(--rs-radius-4);
|
|
3
|
+
padding: 0px;
|
|
4
|
+
width: 80%;
|
|
15
5
|
max-width: 600px;
|
|
16
|
-
padding: 0;
|
|
17
|
-
min-height: 0;
|
|
18
6
|
position: fixed;
|
|
19
7
|
top: 20%;
|
|
20
|
-
left: 50%;
|
|
21
|
-
transform: translateX(-50%);
|
|
22
|
-
border-radius: var(--rs-radius-4);
|
|
23
8
|
}
|
|
24
9
|
|
|
25
10
|
.input {
|
|
26
|
-
|
|
27
|
-
border: none;
|
|
28
|
-
outline: none;
|
|
29
|
-
background: transparent;
|
|
30
|
-
font-size: 16px;
|
|
31
|
-
color: var(--rs-color-foreground-base-primary);
|
|
11
|
+
font-size: var(--rs-font-size-small);
|
|
32
12
|
}
|
|
33
13
|
|
|
34
14
|
.list {
|
|
35
|
-
max-height:
|
|
36
|
-
overflow: auto;
|
|
37
|
-
padding: 0;
|
|
15
|
+
max-height: 400px;
|
|
38
16
|
}
|
|
39
17
|
|
|
40
|
-
.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
overflow: hidden;
|
|
47
|
-
clip: rect(0, 0, 0, 0);
|
|
48
|
-
white-space: nowrap;
|
|
49
|
-
border: 0;
|
|
18
|
+
.list :global([cmdk-group-heading]) {
|
|
19
|
+
color: var(--rs-color-foreground-base-tertiary);
|
|
20
|
+
font-size: var(--rs-font-size-mini);
|
|
21
|
+
font-weight: var(--rs-font-weight-medium);
|
|
22
|
+
letter-spacing: var(--rs-letter-spacing-mini);
|
|
23
|
+
padding: var(--rs-space-6) var(--rs-space-5) var(--rs-space-3);
|
|
50
24
|
}
|
|
51
25
|
|
|
52
26
|
.item {
|
|
53
|
-
|
|
27
|
+
height: 32px;
|
|
28
|
+
padding: var(--rs-space-3);
|
|
29
|
+
gap: var(--rs-space-3);
|
|
30
|
+
border-radius: var(--rs-radius-2);
|
|
54
31
|
cursor: pointer;
|
|
55
|
-
border-radius: 6px;
|
|
56
32
|
}
|
|
57
33
|
|
|
58
34
|
.item[data-selected="true"] {
|
|
59
|
-
background: var(--rs-color-background-base-
|
|
60
|
-
color: var(--rs-color-foreground-accent-primary-hover);
|
|
35
|
+
background: var(--rs-color-background-base-primary-hover);
|
|
61
36
|
}
|
|
62
37
|
|
|
63
38
|
.itemContent {
|
|
@@ -1,28 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
DocumentIcon,
|
|
3
|
+
HashtagIcon,
|
|
4
|
+
MagnifyingGlassIcon
|
|
5
|
+
} from '@heroicons/react/24/outline';
|
|
6
|
+
import { Command, IconButton, Text } from '@raystack/apsara';
|
|
4
7
|
import type { SortedResult } from 'fumadocs-core/search';
|
|
5
8
|
import { useDocsSearch } from 'fumadocs-core/search/client';
|
|
6
9
|
import { useCallback, useEffect, useState } from 'react';
|
|
7
10
|
import { useNavigate } from 'react-router';
|
|
8
11
|
import { MethodBadge } from '@/components/api/method-badge';
|
|
12
|
+
import { usePageContext } from '@/lib/page-context';
|
|
9
13
|
import styles from './search.module.css';
|
|
10
14
|
|
|
11
|
-
function SearchShortcutKey({ className }: { className?: string }) {
|
|
12
|
-
const [key, setKey] = useState('⌘');
|
|
13
|
-
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
const isMac = navigator.platform?.toUpperCase().includes('MAC');
|
|
16
|
-
setKey(isMac ? '⌘' : 'Ctrl');
|
|
17
|
-
}, []);
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<kbd className={className} suppressHydrationWarning>
|
|
21
|
-
{key} K
|
|
22
|
-
</kbd>
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
15
|
interface SearchProps {
|
|
27
16
|
className?: string;
|
|
28
17
|
}
|
|
@@ -30,10 +19,12 @@ interface SearchProps {
|
|
|
30
19
|
export function Search({ className }: SearchProps) {
|
|
31
20
|
const [open, setOpen] = useState(false);
|
|
32
21
|
const navigate = useNavigate();
|
|
22
|
+
const { version } = usePageContext();
|
|
33
23
|
|
|
34
24
|
const { search, setSearch, query } = useDocsSearch({
|
|
35
25
|
type: 'fetch',
|
|
36
26
|
api: '/api/search',
|
|
27
|
+
tag: version.dir ?? undefined,
|
|
37
28
|
delayMs: 100,
|
|
38
29
|
allowEmpty: true
|
|
39
30
|
});
|
|
@@ -64,31 +55,28 @@ export function Search({ className }: SearchProps) {
|
|
|
64
55
|
|
|
65
56
|
return (
|
|
66
57
|
<>
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
58
|
+
<IconButton
|
|
59
|
+
size={3}
|
|
60
|
+
aria-label='Search'
|
|
61
|
+
title='Search (Ctrl/⌘K)'
|
|
71
62
|
onClick={() => setOpen(true)}
|
|
72
|
-
className={
|
|
73
|
-
trailingIcon={<SearchShortcutKey className={styles.kbd} />}
|
|
63
|
+
className={className}
|
|
74
64
|
>
|
|
75
|
-
|
|
76
|
-
</
|
|
77
|
-
|
|
78
|
-
<Dialog open={open} onOpenChange={setOpen}>
|
|
79
|
-
<
|
|
80
|
-
<
|
|
81
|
-
Search documentation
|
|
82
|
-
</Dialog.Title>
|
|
83
|
-
<Command loop>
|
|
65
|
+
<MagnifyingGlassIcon width={16} height={16} />
|
|
66
|
+
</IconButton>
|
|
67
|
+
|
|
68
|
+
<Command.Dialog open={open} onOpenChange={setOpen}>
|
|
69
|
+
<Command.DialogContent className={styles.dialogContent}>
|
|
70
|
+
<Command>
|
|
84
71
|
<Command.Input
|
|
85
72
|
placeholder='Search'
|
|
73
|
+
leadingIcon={<MagnifyingGlassIcon width={16} height={16} />}
|
|
86
74
|
value={search}
|
|
87
|
-
|
|
75
|
+
onChange={(e) => setSearch(e.target.value)}
|
|
88
76
|
className={styles.input}
|
|
89
77
|
/>
|
|
90
78
|
|
|
91
|
-
<Command.
|
|
79
|
+
<Command.Content className={styles.list}>
|
|
92
80
|
{query.isLoading && <Command.Empty>Loading...</Command.Empty>}
|
|
93
81
|
{!query.isLoading &&
|
|
94
82
|
search.length > 0 &&
|
|
@@ -98,12 +86,13 @@ export function Search({ className }: SearchProps) {
|
|
|
98
86
|
{!query.isLoading &&
|
|
99
87
|
search.length === 0 &&
|
|
100
88
|
results.length > 0 && (
|
|
101
|
-
<Command.Group
|
|
89
|
+
<Command.Group>
|
|
90
|
+
<Command.Label>Suggestions</Command.Label>
|
|
102
91
|
{results.slice(0, 8).map((result: SortedResult) => (
|
|
103
92
|
<Command.Item
|
|
104
93
|
key={result.id}
|
|
105
94
|
value={result.id}
|
|
106
|
-
|
|
95
|
+
onClick={() => onSelect(result.url)}
|
|
107
96
|
className={styles.item}
|
|
108
97
|
>
|
|
109
98
|
<div className={styles.itemContent}>
|
|
@@ -123,7 +112,7 @@ export function Search({ className }: SearchProps) {
|
|
|
123
112
|
<Command.Item
|
|
124
113
|
key={result.id}
|
|
125
114
|
value={result.id}
|
|
126
|
-
|
|
115
|
+
onClick={() => onSelect(result.url)}
|
|
127
116
|
className={styles.item}
|
|
128
117
|
>
|
|
129
118
|
<div className={styles.itemContent}>
|
|
@@ -152,10 +141,10 @@ export function Search({ className }: SearchProps) {
|
|
|
152
141
|
</div>
|
|
153
142
|
</Command.Item>
|
|
154
143
|
))}
|
|
155
|
-
</Command.
|
|
144
|
+
</Command.Content>
|
|
156
145
|
</Command>
|
|
157
|
-
</
|
|
158
|
-
</Dialog>
|
|
146
|
+
</Command.DialogContent>
|
|
147
|
+
</Command.Dialog>
|
|
159
148
|
</>
|
|
160
149
|
);
|
|
161
150
|
}
|