deepspace 0.26.3 → 0.27.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/CHANGELOG.md +5 -1
- package/README.md +8 -5
- package/dist/chunk-Q5YJGF5Z.js +769 -0
- package/dist/chunk-Q5YJGF5Z.js.map +1 -0
- package/dist/{chunk-EN5XPHIF.js → chunk-SF6GNPYL.js} +2 -2
- package/dist/{chunk-EN5XPHIF.js.map → chunk-SF6GNPYL.js.map} +1 -1
- package/dist/cli.js +851 -1331
- package/dist/cli.js.map +1 -1
- package/dist/documentation-client-core.js +1 -1
- package/dist/documentation-default-renderer.cjs +1 -1
- package/dist/documentation-react.js +1 -1
- package/dist/documentation-runtime.js +1 -1
- package/dist/documentation-server-core.js +1 -1
- package/dist/documentation.js +1 -1
- package/dist/documentation.js.map +1 -1
- package/dist/repo-api-7GDPVSFV.js +14 -0
- package/dist/repo-api-7GDPVSFV.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-S2OGAK6U.js +0 -1957
- package/dist/chunk-S2OGAK6U.js.map +0 -1
package/dist/chunk-S2OGAK6U.js
DELETED
|
@@ -1,1957 +0,0 @@
|
|
|
1
|
-
// src/documentation/runtime/app.tsx
|
|
2
|
-
import {
|
|
3
|
-
useCallback,
|
|
4
|
-
useEffect as useEffect8,
|
|
5
|
-
useState as useState7
|
|
6
|
-
} from "react";
|
|
7
|
-
|
|
8
|
-
// src/documentation/runtime/article.tsx
|
|
9
|
-
import {
|
|
10
|
-
useEffect as useEffect3,
|
|
11
|
-
useMemo,
|
|
12
|
-
useRef as useRef3,
|
|
13
|
-
useState as useState3
|
|
14
|
-
} from "react";
|
|
15
|
-
import { createPortal } from "react-dom";
|
|
16
|
-
|
|
17
|
-
// src/documentation/types.ts
|
|
18
|
-
var DocumentationError = class extends Error {
|
|
19
|
-
code;
|
|
20
|
-
diagnostics;
|
|
21
|
-
constructor(message, code, diagnostics = []) {
|
|
22
|
-
super(message);
|
|
23
|
-
this.name = "DocumentationError";
|
|
24
|
-
this.code = code;
|
|
25
|
-
this.diagnostics = diagnostics;
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// src/documentation/routing.ts
|
|
30
|
-
function collapseRoute(value) {
|
|
31
|
-
let route = `/${value}`.replace(/\/{2,}/g, "/");
|
|
32
|
-
if (route.length > 1) route = route.replace(/\/$/, "");
|
|
33
|
-
return route;
|
|
34
|
-
}
|
|
35
|
-
function normalizeRoute(value) {
|
|
36
|
-
assertSafeRoute(value);
|
|
37
|
-
let route = collapseRoute(value);
|
|
38
|
-
route = route.replace(/\.(?:md|mdx)$/i, "");
|
|
39
|
-
route = route.replace(/\/index$/i, "");
|
|
40
|
-
return route || "/";
|
|
41
|
-
}
|
|
42
|
-
function normalizeDocumentationBasePath(value) {
|
|
43
|
-
if (!value || value === "/") return "";
|
|
44
|
-
const normalized = normalizeRoute(value);
|
|
45
|
-
if (normalized === "/_documentation") {
|
|
46
|
-
throw new DocumentationError("The internal /_documentation namespace cannot be a public documentation base", "documentation_base_invalid");
|
|
47
|
-
}
|
|
48
|
-
return normalized;
|
|
49
|
-
}
|
|
50
|
-
function documentationPublicPath(basePath, path) {
|
|
51
|
-
const base = normalizeDocumentationBasePath(basePath);
|
|
52
|
-
const suffix = path.startsWith("/") ? path : `/${path}`;
|
|
53
|
-
if (suffix === "/") return base || "/";
|
|
54
|
-
return `${base}${suffix}`;
|
|
55
|
-
}
|
|
56
|
-
function documentationLogicalPath(basePath, pathname) {
|
|
57
|
-
const base = normalizeDocumentationBasePath(basePath);
|
|
58
|
-
if (!base) return pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
59
|
-
if (pathname === base) return "/";
|
|
60
|
-
if (!pathname.startsWith(`${base}/`)) return null;
|
|
61
|
-
return pathname.slice(base.length) || "/";
|
|
62
|
-
}
|
|
63
|
-
function assertSafeRoute(value) {
|
|
64
|
-
if (value.includes("\\") || value.includes("\0")) throw unsafeRoute(value);
|
|
65
|
-
let decoded = value;
|
|
66
|
-
for (let pass = 0; pass < 5; pass++) {
|
|
67
|
-
let next;
|
|
68
|
-
try {
|
|
69
|
-
next = decodeURIComponent(decoded);
|
|
70
|
-
} catch {
|
|
71
|
-
throw unsafeRoute(value);
|
|
72
|
-
}
|
|
73
|
-
if (next === decoded) break;
|
|
74
|
-
decoded = next;
|
|
75
|
-
}
|
|
76
|
-
if (decoded.includes("\\") || decoded.includes("\0") || decoded.split("/").some((segment) => segment === "." || segment === "..")) throw unsafeRoute(value);
|
|
77
|
-
}
|
|
78
|
-
function unsafeRoute(value) {
|
|
79
|
-
return new DocumentationError(
|
|
80
|
-
`Documentation route contains an unsafe path segment: ${value}`,
|
|
81
|
-
"documentation_route_invalid",
|
|
82
|
-
[{ code: "route_path_escape", message: value }]
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// src/documentation/runtime/browser.ts
|
|
87
|
-
async function writeClipboardText(text) {
|
|
88
|
-
try {
|
|
89
|
-
if (navigator.clipboard?.writeText) {
|
|
90
|
-
await navigator.clipboard.writeText(text);
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
} catch {
|
|
94
|
-
}
|
|
95
|
-
const activeElement = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
96
|
-
const textarea = document.createElement("textarea");
|
|
97
|
-
textarea.value = text;
|
|
98
|
-
textarea.readOnly = true;
|
|
99
|
-
textarea.style.position = "fixed";
|
|
100
|
-
textarea.style.inset = "0 auto auto 0";
|
|
101
|
-
textarea.style.opacity = "0";
|
|
102
|
-
textarea.style.pointerEvents = "none";
|
|
103
|
-
document.body.appendChild(textarea);
|
|
104
|
-
textarea.focus({ preventScroll: true });
|
|
105
|
-
textarea.select();
|
|
106
|
-
const copied = document.execCommand("copy");
|
|
107
|
-
textarea.remove();
|
|
108
|
-
activeElement?.focus({ preventScroll: true });
|
|
109
|
-
if (!copied) throw new Error("Unable to copy text");
|
|
110
|
-
}
|
|
111
|
-
function externalProps(href) {
|
|
112
|
-
return isExternal(href) ? { target: "_blank", rel: "noopener noreferrer" } : {};
|
|
113
|
-
}
|
|
114
|
-
function isExternal(href) {
|
|
115
|
-
return /^https?:\/\//i.test(href);
|
|
116
|
-
}
|
|
117
|
-
function safeStorageGet(key) {
|
|
118
|
-
try {
|
|
119
|
-
return localStorage.getItem(key);
|
|
120
|
-
} catch {
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
function safeStorageSet(key, value) {
|
|
125
|
-
try {
|
|
126
|
-
localStorage.setItem(key, value);
|
|
127
|
-
} catch {
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
function errorMessage(error) {
|
|
131
|
-
return error instanceof Error ? error.message : String(error);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// src/documentation/runtime/code-block.tsx
|
|
135
|
-
import {
|
|
136
|
-
createContext,
|
|
137
|
-
useContext,
|
|
138
|
-
useEffect,
|
|
139
|
-
useId,
|
|
140
|
-
useRef,
|
|
141
|
-
useState
|
|
142
|
-
} from "react";
|
|
143
|
-
|
|
144
|
-
// src/documentation/runtime/icons.tsx
|
|
145
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
146
|
-
function Icon({ children, ...props }) {
|
|
147
|
-
return /* @__PURE__ */ jsx(
|
|
148
|
-
"svg",
|
|
149
|
-
{
|
|
150
|
-
"aria-hidden": "true",
|
|
151
|
-
fill: "none",
|
|
152
|
-
height: "18",
|
|
153
|
-
viewBox: "0 0 24 24",
|
|
154
|
-
width: "18",
|
|
155
|
-
...props,
|
|
156
|
-
children
|
|
157
|
-
}
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
function OrbitMark(props) {
|
|
161
|
-
return /* @__PURE__ */ jsxs(Icon, { viewBox: "0 0 32 32", ...props, children: [
|
|
162
|
-
/* @__PURE__ */ jsx("path", { d: "M16 2.5c.5 7.7 5.8 13 13.5 13.5-7.7.5-13 5.8-13.5 13.5C15.5 21.8 10.2 16.5 2.5 16 10.2 15.5 15.5 10.2 16 2.5Z", fill: "currentColor" }),
|
|
163
|
-
/* @__PURE__ */ jsx("circle", { cx: "16", cy: "16", fill: "var(--documentation-bg)", r: "3.25" }),
|
|
164
|
-
/* @__PURE__ */ jsx("path", { d: "M4.5 22.7c5.6-2 16.4-8.3 22.7-14.1", opacity: ".45", stroke: "currentColor", strokeLinecap: "round" })
|
|
165
|
-
] });
|
|
166
|
-
}
|
|
167
|
-
function SearchIcon(props) {
|
|
168
|
-
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
169
|
-
/* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "6.5", stroke: "currentColor", strokeWidth: "1.8" }),
|
|
170
|
-
/* @__PURE__ */ jsx("path", { d: "m16 16 4 4", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.8" })
|
|
171
|
-
] });
|
|
172
|
-
}
|
|
173
|
-
function SparkIcon(props) {
|
|
174
|
-
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
175
|
-
/* @__PURE__ */ jsx("path", { d: "M12 2.8c.3 5 3.7 8.4 8.7 8.7-5 .3-8.4 3.7-8.7 8.7-.3-5-3.7-8.4-8.7-8.7 5-.3 8.4-3.7 8.7-8.7Z", stroke: "currentColor", strokeLinejoin: "round", strokeWidth: "1.6" }),
|
|
176
|
-
/* @__PURE__ */ jsx("path", { d: "M19 3v4M21 5h-4", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.4" })
|
|
177
|
-
] });
|
|
178
|
-
}
|
|
179
|
-
function MenuIcon(props) {
|
|
180
|
-
return /* @__PURE__ */ jsx(Icon, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M4 7h16M4 12h16M4 17h16", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.8" }) });
|
|
181
|
-
}
|
|
182
|
-
function CloseIcon(props) {
|
|
183
|
-
return /* @__PURE__ */ jsx(Icon, { ...props, children: /* @__PURE__ */ jsx("path", { d: "m6 6 12 12M18 6 6 18", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.8" }) });
|
|
184
|
-
}
|
|
185
|
-
function SunIcon(props) {
|
|
186
|
-
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
187
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3.5", stroke: "currentColor", strokeWidth: "1.6" }),
|
|
188
|
-
/* @__PURE__ */ jsx("path", { d: "M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.3 5.3l1.4 1.4M17.3 17.3l1.4 1.4M18.7 5.3l-1.4 1.4M6.7 17.3l-1.4 1.4", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.6" })
|
|
189
|
-
] });
|
|
190
|
-
}
|
|
191
|
-
function MoonIcon(props) {
|
|
192
|
-
return /* @__PURE__ */ jsx(Icon, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M19.5 14.8A8 8 0 0 1 9.2 4.5 8 8 0 1 0 19.5 14.8Z", stroke: "currentColor", strokeLinejoin: "round", strokeWidth: "1.6" }) });
|
|
193
|
-
}
|
|
194
|
-
function SystemIcon(props) {
|
|
195
|
-
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
196
|
-
/* @__PURE__ */ jsx("rect", { x: "3", y: "4", width: "18", height: "13", rx: "2", stroke: "currentColor", strokeWidth: "1.6" }),
|
|
197
|
-
/* @__PURE__ */ jsx("path", { d: "M8 21h8M12 17v4", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.6" })
|
|
198
|
-
] });
|
|
199
|
-
}
|
|
200
|
-
function ChevronRightIcon(props) {
|
|
201
|
-
return /* @__PURE__ */ jsx(Icon, { ...props, children: /* @__PURE__ */ jsx("path", { d: "m9 5 7 7-7 7", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.8" }) });
|
|
202
|
-
}
|
|
203
|
-
function ChevronDownIcon(props) {
|
|
204
|
-
return /* @__PURE__ */ jsx(Icon, { ...props, children: /* @__PURE__ */ jsx("path", { d: "m5 9 7 7 7-7", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.8" }) });
|
|
205
|
-
}
|
|
206
|
-
function ExternalIcon(props) {
|
|
207
|
-
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
208
|
-
/* @__PURE__ */ jsx("path", { d: "M14 4h6v6M20 4l-9 9", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.6" }),
|
|
209
|
-
/* @__PURE__ */ jsx("path", { d: "M18 13v5a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.6" })
|
|
210
|
-
] });
|
|
211
|
-
}
|
|
212
|
-
function CopyIcon(props) {
|
|
213
|
-
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
214
|
-
/* @__PURE__ */ jsx("rect", { x: "8", y: "8", width: "11", height: "11", rx: "2", stroke: "currentColor", strokeWidth: "1.6" }),
|
|
215
|
-
/* @__PURE__ */ jsx("path", { d: "M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2", stroke: "currentColor", strokeWidth: "1.6" })
|
|
216
|
-
] });
|
|
217
|
-
}
|
|
218
|
-
function CheckIcon(props) {
|
|
219
|
-
return /* @__PURE__ */ jsx(Icon, { ...props, children: /* @__PURE__ */ jsx("path", { d: "m5 12.5 4.2 4L19 7", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.9" }) });
|
|
220
|
-
}
|
|
221
|
-
function FileIcon(props) {
|
|
222
|
-
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
223
|
-
/* @__PURE__ */ jsx("path", { d: "M6 3.5h8l4 4V20a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4.5a1 1 0 0 1 1-1Z", stroke: "currentColor", strokeLinejoin: "round", strokeWidth: "1.6" }),
|
|
224
|
-
/* @__PURE__ */ jsx("path", { d: "M14 3.5v4h4M8 12h7M8 16h7", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.6" })
|
|
225
|
-
] });
|
|
226
|
-
}
|
|
227
|
-
function MessageIcon(props) {
|
|
228
|
-
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
229
|
-
/* @__PURE__ */ jsx("path", { d: "M5.5 18.5 4 21l3.5-1.2A8.5 8.5 0 1 0 5.5 18.5Z", stroke: "currentColor", strokeLinejoin: "round", strokeWidth: "1.6" }),
|
|
230
|
-
/* @__PURE__ */ jsx("path", { d: "M8 10h8M8 14h5", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.6" })
|
|
231
|
-
] });
|
|
232
|
-
}
|
|
233
|
-
function TerminalIcon(props) {
|
|
234
|
-
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
235
|
-
/* @__PURE__ */ jsx("rect", { x: "3.5", y: "4.5", width: "17", height: "15", rx: "2", stroke: "currentColor", strokeWidth: "1.6" }),
|
|
236
|
-
/* @__PURE__ */ jsx("path", { d: "m7 9 3 3-3 3M12.5 15H17", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.6" })
|
|
237
|
-
] });
|
|
238
|
-
}
|
|
239
|
-
function EditorIcon(props) {
|
|
240
|
-
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
241
|
-
/* @__PURE__ */ jsx("rect", { x: "3.5", y: "4.5", width: "17", height: "15", rx: "2", stroke: "currentColor", strokeWidth: "1.6" }),
|
|
242
|
-
/* @__PURE__ */ jsx("path", { d: "M8 4.5v15M11.5 9h5M11.5 12h5M11.5 15h3", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.6" })
|
|
243
|
-
] });
|
|
244
|
-
}
|
|
245
|
-
function SendIcon(props) {
|
|
246
|
-
return /* @__PURE__ */ jsx(Icon, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M12 18V6M7.5 10.5 12 6l4.5 4.5", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.8" }) });
|
|
247
|
-
}
|
|
248
|
-
function StopIcon(props) {
|
|
249
|
-
return /* @__PURE__ */ jsx(Icon, { ...props, children: /* @__PURE__ */ jsx("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2", fill: "currentColor" }) });
|
|
250
|
-
}
|
|
251
|
-
function HashIcon(props) {
|
|
252
|
-
return /* @__PURE__ */ jsx(Icon, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M9.5 4 7.5 20M16.5 4l-2 16M4.5 9h15M3.5 15h15", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.6" }) });
|
|
253
|
-
}
|
|
254
|
-
function ListIcon(props) {
|
|
255
|
-
return /* @__PURE__ */ jsx(Icon, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M4 6h16M4 12h11M4 18h7", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.8" }) });
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// src/documentation/runtime/code-block.tsx
|
|
259
|
-
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
260
|
-
var CodeBlockContext = createContext({
|
|
261
|
-
assistantEnabled: false,
|
|
262
|
-
onAsk: () => {
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
var CodeBlockControlsProvider = CodeBlockContext.Provider;
|
|
266
|
-
function CodeBlockActions({ readCode }) {
|
|
267
|
-
const { assistantEnabled, onAsk } = useContext(CodeBlockContext);
|
|
268
|
-
const [copied, setCopied] = useState(false);
|
|
269
|
-
const copy = async () => {
|
|
270
|
-
await writeClipboardText(readCode());
|
|
271
|
-
setCopied(true);
|
|
272
|
-
window.setTimeout(() => setCopied(false), 1400);
|
|
273
|
-
};
|
|
274
|
-
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
275
|
-
/* @__PURE__ */ jsx2("button", { "aria-label": copied ? "Code copied" : "Copy code", onClick: () => {
|
|
276
|
-
void copy();
|
|
277
|
-
}, type: "button", children: copied ? /* @__PURE__ */ jsx2(CheckIcon, {}) : /* @__PURE__ */ jsx2(CopyIcon, {}) }),
|
|
278
|
-
assistantEnabled && /* @__PURE__ */ jsx2(
|
|
279
|
-
"button",
|
|
280
|
-
{
|
|
281
|
-
"aria-label": "Ask the documentation assistant about this code",
|
|
282
|
-
onClick: () => onAsk(readCode().trim().slice(0, 1200)),
|
|
283
|
-
type: "button",
|
|
284
|
-
children: /* @__PURE__ */ jsx2(SparkIcon, {})
|
|
285
|
-
}
|
|
286
|
-
)
|
|
287
|
-
] });
|
|
288
|
-
}
|
|
289
|
-
function codeBlockLanguage(className) {
|
|
290
|
-
return /(?:^|\s)(?:language|lang)-([a-z0-9+#-]{1,20})/i.exec(className)?.[1] ?? "";
|
|
291
|
-
}
|
|
292
|
-
function childCodeClassName(children) {
|
|
293
|
-
const code = children;
|
|
294
|
-
return typeof code?.props?.className === "string" ? code.props.className : "";
|
|
295
|
-
}
|
|
296
|
-
function childCodeTitle(children) {
|
|
297
|
-
const code = children;
|
|
298
|
-
const title = code?.props?.["data-code-title"];
|
|
299
|
-
return typeof title === "string" && title ? title : void 0;
|
|
300
|
-
}
|
|
301
|
-
var CodeGroupContext = createContext(false);
|
|
302
|
-
var CodeGroupProvider = CodeGroupContext.Provider;
|
|
303
|
-
function CodeBlock({ children, ...props }) {
|
|
304
|
-
const preRef = useRef(null);
|
|
305
|
-
const inCodeGroup = useContext(CodeGroupContext);
|
|
306
|
-
const language = codeBlockLanguage(childCodeClassName(children));
|
|
307
|
-
const preTitle = props["data-code-title"];
|
|
308
|
-
const title = inCodeGroup ? void 0 : childCodeTitle(children) ?? (typeof preTitle === "string" && preTitle ? preTitle : void 0);
|
|
309
|
-
const readCode = () => preRef.current?.querySelector("code")?.textContent ?? preRef.current?.textContent ?? "";
|
|
310
|
-
return /* @__PURE__ */ jsxs2("div", { className: "documentation-code-block", children: [
|
|
311
|
-
title ? /* @__PURE__ */ jsx2("div", { className: "documentation-code-title", children: title }) : null,
|
|
312
|
-
/* @__PURE__ */ jsx2("pre", { ...props, ref: preRef, children }),
|
|
313
|
-
/* @__PURE__ */ jsxs2("div", { className: "documentation-code-actions", children: [
|
|
314
|
-
language ? /* @__PURE__ */ jsx2("span", { className: "documentation-code-language", children: language }) : null,
|
|
315
|
-
/* @__PURE__ */ jsx2(CodeBlockActions, { readCode })
|
|
316
|
-
] })
|
|
317
|
-
] });
|
|
318
|
-
}
|
|
319
|
-
var TAB_SELECTION_KEY = "deepspace-documentation-tab-selection";
|
|
320
|
-
var TAB_CHANGE_EVENT = "deepspace-documentation-tab-change";
|
|
321
|
-
function TabGroup({
|
|
322
|
-
className,
|
|
323
|
-
panels,
|
|
324
|
-
title
|
|
325
|
-
}) {
|
|
326
|
-
const groupId = useId();
|
|
327
|
-
const [active, setActive] = useState(0);
|
|
328
|
-
const controlsRef = useRef(null);
|
|
329
|
-
useEffect(() => {
|
|
330
|
-
const stored = safeStorageGet(TAB_SELECTION_KEY);
|
|
331
|
-
const index = stored ? panels.findIndex((panel) => panel.label === stored) : -1;
|
|
332
|
-
if (index >= 0) setActive(index);
|
|
333
|
-
}, [panels]);
|
|
334
|
-
useEffect(() => {
|
|
335
|
-
const sync = (event) => {
|
|
336
|
-
const detail = event.detail;
|
|
337
|
-
if (!detail?.label || detail.source === groupId) return;
|
|
338
|
-
const index = panels.findIndex((panel) => panel.label === detail.label);
|
|
339
|
-
if (index >= 0) setActive(index);
|
|
340
|
-
};
|
|
341
|
-
document.addEventListener(TAB_CHANGE_EVENT, sync);
|
|
342
|
-
return () => document.removeEventListener(TAB_CHANGE_EVENT, sync);
|
|
343
|
-
}, [groupId, panels]);
|
|
344
|
-
const select = (index, broadcast) => {
|
|
345
|
-
setActive(index);
|
|
346
|
-
const label = panels[index]?.label;
|
|
347
|
-
if (!broadcast || !label) return;
|
|
348
|
-
safeStorageSet(TAB_SELECTION_KEY, label);
|
|
349
|
-
document.dispatchEvent(new CustomEvent(TAB_CHANGE_EVENT, { detail: { label, source: groupId } }));
|
|
350
|
-
};
|
|
351
|
-
const onKeyDown = (event, index) => {
|
|
352
|
-
if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) return;
|
|
353
|
-
event.preventDefault();
|
|
354
|
-
const next = event.key === "Home" ? 0 : event.key === "End" ? panels.length - 1 : (index + (event.key === "ArrowRight" ? 1 : -1) + panels.length) % panels.length;
|
|
355
|
-
select(next, true);
|
|
356
|
-
controlsRef.current?.querySelectorAll("button")[next]?.focus();
|
|
357
|
-
};
|
|
358
|
-
return /* @__PURE__ */ jsxs2("div", { className, "data-tab-group": true, children: [
|
|
359
|
-
title,
|
|
360
|
-
/* @__PURE__ */ jsx2("div", { className: "documentation-tab-buttons", ref: controlsRef, role: "tablist", children: panels.map((panel, index) => /* @__PURE__ */ jsx2(
|
|
361
|
-
"button",
|
|
362
|
-
{
|
|
363
|
-
"aria-selected": index === active,
|
|
364
|
-
id: `documentation-tab-${groupId}-${index}`,
|
|
365
|
-
onClick: () => select(index, true),
|
|
366
|
-
onKeyDown: (event) => onKeyDown(event, index),
|
|
367
|
-
role: "tab",
|
|
368
|
-
tabIndex: index === active ? 0 : -1,
|
|
369
|
-
type: "button",
|
|
370
|
-
children: panel.label
|
|
371
|
-
},
|
|
372
|
-
panel.label
|
|
373
|
-
)) }),
|
|
374
|
-
panels.map((panel, index) => /* @__PURE__ */ jsx2(
|
|
375
|
-
"section",
|
|
376
|
-
{
|
|
377
|
-
"aria-labelledby": `documentation-tab-${groupId}-${index}`,
|
|
378
|
-
className: "documentation-tab",
|
|
379
|
-
"data-tab": true,
|
|
380
|
-
"data-tab-title": panel.label,
|
|
381
|
-
hidden: index !== active,
|
|
382
|
-
role: "tabpanel",
|
|
383
|
-
children: panel.content
|
|
384
|
-
},
|
|
385
|
-
panel.label
|
|
386
|
-
))
|
|
387
|
-
] });
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// src/documentation/runtime/page-actions.tsx
|
|
391
|
-
import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
392
|
-
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
393
|
-
function PageActions({
|
|
394
|
-
data,
|
|
395
|
-
onAssistantOpen
|
|
396
|
-
}) {
|
|
397
|
-
const [copied, setCopied] = useState2(null);
|
|
398
|
-
const detailsRef = useRef2(null);
|
|
399
|
-
const actions = data.config.contextual.actions.filter((action) => {
|
|
400
|
-
if (data.page.route === "/404") return false;
|
|
401
|
-
if (action === "assistant" && data.config.assistant.access === "disabled") return false;
|
|
402
|
-
if ((action === "mcp" || action === "add-mcp" || action === "cursor" || action === "vscode") && data.config.mcp.access !== "public") return false;
|
|
403
|
-
return true;
|
|
404
|
-
});
|
|
405
|
-
const primary = actions[0];
|
|
406
|
-
useEffect2(() => {
|
|
407
|
-
const closeOnPointerDown = (event) => {
|
|
408
|
-
const details = detailsRef.current;
|
|
409
|
-
if (details && !details.contains(event.target)) details.open = false;
|
|
410
|
-
};
|
|
411
|
-
const closeOnEscape = (event) => {
|
|
412
|
-
if (event.key === "Escape" && detailsRef.current?.open) {
|
|
413
|
-
detailsRef.current.open = false;
|
|
414
|
-
detailsRef.current.querySelector("summary")?.focus();
|
|
415
|
-
}
|
|
416
|
-
};
|
|
417
|
-
document.addEventListener("pointerdown", closeOnPointerDown);
|
|
418
|
-
document.addEventListener("keydown", closeOnEscape);
|
|
419
|
-
return () => {
|
|
420
|
-
document.removeEventListener("pointerdown", closeOnPointerDown);
|
|
421
|
-
document.removeEventListener("keydown", closeOnEscape);
|
|
422
|
-
};
|
|
423
|
-
}, []);
|
|
424
|
-
if (!primary) return null;
|
|
425
|
-
const markCopied = (action) => {
|
|
426
|
-
setCopied(action);
|
|
427
|
-
window.setTimeout(() => setCopied((current) => current === action ? null : current), 1600);
|
|
428
|
-
};
|
|
429
|
-
const copyPage = async () => {
|
|
430
|
-
const response = await fetch(data.page.markdownUrl);
|
|
431
|
-
if (!response.ok) return;
|
|
432
|
-
await writeClipboardText(await response.text());
|
|
433
|
-
markCopied("copy");
|
|
434
|
-
closeMenu();
|
|
435
|
-
};
|
|
436
|
-
const copyMcp = async () => {
|
|
437
|
-
await writeClipboardText(new URL(documentationPublicPath(data.basePath, "/mcp"), window.location.origin).toString());
|
|
438
|
-
markCopied("mcp");
|
|
439
|
-
closeMenu();
|
|
440
|
-
};
|
|
441
|
-
const copyMcpInstall = async () => {
|
|
442
|
-
const mcpUrl = new URL(documentationPublicPath(data.basePath, "/mcp"), window.location.origin).toString();
|
|
443
|
-
await writeClipboardText(`npx add-mcp ${mcpUrl}`);
|
|
444
|
-
markCopied("add-mcp");
|
|
445
|
-
closeMenu();
|
|
446
|
-
};
|
|
447
|
-
const closeMenu = () => {
|
|
448
|
-
const details = detailsRef.current;
|
|
449
|
-
if (!details?.open) return;
|
|
450
|
-
details.open = false;
|
|
451
|
-
details.querySelector("summary")?.focus();
|
|
452
|
-
};
|
|
453
|
-
const openAiContext = (provider) => {
|
|
454
|
-
const markdownUrl = new URL(data.page.markdownUrl, window.location.origin).toString();
|
|
455
|
-
const prompt = `Use ${markdownUrl} as context. Explain ${data.page.title} and answer my questions about this documentation page.`;
|
|
456
|
-
const destination = new URL(provider === "chatgpt" ? "https://chatgpt.com/" : "https://claude.ai/new");
|
|
457
|
-
destination.searchParams.set("q", prompt);
|
|
458
|
-
window.open(destination.toString(), "_blank", "noopener,noreferrer");
|
|
459
|
-
closeMenu();
|
|
460
|
-
};
|
|
461
|
-
const openMcpEditor = (editor) => {
|
|
462
|
-
const mcpUrl = new URL(documentationPublicPath(data.basePath, "/mcp"), window.location.origin).toString();
|
|
463
|
-
const name = data.config.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "") || "documentation";
|
|
464
|
-
if (editor === "cursor") {
|
|
465
|
-
const config = window.btoa(JSON.stringify({ url: mcpUrl }));
|
|
466
|
-
window.location.href = `cursor://anysphere.cursor-deeplink/mcp/install?name=${encodeURIComponent(name)}&config=${encodeURIComponent(config)}`;
|
|
467
|
-
} else {
|
|
468
|
-
const config = encodeURIComponent(JSON.stringify({ name, type: "http", url: mcpUrl }));
|
|
469
|
-
window.location.href = `vscode:mcp/install?${config}`;
|
|
470
|
-
}
|
|
471
|
-
closeMenu();
|
|
472
|
-
};
|
|
473
|
-
const content = (icon, label, description, menuItem, external = false) => menuItem ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
474
|
-
/* @__PURE__ */ jsx3("span", { className: "documentation-contextual-action-icon", children: icon }),
|
|
475
|
-
/* @__PURE__ */ jsxs3("span", { className: "documentation-contextual-action-copy", children: [
|
|
476
|
-
/* @__PURE__ */ jsx3("strong", { children: label }),
|
|
477
|
-
/* @__PURE__ */ jsx3("small", { children: description })
|
|
478
|
-
] }),
|
|
479
|
-
external && /* @__PURE__ */ jsx3(ExternalIcon, { className: "documentation-contextual-action-external" })
|
|
480
|
-
] }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
481
|
-
icon,
|
|
482
|
-
label
|
|
483
|
-
] });
|
|
484
|
-
const renderAction = (action, menuItem = false) => {
|
|
485
|
-
const role = menuItem ? "menuitem" : void 0;
|
|
486
|
-
if (action === "view") {
|
|
487
|
-
return /* @__PURE__ */ jsx3("a", { href: data.page.markdownUrl, onClick: closeMenu, role, children: content(/* @__PURE__ */ jsx3(FileIcon, {}), "View as Markdown", "Open the raw Markdown page", menuItem) }, action);
|
|
488
|
-
}
|
|
489
|
-
if (action === "assistant") {
|
|
490
|
-
return /* @__PURE__ */ jsx3("button", { role, type: "button", onClick: () => {
|
|
491
|
-
closeMenu();
|
|
492
|
-
onAssistantOpen(`Explain the key ideas on ${data.page.title}.`);
|
|
493
|
-
}, children: content(/* @__PURE__ */ jsx3(OrbitMark, {}), "Ask about this page", "Use the DeepSpace agent with page context", menuItem) }, action);
|
|
494
|
-
}
|
|
495
|
-
if (action === "chatgpt" || action === "claude") {
|
|
496
|
-
const label2 = action === "chatgpt" ? "Open in ChatGPT" : "Open in Claude";
|
|
497
|
-
return /* @__PURE__ */ jsx3("button", { role, type: "button", onClick: () => openAiContext(action), children: content(/* @__PURE__ */ jsx3(MessageIcon, {}), label2, "Ask questions about this page", menuItem, true) }, action);
|
|
498
|
-
}
|
|
499
|
-
if (action === "mcp") {
|
|
500
|
-
const label2 = copied === action ? "MCP URL copied" : "Copy MCP server URL";
|
|
501
|
-
return /* @__PURE__ */ jsx3("button", { role, type: "button", onClick: copyMcp, children: content(copied === action ? /* @__PURE__ */ jsx3(CheckIcon, {}) : /* @__PURE__ */ jsx3(CopyIcon, {}), label2, "Copy the same-release documentation endpoint", menuItem) }, action);
|
|
502
|
-
}
|
|
503
|
-
if (action === "add-mcp") {
|
|
504
|
-
const label2 = copied === action ? "Install command copied" : "Copy MCP install command";
|
|
505
|
-
return /* @__PURE__ */ jsx3("button", { role, type: "button", onClick: copyMcpInstall, children: content(copied === action ? /* @__PURE__ */ jsx3(CheckIcon, {}) : /* @__PURE__ */ jsx3(TerminalIcon, {}), label2, "Copy npx command to install MCP server", menuItem) }, action);
|
|
506
|
-
}
|
|
507
|
-
if (action === "cursor" || action === "vscode") {
|
|
508
|
-
const label2 = action === "cursor" ? "Connect to Cursor" : "Connect to VS Code";
|
|
509
|
-
return /* @__PURE__ */ jsx3("button", { role, type: "button", onClick: () => openMcpEditor(action), children: content(/* @__PURE__ */ jsx3(EditorIcon, {}), label2, `Install MCP server in ${action === "cursor" ? "Cursor" : "VS Code"}`, menuItem, true) }, action);
|
|
510
|
-
}
|
|
511
|
-
const label = copied === action ? "Page copied" : "Copy page";
|
|
512
|
-
return /* @__PURE__ */ jsx3("button", { role, type: "button", onClick: copyPage, children: content(copied === action ? /* @__PURE__ */ jsx3(CheckIcon, {}) : /* @__PURE__ */ jsx3(CopyIcon, {}), label, "Copy page as Markdown for LLMs", menuItem) }, action);
|
|
513
|
-
};
|
|
514
|
-
return /* @__PURE__ */ jsxs3("div", { className: "documentation-contextual-actions", "aria-label": "Page actions", children: [
|
|
515
|
-
/* @__PURE__ */ jsx3("div", { className: "documentation-contextual-primary", "aria-live": "polite", children: renderAction(primary) }),
|
|
516
|
-
actions.length > 0 && /* @__PURE__ */ jsxs3("details", { ref: detailsRef, children: [
|
|
517
|
-
/* @__PURE__ */ jsx3("summary", { "aria-label": "More page actions", children: /* @__PURE__ */ jsx3(ChevronDownIcon, {}) }),
|
|
518
|
-
/* @__PURE__ */ jsx3("div", { "aria-label": "More page actions", className: "documentation-contextual-menu", role: "menu", children: actions.map((action) => renderAction(action, true)) })
|
|
519
|
-
] })
|
|
520
|
-
] });
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
// src/documentation/runtime/article.tsx
|
|
524
|
-
import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
525
|
-
var HTML_PROSE_SCOPE = '.documentation-prose[data-prose="html"]';
|
|
526
|
-
function Article({
|
|
527
|
-
children,
|
|
528
|
-
data,
|
|
529
|
-
launcher,
|
|
530
|
-
onAssistantOpen
|
|
531
|
-
}) {
|
|
532
|
-
const articleRef = useRef3(null);
|
|
533
|
-
const codeBlocks = useCodeBlockMounts(articleRef, data.page.route);
|
|
534
|
-
useArticleEnhancements(articleRef, data);
|
|
535
|
-
const controls = useMemo(() => ({
|
|
536
|
-
assistantEnabled: data.config.assistant.access !== "disabled",
|
|
537
|
-
onAsk: (code) => onAssistantOpen(`Explain this ${data.page.title} example and the important details:
|
|
538
|
-
|
|
539
|
-
${code}`)
|
|
540
|
-
}), [data.config.assistant.access, data.page.title, onAssistantOpen]);
|
|
541
|
-
return /* @__PURE__ */ jsxs4("article", { className: "documentation-article", ref: articleRef, children: [
|
|
542
|
-
/* @__PURE__ */ jsx4(Breadcrumbs, { items: data.breadcrumbs }),
|
|
543
|
-
/* @__PURE__ */ jsxs4("header", { className: "documentation-article-header", children: [
|
|
544
|
-
/* @__PURE__ */ jsxs4("div", { className: "documentation-article-meta", children: [
|
|
545
|
-
data.config.theme.eyebrowStyle !== "none" && /* @__PURE__ */ jsx4("div", { className: "documentation-eyebrow", children: data.page.kind === "openapi" ? "API reference" : data.config.theme.eyebrowStyle === "breadcrumbs" ? data.breadcrumbs.join(" / ") : data.breadcrumbs[0] ?? "Documentation" }),
|
|
546
|
-
/* @__PURE__ */ jsx4(PageActions, { data, onAssistantOpen })
|
|
547
|
-
] }),
|
|
548
|
-
/* @__PURE__ */ jsx4("h1", { children: data.page.title }),
|
|
549
|
-
data.page.description && /* @__PURE__ */ jsx4("p", { className: "documentation-lede", children: data.page.description })
|
|
550
|
-
] }),
|
|
551
|
-
/* @__PURE__ */ jsx4(OutlineDisclosure, { headings: outlineHeadings(data.page.headings) }),
|
|
552
|
-
/* @__PURE__ */ jsxs4(CodeBlockControlsProvider, { value: controls, children: [
|
|
553
|
-
children ?? /* @__PURE__ */ jsx4(
|
|
554
|
-
"div",
|
|
555
|
-
{
|
|
556
|
-
className: "documentation-prose",
|
|
557
|
-
"data-prose": "html",
|
|
558
|
-
dangerouslySetInnerHTML: { __html: data.page.html }
|
|
559
|
-
}
|
|
560
|
-
),
|
|
561
|
-
codeBlocks.map((mount) => createPortal(
|
|
562
|
-
/* @__PURE__ */ jsx4(CodeBlockActions, { readCode: () => readPreText(mount.pre) }),
|
|
563
|
-
mount.host,
|
|
564
|
-
mount.key
|
|
565
|
-
))
|
|
566
|
-
] }),
|
|
567
|
-
data.page.openapi?.playground && /* @__PURE__ */ jsx4(ApiPlayground, { operation: data.page.openapi }),
|
|
568
|
-
launcher && /* @__PURE__ */ jsx4("div", { className: "documentation-launcher-dock", children: launcher }),
|
|
569
|
-
/* @__PURE__ */ jsxs4("nav", { className: "documentation-pagination", "aria-label": "Page navigation", children: [
|
|
570
|
-
data.previous ? /* @__PURE__ */ jsxs4("a", { rel: "prev", href: documentationPublicPath(data.basePath, data.previous.route), children: [
|
|
571
|
-
/* @__PURE__ */ jsx4("small", { children: "Previous" }),
|
|
572
|
-
/* @__PURE__ */ jsxs4("span", { children: [
|
|
573
|
-
/* @__PURE__ */ jsx4(ChevronRightIcon, { className: "is-back" }),
|
|
574
|
-
data.previous.title
|
|
575
|
-
] })
|
|
576
|
-
] }) : /* @__PURE__ */ jsx4("span", {}),
|
|
577
|
-
data.next ? /* @__PURE__ */ jsxs4("a", { rel: "next", href: documentationPublicPath(data.basePath, data.next.route), children: [
|
|
578
|
-
/* @__PURE__ */ jsx4("small", { children: "Next" }),
|
|
579
|
-
/* @__PURE__ */ jsxs4("span", { children: [
|
|
580
|
-
data.next.title,
|
|
581
|
-
/* @__PURE__ */ jsx4(ChevronRightIcon, {})
|
|
582
|
-
] })
|
|
583
|
-
] }) : /* @__PURE__ */ jsx4("span", {})
|
|
584
|
-
] })
|
|
585
|
-
] });
|
|
586
|
-
}
|
|
587
|
-
function Breadcrumbs({ items }) {
|
|
588
|
-
return /* @__PURE__ */ jsx4("nav", { className: "documentation-breadcrumbs", "aria-label": "Breadcrumb", children: items.map((item, index) => /* @__PURE__ */ jsxs4("span", { children: [
|
|
589
|
-
index > 0 && /* @__PURE__ */ jsx4(ChevronRightIcon, {}),
|
|
590
|
-
item
|
|
591
|
-
] }, `${item}:${items.slice(0, index + 1).join("/")}`)) });
|
|
592
|
-
}
|
|
593
|
-
function outlineHeadings(headings) {
|
|
594
|
-
return headings.filter((heading) => heading.depth === 2 || heading.depth === 3);
|
|
595
|
-
}
|
|
596
|
-
function OutlineLinks({
|
|
597
|
-
active,
|
|
598
|
-
headings
|
|
599
|
-
}) {
|
|
600
|
-
return /* @__PURE__ */ jsx4(Fragment3, { children: headings.map((heading) => /* @__PURE__ */ jsx4(
|
|
601
|
-
"a",
|
|
602
|
-
{
|
|
603
|
-
"aria-current": active === heading.id ? "location" : void 0,
|
|
604
|
-
className: `${heading.depth === 3 ? "depth-3 " : ""}${active === heading.id ? "is-active" : ""}`,
|
|
605
|
-
href: `#${heading.id}`,
|
|
606
|
-
children: heading.text
|
|
607
|
-
},
|
|
608
|
-
heading.id
|
|
609
|
-
)) });
|
|
610
|
-
}
|
|
611
|
-
function OutlineDisclosure({ headings }) {
|
|
612
|
-
if (headings.length === 0) return null;
|
|
613
|
-
return /* @__PURE__ */ jsxs4("details", { className: "documentation-outline-disclosure", children: [
|
|
614
|
-
/* @__PURE__ */ jsxs4("summary", { children: [
|
|
615
|
-
/* @__PURE__ */ jsx4(ListIcon, {}),
|
|
616
|
-
"On this page"
|
|
617
|
-
] }),
|
|
618
|
-
/* @__PURE__ */ jsx4("nav", { className: "documentation-outline", "aria-label": "On this page", children: /* @__PURE__ */ jsx4(OutlineLinks, { active: "", headings }) })
|
|
619
|
-
] });
|
|
620
|
-
}
|
|
621
|
-
function ContextRail({
|
|
622
|
-
data
|
|
623
|
-
}) {
|
|
624
|
-
const headings = useMemo(() => outlineHeadings(data.page.headings), [data.page.headings]);
|
|
625
|
-
const [active, setActive] = useState3(headings[0]?.id ?? "");
|
|
626
|
-
useEffect3(() => setActive(headings[0]?.id ?? ""), [headings]);
|
|
627
|
-
useEffect3(() => {
|
|
628
|
-
let frame = null;
|
|
629
|
-
const measure = () => {
|
|
630
|
-
frame = null;
|
|
631
|
-
const root = document.documentElement;
|
|
632
|
-
const clearance = (Number.parseFloat(getComputedStyle(root).scrollPaddingTop) || 96) + 4;
|
|
633
|
-
const scrollable = root.scrollHeight > window.innerHeight + 4;
|
|
634
|
-
const atBottom = scrollable && window.innerHeight + window.scrollY >= root.scrollHeight - 2;
|
|
635
|
-
let next = headings[0]?.id ?? "";
|
|
636
|
-
for (const heading of headings) {
|
|
637
|
-
const element = document.getElementById(heading.id);
|
|
638
|
-
if (!element) continue;
|
|
639
|
-
if (element.getBoundingClientRect().top <= clearance) next = heading.id;
|
|
640
|
-
else break;
|
|
641
|
-
}
|
|
642
|
-
if (atBottom) {
|
|
643
|
-
const hashId = decodeURIComponent(window.location.hash.slice(1));
|
|
644
|
-
if (hashId && headings.some((heading) => heading.id === hashId)) {
|
|
645
|
-
const top = document.getElementById(hashId)?.getBoundingClientRect().top;
|
|
646
|
-
if (top !== void 0 && top > clearance && top < window.innerHeight) next = hashId;
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
setActive(next);
|
|
650
|
-
};
|
|
651
|
-
const schedule = () => {
|
|
652
|
-
if (frame === null) frame = window.requestAnimationFrame(measure);
|
|
653
|
-
};
|
|
654
|
-
const onOutlineClick = (event) => {
|
|
655
|
-
if (event.target instanceof Element && event.target.closest(".documentation-outline a")) {
|
|
656
|
-
window.setTimeout(schedule, 0);
|
|
657
|
-
}
|
|
658
|
-
};
|
|
659
|
-
measure();
|
|
660
|
-
window.addEventListener("scroll", schedule, { passive: true });
|
|
661
|
-
window.addEventListener("resize", schedule, { passive: true });
|
|
662
|
-
window.addEventListener("popstate", schedule);
|
|
663
|
-
window.addEventListener("hashchange", schedule);
|
|
664
|
-
document.addEventListener("click", onOutlineClick);
|
|
665
|
-
return () => {
|
|
666
|
-
window.removeEventListener("scroll", schedule);
|
|
667
|
-
window.removeEventListener("resize", schedule);
|
|
668
|
-
window.removeEventListener("popstate", schedule);
|
|
669
|
-
window.removeEventListener("hashchange", schedule);
|
|
670
|
-
document.removeEventListener("click", onOutlineClick);
|
|
671
|
-
if (frame !== null) window.cancelAnimationFrame(frame);
|
|
672
|
-
};
|
|
673
|
-
}, [headings]);
|
|
674
|
-
return /* @__PURE__ */ jsx4("aside", { className: "documentation-context-rail", "aria-label": "Page context", children: headings.length > 0 && /* @__PURE__ */ jsxs4("nav", { className: "documentation-outline", "aria-label": "On this page", children: [
|
|
675
|
-
/* @__PURE__ */ jsx4("h2", { children: "On this page" }),
|
|
676
|
-
/* @__PURE__ */ jsx4(OutlineLinks, { active, headings })
|
|
677
|
-
] }) });
|
|
678
|
-
}
|
|
679
|
-
function ApiPlayground({ operation }) {
|
|
680
|
-
const [body, setBody] = useState3("");
|
|
681
|
-
const [token, setToken] = useState3("");
|
|
682
|
-
const [responseText, setResponseText] = useState3("No request sent.");
|
|
683
|
-
const [sending, setSending] = useState3(false);
|
|
684
|
-
if (!operation.baseUrl) return null;
|
|
685
|
-
const url = `${operation.baseUrl.replace(/\/$/, "")}${operation.path}`;
|
|
686
|
-
const send = async () => {
|
|
687
|
-
setSending(true);
|
|
688
|
-
setResponseText("Sending request\u2026");
|
|
689
|
-
try {
|
|
690
|
-
const headers = {};
|
|
691
|
-
if (token) headers.Authorization = `Bearer ${token}`;
|
|
692
|
-
if (body.trim()) headers["Content-Type"] = "application/json";
|
|
693
|
-
const response = await fetch(url, {
|
|
694
|
-
method: operation.method,
|
|
695
|
-
headers,
|
|
696
|
-
body: ["GET", "HEAD"].includes(operation.method) ? void 0 : body.trim() || void 0
|
|
697
|
-
});
|
|
698
|
-
const text = await response.text();
|
|
699
|
-
setResponseText(`${response.status} ${response.statusText}
|
|
700
|
-
|
|
701
|
-
${text}`);
|
|
702
|
-
} catch (error) {
|
|
703
|
-
setResponseText(errorMessage(error));
|
|
704
|
-
} finally {
|
|
705
|
-
setSending(false);
|
|
706
|
-
}
|
|
707
|
-
};
|
|
708
|
-
return /* @__PURE__ */ jsxs4("section", { className: "documentation-playground", "data-playground": true, children: [
|
|
709
|
-
/* @__PURE__ */ jsxs4("div", { className: "documentation-playground-title", children: [
|
|
710
|
-
/* @__PURE__ */ jsxs4("div", { children: [
|
|
711
|
-
/* @__PURE__ */ jsx4("span", { className: `method method-${operation.method.toLowerCase()}`, children: operation.method }),
|
|
712
|
-
/* @__PURE__ */ jsx4("strong", { children: "Try this operation" })
|
|
713
|
-
] }),
|
|
714
|
-
/* @__PURE__ */ jsx4("code", { children: url })
|
|
715
|
-
] }),
|
|
716
|
-
/* @__PURE__ */ jsx4("p", { children: "Requests run in your browser. Tokens stay in memory and never enter search or assistant context." }),
|
|
717
|
-
/* @__PURE__ */ jsxs4("label", { children: [
|
|
718
|
-
/* @__PURE__ */ jsx4("span", { children: "Bearer token" }),
|
|
719
|
-
/* @__PURE__ */ jsx4("input", { type: "password", autoCapitalize: "none", autoComplete: "off", autoCorrect: "off", spellCheck: false, value: token, onChange: (event) => setToken(event.target.value), placeholder: "Optional" })
|
|
720
|
-
] }),
|
|
721
|
-
/* @__PURE__ */ jsxs4("label", { children: [
|
|
722
|
-
/* @__PURE__ */ jsx4("span", { children: "JSON body" }),
|
|
723
|
-
/* @__PURE__ */ jsx4("textarea", { rows: 7, autoCapitalize: "none", autoComplete: "off", autoCorrect: "off", spellCheck: false, value: body, onChange: (event) => setBody(event.target.value), placeholder: "{}" })
|
|
724
|
-
] }),
|
|
725
|
-
/* @__PURE__ */ jsx4("button", { type: "button", disabled: sending, onClick: send, children: sending ? "Sending\u2026" : `Send ${operation.method} request` }),
|
|
726
|
-
/* @__PURE__ */ jsx4("pre", { "aria-live": "polite", children: responseText })
|
|
727
|
-
] });
|
|
728
|
-
}
|
|
729
|
-
function useCodeBlockMounts(articleRef, route) {
|
|
730
|
-
const [mounts, setMounts] = useState3([]);
|
|
731
|
-
useEffect3(() => {
|
|
732
|
-
const article = articleRef.current;
|
|
733
|
-
if (!article) return;
|
|
734
|
-
const created = [];
|
|
735
|
-
const next = [];
|
|
736
|
-
article.querySelectorAll(HTML_PROSE_SCOPE + " pre").forEach((pre, index) => {
|
|
737
|
-
const block = document.createElement("div");
|
|
738
|
-
block.className = "documentation-code-block";
|
|
739
|
-
pre.replaceWith(block);
|
|
740
|
-
block.appendChild(pre);
|
|
741
|
-
const title = pre.getAttribute("data-code-title");
|
|
742
|
-
if (title && !block.closest("[data-tab-group]")) {
|
|
743
|
-
const bar = document.createElement("div");
|
|
744
|
-
bar.className = "documentation-code-title";
|
|
745
|
-
bar.textContent = title;
|
|
746
|
-
block.insertBefore(bar, pre);
|
|
747
|
-
}
|
|
748
|
-
const host = document.createElement("div");
|
|
749
|
-
host.className = "documentation-code-actions";
|
|
750
|
-
const language = codeBlockLanguage(pre.querySelector("code")?.className ?? "");
|
|
751
|
-
if (language) {
|
|
752
|
-
const label = document.createElement("span");
|
|
753
|
-
label.className = "documentation-code-language";
|
|
754
|
-
label.textContent = language;
|
|
755
|
-
host.appendChild(label);
|
|
756
|
-
}
|
|
757
|
-
block.appendChild(host);
|
|
758
|
-
created.push({ block, pre });
|
|
759
|
-
next.push({ key: `${route}:${index}`, host, pre });
|
|
760
|
-
});
|
|
761
|
-
setMounts(next);
|
|
762
|
-
return () => {
|
|
763
|
-
setMounts([]);
|
|
764
|
-
for (const { block, pre } of created) block.replaceWith(pre);
|
|
765
|
-
};
|
|
766
|
-
}, [articleRef, route]);
|
|
767
|
-
return mounts;
|
|
768
|
-
}
|
|
769
|
-
function readPreText(pre) {
|
|
770
|
-
return pre.querySelector("code")?.textContent ?? pre.textContent ?? "";
|
|
771
|
-
}
|
|
772
|
-
function useArticleEnhancements(articleRef, data) {
|
|
773
|
-
useEffect3(() => {
|
|
774
|
-
const article = articleRef.current;
|
|
775
|
-
if (!article) return;
|
|
776
|
-
const cleanups = [];
|
|
777
|
-
article.querySelectorAll(`${HTML_PROSE_SCOPE} [data-tab-group]`).forEach((group, groupIndex) => {
|
|
778
|
-
if (group.querySelector(":scope > .documentation-tab-buttons")) return;
|
|
779
|
-
const tabs = Array.from(group.querySelectorAll(":scope > [data-tab]"));
|
|
780
|
-
if (tabs.length === 0) return;
|
|
781
|
-
const controls = document.createElement("div");
|
|
782
|
-
controls.className = "documentation-tab-buttons";
|
|
783
|
-
controls.setAttribute("role", "tablist");
|
|
784
|
-
const labels = tabs.map((tab, tabIndex) => tab.dataset.tabTitle ?? `Tab ${tabIndex + 1}`);
|
|
785
|
-
const activate = (activeIndex, broadcast = false) => {
|
|
786
|
-
tabs.forEach((tab, index) => {
|
|
787
|
-
tab.hidden = index !== activeIndex;
|
|
788
|
-
tab.setAttribute("role", "tabpanel");
|
|
789
|
-
});
|
|
790
|
-
Array.from(controls.querySelectorAll("button")).forEach((button, index) => {
|
|
791
|
-
button.setAttribute("aria-selected", index === activeIndex ? "true" : "false");
|
|
792
|
-
button.setAttribute("tabindex", index === activeIndex ? "0" : "-1");
|
|
793
|
-
});
|
|
794
|
-
if (broadcast) {
|
|
795
|
-
const label = labels[activeIndex];
|
|
796
|
-
if (label) {
|
|
797
|
-
safeStorageSet("deepspace-documentation-tab-selection", label);
|
|
798
|
-
document.dispatchEvent(new CustomEvent("deepspace-documentation-tab-change", {
|
|
799
|
-
detail: { label, source: group }
|
|
800
|
-
}));
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
};
|
|
804
|
-
tabs.forEach((tab, tabIndex) => {
|
|
805
|
-
const button = document.createElement("button");
|
|
806
|
-
button.type = "button";
|
|
807
|
-
button.id = `documentation-tab-${groupIndex}-${tabIndex}`;
|
|
808
|
-
button.setAttribute("role", "tab");
|
|
809
|
-
button.textContent = labels[tabIndex];
|
|
810
|
-
tab.setAttribute("aria-labelledby", button.id);
|
|
811
|
-
const click = () => activate(tabIndex, true);
|
|
812
|
-
const keydown = (event) => {
|
|
813
|
-
if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) return;
|
|
814
|
-
event.preventDefault();
|
|
815
|
-
const next = event.key === "Home" ? 0 : event.key === "End" ? tabs.length - 1 : (tabIndex + (event.key === "ArrowRight" ? 1 : -1) + tabs.length) % tabs.length;
|
|
816
|
-
activate(next);
|
|
817
|
-
controls.querySelectorAll("button")[next]?.focus();
|
|
818
|
-
};
|
|
819
|
-
button.addEventListener("click", click);
|
|
820
|
-
button.addEventListener("keydown", keydown);
|
|
821
|
-
controls.appendChild(button);
|
|
822
|
-
cleanups.push(() => {
|
|
823
|
-
button.removeEventListener("click", click);
|
|
824
|
-
button.removeEventListener("keydown", keydown);
|
|
825
|
-
});
|
|
826
|
-
});
|
|
827
|
-
const title = group.querySelector(":scope > .documentation-code-group-title");
|
|
828
|
-
if (title) group.insertBefore(controls, title.nextSibling);
|
|
829
|
-
if (!title) group.insertBefore(controls, group.firstChild);
|
|
830
|
-
const sync = (event) => {
|
|
831
|
-
const detail = event.detail;
|
|
832
|
-
if (!detail?.label || detail.source === group) return;
|
|
833
|
-
const matchingIndex = labels.findIndex((label) => label === detail.label);
|
|
834
|
-
if (matchingIndex >= 0) activate(matchingIndex);
|
|
835
|
-
};
|
|
836
|
-
document.addEventListener("deepspace-documentation-tab-change", sync);
|
|
837
|
-
const stored = safeStorageGet("deepspace-documentation-tab-selection");
|
|
838
|
-
const initial = stored ? labels.findIndex((label) => label === stored) : -1;
|
|
839
|
-
activate(initial >= 0 ? initial : 0);
|
|
840
|
-
cleanups.push(() => {
|
|
841
|
-
document.removeEventListener("deepspace-documentation-tab-change", sync);
|
|
842
|
-
controls.remove();
|
|
843
|
-
});
|
|
844
|
-
});
|
|
845
|
-
return () => cleanups.reverse().forEach((cleanup) => cleanup());
|
|
846
|
-
}, [articleRef, data.page.route]);
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
// src/documentation/runtime/assistant.tsx
|
|
850
|
-
import {
|
|
851
|
-
useEffect as useEffect5,
|
|
852
|
-
useRef as useRef4,
|
|
853
|
-
useState as useState4
|
|
854
|
-
} from "react";
|
|
855
|
-
|
|
856
|
-
// src/client/ai-stream.ts
|
|
857
|
-
function parseSseLine(line) {
|
|
858
|
-
if (!line) return null;
|
|
859
|
-
if (line.startsWith(":")) return null;
|
|
860
|
-
if (!line.startsWith("data:")) return null;
|
|
861
|
-
const raw = line.slice(5).replace(/^ /, "").replace(/\r$/, "");
|
|
862
|
-
if (raw === "[DONE]") return null;
|
|
863
|
-
try {
|
|
864
|
-
const parsed = JSON.parse(raw);
|
|
865
|
-
if (!parsed || typeof parsed !== "object") return null;
|
|
866
|
-
return parsed;
|
|
867
|
-
} catch {
|
|
868
|
-
return null;
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
// src/documentation/text.ts
|
|
873
|
-
function documentationSubject(name) {
|
|
874
|
-
const normalized = name.trim();
|
|
875
|
-
if (!normalized || /^documentation$/i.test(normalized)) return "documentation";
|
|
876
|
-
return /(?:\bdocs?|documentation)$/i.test(normalized) ? normalized : `${normalized} documentation`;
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
// src/documentation/runtime/assistant-transcript.ts
|
|
880
|
-
function completedDocumentationAssistantTranscript(messages, maxMessages = 12) {
|
|
881
|
-
const pairs = [];
|
|
882
|
-
for (let index = 0; index < messages.length - 1; index += 1) {
|
|
883
|
-
const user = messages[index];
|
|
884
|
-
if (user?.role !== "user" || user.state !== void 0 || !user.text.trim()) continue;
|
|
885
|
-
const assistant = messages[index + 1];
|
|
886
|
-
if (assistant?.role !== "assistant" || assistant.state !== void 0 || !assistant.text.trim()) {
|
|
887
|
-
continue;
|
|
888
|
-
}
|
|
889
|
-
pairs.push([
|
|
890
|
-
{ role: "user", content: user.text },
|
|
891
|
-
{ role: "assistant", content: assistant.text }
|
|
892
|
-
]);
|
|
893
|
-
index += 1;
|
|
894
|
-
}
|
|
895
|
-
const pairLimit = Math.max(0, Math.floor(maxMessages / 2));
|
|
896
|
-
if (pairLimit === 0) return [];
|
|
897
|
-
return pairs.slice(-pairLimit).flat();
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
// src/documentation/runtime/dialog.ts
|
|
901
|
-
import { useEffect as useEffect4 } from "react";
|
|
902
|
-
function useDialogFocus(open, ref, onClose, trap = true, restoreId) {
|
|
903
|
-
useEffect4(() => {
|
|
904
|
-
if (!open) return;
|
|
905
|
-
const previous = document.activeElement;
|
|
906
|
-
const element = ref.current;
|
|
907
|
-
const frame = window.requestAnimationFrame(() => {
|
|
908
|
-
const target = element?.querySelector("[data-autofocus]") ?? element?.querySelector("button,a,input,textarea");
|
|
909
|
-
target?.focus();
|
|
910
|
-
});
|
|
911
|
-
const keydown = (event) => {
|
|
912
|
-
if (event.key === "Escape") {
|
|
913
|
-
event.preventDefault();
|
|
914
|
-
onClose();
|
|
915
|
-
return;
|
|
916
|
-
}
|
|
917
|
-
if (!trap || event.key !== "Tab" || !element) return;
|
|
918
|
-
const focusable = Array.from(element.querySelectorAll(
|
|
919
|
-
'a[href],button:not([disabled]),input:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])'
|
|
920
|
-
));
|
|
921
|
-
if (focusable.length === 0) return;
|
|
922
|
-
const first = focusable[0];
|
|
923
|
-
const last = focusable[focusable.length - 1];
|
|
924
|
-
if (event.shiftKey && document.activeElement === first) {
|
|
925
|
-
event.preventDefault();
|
|
926
|
-
last?.focus();
|
|
927
|
-
} else if (!event.shiftKey && document.activeElement === last) {
|
|
928
|
-
event.preventDefault();
|
|
929
|
-
first?.focus();
|
|
930
|
-
}
|
|
931
|
-
};
|
|
932
|
-
document.addEventListener("keydown", keydown);
|
|
933
|
-
return () => {
|
|
934
|
-
window.cancelAnimationFrame(frame);
|
|
935
|
-
document.removeEventListener("keydown", keydown);
|
|
936
|
-
const restoreTarget = restoreId ? document.getElementById(restoreId) : previous?.isConnected && previous !== document.body && !element?.contains(previous) ? previous : null;
|
|
937
|
-
restoreTarget?.focus();
|
|
938
|
-
};
|
|
939
|
-
}, [onClose, open, ref, restoreId, trap]);
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
// src/documentation/runtime/assistant.tsx
|
|
943
|
-
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
944
|
-
function AssistantLauncher({
|
|
945
|
-
input,
|
|
946
|
-
name,
|
|
947
|
-
onInputChange,
|
|
948
|
-
onSubmit
|
|
949
|
-
}) {
|
|
950
|
-
const subject = documentationSubject(name);
|
|
951
|
-
const submit = (event) => {
|
|
952
|
-
event.preventDefault();
|
|
953
|
-
const question = input.trim();
|
|
954
|
-
if (!question) return;
|
|
955
|
-
onSubmit(question);
|
|
956
|
-
};
|
|
957
|
-
return /* @__PURE__ */ jsxs5(
|
|
958
|
-
"form",
|
|
959
|
-
{
|
|
960
|
-
className: "documentation-assistant-launcher",
|
|
961
|
-
id: "deepspace-documentation-assistant-launcher",
|
|
962
|
-
onSubmit: submit,
|
|
963
|
-
children: [
|
|
964
|
-
/* @__PURE__ */ jsx5(
|
|
965
|
-
"input",
|
|
966
|
-
{
|
|
967
|
-
"aria-label": `Ask the ${subject} agent`,
|
|
968
|
-
autoCapitalize: "sentences",
|
|
969
|
-
autoComplete: "off",
|
|
970
|
-
autoCorrect: "off",
|
|
971
|
-
enterKeyHint: "send",
|
|
972
|
-
id: "deepspace-documentation-assistant-launcher-input",
|
|
973
|
-
maxLength: 4e3,
|
|
974
|
-
onChange: (event) => onInputChange(event.target.value),
|
|
975
|
-
placeholder: "Ask anything\u2026",
|
|
976
|
-
spellCheck: false,
|
|
977
|
-
value: input
|
|
978
|
-
}
|
|
979
|
-
),
|
|
980
|
-
/* @__PURE__ */ jsxs5("span", { "aria-hidden": "true", className: "documentation-launcher-hint", children: [
|
|
981
|
-
/* @__PURE__ */ jsx5("kbd", { children: "\u2318" }),
|
|
982
|
-
/* @__PURE__ */ jsx5("kbd", { children: "I" })
|
|
983
|
-
] }),
|
|
984
|
-
/* @__PURE__ */ jsx5("button", { className: "documentation-launcher-send", type: "submit", disabled: !input.trim(), "aria-label": "Send question to documentation agent", children: /* @__PURE__ */ jsx5(SendIcon, {}) })
|
|
985
|
-
]
|
|
986
|
-
}
|
|
987
|
-
);
|
|
988
|
-
}
|
|
989
|
-
function DocumentationAssistant({
|
|
990
|
-
access,
|
|
991
|
-
basePath,
|
|
992
|
-
input,
|
|
993
|
-
name,
|
|
994
|
-
onClose,
|
|
995
|
-
onInputChange,
|
|
996
|
-
open,
|
|
997
|
-
route,
|
|
998
|
-
seed,
|
|
999
|
-
suggestions
|
|
1000
|
-
}) {
|
|
1001
|
-
const panelRef = useRef4(null);
|
|
1002
|
-
const formRef = useRef4(null);
|
|
1003
|
-
const messagesRef = useRef4(null);
|
|
1004
|
-
const composerRef = useRef4(null);
|
|
1005
|
-
const abortRef = useRef4(null);
|
|
1006
|
-
const queuedQuestionRef = useRef4(null);
|
|
1007
|
-
const handledSeedRef = useRef4(0);
|
|
1008
|
-
const [messages, setMessages] = useState4([
|
|
1009
|
-
{ id: "welcome", role: "assistant", text: `I can search the ${documentationSubject(name)} and cite the exact pages I use.` }
|
|
1010
|
-
]);
|
|
1011
|
-
const [sending, setSending] = useState4(false);
|
|
1012
|
-
useDialogFocus(open, panelRef, onClose, false, "deepspace-documentation-assistant-launcher-input");
|
|
1013
|
-
useEffect5(() => {
|
|
1014
|
-
if (!open || seed.id === 0 || handledSeedRef.current === seed.id) return;
|
|
1015
|
-
handledSeedRef.current = seed.id;
|
|
1016
|
-
if (!seed.submit || !seed.value?.trim()) return;
|
|
1017
|
-
queuedQuestionRef.current = seed.value;
|
|
1018
|
-
const frame = window.requestAnimationFrame(() => formRef.current?.requestSubmit());
|
|
1019
|
-
return () => window.cancelAnimationFrame(frame);
|
|
1020
|
-
}, [open, seed]);
|
|
1021
|
-
useEffect5(() => {
|
|
1022
|
-
const element = messagesRef.current;
|
|
1023
|
-
if (element) element.scrollTop = element.scrollHeight;
|
|
1024
|
-
}, [messages]);
|
|
1025
|
-
useEffect5(() => {
|
|
1026
|
-
const element = composerRef.current;
|
|
1027
|
-
if (!element) return;
|
|
1028
|
-
element.style.height = "auto";
|
|
1029
|
-
element.style.height = `${Math.min(element.scrollHeight, 160)}px`;
|
|
1030
|
-
element.style.overflowY = element.scrollHeight > 160 ? "auto" : "hidden";
|
|
1031
|
-
}, [input, open]);
|
|
1032
|
-
useEffect5(() => () => abortRef.current?.abort(), []);
|
|
1033
|
-
if (!open) return null;
|
|
1034
|
-
const submit = async (event) => {
|
|
1035
|
-
event?.preventDefault();
|
|
1036
|
-
const question = (queuedQuestionRef.current ?? input).trim();
|
|
1037
|
-
queuedQuestionRef.current = null;
|
|
1038
|
-
if (!question || sending) return;
|
|
1039
|
-
const transcript = completedDocumentationAssistantTranscript(messages);
|
|
1040
|
-
onInputChange("");
|
|
1041
|
-
setSending(true);
|
|
1042
|
-
const userId = `user-${Date.now()}`;
|
|
1043
|
-
const answerId = `assistant-${Date.now()}`;
|
|
1044
|
-
setMessages((current) => [...current, { id: userId, role: "user", text: question }, { id: answerId, role: "assistant", text: "", state: "streaming", status: "Searching this documentation\u2026" }]);
|
|
1045
|
-
const controller = new AbortController();
|
|
1046
|
-
abortRef.current = controller;
|
|
1047
|
-
let timedOut = false;
|
|
1048
|
-
const slowTimer = window.setTimeout(() => {
|
|
1049
|
-
setMessages((current) => current.map((message) => message.id === answerId ? { ...message, status: "Still working through the documentation\u2026" } : message));
|
|
1050
|
-
}, 12e3);
|
|
1051
|
-
const timeoutTimer = window.setTimeout(() => {
|
|
1052
|
-
timedOut = true;
|
|
1053
|
-
controller.abort();
|
|
1054
|
-
}, 12e4);
|
|
1055
|
-
try {
|
|
1056
|
-
const headers = {
|
|
1057
|
-
"Content-Type": "application/json"
|
|
1058
|
-
};
|
|
1059
|
-
if (access === "authenticated") {
|
|
1060
|
-
const tokenResponse = await fetch("/api/auth/token", { method: "POST", credentials: "include", headers: { "Content-Type": "application/json" } });
|
|
1061
|
-
const tokenData = tokenResponse.ok ? await tokenResponse.json().catch(() => null) : null;
|
|
1062
|
-
if (!tokenData?.token) throw new Error("Sign in to use the documentation assistant.");
|
|
1063
|
-
headers.Authorization = `Bearer ${tokenData.token}`;
|
|
1064
|
-
}
|
|
1065
|
-
const response = await fetch(documentationPublicPath(basePath, "/api/ai"), {
|
|
1066
|
-
method: "POST",
|
|
1067
|
-
headers,
|
|
1068
|
-
body: JSON.stringify({ question, route, messages: transcript }),
|
|
1069
|
-
signal: controller.signal
|
|
1070
|
-
});
|
|
1071
|
-
if (!response.ok || !response.body) {
|
|
1072
|
-
const body = await response.json().catch(() => null);
|
|
1073
|
-
throw new Error(body?.error ?? `Assistant unavailable (${response.status})`);
|
|
1074
|
-
}
|
|
1075
|
-
const reader = response.body.getReader();
|
|
1076
|
-
const decoder = new TextDecoder();
|
|
1077
|
-
let buffer = "";
|
|
1078
|
-
let answer = "";
|
|
1079
|
-
const consumeLine = (line) => {
|
|
1080
|
-
const data = parseSseLine(line);
|
|
1081
|
-
if (!data) return;
|
|
1082
|
-
if (data.type === "text-delta" && typeof data.delta === "string") {
|
|
1083
|
-
answer += data.delta;
|
|
1084
|
-
setMessages((current) => current.map((message) => message.id === answerId ? { ...message, text: answer, state: "streaming", status: void 0 } : message));
|
|
1085
|
-
} else if (data.type === "tool-input-available") {
|
|
1086
|
-
const status = data.toolName === "documentation_read" ? "Reading the relevant source pages\u2026" : "Searching this documentation\u2026";
|
|
1087
|
-
setMessages((current) => current.map((message) => message.id === answerId ? { ...message, status } : message));
|
|
1088
|
-
} else if (data.type === "tool-output-available") {
|
|
1089
|
-
setMessages((current) => current.map((message) => message.id === answerId ? { ...message, status: "Reviewing the source material\u2026" } : message));
|
|
1090
|
-
} else if (data.type === "error") {
|
|
1091
|
-
throw new Error(typeof data.errorText === "string" ? data.errorText : "The assistant stream failed.");
|
|
1092
|
-
}
|
|
1093
|
-
};
|
|
1094
|
-
while (true) {
|
|
1095
|
-
const chunk = await reader.read();
|
|
1096
|
-
if (chunk.done) break;
|
|
1097
|
-
buffer += decoder.decode(chunk.value, { stream: true });
|
|
1098
|
-
const lines = buffer.split(/\r?\n/);
|
|
1099
|
-
buffer = lines.pop() ?? "";
|
|
1100
|
-
for (const line of lines) consumeLine(line);
|
|
1101
|
-
}
|
|
1102
|
-
buffer += decoder.decode();
|
|
1103
|
-
consumeLine(buffer);
|
|
1104
|
-
setMessages((current) => current.map((message) => message.id === answerId ? { ...message, text: answer || "No answer was returned.", state: void 0 } : message));
|
|
1105
|
-
} catch (error) {
|
|
1106
|
-
const message = timedOut ? "The documentation search took too long. Try a narrower question." : controller.signal.aborted ? "Response stopped." : errorMessage(error);
|
|
1107
|
-
setMessages((current) => current.map((item) => item.id === answerId ? { ...item, text: message, state: "error" } : item));
|
|
1108
|
-
} finally {
|
|
1109
|
-
window.clearTimeout(slowTimer);
|
|
1110
|
-
window.clearTimeout(timeoutTimer);
|
|
1111
|
-
abortRef.current = null;
|
|
1112
|
-
setSending(false);
|
|
1113
|
-
}
|
|
1114
|
-
};
|
|
1115
|
-
const defaults = suggestions ?? ["How do I get started?", "Show me a complete example", "What should I understand first?"];
|
|
1116
|
-
return /* @__PURE__ */ jsxs5(
|
|
1117
|
-
"aside",
|
|
1118
|
-
{
|
|
1119
|
-
"aria-label": "Documentation assistant",
|
|
1120
|
-
className: "documentation-assistant",
|
|
1121
|
-
id: "deepspace-documentation-assistant",
|
|
1122
|
-
ref: panelRef,
|
|
1123
|
-
role: "complementary",
|
|
1124
|
-
children: [
|
|
1125
|
-
/* @__PURE__ */ jsxs5("header", { children: [
|
|
1126
|
-
/* @__PURE__ */ jsx5("div", { children: /* @__PURE__ */ jsxs5("span", { children: [
|
|
1127
|
-
/* @__PURE__ */ jsxs5("strong", { id: "deepspace-documentation-assistant-title", children: [
|
|
1128
|
-
"Ask ",
|
|
1129
|
-
name
|
|
1130
|
-
] }),
|
|
1131
|
-
/* @__PURE__ */ jsx5("small", { children: "Answers from this documentation build" })
|
|
1132
|
-
] }) }),
|
|
1133
|
-
/* @__PURE__ */ jsx5("button", { type: "button", onClick: onClose, "aria-label": "Close documentation assistant", children: /* @__PURE__ */ jsx5(CloseIcon, {}) })
|
|
1134
|
-
] }),
|
|
1135
|
-
/* @__PURE__ */ jsxs5("div", { className: "documentation-assistant-messages", ref: messagesRef, "aria-live": "polite", children: [
|
|
1136
|
-
messages.map((message) => /* @__PURE__ */ jsx5("div", { className: `documentation-assistant-message is-${message.role}${message.state ? ` is-${message.state}` : ""}`, children: /* @__PURE__ */ jsxs5("div", { children: [
|
|
1137
|
-
message.role === "assistant" ? /* @__PURE__ */ jsx5(AssistantMarkdown, { value: message.text }) : message.text,
|
|
1138
|
-
message.state === "streaming" && !message.text && /* @__PURE__ */ jsxs5("span", { className: "documentation-assistant-activity", role: "status", children: [
|
|
1139
|
-
/* @__PURE__ */ jsx5("span", { "aria-hidden": "true" }),
|
|
1140
|
-
message.status ?? "Working\u2026"
|
|
1141
|
-
] })
|
|
1142
|
-
] }) }, message.id)),
|
|
1143
|
-
messages.length === 1 && /* @__PURE__ */ jsxs5("div", { className: "documentation-assistant-suggestions", children: [
|
|
1144
|
-
/* @__PURE__ */ jsx5("p", { children: "Try asking" }),
|
|
1145
|
-
defaults.map((suggestion) => /* @__PURE__ */ jsx5("button", { type: "button", onClick: () => onInputChange(suggestion), children: suggestion }, suggestion))
|
|
1146
|
-
] })
|
|
1147
|
-
] }),
|
|
1148
|
-
/* @__PURE__ */ jsxs5("form", { className: "documentation-assistant-composer", onSubmit: submit, ref: formRef, children: [
|
|
1149
|
-
/* @__PURE__ */ jsx5(
|
|
1150
|
-
"textarea",
|
|
1151
|
-
{
|
|
1152
|
-
"aria-label": "Ask a documentation question",
|
|
1153
|
-
autoCapitalize: "sentences",
|
|
1154
|
-
autoComplete: "off",
|
|
1155
|
-
autoCorrect: "off",
|
|
1156
|
-
"data-autofocus": true,
|
|
1157
|
-
enterKeyHint: "send",
|
|
1158
|
-
maxLength: 4e3,
|
|
1159
|
-
onChange: (event) => onInputChange(event.target.value),
|
|
1160
|
-
onKeyDown: (event) => {
|
|
1161
|
-
if (event.key === "Enter" && !event.shiftKey) {
|
|
1162
|
-
event.preventDefault();
|
|
1163
|
-
void submit();
|
|
1164
|
-
}
|
|
1165
|
-
},
|
|
1166
|
-
placeholder: "Ask a question about this documentation",
|
|
1167
|
-
ref: composerRef,
|
|
1168
|
-
rows: 1,
|
|
1169
|
-
spellCheck: false,
|
|
1170
|
-
value: input
|
|
1171
|
-
}
|
|
1172
|
-
),
|
|
1173
|
-
sending ? /* @__PURE__ */ jsx5("button", { type: "button", onClick: () => abortRef.current?.abort(), "aria-label": "Stop response", children: /* @__PURE__ */ jsx5(StopIcon, {}) }) : /* @__PURE__ */ jsx5("button", { type: "submit", disabled: !input.trim(), "aria-label": "Send question", children: /* @__PURE__ */ jsx5(SendIcon, {}) })
|
|
1174
|
-
] }),
|
|
1175
|
-
/* @__PURE__ */ jsx5("footer", { children: "Responses cite this deployment and may still contain mistakes." })
|
|
1176
|
-
]
|
|
1177
|
-
}
|
|
1178
|
-
);
|
|
1179
|
-
}
|
|
1180
|
-
function AssistantMarkdown({ value }) {
|
|
1181
|
-
const blocks = [];
|
|
1182
|
-
const fence = /```([^\n`]*)\n([\s\S]*?)(?:```|$)/g;
|
|
1183
|
-
let cursor = 0;
|
|
1184
|
-
for (const match of value.matchAll(fence)) {
|
|
1185
|
-
const index = match.index ?? 0;
|
|
1186
|
-
if (index > cursor) blocks.push(...renderAssistantText(value.slice(cursor, index), `text-${cursor}`));
|
|
1187
|
-
blocks.push(
|
|
1188
|
-
/* @__PURE__ */ jsx5(
|
|
1189
|
-
AssistantCodeBlock,
|
|
1190
|
-
{
|
|
1191
|
-
code: (match[2] ?? "").replace(/\n$/, ""),
|
|
1192
|
-
language: (match[1] ?? "").trim().split(/\s+/, 1)[0] ?? ""
|
|
1193
|
-
},
|
|
1194
|
-
`code-${index}`
|
|
1195
|
-
)
|
|
1196
|
-
);
|
|
1197
|
-
cursor = index + match[0].length;
|
|
1198
|
-
}
|
|
1199
|
-
if (cursor < value.length) blocks.push(...renderAssistantText(value.slice(cursor), `text-${cursor}`));
|
|
1200
|
-
return /* @__PURE__ */ jsx5("div", { className: "documentation-assistant-markdown", children: blocks });
|
|
1201
|
-
}
|
|
1202
|
-
function AssistantCodeBlock({ code, language }) {
|
|
1203
|
-
const [copied, setCopied] = useState4(false);
|
|
1204
|
-
const copy = async () => {
|
|
1205
|
-
await writeClipboardText(code);
|
|
1206
|
-
setCopied(true);
|
|
1207
|
-
window.setTimeout(() => setCopied(false), 1400);
|
|
1208
|
-
};
|
|
1209
|
-
return /* @__PURE__ */ jsxs5("figure", { className: "documentation-assistant-code", children: [
|
|
1210
|
-
/* @__PURE__ */ jsxs5("figcaption", { children: [
|
|
1211
|
-
/* @__PURE__ */ jsx5("span", { children: language || "Code" }),
|
|
1212
|
-
/* @__PURE__ */ jsx5("button", { type: "button", onClick: copy, children: copied ? "Copied" : "Copy" })
|
|
1213
|
-
] }),
|
|
1214
|
-
/* @__PURE__ */ jsx5("pre", { children: /* @__PURE__ */ jsx5("code", { children: code }) })
|
|
1215
|
-
] });
|
|
1216
|
-
}
|
|
1217
|
-
function renderAssistantText(value, keyPrefix) {
|
|
1218
|
-
const lines = value.split("\n");
|
|
1219
|
-
const blocks = [];
|
|
1220
|
-
let index = 0;
|
|
1221
|
-
while (index < lines.length) {
|
|
1222
|
-
const line = lines[index]?.trim() ?? "";
|
|
1223
|
-
if (!line) {
|
|
1224
|
-
index += 1;
|
|
1225
|
-
continue;
|
|
1226
|
-
}
|
|
1227
|
-
const heading = line.match(/^(#{1,4})\s+(.+)$/);
|
|
1228
|
-
if (heading) {
|
|
1229
|
-
blocks.push(/* @__PURE__ */ jsx5("strong", { className: "documentation-assistant-heading", children: renderInlineMarkdown(heading[2]) }, `${keyPrefix}-heading-${index}`));
|
|
1230
|
-
index += 1;
|
|
1231
|
-
continue;
|
|
1232
|
-
}
|
|
1233
|
-
const unordered = /^[-*]\s+/.test(line);
|
|
1234
|
-
const ordered = /^\d+[.)]\s+/.test(line);
|
|
1235
|
-
if (unordered || ordered) {
|
|
1236
|
-
const items = [];
|
|
1237
|
-
while (index < lines.length) {
|
|
1238
|
-
const candidate = lines[index]?.trim() ?? "";
|
|
1239
|
-
const match = unordered ? candidate.match(/^[-*]\s+(.+)$/) : candidate.match(/^\d+[.)]\s+(.+)$/);
|
|
1240
|
-
if (!match) break;
|
|
1241
|
-
items.push(/* @__PURE__ */ jsx5("li", { children: renderInlineMarkdown(match[1]) }, `${keyPrefix}-item-${index}`));
|
|
1242
|
-
index += 1;
|
|
1243
|
-
}
|
|
1244
|
-
blocks.push(unordered ? /* @__PURE__ */ jsx5("ul", { children: items }, `${keyPrefix}-list-${index}`) : /* @__PURE__ */ jsx5("ol", { children: items }, `${keyPrefix}-list-${index}`));
|
|
1245
|
-
continue;
|
|
1246
|
-
}
|
|
1247
|
-
const paragraph = [line];
|
|
1248
|
-
index += 1;
|
|
1249
|
-
while (index < lines.length) {
|
|
1250
|
-
const candidate = lines[index]?.trim() ?? "";
|
|
1251
|
-
if (!candidate || /^(?:#{1,4}\s+|[-*]\s+|\d+[.)]\s+)/.test(candidate)) break;
|
|
1252
|
-
paragraph.push(candidate);
|
|
1253
|
-
index += 1;
|
|
1254
|
-
}
|
|
1255
|
-
blocks.push(/* @__PURE__ */ jsx5("p", { children: paragraph.map((part, partIndex) => /* @__PURE__ */ jsxs5("span", { children: [
|
|
1256
|
-
renderInlineMarkdown(part),
|
|
1257
|
-
partIndex < paragraph.length - 1 && " "
|
|
1258
|
-
] }, `${partIndex}:${part.slice(0, 18)}`)) }, `${keyPrefix}-paragraph-${index}`));
|
|
1259
|
-
}
|
|
1260
|
-
return blocks;
|
|
1261
|
-
}
|
|
1262
|
-
function renderInlineMarkdown(value) {
|
|
1263
|
-
const pattern = /(\[[^\]]+\]\((?:https?:\/\/|\/)[^)]+\)|`[^`]+`|\*\*[^*]+\*\*)/g;
|
|
1264
|
-
return value.split(pattern).filter(Boolean).map((part, index) => {
|
|
1265
|
-
const link = part.match(/^\[([^\]]+)\]\(((?:https?:\/\/|\/)[^)]+)\)$/);
|
|
1266
|
-
if (link) return /* @__PURE__ */ jsx5("a", { href: link[2], ...externalProps(link[2]), children: link[1] }, `${index}:${part}`);
|
|
1267
|
-
if (part.startsWith("`") && part.endsWith("`")) return /* @__PURE__ */ jsx5("code", { children: part.slice(1, -1) }, `${index}:${part}`);
|
|
1268
|
-
if (part.startsWith("**") && part.endsWith("**")) return /* @__PURE__ */ jsx5("strong", { children: part.slice(2, -2) }, `${index}:${part}`);
|
|
1269
|
-
return /* @__PURE__ */ jsx5("span", { children: part }, `${index}:${part}`);
|
|
1270
|
-
});
|
|
1271
|
-
}
|
|
1272
|
-
|
|
1273
|
-
// src/documentation/runtime/navigation.tsx
|
|
1274
|
-
import { useEffect as useEffect6, useRef as useRef5, useState as useState5 } from "react";
|
|
1275
|
-
|
|
1276
|
-
// package.json
|
|
1277
|
-
var version = "0.26.2";
|
|
1278
|
-
|
|
1279
|
-
// src/documentation/runtime/navigation.tsx
|
|
1280
|
-
import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1281
|
-
function DocumentationHeader({
|
|
1282
|
-
data,
|
|
1283
|
-
onMenuOpen,
|
|
1284
|
-
onSearchOpen
|
|
1285
|
-
}) {
|
|
1286
|
-
return /* @__PURE__ */ jsxs6("header", { className: "documentation-header", children: [
|
|
1287
|
-
/* @__PURE__ */ jsx6(
|
|
1288
|
-
"a",
|
|
1289
|
-
{
|
|
1290
|
-
className: "documentation-brand",
|
|
1291
|
-
href: data.config.theme.logoHref ?? documentationPublicPath(data.basePath, "/"),
|
|
1292
|
-
"aria-label": `${documentationSubject(data.config.name)} home`,
|
|
1293
|
-
...externalProps(data.config.theme.logoHref ?? documentationPublicPath(data.basePath, "/")),
|
|
1294
|
-
children: /* @__PURE__ */ jsx6(BrandLogo, { data })
|
|
1295
|
-
}
|
|
1296
|
-
),
|
|
1297
|
-
/* @__PURE__ */ jsx6("div", { className: "documentation-header-center", children: /* @__PURE__ */ jsxs6("button", { className: "documentation-search-trigger", type: "button", onClick: onSearchOpen, "aria-label": "Search documentation", children: [
|
|
1298
|
-
/* @__PURE__ */ jsx6(SearchIcon, {}),
|
|
1299
|
-
/* @__PURE__ */ jsx6("span", { children: "Search documentation" }),
|
|
1300
|
-
/* @__PURE__ */ jsx6("kbd", { children: "\u2318K" })
|
|
1301
|
-
] }) }),
|
|
1302
|
-
/* @__PURE__ */ jsx6("nav", { className: "documentation-top-links", "aria-label": "Product navigation", children: data.config.links.map((link) => /* @__PURE__ */ jsxs6("a", { href: link.href, ...externalProps(link.href), children: [
|
|
1303
|
-
link.label,
|
|
1304
|
-
isExternal(link.href) && /* @__PURE__ */ jsx6(ExternalIcon, {})
|
|
1305
|
-
] }, `${link.label}:${link.href}`)) }),
|
|
1306
|
-
/* @__PURE__ */ jsxs6("div", { className: "documentation-mobile-actions", children: [
|
|
1307
|
-
/* @__PURE__ */ jsx6("button", { className: "documentation-icon-button", type: "button", onClick: onSearchOpen, "aria-label": "Search documentation", children: /* @__PURE__ */ jsx6(SearchIcon, {}) }),
|
|
1308
|
-
/* @__PURE__ */ jsx6("button", { className: "documentation-icon-button", type: "button", onClick: onMenuOpen, "aria-label": "Open documentation navigation", children: /* @__PURE__ */ jsx6(MenuIcon, {}) })
|
|
1309
|
-
] })
|
|
1310
|
-
] });
|
|
1311
|
-
}
|
|
1312
|
-
function BrandLogo({ data }) {
|
|
1313
|
-
const { logo, logoDark } = data.config.theme;
|
|
1314
|
-
if (logo) {
|
|
1315
|
-
return /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1316
|
-
/* @__PURE__ */ jsx6("img", { className: "documentation-brand-logo documentation-brand-logo-light", src: logo, alt: "" }),
|
|
1317
|
-
/* @__PURE__ */ jsx6("img", { className: "documentation-brand-logo documentation-brand-logo-dark", src: logoDark ?? logo, alt: "" }),
|
|
1318
|
-
/* @__PURE__ */ jsx6("span", { className: "documentation-brand-product", children: "Documentation" })
|
|
1319
|
-
] });
|
|
1320
|
-
}
|
|
1321
|
-
return /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1322
|
-
/* @__PURE__ */ jsx6("span", { className: "documentation-brand-mark", children: /* @__PURE__ */ jsx6(OrbitMark, {}) }),
|
|
1323
|
-
/* @__PURE__ */ jsx6("span", { className: "documentation-brand-name", children: data.config.name })
|
|
1324
|
-
] });
|
|
1325
|
-
}
|
|
1326
|
-
function DesktopSidebar({ data }) {
|
|
1327
|
-
return /* @__PURE__ */ jsxs6("aside", { className: "documentation-sidebar", "aria-label": "Documentation navigation", children: [
|
|
1328
|
-
/* @__PURE__ */ jsx6("nav", { className: "documentation-page-tree", children: /* @__PURE__ */ jsx6(NavigationTree, { activeRoute: data.page.route, basePath: data.basePath, nodes: data.navigation }) }),
|
|
1329
|
-
/* @__PURE__ */ jsxs6("div", { className: "documentation-sidebar-footer", children: [
|
|
1330
|
-
!data.config.theme.strictMode && /* @__PURE__ */ jsx6(ThemeControls, { defaultMode: data.config.theme.defaultMode ?? "system" }),
|
|
1331
|
-
data.config.footer.length > 0 && /* @__PURE__ */ jsx6("nav", { "aria-label": "Documentation footer", children: data.config.footer.map((link) => /* @__PURE__ */ jsx6("a", { href: link.href, ...externalProps(link.href), children: link.label }, `${link.label}:${link.href}`)) }),
|
|
1332
|
-
/* @__PURE__ */ jsx6("span", { children: `Built with deepspace ${version}` })
|
|
1333
|
-
] })
|
|
1334
|
-
] });
|
|
1335
|
-
}
|
|
1336
|
-
function NavigationTree({
|
|
1337
|
-
activeRoute,
|
|
1338
|
-
basePath,
|
|
1339
|
-
depth = 0,
|
|
1340
|
-
nodes
|
|
1341
|
-
}) {
|
|
1342
|
-
return /* @__PURE__ */ jsx6(Fragment4, { children: nodes.map((node) => {
|
|
1343
|
-
if (node.kind === "group") {
|
|
1344
|
-
const active2 = containsRoute(node, activeRoute);
|
|
1345
|
-
if (depth === 0) {
|
|
1346
|
-
return /* @__PURE__ */ jsxs6("section", { className: "documentation-nav-section", children: [
|
|
1347
|
-
/* @__PURE__ */ jsx6("h2", { children: node.label }),
|
|
1348
|
-
/* @__PURE__ */ jsx6(NavigationTree, { activeRoute, basePath, depth: depth + 1, nodes: node.items })
|
|
1349
|
-
] }, `group:${node.label}`);
|
|
1350
|
-
}
|
|
1351
|
-
return /* @__PURE__ */ jsxs6("details", { className: "documentation-nav-folder", open: active2, children: [
|
|
1352
|
-
/* @__PURE__ */ jsxs6("summary", { children: [
|
|
1353
|
-
/* @__PURE__ */ jsx6("span", { children: node.label }),
|
|
1354
|
-
/* @__PURE__ */ jsx6(ChevronDownIcon, {})
|
|
1355
|
-
] }),
|
|
1356
|
-
/* @__PURE__ */ jsx6("div", { children: /* @__PURE__ */ jsx6(NavigationTree, { activeRoute, basePath, depth: depth + 1, nodes: node.items }) })
|
|
1357
|
-
] }, `group:${node.label}`);
|
|
1358
|
-
}
|
|
1359
|
-
const href = node.kind === "page" ? documentationPublicPath(basePath, node.route) : node.href;
|
|
1360
|
-
const active = node.kind === "page" && node.route === activeRoute;
|
|
1361
|
-
return /* @__PURE__ */ jsxs6(
|
|
1362
|
-
"a",
|
|
1363
|
-
{
|
|
1364
|
-
"aria-current": active ? "page" : void 0,
|
|
1365
|
-
className: active ? "documentation-nav-link is-active" : "documentation-nav-link",
|
|
1366
|
-
href,
|
|
1367
|
-
...externalProps(href),
|
|
1368
|
-
children: [
|
|
1369
|
-
/* @__PURE__ */ jsx6("span", { children: node.label }),
|
|
1370
|
-
isExternal(href) && /* @__PURE__ */ jsx6(ExternalIcon, {})
|
|
1371
|
-
]
|
|
1372
|
-
},
|
|
1373
|
-
`${node.kind}:${href}`
|
|
1374
|
-
);
|
|
1375
|
-
}) });
|
|
1376
|
-
}
|
|
1377
|
-
function MobileNavigation({
|
|
1378
|
-
data,
|
|
1379
|
-
onClose,
|
|
1380
|
-
open
|
|
1381
|
-
}) {
|
|
1382
|
-
const dialogRef = useRef5(null);
|
|
1383
|
-
useDialogFocus(open, dialogRef, onClose);
|
|
1384
|
-
if (!open) return null;
|
|
1385
|
-
return /* @__PURE__ */ jsx6("div", { className: "documentation-modal-layer", role: "presentation", onMouseDown: (event) => {
|
|
1386
|
-
if (event.currentTarget === event.target) onClose();
|
|
1387
|
-
}, children: /* @__PURE__ */ jsxs6("div", { className: "documentation-mobile-nav", role: "dialog", "aria-modal": "true", "aria-label": "Documentation navigation", ref: dialogRef, children: [
|
|
1388
|
-
/* @__PURE__ */ jsxs6("header", { children: [
|
|
1389
|
-
/* @__PURE__ */ jsx6(
|
|
1390
|
-
"a",
|
|
1391
|
-
{
|
|
1392
|
-
"aria-label": `${documentationSubject(data.config.name)} home`,
|
|
1393
|
-
className: "documentation-brand",
|
|
1394
|
-
href: data.config.theme.logoHref ?? documentationPublicPath(data.basePath, "/"),
|
|
1395
|
-
...externalProps(data.config.theme.logoHref ?? documentationPublicPath(data.basePath, "/")),
|
|
1396
|
-
children: /* @__PURE__ */ jsx6(BrandLogo, { data })
|
|
1397
|
-
}
|
|
1398
|
-
),
|
|
1399
|
-
/* @__PURE__ */ jsx6("button", { className: "documentation-icon-button", type: "button", onClick: onClose, "aria-label": "Close documentation navigation", "data-autofocus": true, children: /* @__PURE__ */ jsx6(CloseIcon, {}) })
|
|
1400
|
-
] }),
|
|
1401
|
-
/* @__PURE__ */ jsx6("nav", { className: "documentation-page-tree", children: /* @__PURE__ */ jsx6(NavigationTree, { activeRoute: data.page.route, basePath: data.basePath, nodes: data.navigation }) }),
|
|
1402
|
-
/* @__PURE__ */ jsxs6("footer", { children: [
|
|
1403
|
-
!data.config.theme.strictMode && /* @__PURE__ */ jsx6(ThemeControls, { defaultMode: data.config.theme.defaultMode ?? "system" }),
|
|
1404
|
-
data.config.footer.map((link) => /* @__PURE__ */ jsx6("a", { href: link.href, ...externalProps(link.href), children: link.label }, `${link.label}:${link.href}`))
|
|
1405
|
-
] })
|
|
1406
|
-
] }) });
|
|
1407
|
-
}
|
|
1408
|
-
function ThemeControls({ defaultMode }) {
|
|
1409
|
-
const [mode, setMode] = useState5(defaultMode);
|
|
1410
|
-
useEffect6(() => {
|
|
1411
|
-
const saved = safeStorageGet("deepspace-documentation-theme");
|
|
1412
|
-
if (saved === "light" || saved === "dark" || saved === "system") setMode(saved);
|
|
1413
|
-
}, []);
|
|
1414
|
-
useEffect6(() => applyThemeMode(mode), [mode]);
|
|
1415
|
-
const choose = (next) => {
|
|
1416
|
-
setMode(next);
|
|
1417
|
-
safeStorageSet("deepspace-documentation-theme", next);
|
|
1418
|
-
};
|
|
1419
|
-
return /* @__PURE__ */ jsxs6("div", { className: "documentation-theme-controls", role: "group", "aria-label": "Theme preference", children: [
|
|
1420
|
-
/* @__PURE__ */ jsx6("button", { "aria-pressed": mode === "system", "aria-label": "Use system theme", onClick: () => choose("system"), type: "button", children: /* @__PURE__ */ jsx6(SystemIcon, {}) }),
|
|
1421
|
-
/* @__PURE__ */ jsx6("button", { "aria-pressed": mode === "light", "aria-label": "Use light theme", onClick: () => choose("light"), type: "button", children: /* @__PURE__ */ jsx6(SunIcon, {}) }),
|
|
1422
|
-
/* @__PURE__ */ jsx6("button", { "aria-pressed": mode === "dark", "aria-label": "Use dark theme", onClick: () => choose("dark"), type: "button", children: /* @__PURE__ */ jsx6(MoonIcon, {}) })
|
|
1423
|
-
] });
|
|
1424
|
-
}
|
|
1425
|
-
function containsRoute(node, route) {
|
|
1426
|
-
return node.items.some((item) => item.kind === "page" ? item.route === route : item.kind === "group" && containsRoute(item, route));
|
|
1427
|
-
}
|
|
1428
|
-
function applyThemeMode(mode) {
|
|
1429
|
-
const media = window.matchMedia("(prefers-color-scheme: dark)");
|
|
1430
|
-
const apply = () => {
|
|
1431
|
-
document.documentElement.dataset.themeMode = mode;
|
|
1432
|
-
document.documentElement.dataset.theme = mode === "system" ? media.matches ? "dark" : "light" : mode;
|
|
1433
|
-
};
|
|
1434
|
-
apply();
|
|
1435
|
-
media.addEventListener?.("change", apply);
|
|
1436
|
-
return () => media.removeEventListener?.("change", apply);
|
|
1437
|
-
}
|
|
1438
|
-
|
|
1439
|
-
// src/documentation/runtime/search.tsx
|
|
1440
|
-
import {
|
|
1441
|
-
useEffect as useEffect7,
|
|
1442
|
-
useMemo as useMemo2,
|
|
1443
|
-
useRef as useRef6,
|
|
1444
|
-
useState as useState6
|
|
1445
|
-
} from "react";
|
|
1446
|
-
import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1447
|
-
function SearchCommand({
|
|
1448
|
-
assistantEnabled,
|
|
1449
|
-
basePath,
|
|
1450
|
-
name,
|
|
1451
|
-
onAssistantOpen,
|
|
1452
|
-
onClose,
|
|
1453
|
-
onNavigate,
|
|
1454
|
-
open
|
|
1455
|
-
}) {
|
|
1456
|
-
const dialogRef = useRef6(null);
|
|
1457
|
-
const resultsRef = useRef6(null);
|
|
1458
|
-
const [index, setIndex] = useState6(null);
|
|
1459
|
-
const [loading, setLoading] = useState6(false);
|
|
1460
|
-
const [query, setQuery] = useState6("");
|
|
1461
|
-
const [activeIndex, setActiveIndex] = useState6(0);
|
|
1462
|
-
useDialogFocus(open, dialogRef, onClose);
|
|
1463
|
-
useEffect7(() => {
|
|
1464
|
-
if (!open || index || loading) return;
|
|
1465
|
-
setLoading(true);
|
|
1466
|
-
fetch(documentationPublicPath(basePath, "/search.json")).then((response) => response.ok ? response.json() : []).then(setIndex).catch(() => setIndex([])).finally(() => setLoading(false));
|
|
1467
|
-
}, [basePath, index, loading, open]);
|
|
1468
|
-
useEffect7(() => {
|
|
1469
|
-
if (!open) {
|
|
1470
|
-
setQuery("");
|
|
1471
|
-
setActiveIndex(0);
|
|
1472
|
-
}
|
|
1473
|
-
}, [open]);
|
|
1474
|
-
useEffect7(() => {
|
|
1475
|
-
resultsRef.current?.querySelector(`#documentation-search-option-${activeIndex}`)?.scrollIntoView({ block: "nearest" });
|
|
1476
|
-
}, [activeIndex, query]);
|
|
1477
|
-
const preparedIndex = useMemo2(() => prepareSearchIndex(index ?? []), [index]);
|
|
1478
|
-
const results = useMemo2(() => rankSearch(preparedIndex, query), [preparedIndex, query]);
|
|
1479
|
-
if (!open) return null;
|
|
1480
|
-
const selectableCount = results.length + (assistantEnabled && query.trim() ? 1 : 0);
|
|
1481
|
-
const handleKeyDown = (event) => {
|
|
1482
|
-
if (event.key === "ArrowDown" && selectableCount > 0) {
|
|
1483
|
-
event.preventDefault();
|
|
1484
|
-
setActiveIndex((current) => (current + 1) % selectableCount);
|
|
1485
|
-
} else if (event.key === "ArrowUp" && selectableCount > 0) {
|
|
1486
|
-
event.preventDefault();
|
|
1487
|
-
setActiveIndex((current) => (current - 1 + selectableCount) % selectableCount);
|
|
1488
|
-
} else if (event.key === "Enter") {
|
|
1489
|
-
event.preventDefault();
|
|
1490
|
-
const result = activeIndex < results.length ? results[activeIndex] : void 0;
|
|
1491
|
-
if (result) {
|
|
1492
|
-
onClose();
|
|
1493
|
-
const href = documentationPublicPath(basePath, result.href);
|
|
1494
|
-
if (onNavigate) onNavigate(href);
|
|
1495
|
-
else window.location.assign(href);
|
|
1496
|
-
} else if (assistantEnabled && query.trim()) {
|
|
1497
|
-
onAssistantOpen(query.trim());
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
|
-
};
|
|
1501
|
-
return /* @__PURE__ */ jsx7("div", { className: "documentation-modal-layer documentation-search-layer", role: "presentation", onMouseDown: (event) => {
|
|
1502
|
-
if (event.currentTarget === event.target) onClose();
|
|
1503
|
-
}, children: /* @__PURE__ */ jsxs7("div", { className: "documentation-search-dialog", role: "dialog", "aria-modal": "true", "aria-label": "Search documentation", ref: dialogRef, children: [
|
|
1504
|
-
/* @__PURE__ */ jsxs7("label", { className: "documentation-search-input", children: [
|
|
1505
|
-
/* @__PURE__ */ jsx7(SearchIcon, {}),
|
|
1506
|
-
/* @__PURE__ */ jsx7(
|
|
1507
|
-
"input",
|
|
1508
|
-
{
|
|
1509
|
-
"aria-activedescendant": selectableCount > 0 ? `documentation-search-option-${activeIndex}` : void 0,
|
|
1510
|
-
"aria-controls": "documentation-search-results",
|
|
1511
|
-
"aria-expanded": "true",
|
|
1512
|
-
"aria-label": `Search ${documentationSubject(name)}`,
|
|
1513
|
-
autoCapitalize: "none",
|
|
1514
|
-
autoComplete: "off",
|
|
1515
|
-
autoCorrect: "off",
|
|
1516
|
-
"data-autofocus": true,
|
|
1517
|
-
enterKeyHint: "go",
|
|
1518
|
-
onChange: (event) => {
|
|
1519
|
-
setQuery(event.target.value);
|
|
1520
|
-
setActiveIndex(0);
|
|
1521
|
-
},
|
|
1522
|
-
onKeyDown: handleKeyDown,
|
|
1523
|
-
placeholder: `Search ${name}`,
|
|
1524
|
-
role: "combobox",
|
|
1525
|
-
spellCheck: false,
|
|
1526
|
-
value: query
|
|
1527
|
-
}
|
|
1528
|
-
),
|
|
1529
|
-
/* @__PURE__ */ jsx7("kbd", { children: "Esc" })
|
|
1530
|
-
] }),
|
|
1531
|
-
/* @__PURE__ */ jsxs7("div", { className: "documentation-search-results", id: "documentation-search-results", ref: resultsRef, role: "listbox", "aria-label": "Search results", children: [
|
|
1532
|
-
!query.trim() && /* @__PURE__ */ jsxs7("div", { className: "documentation-search-empty", children: [
|
|
1533
|
-
/* @__PURE__ */ jsx7(OrbitMark, {}),
|
|
1534
|
-
/* @__PURE__ */ jsx7("strong", { children: "Find an answer in these docs" }),
|
|
1535
|
-
/* @__PURE__ */ jsx7("span", { children: "Search pages, headings, APIs, and examples." })
|
|
1536
|
-
] }),
|
|
1537
|
-
query.trim() && loading && /* @__PURE__ */ jsx7("div", { className: "documentation-search-state", children: "Searching this documentation\u2026" }),
|
|
1538
|
-
query.trim() && !loading && results.length === 0 && /* @__PURE__ */ jsxs7("div", { className: "documentation-search-state", children: [
|
|
1539
|
-
"No documentation matched \u201C",
|
|
1540
|
-
query.trim(),
|
|
1541
|
-
"\u201D."
|
|
1542
|
-
] }),
|
|
1543
|
-
results.map((result, resultIndex) => /* @__PURE__ */ jsxs7(
|
|
1544
|
-
"a",
|
|
1545
|
-
{
|
|
1546
|
-
"aria-selected": activeIndex === resultIndex,
|
|
1547
|
-
className: activeIndex === resultIndex ? "documentation-search-result is-active" : "documentation-search-result",
|
|
1548
|
-
href: documentationPublicPath(basePath, result.href),
|
|
1549
|
-
id: `documentation-search-option-${resultIndex}`,
|
|
1550
|
-
onClick: onClose,
|
|
1551
|
-
onMouseEnter: () => setActiveIndex(resultIndex),
|
|
1552
|
-
role: "option",
|
|
1553
|
-
children: [
|
|
1554
|
-
/* @__PURE__ */ jsx7("span", { className: "documentation-search-kind", children: result.kind === "section" ? /* @__PURE__ */ jsx7(HashIcon, {}) : /* @__PURE__ */ jsx7(FileIcon, {}) }),
|
|
1555
|
-
/* @__PURE__ */ jsxs7("span", { className: "documentation-search-copy", children: [
|
|
1556
|
-
/* @__PURE__ */ jsx7("strong", { children: highlightMatch(result.title, query) }),
|
|
1557
|
-
result.kind === "section" ? /* @__PURE__ */ jsxs7("span", { className: "documentation-search-crumbs", children: [
|
|
1558
|
-
result.context,
|
|
1559
|
-
/* @__PURE__ */ jsx7(ChevronRightIcon, {}),
|
|
1560
|
-
result.title
|
|
1561
|
-
] }) : /* @__PURE__ */ jsx7("small", { children: result.context })
|
|
1562
|
-
] }),
|
|
1563
|
-
/* @__PURE__ */ jsx7(ChevronRightIcon, {})
|
|
1564
|
-
]
|
|
1565
|
-
},
|
|
1566
|
-
result.href
|
|
1567
|
-
)),
|
|
1568
|
-
assistantEnabled && query.trim() && /* @__PURE__ */ jsxs7(
|
|
1569
|
-
"button",
|
|
1570
|
-
{
|
|
1571
|
-
"aria-selected": activeIndex === results.length,
|
|
1572
|
-
className: activeIndex === results.length ? "documentation-search-assistant is-active" : "documentation-search-assistant",
|
|
1573
|
-
id: `documentation-search-option-${results.length}`,
|
|
1574
|
-
onClick: () => onAssistantOpen(query.trim()),
|
|
1575
|
-
onMouseEnter: () => setActiveIndex(results.length),
|
|
1576
|
-
role: "option",
|
|
1577
|
-
type: "button",
|
|
1578
|
-
children: [
|
|
1579
|
-
/* @__PURE__ */ jsx7(SparkIcon, {}),
|
|
1580
|
-
/* @__PURE__ */ jsxs7("span", { children: [
|
|
1581
|
-
/* @__PURE__ */ jsx7("strong", { children: "Ask DeepSpace" }),
|
|
1582
|
-
/* @__PURE__ */ jsx7("small", { children: "Answer from the current documentation with citations" })
|
|
1583
|
-
] }),
|
|
1584
|
-
/* @__PURE__ */ jsx7(ChevronRightIcon, {})
|
|
1585
|
-
]
|
|
1586
|
-
}
|
|
1587
|
-
)
|
|
1588
|
-
] }),
|
|
1589
|
-
/* @__PURE__ */ jsxs7("footer", { children: [
|
|
1590
|
-
/* @__PURE__ */ jsxs7("span", { children: [
|
|
1591
|
-
/* @__PURE__ */ jsx7("kbd", { children: "\u2191" }),
|
|
1592
|
-
/* @__PURE__ */ jsx7("kbd", { children: "\u2193" }),
|
|
1593
|
-
" select"
|
|
1594
|
-
] }),
|
|
1595
|
-
/* @__PURE__ */ jsxs7("span", { children: [
|
|
1596
|
-
/* @__PURE__ */ jsx7("kbd", { children: "\u21B5" }),
|
|
1597
|
-
" open"
|
|
1598
|
-
] }),
|
|
1599
|
-
/* @__PURE__ */ jsxs7("span", { children: [
|
|
1600
|
-
/* @__PURE__ */ jsx7("kbd", { children: "esc" }),
|
|
1601
|
-
" close"
|
|
1602
|
-
] })
|
|
1603
|
-
] })
|
|
1604
|
-
] }) });
|
|
1605
|
-
}
|
|
1606
|
-
function prepareSearchIndex(index) {
|
|
1607
|
-
return index.map((entry) => ({
|
|
1608
|
-
entry,
|
|
1609
|
-
title: normalizeSearch(entry.title),
|
|
1610
|
-
headings: entry.headings.map((heading) => ({ heading, normalized: normalizeSearch(heading.text) })),
|
|
1611
|
-
headingText: normalizeSearch(entry.headings.map((heading) => heading.text).join(" ")),
|
|
1612
|
-
haystack: normalizeSearch(`${entry.description ?? ""} ${entry.text}`)
|
|
1613
|
-
}));
|
|
1614
|
-
}
|
|
1615
|
-
function rankSearch(index, query) {
|
|
1616
|
-
const normalized = normalizeSearch(query);
|
|
1617
|
-
if (!normalized) return [];
|
|
1618
|
-
const tokens = normalized.split(" ").filter(Boolean);
|
|
1619
|
-
const scored = [];
|
|
1620
|
-
for (const { entry, title, headings, headingText, haystack } of index) {
|
|
1621
|
-
let score = title === normalized ? 180 : title.startsWith(normalized) ? 110 : title.includes(normalized) ? 75 : 0;
|
|
1622
|
-
if (headingText.includes(normalized)) score += 55;
|
|
1623
|
-
for (const token of tokens) {
|
|
1624
|
-
if (title.includes(token)) score += 24;
|
|
1625
|
-
else if (headingText.includes(token)) score += 14;
|
|
1626
|
-
else if (haystack.includes(token)) score += 5;
|
|
1627
|
-
else score -= 18;
|
|
1628
|
-
}
|
|
1629
|
-
if (score > 0) {
|
|
1630
|
-
scored.push({
|
|
1631
|
-
route: entry.route,
|
|
1632
|
-
score,
|
|
1633
|
-
result: {
|
|
1634
|
-
href: entry.route,
|
|
1635
|
-
kind: "page",
|
|
1636
|
-
title: entry.title,
|
|
1637
|
-
context: entry.description ?? entry.text.slice(0, 150)
|
|
1638
|
-
}
|
|
1639
|
-
});
|
|
1640
|
-
}
|
|
1641
|
-
for (const { heading, normalized: headingNormalized } of headings) {
|
|
1642
|
-
let sectionScore = headingNormalized === normalized ? 120 : headingNormalized.startsWith(normalized) ? 80 : headingNormalized.includes(normalized) ? 60 : 0;
|
|
1643
|
-
if (sectionScore === 0) {
|
|
1644
|
-
for (const token of tokens) if (headingNormalized.includes(token)) sectionScore += 18;
|
|
1645
|
-
}
|
|
1646
|
-
if (sectionScore <= 0) continue;
|
|
1647
|
-
scored.push({
|
|
1648
|
-
route: `${entry.route}#${heading.id}`,
|
|
1649
|
-
score: sectionScore,
|
|
1650
|
-
result: {
|
|
1651
|
-
href: `${entry.route}#${heading.id}`,
|
|
1652
|
-
kind: "section",
|
|
1653
|
-
title: heading.text,
|
|
1654
|
-
context: entry.title
|
|
1655
|
-
}
|
|
1656
|
-
});
|
|
1657
|
-
}
|
|
1658
|
-
}
|
|
1659
|
-
return scored.sort((left, right) => right.score - left.score || left.route.localeCompare(right.route)).slice(0, 10).map((item) => item.result);
|
|
1660
|
-
}
|
|
1661
|
-
function highlightMatch(value, query) {
|
|
1662
|
-
const normalizedQuery = query.trim();
|
|
1663
|
-
if (!normalizedQuery) return value;
|
|
1664
|
-
const index = value.toLowerCase().indexOf(normalizedQuery.toLowerCase());
|
|
1665
|
-
if (index < 0) return value;
|
|
1666
|
-
return /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
1667
|
-
value.slice(0, index),
|
|
1668
|
-
/* @__PURE__ */ jsx7("mark", { children: value.slice(index, index + normalizedQuery.length) }),
|
|
1669
|
-
value.slice(index + normalizedQuery.length)
|
|
1670
|
-
] });
|
|
1671
|
-
}
|
|
1672
|
-
function normalizeSearch(value) {
|
|
1673
|
-
return value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
|
|
1674
|
-
}
|
|
1675
|
-
|
|
1676
|
-
// src/documentation/runtime/app.tsx
|
|
1677
|
-
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1678
|
-
function DocumentationApp({
|
|
1679
|
-
data,
|
|
1680
|
-
children,
|
|
1681
|
-
navigating = false,
|
|
1682
|
-
onNavigate
|
|
1683
|
-
}) {
|
|
1684
|
-
const [mobileNavOpen, setMobileNavOpen] = useState7(false);
|
|
1685
|
-
const [searchOpen, setSearchOpen] = useState7(false);
|
|
1686
|
-
const [assistantOpen, setAssistantOpen] = useState7(false);
|
|
1687
|
-
const [assistantDraft, setAssistantDraft] = useState7("");
|
|
1688
|
-
const [assistantSeed, setAssistantSeed] = useState7({ id: 0, submit: false });
|
|
1689
|
-
const assistantAccess = data.config.assistant.access === "disabled" ? null : data.config.assistant.access;
|
|
1690
|
-
const assistantEnabled = assistantAccess !== null;
|
|
1691
|
-
const appClassName = [
|
|
1692
|
-
"documentation-app",
|
|
1693
|
-
assistantEnabled ? "has-assistant" : "",
|
|
1694
|
-
assistantOpen ? "is-assistant-open" : "",
|
|
1695
|
-
navigating ? "is-navigating" : ""
|
|
1696
|
-
].filter(Boolean).join(" ");
|
|
1697
|
-
const openAssistant = useCallback((seed, submit = false) => {
|
|
1698
|
-
if (seed !== void 0) setAssistantDraft(seed);
|
|
1699
|
-
setAssistantSeed((current) => ({ id: current.id + 1, submit, value: seed }));
|
|
1700
|
-
setSearchOpen(false);
|
|
1701
|
-
setAssistantOpen(true);
|
|
1702
|
-
}, []);
|
|
1703
|
-
useEffect8(() => {
|
|
1704
|
-
const handleKeydown = (event) => {
|
|
1705
|
-
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
|
|
1706
|
-
event.preventDefault();
|
|
1707
|
-
setSearchOpen(true);
|
|
1708
|
-
}
|
|
1709
|
-
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "i") {
|
|
1710
|
-
event.preventDefault();
|
|
1711
|
-
if (data.config.assistant.access !== "disabled") openAssistant();
|
|
1712
|
-
}
|
|
1713
|
-
};
|
|
1714
|
-
document.addEventListener("keydown", handleKeydown);
|
|
1715
|
-
return () => document.removeEventListener("keydown", handleKeydown);
|
|
1716
|
-
}, [data.config.assistant.access, openAssistant]);
|
|
1717
|
-
useEffect8(() => {
|
|
1718
|
-
setMobileNavOpen(false);
|
|
1719
|
-
setSearchOpen(false);
|
|
1720
|
-
}, [data.page.route]);
|
|
1721
|
-
return /* @__PURE__ */ jsxs8(
|
|
1722
|
-
"div",
|
|
1723
|
-
{
|
|
1724
|
-
"aria-busy": navigating || void 0,
|
|
1725
|
-
className: appClassName,
|
|
1726
|
-
children: [
|
|
1727
|
-
/* @__PURE__ */ jsx8("a", { className: "documentation-skip-link", href: "#documentation-content", children: "Skip to main content" }),
|
|
1728
|
-
/* @__PURE__ */ jsx8(
|
|
1729
|
-
DocumentationHeader,
|
|
1730
|
-
{
|
|
1731
|
-
data,
|
|
1732
|
-
onMenuOpen: () => setMobileNavOpen(true),
|
|
1733
|
-
onSearchOpen: () => setSearchOpen(true)
|
|
1734
|
-
}
|
|
1735
|
-
),
|
|
1736
|
-
/* @__PURE__ */ jsxs8("div", { className: "documentation-frame", children: [
|
|
1737
|
-
/* @__PURE__ */ jsx8(DesktopSidebar, { data }),
|
|
1738
|
-
/* @__PURE__ */ jsx8("main", { className: "documentation-main", id: "documentation-content", children: /* @__PURE__ */ jsxs8("div", { className: "documentation-reader-grid", children: [
|
|
1739
|
-
/* @__PURE__ */ jsx8("div", { className: "documentation-reader-column", children: /* @__PURE__ */ jsx8(
|
|
1740
|
-
Article,
|
|
1741
|
-
{
|
|
1742
|
-
data,
|
|
1743
|
-
launcher: assistantAccess && !assistantOpen ? /* @__PURE__ */ jsx8(
|
|
1744
|
-
AssistantLauncher,
|
|
1745
|
-
{
|
|
1746
|
-
input: assistantDraft,
|
|
1747
|
-
name: data.config.name,
|
|
1748
|
-
onInputChange: setAssistantDraft,
|
|
1749
|
-
onSubmit: (question) => openAssistant(question, true)
|
|
1750
|
-
}
|
|
1751
|
-
) : void 0,
|
|
1752
|
-
onAssistantOpen: openAssistant,
|
|
1753
|
-
children
|
|
1754
|
-
}
|
|
1755
|
-
) }),
|
|
1756
|
-
/* @__PURE__ */ jsx8(ContextRail, { data })
|
|
1757
|
-
] }) })
|
|
1758
|
-
] }),
|
|
1759
|
-
/* @__PURE__ */ jsx8(
|
|
1760
|
-
MobileNavigation,
|
|
1761
|
-
{
|
|
1762
|
-
data,
|
|
1763
|
-
onClose: () => setMobileNavOpen(false),
|
|
1764
|
-
open: mobileNavOpen
|
|
1765
|
-
}
|
|
1766
|
-
),
|
|
1767
|
-
/* @__PURE__ */ jsx8(
|
|
1768
|
-
SearchCommand,
|
|
1769
|
-
{
|
|
1770
|
-
assistantEnabled,
|
|
1771
|
-
basePath: data.basePath,
|
|
1772
|
-
name: data.config.name,
|
|
1773
|
-
onAssistantOpen: openAssistant,
|
|
1774
|
-
onClose: () => setSearchOpen(false),
|
|
1775
|
-
onNavigate,
|
|
1776
|
-
open: searchOpen
|
|
1777
|
-
}
|
|
1778
|
-
),
|
|
1779
|
-
assistantAccess && /* @__PURE__ */ jsx8(
|
|
1780
|
-
DocumentationAssistant,
|
|
1781
|
-
{
|
|
1782
|
-
access: assistantAccess,
|
|
1783
|
-
basePath: data.basePath,
|
|
1784
|
-
input: assistantDraft,
|
|
1785
|
-
name: data.config.name,
|
|
1786
|
-
onClose: () => setAssistantOpen(false),
|
|
1787
|
-
onInputChange: setAssistantDraft,
|
|
1788
|
-
open: assistantOpen,
|
|
1789
|
-
route: data.page.route,
|
|
1790
|
-
seed: assistantSeed,
|
|
1791
|
-
suggestions: data.config.assistant.suggestions
|
|
1792
|
-
}
|
|
1793
|
-
)
|
|
1794
|
-
]
|
|
1795
|
-
}
|
|
1796
|
-
);
|
|
1797
|
-
}
|
|
1798
|
-
|
|
1799
|
-
// src/documentation/runtime/mdx-components.tsx
|
|
1800
|
-
import { Children, createElement, isValidElement } from "react";
|
|
1801
|
-
import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1802
|
-
function Callout({ children, title, kind }) {
|
|
1803
|
-
const label = title ?? kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
1804
|
-
return /* @__PURE__ */ jsxs9("aside", { className: `documentation-callout documentation-callout-${kind}`, children: [
|
|
1805
|
-
/* @__PURE__ */ jsx9("strong", { children: label }),
|
|
1806
|
-
children
|
|
1807
|
-
] });
|
|
1808
|
-
}
|
|
1809
|
-
function Note(props) {
|
|
1810
|
-
return /* @__PURE__ */ jsx9(Callout, { ...props, kind: "note" });
|
|
1811
|
-
}
|
|
1812
|
-
function Tip(props) {
|
|
1813
|
-
return /* @__PURE__ */ jsx9(Callout, { ...props, kind: "tip" });
|
|
1814
|
-
}
|
|
1815
|
-
function Warning(props) {
|
|
1816
|
-
return /* @__PURE__ */ jsx9(Callout, { ...props, kind: "warning" });
|
|
1817
|
-
}
|
|
1818
|
-
function Info(props) {
|
|
1819
|
-
return /* @__PURE__ */ jsx9(Callout, { ...props, kind: "info" });
|
|
1820
|
-
}
|
|
1821
|
-
function Card({ children, href, label, title }) {
|
|
1822
|
-
const content = /* @__PURE__ */ jsxs9(Fragment6, { children: [
|
|
1823
|
-
title ?? label ? /* @__PURE__ */ jsx9("strong", { children: title ?? label }) : null,
|
|
1824
|
-
children
|
|
1825
|
-
] });
|
|
1826
|
-
return href ? /* @__PURE__ */ jsxs9("a", { className: "documentation-card", href, children: [
|
|
1827
|
-
content,
|
|
1828
|
-
/* @__PURE__ */ jsx9("span", { "aria-hidden": "true", children: "\u2192" })
|
|
1829
|
-
] }) : /* @__PURE__ */ jsx9("div", { className: "documentation-card", children: content });
|
|
1830
|
-
}
|
|
1831
|
-
function Accordion({ children, label, title }) {
|
|
1832
|
-
return /* @__PURE__ */ jsxs9("details", { className: "documentation-accordion", children: [
|
|
1833
|
-
/* @__PURE__ */ jsx9("summary", { children: title ?? label ?? "Details" }),
|
|
1834
|
-
children
|
|
1835
|
-
] });
|
|
1836
|
-
}
|
|
1837
|
-
function AccordionGroup({ children }) {
|
|
1838
|
-
return /* @__PURE__ */ jsx9("div", { className: "documentation-accordion-group", children });
|
|
1839
|
-
}
|
|
1840
|
-
function Step({ children, label, title }) {
|
|
1841
|
-
return /* @__PURE__ */ jsxs9("section", { className: "documentation-step", children: [
|
|
1842
|
-
title ?? label ? /* @__PURE__ */ jsx9("h3", { children: title ?? label }) : null,
|
|
1843
|
-
children
|
|
1844
|
-
] });
|
|
1845
|
-
}
|
|
1846
|
-
function Steps({ children }) {
|
|
1847
|
-
return /* @__PURE__ */ jsx9("div", { className: "documentation-steps", children });
|
|
1848
|
-
}
|
|
1849
|
-
function Tab({ children, label, title }) {
|
|
1850
|
-
return /* @__PURE__ */ jsx9("section", { className: "documentation-tab", "data-tab": true, "data-tab-title": title ?? label ?? "Tab", children });
|
|
1851
|
-
}
|
|
1852
|
-
function Tabs({ children }) {
|
|
1853
|
-
return /* @__PURE__ */ jsx9(TabGroup, { className: "documentation-tabs", panels: tabPanels(children) });
|
|
1854
|
-
}
|
|
1855
|
-
function CodeGroup({ children, label, title }) {
|
|
1856
|
-
const panels = Children.toArray(children).map((child, index) => ({
|
|
1857
|
-
label: codeBlockTitle(child) ?? `Example ${index + 1}`,
|
|
1858
|
-
content: child
|
|
1859
|
-
}));
|
|
1860
|
-
return /* @__PURE__ */ jsx9(CodeGroupProvider, { value: true, children: /* @__PURE__ */ jsx9(
|
|
1861
|
-
TabGroup,
|
|
1862
|
-
{
|
|
1863
|
-
className: "documentation-code-group",
|
|
1864
|
-
panels,
|
|
1865
|
-
title: title ?? label ? /* @__PURE__ */ jsx9("div", { className: "documentation-code-group-title", children: title ?? label }) : void 0
|
|
1866
|
-
}
|
|
1867
|
-
) });
|
|
1868
|
-
}
|
|
1869
|
-
function tabPanels(children) {
|
|
1870
|
-
return Children.toArray(children).map((child, index) => {
|
|
1871
|
-
const props = isValidElement(child) ? child.props : void 0;
|
|
1872
|
-
return {
|
|
1873
|
-
label: props?.title ?? props?.label ?? `Tab ${index + 1}`,
|
|
1874
|
-
content: props && "children" in props ? props.children : child
|
|
1875
|
-
};
|
|
1876
|
-
});
|
|
1877
|
-
}
|
|
1878
|
-
function codeBlockTitle(node) {
|
|
1879
|
-
if (!isValidElement(node)) return void 0;
|
|
1880
|
-
const code = node.props.children;
|
|
1881
|
-
if (!isValidElement(code)) return void 0;
|
|
1882
|
-
const title = code.props["data-code-title"];
|
|
1883
|
-
return typeof title === "string" && title ? title : void 0;
|
|
1884
|
-
}
|
|
1885
|
-
function Heading({ level, ...props }) {
|
|
1886
|
-
const id = props.id;
|
|
1887
|
-
return createElement(
|
|
1888
|
-
`h${level}`,
|
|
1889
|
-
props,
|
|
1890
|
-
props.children,
|
|
1891
|
-
id ? /* @__PURE__ */ jsx9("a", { "aria-label": "Link to this section", className: "documentation-heading-anchor", href: `#${id}`, children: "#" }) : null
|
|
1892
|
-
);
|
|
1893
|
-
}
|
|
1894
|
-
var documentationMdxComponents = {
|
|
1895
|
-
/** React renders the code-block wrapper so nothing has to move a `pre` that
|
|
1896
|
-
* the reconciler already owns. */
|
|
1897
|
-
pre: CodeBlock,
|
|
1898
|
-
Accordion,
|
|
1899
|
-
AccordionGroup,
|
|
1900
|
-
Card,
|
|
1901
|
-
CodeGroup,
|
|
1902
|
-
Info,
|
|
1903
|
-
Note,
|
|
1904
|
-
Step,
|
|
1905
|
-
Steps,
|
|
1906
|
-
Tab,
|
|
1907
|
-
Tabs,
|
|
1908
|
-
Tip,
|
|
1909
|
-
Warning,
|
|
1910
|
-
h1: (props) => /* @__PURE__ */ jsx9(Heading, { ...props, level: 1 }),
|
|
1911
|
-
h2: (props) => /* @__PURE__ */ jsx9(Heading, { ...props, level: 2 }),
|
|
1912
|
-
h3: (props) => /* @__PURE__ */ jsx9(Heading, { ...props, level: 3 }),
|
|
1913
|
-
h4: (props) => /* @__PURE__ */ jsx9(Heading, { ...props, level: 4 }),
|
|
1914
|
-
h5: (props) => /* @__PURE__ */ jsx9(Heading, { ...props, level: 5 }),
|
|
1915
|
-
h6: (props) => /* @__PURE__ */ jsx9(Heading, { ...props, level: 6 })
|
|
1916
|
-
};
|
|
1917
|
-
|
|
1918
|
-
// src/documentation/runtime/public.tsx
|
|
1919
|
-
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1920
|
-
var DefaultDocumentation = DocumentationApp;
|
|
1921
|
-
function DocumentationContent({
|
|
1922
|
-
data,
|
|
1923
|
-
Page
|
|
1924
|
-
}) {
|
|
1925
|
-
if (!Page) {
|
|
1926
|
-
return /* @__PURE__ */ jsx10(
|
|
1927
|
-
"div",
|
|
1928
|
-
{
|
|
1929
|
-
className: "documentation-prose",
|
|
1930
|
-
"data-prose": "html",
|
|
1931
|
-
dangerouslySetInnerHTML: { __html: data.page.html }
|
|
1932
|
-
}
|
|
1933
|
-
);
|
|
1934
|
-
}
|
|
1935
|
-
return /* @__PURE__ */ jsx10("div", { className: "documentation-prose", "data-prose": "react", children: /* @__PURE__ */ jsx10(Page, { components: documentationMdxComponents }) });
|
|
1936
|
-
}
|
|
1937
|
-
|
|
1938
|
-
export {
|
|
1939
|
-
documentationPublicPath,
|
|
1940
|
-
documentationLogicalPath,
|
|
1941
|
-
DocumentationApp,
|
|
1942
|
-
Note,
|
|
1943
|
-
Tip,
|
|
1944
|
-
Warning,
|
|
1945
|
-
Info,
|
|
1946
|
-
Card,
|
|
1947
|
-
Accordion,
|
|
1948
|
-
AccordionGroup,
|
|
1949
|
-
Step,
|
|
1950
|
-
Steps,
|
|
1951
|
-
Tab,
|
|
1952
|
-
Tabs,
|
|
1953
|
-
CodeGroup,
|
|
1954
|
-
DefaultDocumentation,
|
|
1955
|
-
DocumentationContent
|
|
1956
|
-
};
|
|
1957
|
-
//# sourceMappingURL=chunk-S2OGAK6U.js.map
|