svedocs 0.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/LICENSE +5 -0
  2. package/README.md +38 -0
  3. package/dist/ai/openai-compatible.d.ts +13 -0
  4. package/dist/ai/openai-compatible.d.ts.map +1 -0
  5. package/dist/ai/openai-compatible.js +92 -0
  6. package/dist/ai/providers.d.ts +19 -0
  7. package/dist/ai/providers.d.ts.map +1 -0
  8. package/dist/ai/providers.js +185 -0
  9. package/dist/ai/rate-limit.d.ts +18 -0
  10. package/dist/ai/rate-limit.d.ts.map +1 -0
  11. package/dist/ai/rate-limit.js +52 -0
  12. package/dist/ai/response.d.ts +4 -0
  13. package/dist/ai/response.d.ts.map +1 -0
  14. package/dist/ai/response.js +151 -0
  15. package/dist/ai/runtime.d.ts +30 -0
  16. package/dist/ai/runtime.d.ts.map +1 -0
  17. package/dist/ai/runtime.js +105 -0
  18. package/dist/ai/types.d.ts +93 -0
  19. package/dist/ai/types.d.ts.map +1 -0
  20. package/dist/ai/types.js +1 -0
  21. package/dist/ai.d.ts +7 -0
  22. package/dist/ai.d.ts.map +1 -0
  23. package/dist/ai.js +6 -0
  24. package/dist/ambient.d.ts +5 -0
  25. package/dist/cloudflare.d.ts +27 -0
  26. package/dist/cloudflare.d.ts.map +1 -0
  27. package/dist/cloudflare.js +146 -0
  28. package/dist/config.d.ts +311 -0
  29. package/dist/config.d.ts.map +1 -0
  30. package/dist/config.js +243 -0
  31. package/dist/core/checks.d.ts +4 -0
  32. package/dist/core/checks.d.ts.map +1 -0
  33. package/dist/core/checks.js +252 -0
  34. package/dist/core/config.d.ts +5 -0
  35. package/dist/core/config.d.ts.map +1 -0
  36. package/dist/core/config.js +182 -0
  37. package/dist/core/content.d.ts +7 -0
  38. package/dist/core/content.d.ts.map +1 -0
  39. package/dist/core/content.js +211 -0
  40. package/dist/core/links.d.ts +8 -0
  41. package/dist/core/links.d.ts.map +1 -0
  42. package/dist/core/links.js +94 -0
  43. package/dist/core/navigation.d.ts +5 -0
  44. package/dist/core/navigation.d.ts.map +1 -0
  45. package/dist/core/navigation.js +144 -0
  46. package/dist/core/search.d.ts +5 -0
  47. package/dist/core/search.d.ts.map +1 -0
  48. package/dist/core/search.js +41 -0
  49. package/dist/core/types.d.ts +269 -0
  50. package/dist/core/types.d.ts.map +1 -0
  51. package/dist/core/types.js +4 -0
  52. package/dist/core/utils.d.ts +12 -0
  53. package/dist/core/utils.d.ts.map +1 -0
  54. package/dist/core/utils.js +52 -0
  55. package/dist/core.d.ts +8 -0
  56. package/dist/core.d.ts.map +1 -0
  57. package/dist/core.js +7 -0
  58. package/dist/index.d.ts +6 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +3 -0
  61. package/dist/mdx/ast.d.ts +32 -0
  62. package/dist/mdx/ast.d.ts.map +1 -0
  63. package/dist/mdx/ast.js +148 -0
  64. package/dist/mdx/code.d.ts +14 -0
  65. package/dist/mdx/code.d.ts.map +1 -0
  66. package/dist/mdx/code.js +315 -0
  67. package/dist/mdx/compile.d.ts +26 -0
  68. package/dist/mdx/compile.d.ts.map +1 -0
  69. package/dist/mdx/compile.js +63 -0
  70. package/dist/mdx/diff.d.ts +5 -0
  71. package/dist/mdx/diff.d.ts.map +1 -0
  72. package/dist/mdx/diff.js +160 -0
  73. package/dist/mdx/utils.d.ts +10 -0
  74. package/dist/mdx/utils.d.ts.map +1 -0
  75. package/dist/mdx/utils.js +64 -0
  76. package/dist/og/image.d.ts +21 -0
  77. package/dist/og/image.d.ts.map +1 -0
  78. package/dist/og/image.js +216 -0
  79. package/dist/og/metadata.d.ts +7 -0
  80. package/dist/og/metadata.d.ts.map +1 -0
  81. package/dist/og/metadata.js +160 -0
  82. package/dist/og/types.d.ts +59 -0
  83. package/dist/og/types.d.ts.map +1 -0
  84. package/dist/og/types.js +1 -0
  85. package/dist/og.d.ts +4 -0
  86. package/dist/og.d.ts.map +1 -0
  87. package/dist/og.js +3 -0
  88. package/dist/search/algolia.d.ts +10 -0
  89. package/dist/search/algolia.d.ts.map +1 -0
  90. package/dist/search/algolia.js +82 -0
  91. package/dist/search/cloudflare-sync.d.ts +5 -0
  92. package/dist/search/cloudflare-sync.d.ts.map +1 -0
  93. package/dist/search/cloudflare-sync.js +169 -0
  94. package/dist/search/cloudflare.d.ts +9 -0
  95. package/dist/search/cloudflare.d.ts.map +1 -0
  96. package/dist/search/cloudflare.js +115 -0
  97. package/dist/search/local.d.ts +9 -0
  98. package/dist/search/local.d.ts.map +1 -0
  99. package/dist/search/local.js +122 -0
  100. package/dist/search/runtime.d.ts +41 -0
  101. package/dist/search/runtime.d.ts.map +1 -0
  102. package/dist/search/runtime.js +151 -0
  103. package/dist/search/types.d.ts +172 -0
  104. package/dist/search/types.d.ts.map +1 -0
  105. package/dist/search/types.js +1 -0
  106. package/dist/search/typesense.d.ts +11 -0
  107. package/dist/search/typesense.d.ts.map +1 -0
  108. package/dist/search/typesense.js +91 -0
  109. package/dist/search/utils.d.ts +10 -0
  110. package/dist/search/utils.d.ts.map +1 -0
  111. package/dist/search/utils.js +55 -0
  112. package/dist/search.d.ts +8 -0
  113. package/dist/search.d.ts.map +1 -0
  114. package/dist/search.js +7 -0
  115. package/dist/svelte.d.ts +24 -0
  116. package/dist/svelte.d.ts.map +1 -0
  117. package/dist/svelte.js +51 -0
  118. package/dist/testing.d.ts +3 -0
  119. package/dist/testing.d.ts.map +1 -0
  120. package/dist/testing.js +23 -0
  121. package/dist/theme/AskAiPanel.svelte +433 -0
  122. package/dist/theme/AskAiPanel.svelte.d.ts +27 -0
  123. package/dist/theme/AskAiPanel.svelte.d.ts.map +1 -0
  124. package/dist/theme/Button.svelte +34 -0
  125. package/dist/theme/Button.svelte.d.ts +41 -0
  126. package/dist/theme/Button.svelte.d.ts.map +1 -0
  127. package/dist/theme/Checkbox.svelte +63 -0
  128. package/dist/theme/Checkbox.svelte.d.ts +45 -0
  129. package/dist/theme/Checkbox.svelte.d.ts.map +1 -0
  130. package/dist/theme/CodeBlock.svelte +6 -0
  131. package/dist/theme/CodeBlock.svelte.d.ts +22 -0
  132. package/dist/theme/CodeBlock.svelte.d.ts.map +1 -0
  133. package/dist/theme/DocPage.svelte +121 -0
  134. package/dist/theme/DocPage.svelte.d.ts +33 -0
  135. package/dist/theme/DocPage.svelte.d.ts.map +1 -0
  136. package/dist/theme/DocsApp.svelte +78 -0
  137. package/dist/theme/DocsApp.svelte.d.ts +63 -0
  138. package/dist/theme/DocsApp.svelte.d.ts.map +1 -0
  139. package/dist/theme/DocsLayout.svelte +167 -0
  140. package/dist/theme/DocsLayout.svelte.d.ts +40 -0
  141. package/dist/theme/DocsLayout.svelte.d.ts.map +1 -0
  142. package/dist/theme/FloatingToolbar.svelte +73 -0
  143. package/dist/theme/FloatingToolbar.svelte.d.ts +22 -0
  144. package/dist/theme/FloatingToolbar.svelte.d.ts.map +1 -0
  145. package/dist/theme/FormField.svelte +41 -0
  146. package/dist/theme/FormField.svelte.d.ts +35 -0
  147. package/dist/theme/FormField.svelte.d.ts.map +1 -0
  148. package/dist/theme/HomePage.svelte +228 -0
  149. package/dist/theme/HomePage.svelte.d.ts +58 -0
  150. package/dist/theme/HomePage.svelte.d.ts.map +1 -0
  151. package/dist/theme/Input.svelte +36 -0
  152. package/dist/theme/Input.svelte.d.ts +34 -0
  153. package/dist/theme/Input.svelte.d.ts.map +1 -0
  154. package/dist/theme/PageLayout.svelte +36 -0
  155. package/dist/theme/PageLayout.svelte.d.ts +31 -0
  156. package/dist/theme/PageLayout.svelte.d.ts.map +1 -0
  157. package/dist/theme/RootLayout.svelte +330 -0
  158. package/dist/theme/RootLayout.svelte.d.ts +40 -0
  159. package/dist/theme/RootLayout.svelte.d.ts.map +1 -0
  160. package/dist/theme/ScopeSwitcher.svelte +103 -0
  161. package/dist/theme/ScopeSwitcher.svelte.d.ts +24 -0
  162. package/dist/theme/ScopeSwitcher.svelte.d.ts.map +1 -0
  163. package/dist/theme/SearchDialog.svelte +253 -0
  164. package/dist/theme/SearchDialog.svelte.d.ts +28 -0
  165. package/dist/theme/SearchDialog.svelte.d.ts.map +1 -0
  166. package/dist/theme/Select.svelte +37 -0
  167. package/dist/theme/Select.svelte.d.ts +42 -0
  168. package/dist/theme/Select.svelte.d.ts.map +1 -0
  169. package/dist/theme/SidebarTree.svelte +136 -0
  170. package/dist/theme/SidebarTree.svelte.d.ts +24 -0
  171. package/dist/theme/SidebarTree.svelte.d.ts.map +1 -0
  172. package/dist/theme/Textarea.svelte +33 -0
  173. package/dist/theme/Textarea.svelte.d.ts +33 -0
  174. package/dist/theme/Textarea.svelte.d.ts.map +1 -0
  175. package/dist/theme/ThemeToggle.svelte +39 -0
  176. package/dist/theme/ThemeToggle.svelte.d.ts +21 -0
  177. package/dist/theme/ThemeToggle.svelte.d.ts.map +1 -0
  178. package/dist/theme/forms.d.ts +4 -0
  179. package/dist/theme/forms.d.ts.map +1 -0
  180. package/dist/theme/forms.js +3 -0
  181. package/dist/theme/index.d.ts +21 -0
  182. package/dist/theme/index.d.ts.map +1 -0
  183. package/dist/theme/index.js +19 -0
  184. package/dist/theme/portal.d.ts +5 -0
  185. package/dist/theme/portal.d.ts.map +1 -0
  186. package/dist/theme/portal.js +19 -0
  187. package/dist/theme/styles.css +3697 -0
  188. package/dist/virtual.d.ts +59 -0
  189. package/dist/vite.d.ts +10 -0
  190. package/dist/vite.d.ts.map +1 -0
  191. package/dist/vite.js +304 -0
  192. package/package.json +118 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/search/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAK7E,OAAO,KAAK,EACV,0BAA0B,EAC1B,2BAA2B,EAC3B,cAAc,EACd,WAAW,EAEZ,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,uBAAuB;IACtC,iBAAiB,CAAC,EAAE,0BAA0B,GAAG,2BAA2B,GAAG,SAAS,CAAC;IACzF,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,sBAAsB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,0BAA0B,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,uBAAuB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,0BAA0B,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,yBAAyB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/C,sBAAsB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,qBAAqB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,4BAA4B,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClD,yBAAyB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/C,4BAA4B,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClD,iCAAiC,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,qCAAqC;IACpD,MAAM,EAAE,IAAI,CAAC,qBAAqB,EAAE,QAAQ,GAAG,YAAY,CAAC,CAAC;IAC7D,OAAO,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAChC,GAAG,CAAC,EAAE,uBAAuB,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,qCAAsC,SAAQ,IAAI,CAAC,qCAAqC,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;IAC3I,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,qCAAqC,GAAG,cAAc,CAkD7G;AAED,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,IAAI,CAAC,qBAAqB,EAAE,QAAQ,GAAG,YAAY,CAAC,EAC5D,OAAO,EAAE,mBAAmB,EAAE,EAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,qCAA0C,GAClD,OAAO,CAAC,QAAQ,CAAC,CAkBnB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAU7D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGtE"}
@@ -0,0 +1,151 @@
1
+ import { createAlgoliaSearchProvider } from './algolia.js';
2
+ import { createCloudflareAiSearchProvider } from './cloudflare.js';
3
+ import { createLocalSearchProvider, createSearchResponse } from './local.js';
4
+ import { createTypesenseSearchProvider } from './typesense.js';
5
+ import { jsonResponse } from './utils.js';
6
+ export function createConfiguredSearchProvider(options) {
7
+ const provider = normalizeProviderName(options.provider ?? options.config.search.provider);
8
+ const records = options.records ?? [];
9
+ if (!options.config.search.enabled)
10
+ return createDisabledSearchProvider();
11
+ if (provider === 'cloudflare-ai-search') {
12
+ const binding = readCloudflareAiSearchBinding(options.env, options.config);
13
+ if (binding) {
14
+ return createCloudflareAiSearchProvider({
15
+ binding,
16
+ instanceName: options.config.cloudflare.aiSearch.instanceName
17
+ });
18
+ }
19
+ return createLocalSearchProvider(records);
20
+ }
21
+ if (provider === 'algolia') {
22
+ const appId = readFirstEnv(options.env, ['SVEDOCS_ALGOLIA_APP_ID', 'ALGOLIA_APP_ID']);
23
+ const apiKey = readFirstEnv(options.env, ['SVEDOCS_ALGOLIA_SEARCH_KEY', 'SVEDOCS_ALGOLIA_API_KEY', 'ALGOLIA_SEARCH_KEY', 'ALGOLIA_API_KEY']);
24
+ const indexName = readFirstEnv(options.env, ['SVEDOCS_ALGOLIA_INDEX_NAME', 'ALGOLIA_INDEX_NAME']);
25
+ if (appId && apiKey && indexName) {
26
+ return createAlgoliaSearchProvider({
27
+ appId,
28
+ apiKey,
29
+ indexName,
30
+ filters: createAlgoliaScopeFilters,
31
+ ...(options.fetch ? { fetch: options.fetch } : {})
32
+ });
33
+ }
34
+ return createLocalSearchProvider(records);
35
+ }
36
+ if (provider === 'typesense') {
37
+ const host = readFirstEnv(options.env, ['SVEDOCS_TYPESENSE_HOST', 'SVEDOCS_TYPESENSE_URL', 'TYPESENSE_HOST', 'TYPESENSE_URL']);
38
+ const apiKey = readFirstEnv(options.env, ['SVEDOCS_TYPESENSE_SEARCH_KEY', 'SVEDOCS_TYPESENSE_API_KEY', 'TYPESENSE_SEARCH_KEY', 'TYPESENSE_API_KEY']);
39
+ const collection = readFirstEnv(options.env, [
40
+ 'SVEDOCS_TYPESENSE_COLLECTION',
41
+ 'SVEDOCS_TYPESENSE_COLLECTION_NAME',
42
+ 'TYPESENSE_COLLECTION',
43
+ 'TYPESENSE_COLLECTION_NAME'
44
+ ]) ?? 'docs';
45
+ if (host && apiKey) {
46
+ return createTypesenseSearchProvider({
47
+ host,
48
+ apiKey,
49
+ collection,
50
+ filterBy: createTypesenseScopeFilters,
51
+ ...(options.fetch ? { fetch: options.fetch } : {})
52
+ });
53
+ }
54
+ return createLocalSearchProvider(records);
55
+ }
56
+ return createLocalSearchProvider(records);
57
+ }
58
+ export async function createConfiguredSearchResponse(config, records, request, options = {}) {
59
+ if (!config.search.enabled) {
60
+ return jsonResponse({ query: readSearchQuery(request).query, results: [] });
61
+ }
62
+ const providerName = options.provider ?? readProviderParam(request) ?? config.search.provider;
63
+ const provider = createConfiguredSearchProvider({
64
+ config,
65
+ records,
66
+ provider: providerName,
67
+ ...(options.env ? { env: options.env } : {}),
68
+ ...(options.fetch ? { fetch: options.fetch } : {})
69
+ });
70
+ if (provider.name === 'local-json' || provider.name === 'disabled') {
71
+ return createSearchResponse(records, request);
72
+ }
73
+ const query = readSearchQuery(request);
74
+ const results = await provider.search(query);
75
+ return jsonResponse({ query: query.query, provider: provider.name, results });
76
+ }
77
+ export function readSearchQuery(request) {
78
+ const url = new URL(request.url);
79
+ const locale = readScopeParam(url, 'locale');
80
+ const kind = readScopeParam(url, 'kind');
81
+ return {
82
+ query: url.searchParams.get('q') ?? url.searchParams.get('query') ?? '',
83
+ limit: clampLimit(Number(url.searchParams.get('limit') ?? 10)),
84
+ ...(locale ? { locale } : {}),
85
+ ...(kind ? { kind } : {})
86
+ };
87
+ }
88
+ export function readProviderParam(request) {
89
+ const provider = new URL(request.url).searchParams.get('provider')?.trim();
90
+ return provider || undefined;
91
+ }
92
+ function createDisabledSearchProvider() {
93
+ return {
94
+ name: 'disabled',
95
+ index() { },
96
+ search() {
97
+ return [];
98
+ }
99
+ };
100
+ }
101
+ function readCloudflareAiSearchBinding(env, config) {
102
+ const bindingName = config.cloudflare.aiSearch.binding;
103
+ const dynamicBinding = env?.[bindingName];
104
+ if (isCloudflareAiSearchBinding(dynamicBinding))
105
+ return dynamicBinding;
106
+ if (isCloudflareAiSearchBinding(env?.SVEDOCS_AI_SEARCH))
107
+ return env.SVEDOCS_AI_SEARCH;
108
+ return undefined;
109
+ }
110
+ function isCloudflareAiSearchBinding(value) {
111
+ if (!value || typeof value !== 'object')
112
+ return false;
113
+ return 'search' in value || 'get' in value;
114
+ }
115
+ function readFirstEnv(env, keys) {
116
+ for (const key of keys) {
117
+ const value = env?.[key];
118
+ if (typeof value === 'string' && value.trim())
119
+ return value.trim();
120
+ }
121
+ return undefined;
122
+ }
123
+ function createAlgoliaScopeFilters(query) {
124
+ return [
125
+ query.locale ? `locale:${quoteAlgoliaFilterValue(query.locale)}` : undefined,
126
+ query.kind ? `kind:${quoteAlgoliaFilterValue(query.kind)}` : undefined
127
+ ].filter(Boolean).join(' AND ') || undefined;
128
+ }
129
+ function quoteAlgoliaFilterValue(value) {
130
+ return /^[\w-]+$/.test(value) ? value : JSON.stringify(value);
131
+ }
132
+ function createTypesenseScopeFilters(query) {
133
+ return [
134
+ query.locale ? `locale:=${quoteTypesenseFilterValue(query.locale)}` : undefined,
135
+ query.kind ? `kind:=${quoteTypesenseFilterValue(query.kind)}` : undefined
136
+ ].filter(Boolean).join(' && ') || undefined;
137
+ }
138
+ function quoteTypesenseFilterValue(value) {
139
+ return /^[\w-]+$/.test(value) ? value : `\`${value.replace(/`/g, '\\`')}\``;
140
+ }
141
+ function normalizeProviderName(provider) {
142
+ return provider?.trim().toLowerCase() || 'local';
143
+ }
144
+ function readScopeParam(url, key) {
145
+ return url.searchParams.get(key)?.trim() || undefined;
146
+ }
147
+ function clampLimit(value) {
148
+ if (!Number.isFinite(value))
149
+ return 10;
150
+ return Math.min(50, Math.max(1, Math.floor(value)));
151
+ }
@@ -0,0 +1,172 @@
1
+ import type { SvedocsSearchRecord } from '../core.js';
2
+ export interface SearchQuery {
3
+ query: string;
4
+ limit?: number;
5
+ locale?: string;
6
+ kind?: string;
7
+ }
8
+ export interface SearchScope {
9
+ locale?: string;
10
+ kind?: string;
11
+ }
12
+ export interface SearchResult {
13
+ id: string;
14
+ title: string;
15
+ url: string;
16
+ excerpt: string;
17
+ score: number;
18
+ section?: string;
19
+ metadata: SvedocsSearchRecord['metadata'];
20
+ }
21
+ export interface SearchProvider {
22
+ name: string;
23
+ index(records: SvedocsSearchRecord[]): Promise<void> | void;
24
+ search(query: SearchQuery): Promise<SearchResult[]> | SearchResult[];
25
+ }
26
+ export interface CloudflareAiSearchSyncDocument {
27
+ id: string;
28
+ title: string;
29
+ url: string;
30
+ content: string;
31
+ metadata: Record<string, string>;
32
+ }
33
+ export interface CloudflareAiSearchSyncOptions {
34
+ records: SvedocsSearchRecord[];
35
+ accountId?: string;
36
+ apiToken?: string;
37
+ instanceName: string;
38
+ namespace?: string;
39
+ endpoint?: string;
40
+ dryRun?: boolean;
41
+ waitForCompletion?: boolean;
42
+ strategy?: 'append' | 'replace';
43
+ deleteIds?: string[];
44
+ existingIds?: string[];
45
+ batchSize?: number;
46
+ maxRetries?: number;
47
+ retryDelayMs?: number;
48
+ fetch?: typeof fetch;
49
+ }
50
+ export interface CloudflareAiSearchSyncResult {
51
+ provider: 'cloudflare-ai-search';
52
+ instanceName: string;
53
+ endpoint: string;
54
+ dryRun: boolean;
55
+ indexed: number;
56
+ deleted: number;
57
+ failed: number;
58
+ planned: {
59
+ uploadIds: string[];
60
+ deleteIds: string[];
61
+ };
62
+ errors: Array<{
63
+ id: string;
64
+ message: string;
65
+ }>;
66
+ }
67
+ export interface CloudflareAiSearchInstance {
68
+ search(input: CloudflareAiSearchInput): Promise<CloudflareAiSearchOutput>;
69
+ chatCompletions?(input: CloudflareAiSearchChatInput): Promise<CloudflareAiSearchChatOutput | ReadableStream<Uint8Array> | Response>;
70
+ items?: CloudflareAiSearchItemsBinding;
71
+ }
72
+ export interface CloudflareAiSearchItemsBinding {
73
+ upload(input: File | Blob | ArrayBuffer | string, options?: CloudflareAiSearchItemUploadOptions): Promise<unknown>;
74
+ uploadAndPoll?(input: File | Blob | ArrayBuffer | string, options?: CloudflareAiSearchItemUploadOptions): Promise<unknown>;
75
+ delete?(itemId: string): Promise<unknown>;
76
+ get?(itemId: string): Promise<unknown>;
77
+ list?(options?: {
78
+ limit?: number;
79
+ cursor?: string;
80
+ }): Promise<unknown>;
81
+ }
82
+ export interface CloudflareAiSearchItemUploadOptions {
83
+ id?: string;
84
+ metadata?: Record<string, string>;
85
+ contentType?: string;
86
+ filename?: string;
87
+ }
88
+ export interface CloudflareAiSearchMessage {
89
+ role: 'system' | 'developer' | 'user' | 'assistant' | 'tool';
90
+ content: string;
91
+ }
92
+ export interface CloudflareAiSearchInput {
93
+ query?: string;
94
+ messages?: CloudflareAiSearchMessage[];
95
+ ai_search_options?: {
96
+ instance_ids?: string[];
97
+ query_rewrite?: boolean | {
98
+ enabled?: boolean;
99
+ model?: string;
100
+ };
101
+ retrieval?: {
102
+ retrieval_type?: 'vector' | 'keyword' | 'hybrid';
103
+ match_threshold?: number;
104
+ max_num_results?: number;
105
+ filters?: Record<string, unknown>;
106
+ context_expansion?: number;
107
+ fusion_method?: 'rrf' | 'max';
108
+ keyword_match_mode?: string;
109
+ reranking?: {
110
+ enabled?: boolean;
111
+ model?: string;
112
+ };
113
+ };
114
+ };
115
+ max_num_results?: number;
116
+ }
117
+ export interface CloudflareAiSearchItem {
118
+ id?: string;
119
+ title?: string;
120
+ url?: string;
121
+ content?: string;
122
+ text?: string;
123
+ score?: number;
124
+ metadata?: Record<string, unknown>;
125
+ }
126
+ export interface CloudflareAiSearchChunk {
127
+ id?: string;
128
+ type?: string;
129
+ text?: string;
130
+ content?: string;
131
+ score?: number;
132
+ metadata?: Record<string, unknown>;
133
+ attributes?: Record<string, unknown>;
134
+ item?: {
135
+ id?: string;
136
+ key?: string;
137
+ filename?: string;
138
+ title?: string;
139
+ metadata?: Record<string, unknown>;
140
+ };
141
+ }
142
+ export interface CloudflareAiSearchOutput {
143
+ response?: string;
144
+ answer?: string;
145
+ data?: CloudflareAiSearchItem[];
146
+ chunks?: CloudflareAiSearchChunk[];
147
+ }
148
+ export interface CloudflareAiSearchChatInput {
149
+ messages: CloudflareAiSearchMessage[];
150
+ ai_search_options?: CloudflareAiSearchInput['ai_search_options'];
151
+ model?: string;
152
+ stream?: boolean;
153
+ }
154
+ export interface CloudflareAiSearchChatOutput extends CloudflareAiSearchOutput {
155
+ choices?: Array<{
156
+ text?: string;
157
+ message?: {
158
+ content?: string;
159
+ };
160
+ }>;
161
+ citations?: Array<{
162
+ title?: string;
163
+ url?: string;
164
+ section?: string;
165
+ }>;
166
+ }
167
+ export interface CloudflareAiSearchNamespace {
168
+ get(instanceName: string): CloudflareAiSearchInstance;
169
+ search?(input: CloudflareAiSearchInput): Promise<CloudflareAiSearchOutput>;
170
+ chatCompletions?(input: CloudflareAiSearchChatInput): Promise<CloudflareAiSearchChatOutput | ReadableStream<Uint8Array> | Response>;
171
+ }
172
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/search/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { SearchProvider, SearchQuery } from './types.js';
2
+ export interface TypesenseSearchProviderOptions {
3
+ host: string;
4
+ apiKey: string;
5
+ collection: string | ((query: SearchQuery) => string);
6
+ queryBy?: string | string[];
7
+ filterBy?: string | ((query: SearchQuery) => string | undefined);
8
+ fetch?: typeof fetch;
9
+ }
10
+ export declare function createTypesenseSearchProvider(options: TypesenseSearchProviderOptions): SearchProvider;
11
+ //# sourceMappingURL=typesense.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typesense.d.ts","sourceRoot":"","sources":["../../src/search/typesense.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAgB,MAAM,YAAY,CAAC;AAG5E,MAAM,WAAW,8BAA8B;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,MAAM,CAAC,CAAC;IACtD,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;IACjE,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AA6BD,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,8BAA8B,GAAG,cAAc,CAsBrG"}
@@ -0,0 +1,91 @@
1
+ import { matchesSearchScope } from './local.js';
2
+ import { createExcerpt, stringMetadata, stringifyMetadata } from './utils.js';
3
+ export function createTypesenseSearchProvider(options) {
4
+ return {
5
+ name: 'typesense',
6
+ index() {
7
+ // Typesense indexing is commonly handled by a crawler or CI sync script.
8
+ },
9
+ async search(query) {
10
+ const requestFetch = options.fetch ?? fetch;
11
+ const response = await requestFetch(createTypesenseSearchUrl(options, query), {
12
+ headers: {
13
+ 'x-typesense-api-key': options.apiKey
14
+ }
15
+ });
16
+ if (!response.ok) {
17
+ throw new Error(`Typesense search returned ${response.status}: ${(await response.text()).slice(0, 500)}`);
18
+ }
19
+ const payload = await response.json();
20
+ return (payload.hits ?? [])
21
+ .map((hit, index) => createTypesenseResult(hit, index, query.query))
22
+ .filter((result) => matchesSearchScope({ metadata: result.metadata }, query));
23
+ }
24
+ };
25
+ }
26
+ function createTypesenseSearchUrl(options, query) {
27
+ const collection = typeof options.collection === 'function' ? options.collection(query) : options.collection;
28
+ const base = options.host.replace(/\/$/, '');
29
+ const url = new URL(`${base}/collections/${encodeURIComponent(collection)}/documents/search`);
30
+ url.searchParams.set('q', query.query || '*');
31
+ url.searchParams.set('query_by', Array.isArray(options.queryBy) ? options.queryBy.join(',') : options.queryBy ?? 'title,section,content');
32
+ url.searchParams.set('per_page', String(query.limit ?? 10));
33
+ const filterBy = typeof options.filterBy === 'function' ? options.filterBy(query) : options.filterBy;
34
+ if (filterBy)
35
+ url.searchParams.set('filter_by', filterBy);
36
+ return url.toString();
37
+ }
38
+ function createTypesenseResult(hit, index, query) {
39
+ const document = hit.document ?? {};
40
+ const metadata = normalizeTypesenseMetadata(document);
41
+ const section = stringMetadata(document.section) ?? stringMetadata(metadata.section);
42
+ const content = stringMetadata(document.content) ?? stringMetadata(metadata.content) ?? stringMetadata(document.title) ?? '';
43
+ return {
44
+ id: stringMetadata(document.id) ?? stringMetadata(document.objectID) ?? `typesense:${index}`,
45
+ title: stringMetadata(document.title) ?? stringMetadata(metadata.title) ?? 'Result',
46
+ url: createTypesenseUrl(document, metadata),
47
+ ...(section ? { section } : {}),
48
+ excerpt: createExcerpt(content, query),
49
+ score: createTypesenseScore(hit, index),
50
+ metadata
51
+ };
52
+ }
53
+ function createTypesenseUrl(document, metadata) {
54
+ const url = stringMetadata(document.url) ?? stringMetadata(metadata.url) ?? '#';
55
+ const anchor = stringMetadata(document.anchor) ?? stringMetadata(metadata.anchor);
56
+ if (!anchor || url.includes('#'))
57
+ return url;
58
+ return `${url}#${anchor}`;
59
+ }
60
+ function normalizeTypesenseMetadata(document) {
61
+ const metadata = stringifyMetadata({
62
+ ...(document.metadata ?? {}),
63
+ locale: document.locale ?? document.metadata?.locale,
64
+ kind: document.kind ?? document.metadata?.kind
65
+ });
66
+ const embedded = stringMetadata(document.svedocs) ?? stringMetadata(document.metadata?.svedocs);
67
+ if (!embedded)
68
+ return metadata;
69
+ try {
70
+ const parsed = JSON.parse(embedded);
71
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
72
+ return metadata;
73
+ return {
74
+ ...metadata,
75
+ ...stringifyMetadata(parsed)
76
+ };
77
+ }
78
+ catch {
79
+ return metadata;
80
+ }
81
+ }
82
+ function createTypesenseScore(hit, index) {
83
+ if (typeof hit.text_match === 'number')
84
+ return hit.text_match;
85
+ const score = hit.text_match_info?.score;
86
+ if (typeof score === 'number')
87
+ return score;
88
+ if (typeof score === 'string' && Number.isFinite(Number(score)))
89
+ return Number(score);
90
+ return 1 / (index + 1);
91
+ }
@@ -0,0 +1,10 @@
1
+ export declare function createExcerpt(content: string, query: string): string;
2
+ export declare function normalizeSearchText(value: string): string;
3
+ export declare function tokenizeSearchQuery(query: string): string[];
4
+ export declare function stringMetadata(value: unknown): string | undefined;
5
+ export declare function stringifyMetadata(metadata: Record<string, unknown>): Record<string, string>;
6
+ export declare function uniqueStrings(values: string[]): string[];
7
+ export declare function jsonResponse(value: unknown, status?: number): Response;
8
+ export declare function chunkArray<T>(items: T[], size: number): T[][];
9
+ export declare function wait(ms: number): Promise<void>;
10
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/search/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAWpE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAE3D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAEjE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAM3F;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAExD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,SAAM,GAAG,QAAQ,CAOnE;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,CAO7D;AAED,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9C"}
@@ -0,0 +1,55 @@
1
+ export function createExcerpt(content, query) {
2
+ const terms = tokenizeSearchQuery(query);
3
+ const haystack = content.toLowerCase();
4
+ const index = terms.reduce((best, term) => {
5
+ const next = haystack.indexOf(term);
6
+ if (next < 0)
7
+ return best;
8
+ return best < 0 ? next : Math.min(best, next);
9
+ }, -1);
10
+ if (index < 0)
11
+ return content.slice(0, 160);
12
+ const start = Math.max(0, index - 60);
13
+ return content.slice(start, start + 180).trim();
14
+ }
15
+ export function normalizeSearchText(value) {
16
+ return value
17
+ .toLowerCase()
18
+ .normalize('NFKD')
19
+ .replace(/[\u0300-\u036f]/g, '')
20
+ .replace(/[^\p{L}\p{N}]+/gu, ' ')
21
+ .trim();
22
+ }
23
+ export function tokenizeSearchQuery(query) {
24
+ return normalizeSearchText(query).split(/\s+/).filter(Boolean);
25
+ }
26
+ export function stringMetadata(value) {
27
+ return typeof value === 'string' && value.trim() ? value : undefined;
28
+ }
29
+ export function stringifyMetadata(metadata) {
30
+ return Object.fromEntries(Object.entries(metadata)
31
+ .filter(([, value]) => value !== undefined && value !== null)
32
+ .map(([key, value]) => [key, Array.isArray(value) ? value.join(',') : String(value)]));
33
+ }
34
+ export function uniqueStrings(values) {
35
+ return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
36
+ }
37
+ export function jsonResponse(value, status = 200) {
38
+ return new Response(JSON.stringify(value), {
39
+ status,
40
+ headers: {
41
+ 'content-type': 'application/json; charset=utf-8'
42
+ }
43
+ });
44
+ }
45
+ export function chunkArray(items, size) {
46
+ const safeSize = Math.max(1, Math.floor(size));
47
+ const chunks = [];
48
+ for (let index = 0; index < items.length; index += safeSize) {
49
+ chunks.push(items.slice(index, index + safeSize));
50
+ }
51
+ return chunks;
52
+ }
53
+ export function wait(ms) {
54
+ return new Promise((resolve) => setTimeout(resolve, ms));
55
+ }
@@ -0,0 +1,8 @@
1
+ export * from './search/types.js';
2
+ export * from './search/local.js';
3
+ export * from './search/algolia.js';
4
+ export * from './search/typesense.js';
5
+ export * from './search/cloudflare.js';
6
+ export * from './search/cloudflare-sync.js';
7
+ export * from './search/runtime.js';
8
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC"}
package/dist/search.js ADDED
@@ -0,0 +1,7 @@
1
+ export * from './search/types.js';
2
+ export * from './search/local.js';
3
+ export * from './search/algolia.js';
4
+ export * from './search/typesense.js';
5
+ export * from './search/cloudflare.js';
6
+ export * from './search/cloudflare-sync.js';
7
+ export * from './search/runtime.js';
@@ -0,0 +1,24 @@
1
+ import type { MdsvexOptions } from 'mdsvex';
2
+ export declare const svedocsContentExtensions: readonly [".md", ".mdx", ".svx"];
3
+ export declare const svedocsSvelteExtensions: readonly [".svelte", ".md", ".mdx", ".svx"];
4
+ export interface SvedocsPreprocessor {
5
+ name: string;
6
+ markup(input: {
7
+ content: string;
8
+ filename?: string;
9
+ }): Promise<{
10
+ code: string;
11
+ data?: Record<string, unknown>;
12
+ map?: string;
13
+ } | undefined>;
14
+ }
15
+ export declare function svedocsPreprocess(options?: MdsvexOptions): SvedocsPreprocessor;
16
+ export declare function createSvedocsMdsvexOptions(source: string, options?: MdsvexOptions, svedocsOptions?: {
17
+ codeTheme?: string;
18
+ codeThemes?: {
19
+ light?: string;
20
+ dark?: string;
21
+ };
22
+ shikiTransformers?: unknown[];
23
+ }): MdsvexOptions;
24
+ //# sourceMappingURL=svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svelte.d.ts","sourceRoot":"","sources":["../src/svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAQ5C,eAAO,MAAM,wBAAwB,kCAAmC,CAAC;AACzE,eAAO,MAAM,uBAAuB,6CAAoD,CAAC;AAEzF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,KAAK,EAAE;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC;QACV,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,GAAG,SAAS,CAAC,CAAC;CAChB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,aAAkB,GAAG,mBAAmB,CAQlF;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,aAAkB,EAC3B,cAAc,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,CAAA;CAAO,GACzH,aAAa,CAgCf"}
package/dist/svelte.js ADDED
@@ -0,0 +1,51 @@
1
+ import { mdsvex } from 'mdsvex';
2
+ import rehypeAutolinkHeadings from 'rehype-autolink-headings';
3
+ import rehypeKatex from 'rehype-katex';
4
+ import rehypeSlug from 'rehype-slug';
5
+ import remarkGfm from 'remark-gfm';
6
+ import remarkMath from 'remark-math';
7
+ import { extractCodeBlocks, rehypeCodeBlocks, remarkSvedocsCodeBlocks } from './mdx/code.js';
8
+ export const svedocsContentExtensions = ['.md', '.mdx', '.svx'];
9
+ export const svedocsSvelteExtensions = ['.svelte', ...svedocsContentExtensions];
10
+ export function svedocsPreprocess(options = {}) {
11
+ return {
12
+ name: 'svedocs-mdsvex',
13
+ async markup(input) {
14
+ const processor = mdsvex(createSvedocsMdsvexOptions(input.content, options));
15
+ return processor.markup(input);
16
+ }
17
+ };
18
+ }
19
+ export function createSvedocsMdsvexOptions(source, options = {}, svedocsOptions = {}) {
20
+ const codeBlocks = extractCodeBlocks(source);
21
+ return {
22
+ extensions: [...svedocsContentExtensions],
23
+ ...options,
24
+ remarkPlugins: [
25
+ remarkGfm,
26
+ remarkMath,
27
+ [remarkSvedocsCodeBlocks, codeBlocks, { theme: svedocsOptions.codeTheme, themes: svedocsOptions.codeThemes, transformers: svedocsOptions.shikiTransformers }],
28
+ ...(options.remarkPlugins ?? [])
29
+ ],
30
+ rehypePlugins: [
31
+ rehypeSlug,
32
+ [
33
+ rehypeAutolinkHeadings,
34
+ {
35
+ behavior: 'append',
36
+ properties: {
37
+ className: ['sd-heading-anchor'],
38
+ ariaHidden: 'true'
39
+ },
40
+ content: {
41
+ type: 'text',
42
+ value: '#'
43
+ }
44
+ }
45
+ ],
46
+ rehypeKatex,
47
+ [rehypeCodeBlocks, codeBlocks],
48
+ ...(options.rehypePlugins ?? [])
49
+ ]
50
+ };
51
+ }
@@ -0,0 +1,3 @@
1
+ import type { SvedocsPage } from './core.js';
2
+ export declare function createFixturePage(overrides?: Partial<SvedocsPage>): SvedocsPage;
3
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CAsBnF"}
@@ -0,0 +1,23 @@
1
+ export function createFixturePage(overrides = {}) {
2
+ const id = overrides.id ?? 'index';
3
+ const routePath = overrides.routePath ?? '/';
4
+ return {
5
+ id,
6
+ sourcePath: overrides.sourcePath ?? 'content/index.md',
7
+ routePath,
8
+ scopePath: overrides.scopePath ?? routePath,
9
+ slug: overrides.slug ?? [],
10
+ kind: overrides.kind ?? 'doc',
11
+ title: overrides.title ?? 'Introduction',
12
+ html: overrides.html ?? '<h1>Introduction</h1>',
13
+ plainText: overrides.plainText ?? 'Introduction',
14
+ headings: overrides.headings ?? [],
15
+ links: overrides.links ?? [],
16
+ codeBlocks: overrides.codeBlocks ?? [],
17
+ frontmatter: overrides.frontmatter ?? {},
18
+ seo: overrides.seo ?? { title: overrides.title ?? 'Introduction' },
19
+ search: overrides.search ?? [],
20
+ lastUpdated: overrides.lastUpdated ?? '2026-05-18T00:00:00.000Z',
21
+ ...overrides
22
+ };
23
+ }