svelte-docsmith 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +57 -25
  2. package/dist/clipboard.svelte.d.ts +1 -1
  3. package/dist/clipboard.svelte.js +15 -8
  4. package/dist/config.d.ts +36 -6
  5. package/dist/config.js +33 -7
  6. package/dist/index.d.ts +4 -2
  7. package/dist/index.js +4 -0
  8. package/dist/markdown-layout.svelte +14 -1
  9. package/dist/markdown-layout.svelte.d.ts +2 -0
  10. package/dist/preprocess.d.ts +4 -5
  11. package/dist/preprocess.js +4 -5
  12. package/dist/search/context.svelte.d.ts +7 -0
  13. package/dist/search/context.svelte.js +20 -0
  14. package/dist/search/create-search.d.ts +14 -0
  15. package/dist/search/create-search.js +56 -0
  16. package/dist/search/snippet.d.ts +7 -0
  17. package/dist/search/snippet.js +43 -0
  18. package/dist/search.d.ts +10 -0
  19. package/dist/search.js +4 -0
  20. package/dist/theme.css +25 -0
  21. package/dist/types.d.ts +0 -6
  22. package/dist/ui/badge.svelte +10 -1
  23. package/dist/ui/badge.svelte.d.ts +2 -0
  24. package/dist/ui/callout.svelte +9 -9
  25. package/dist/ui/callout.svelte.d.ts +3 -3
  26. package/dist/ui/layouts/docs-header.svelte +5 -11
  27. package/dist/ui/layouts/docs-header.svelte.d.ts +0 -6
  28. package/dist/ui/layouts/docs-mobile-header.svelte +40 -8
  29. package/dist/ui/layouts/docs-mobile-header.svelte.d.ts +5 -4
  30. package/dist/ui/layouts/docs-shell.svelte +49 -5
  31. package/dist/ui/layouts/docs-shell.svelte.d.ts +16 -1
  32. package/dist/ui/layouts/error-page.svelte +82 -0
  33. package/dist/ui/layouts/error-page.svelte.d.ts +25 -0
  34. package/dist/ui/layouts/seo-head.svelte +65 -0
  35. package/dist/ui/layouts/seo-head.svelte.d.ts +11 -0
  36. package/dist/ui/markdown/h2.svelte +7 -3
  37. package/dist/ui/markdown/h3.svelte +7 -3
  38. package/dist/ui/markdown/pre.svelte +1 -1
  39. package/dist/ui/prop.svelte +71 -36
  40. package/dist/ui/prop.svelte.d.ts +1 -1
  41. package/dist/ui/props-table.svelte +10 -62
  42. package/dist/ui/search-trigger.svelte +31 -0
  43. package/dist/ui/search-trigger.svelte.d.ts +6 -0
  44. package/dist/ui/search.svelte +167 -0
  45. package/dist/ui/search.svelte.d.ts +13 -0
  46. package/dist/ui/shadcn/accordion/accordion.svelte.d.ts +1 -1
  47. package/dist/ui/shadcn/command/command-dialog.svelte +42 -0
  48. package/dist/ui/shadcn/command/command-dialog.svelte.d.ts +14 -0
  49. package/dist/ui/shadcn/command/command-empty.svelte +17 -0
  50. package/dist/ui/shadcn/command/command-empty.svelte.d.ts +4 -0
  51. package/dist/ui/shadcn/command/command-group.svelte +33 -0
  52. package/dist/ui/shadcn/command/command-group.svelte.d.ts +7 -0
  53. package/dist/ui/shadcn/command/command-input.svelte +36 -0
  54. package/dist/ui/shadcn/command/command-input.svelte.d.ts +4 -0
  55. package/dist/ui/shadcn/command/command-item.svelte +27 -0
  56. package/dist/ui/shadcn/command/command-item.svelte.d.ts +4 -0
  57. package/dist/ui/shadcn/command/command-link-item.svelte +20 -0
  58. package/dist/ui/shadcn/command/command-link-item.svelte.d.ts +4 -0
  59. package/dist/ui/shadcn/command/command-list.svelte +20 -0
  60. package/dist/ui/shadcn/command/command-list.svelte.d.ts +4 -0
  61. package/dist/ui/shadcn/command/command-loading.svelte +7 -0
  62. package/dist/ui/shadcn/command/command-loading.svelte.d.ts +4 -0
  63. package/dist/ui/shadcn/command/command-separator.svelte +17 -0
  64. package/dist/ui/shadcn/command/command-separator.svelte.d.ts +4 -0
  65. package/dist/ui/shadcn/command/command-shortcut.svelte +23 -0
  66. package/dist/ui/shadcn/command/command-shortcut.svelte.d.ts +5 -0
  67. package/dist/ui/shadcn/command/command.svelte +28 -0
  68. package/dist/ui/shadcn/command/command.svelte.d.ts +8 -0
  69. package/dist/ui/shadcn/command/index.d.ts +12 -0
  70. package/dist/ui/shadcn/command/index.js +14 -0
  71. package/dist/ui/shadcn/dialog/dialog-close.svelte +11 -0
  72. package/dist/ui/shadcn/dialog/dialog-close.svelte.d.ts +4 -0
  73. package/dist/ui/shadcn/dialog/dialog-content.svelte +48 -0
  74. package/dist/ui/shadcn/dialog/dialog-content.svelte.d.ts +13 -0
  75. package/dist/ui/shadcn/dialog/dialog-description.svelte +20 -0
  76. package/dist/ui/shadcn/dialog/dialog-description.svelte.d.ts +4 -0
  77. package/dist/ui/shadcn/dialog/dialog-footer.svelte +32 -0
  78. package/dist/ui/shadcn/dialog/dialog-footer.svelte.d.ts +8 -0
  79. package/dist/ui/shadcn/dialog/dialog-header.svelte +20 -0
  80. package/dist/ui/shadcn/dialog/dialog-header.svelte.d.ts +5 -0
  81. package/dist/ui/shadcn/dialog/dialog-overlay.svelte +20 -0
  82. package/dist/ui/shadcn/dialog/dialog-overlay.svelte.d.ts +4 -0
  83. package/dist/ui/shadcn/dialog/dialog-portal.svelte +7 -0
  84. package/dist/ui/shadcn/dialog/dialog-portal.svelte.d.ts +3 -0
  85. package/dist/ui/shadcn/dialog/dialog-title.svelte +17 -0
  86. package/dist/ui/shadcn/dialog/dialog-title.svelte.d.ts +4 -0
  87. package/dist/ui/shadcn/dialog/dialog-trigger.svelte +11 -0
  88. package/dist/ui/shadcn/dialog/dialog-trigger.svelte.d.ts +4 -0
  89. package/dist/ui/shadcn/dialog/dialog.svelte +7 -0
  90. package/dist/ui/shadcn/dialog/dialog.svelte.d.ts +3 -0
  91. package/dist/ui/shadcn/dialog/index.d.ts +11 -0
  92. package/dist/ui/shadcn/dialog/index.js +13 -0
  93. package/dist/ui/shadcn/input/index.d.ts +2 -0
  94. package/dist/ui/shadcn/input/index.js +4 -0
  95. package/dist/ui/shadcn/input/input.svelte +48 -0
  96. package/dist/ui/shadcn/input/input.svelte.d.ts +13 -0
  97. package/dist/ui/shadcn/input-group/index.d.ts +7 -0
  98. package/dist/ui/shadcn/input-group/index.js +9 -0
  99. package/dist/ui/shadcn/input-group/input-group-addon.svelte +53 -0
  100. package/dist/ui/shadcn/input-group/input-group-addon.svelte.d.ts +32 -0
  101. package/dist/ui/shadcn/input-group/input-group-button.svelte +49 -0
  102. package/dist/ui/shadcn/input-group/input-group-button.svelte.d.ts +32 -0
  103. package/dist/ui/shadcn/input-group/input-group-input.svelte +23 -0
  104. package/dist/ui/shadcn/input-group/input-group-input.svelte.d.ts +11 -0
  105. package/dist/ui/shadcn/input-group/input-group-text.svelte +22 -0
  106. package/dist/ui/shadcn/input-group/input-group-text.svelte.d.ts +5 -0
  107. package/dist/ui/shadcn/input-group/input-group-textarea.svelte +23 -0
  108. package/dist/ui/shadcn/input-group/input-group-textarea.svelte.d.ts +3 -0
  109. package/dist/ui/shadcn/input-group/input-group.svelte +24 -0
  110. package/dist/ui/shadcn/input-group/input-group.svelte.d.ts +5 -0
  111. package/dist/ui/shadcn/tabs/tabs.svelte.d.ts +1 -1
  112. package/dist/ui/shadcn/textarea/index.d.ts +2 -0
  113. package/dist/ui/shadcn/textarea/index.js +4 -0
  114. package/dist/ui/shadcn/textarea/textarea.svelte +23 -0
  115. package/dist/ui/shadcn/textarea/textarea.svelte.d.ts +5 -0
  116. package/dist/ui/tab-item.svelte +35 -9
  117. package/dist/ui/tab-item.svelte.d.ts +9 -4
  118. package/dist/ui/tabs-phase.svelte +19 -0
  119. package/dist/ui/tabs-phase.svelte.d.ts +9 -0
  120. package/dist/ui/tabs.svelte +47 -24
  121. package/dist/ui/tabs.svelte.d.ts +16 -6
  122. package/dist/vite.d.ts +8 -6
  123. package/dist/vite.js +140 -47
  124. package/package.json +8 -2
package/dist/vite.js CHANGED
@@ -1,16 +1,20 @@
1
1
  /**
2
2
  * `svelte-docsmith/vite` — the build-time half of the framework. Node context
3
- * only. One `docsmith()` call in `vite.config.ts` wires two things:
3
+ * only. One `docsmith()` call in `vite.config.ts` wires three things:
4
4
  *
5
5
  * 1. A **content index** served as the virtual module `svelte-docsmith/content`
6
6
  * — your doc pages' frontmatter, scanned at build time, so the sidebar nav
7
- * is derived from content and never hand-written. No velite, no collection
8
- * config, no aliases.
9
- * 2. The **`?source` transform** powering `LiveExample`: importing
7
+ * is derived from content and never hand-written. No collection config, no
8
+ * aliases.
9
+ * 2. A **search index** served as the virtual module `svelte-docsmith/search`
10
+ * — the same pages reduced to plain-text bodies, in a separate chunk so it
11
+ * can be lazy-loaded only when search opens.
12
+ * 3. The **`?source` transform** powering `LiveExample`: importing
10
13
  * `Component.svelte?source` yields that file's Shiki-highlighted source.
11
14
  */
12
15
  import fs from 'node:fs';
13
16
  import path from 'node:path';
17
+ import GithubSlugger from 'github-slugger';
14
18
  import yaml from 'js-yaml';
15
19
  import { DEFAULT_THEMES, lazyHighlighter } from './highlight.js';
16
20
  /**
@@ -27,6 +31,8 @@ export function docsmith(options = {}) {
27
31
  // --- content index -------------------------------------------------------
28
32
  const CONTENT_SPECIFIER = 'svelte-docsmith/content';
29
33
  const VIRTUAL_CONTENT_ID = '\0svelte-docsmith:content';
34
+ const SEARCH_SPECIFIER = 'svelte-docsmith/search';
35
+ const VIRTUAL_SEARCH_ID = '\0svelte-docsmith:search';
30
36
  const PAGE_NAMES = ['+page.md', '+page.svx'];
31
37
  function isPageFile(file) {
32
38
  return PAGE_NAMES.some((name) => file.endsWith(name));
@@ -47,18 +53,10 @@ function listPageFiles(contentDir) {
47
53
  }
48
54
  return files;
49
55
  }
50
- /** Slugify heading text the way rehype-slug (github-slugger) does for common
51
- * cases: lowercase, drop punctuation/symbols, spaces → hyphens. */
52
- function slugify(text) {
53
- return text
54
- .trim()
55
- .toLowerCase()
56
- .replace(/[^\p{L}\p{N}\s-]/gu, '')
57
- .replace(/\s+/g, '-');
58
- }
59
56
  /** Strip inline markdown so a heading's TOC label is plain text. */
60
57
  function stripInlineMarkdown(text) {
61
58
  return text
59
+ .replace(/!\[([^\]]*)\]\([^)]*\)/g, '$1')
62
60
  .replace(/`([^`]+)`/g, '$1')
63
61
  .replace(/\*\*([^*]+)\*\*/g, '$1')
64
62
  .replace(/\*([^*]+)\*/g, '$1')
@@ -66,15 +64,56 @@ function stripInlineMarkdown(text) {
66
64
  .replace(/[_~]/g, '')
67
65
  .trim();
68
66
  }
67
+ /**
68
+ * Reduce a markdown page to plain, searchable body text: prose and heading text
69
+ * with frontmatter, `<script>`/`<style>` blocks, fenced code, HTML/Svelte tags,
70
+ * and markdown punctuation removed. Feeds the generated search index. Code
71
+ * samples are intentionally dropped to keep the index small and prose-focused.
72
+ */
73
+ function extractSearchText(source) {
74
+ let body = source.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, '');
75
+ // Component/setup blocks aren't prose; drop them whole before line scanning.
76
+ body = body.replace(/<script[\s\S]*?<\/script>/gi, '').replace(/<style[\s\S]*?<\/style>/gi, '');
77
+ const out = [];
78
+ let fence = null;
79
+ for (const line of body.split('\n')) {
80
+ const f = /^\s*(`{3,}|~{3,})/.exec(line);
81
+ if (f) {
82
+ const ch = f[1][0];
83
+ if (fence === null)
84
+ fence = ch;
85
+ else if (ch === fence)
86
+ fence = null;
87
+ continue;
88
+ }
89
+ if (fence !== null)
90
+ continue;
91
+ // Skip table delimiter rows (`| --- | :--: |`) — pure structure, no words.
92
+ if (/^\s*\|?[\s:|-]+\|[\s:|-]*$/.test(line))
93
+ continue;
94
+ const text = stripInlineMarkdown(line
95
+ .replace(/<[^>]+>/g, ' ') // strip HTML/Svelte tags, keep their text content
96
+ .replace(/^\s{0,3}#{1,6}\s+/, '') // heading markers
97
+ .replace(/^\s{0,3}>\s?/, '') // blockquote markers
98
+ .replace(/^\s*[-*+]\s+/, '') // unordered list bullets
99
+ .replace(/^\s*\d+\.\s+/, '') // ordered list markers
100
+ .replace(/\s*\|\s*/g, ' ') // table cell separators → spaces, not "| a | b |"
101
+ ).replace(/\s+/g, ' ');
102
+ if (text)
103
+ out.push(text);
104
+ }
105
+ return out.join(' ');
106
+ }
69
107
  /**
70
108
  * Extract `h2`/`h3` headings from a markdown page so the in-page TOC can be
71
- * server-rendered (no post-hydration pop-in). Skips fenced code blocks; ids
72
- * match rehype-slug for typical headings, and the runtime engine's DOM re-scan
73
- * corrects any edge cases after hydration.
109
+ * server-rendered (no post-hydration pop-in). Skips fenced code blocks. Ids are
110
+ * produced with the same `github-slugger` that `rehype-slug` uses at render
111
+ * time including its duplicate-suffixing — so the SSR anchors match the real
112
+ * heading ids exactly, not just for common cases.
74
113
  */
75
114
  function extractToc(source) {
76
115
  const body = source.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, '');
77
- const seen = new Map();
116
+ const slugger = new GithubSlugger();
78
117
  const toc = [];
79
118
  let fence = null;
80
119
  for (const line of body.split('\n')) {
@@ -95,30 +134,37 @@ function extractToc(source) {
95
134
  const title = stripInlineMarkdown(m[2]);
96
135
  if (!title)
97
136
  continue;
98
- const base = slugify(title);
99
- const n = seen.get(base) ?? 0;
100
- seen.set(base, n + 1);
101
- toc.push({ id: n > 0 ? `${base}-${n}` : base, title, depth: m[1].length });
137
+ toc.push({ id: slugger.slug(title), title, depth: m[1].length });
102
138
  }
103
139
  return toc;
104
140
  }
105
141
  /**
106
- * Scan `contentDir` for `+page.md`/`+page.svx` files and read the frontmatter
107
- * fields the sidebar needs (plus the heading list for a server-rendered TOC),
108
- * deriving each page's URL from its directory relative to `routesDir`. Pure and
109
- * synchronous so it can be unit-tested.
142
+ * Walk every nav-worthy page under `contentDir` once: a page is nav-worthy when
143
+ * its frontmatter has a string `title`. Yields the raw source, parsed
144
+ * frontmatter, derived URL, and title so both the nav index and the search
145
+ * index can be built from a single read of each file.
110
146
  */
111
- export function collectDocs(contentDir, routesDir) {
112
- const items = [];
147
+ function* eachTitledPage(contentDir, routesDir) {
113
148
  for (const file of listPageFiles(contentDir)) {
114
149
  const source = fs.readFileSync(file, 'utf-8');
115
- const front = parseFrontmatter(source);
150
+ const front = parseFrontmatter(source, file);
116
151
  if (typeof front.title !== 'string')
117
- continue; // a page without a title isn't nav-worthy
152
+ continue;
118
153
  const dir = path.dirname(file);
119
154
  const url = '/' + path.relative(routesDir, dir).split(path.sep).join('/');
155
+ yield { source, front, url, title: front.title };
156
+ }
157
+ }
158
+ export function collectDocs(contentDir, routesDir) {
159
+ if (!fs.existsSync(contentDir)) {
160
+ console.warn(`[svelte-docsmith] content directory not found: ${contentDir}\n` +
161
+ ` The sidebar will be empty. Create your doc pages there, or point docsmith() at the right place with \`content\`.`);
162
+ return [];
163
+ }
164
+ const items = [];
165
+ for (const { source, front, url, title } of eachTitledPage(contentDir, routesDir)) {
120
166
  items.push({
121
- title: front.title,
167
+ title,
122
168
  path: url,
123
169
  description: typeof front.description === 'string' ? front.description : undefined,
124
170
  section: typeof front.section === 'string' ? front.section : undefined,
@@ -126,14 +172,48 @@ export function collectDocs(contentDir, routesDir) {
126
172
  toc: extractToc(source)
127
173
  });
128
174
  }
175
+ if (items.length === 0) {
176
+ console.warn(`[svelte-docsmith] no doc pages found under ${contentDir}\n` +
177
+ ` Add \`+page.md\` files with at least a \`title:\` in their frontmatter to populate the sidebar.`);
178
+ }
129
179
  // Stable output keeps the generated module diff-friendly across rebuilds.
130
180
  return items.sort((a, b) => a.path.localeCompare(b.path));
131
181
  }
132
- function parseFrontmatter(source) {
182
+ /**
183
+ * Build the search records for every page under `contentDir`: title, section,
184
+ * description, heading list, and plain-text body. Served as the lazy-loaded
185
+ * `svelte-docsmith/search` virtual module so search can index bodies without
186
+ * bloating the eagerly-imported nav index. The missing-directory case is
187
+ * already reported by {@link collectDocs}, so this stays quiet.
188
+ */
189
+ export function collectSearchDocs(contentDir, routesDir) {
190
+ if (!fs.existsSync(contentDir))
191
+ return [];
192
+ const docs = [];
193
+ for (const { source, front, url, title } of eachTitledPage(contentDir, routesDir)) {
194
+ docs.push({
195
+ path: url,
196
+ title,
197
+ section: typeof front.section === 'string' ? front.section : undefined,
198
+ description: typeof front.description === 'string' ? front.description : undefined,
199
+ headings: extractToc(source).map((entry) => entry.title),
200
+ text: extractSearchText(source)
201
+ });
202
+ }
203
+ return docs.sort((a, b) => a.path.localeCompare(b.path));
204
+ }
205
+ function parseFrontmatter(source, file) {
133
206
  const match = /^---\r?\n([\s\S]*?)\r?\n---/.exec(source);
134
207
  if (!match)
135
208
  return {};
136
- const data = yaml.load(match[1]);
209
+ let data;
210
+ try {
211
+ data = yaml.load(match[1]);
212
+ }
213
+ catch (err) {
214
+ const reason = err instanceof Error ? err.message : String(err);
215
+ throw new Error(`[svelte-docsmith] invalid YAML frontmatter in ${file}\n${reason}`);
216
+ }
137
217
  return data && typeof data === 'object' ? data : {};
138
218
  }
139
219
  function contentIndexPlugin(options) {
@@ -145,29 +225,42 @@ function contentIndexPlugin(options) {
145
225
  resolveId(id) {
146
226
  if (id === CONTENT_SPECIFIER)
147
227
  return VIRTUAL_CONTENT_ID;
228
+ if (id === SEARCH_SPECIFIER)
229
+ return VIRTUAL_SEARCH_ID;
148
230
  },
149
231
  load(id) {
150
- if (id !== VIRTUAL_CONTENT_ID)
151
- return;
152
- // Watch each page file (not the directory) so editing frontmatter
153
- // re-runs this load. A directory here is treated as an unresolvable
154
- // import by vite:import-analysis; new/removed pages are handled by
155
- // the watcher in configureServer.
156
- for (const file of listPageFiles(contentDir))
157
- this.addWatchFile(file);
158
- const docs = collectDocs(contentDir, routesDir);
159
- return `export const docs = ${JSON.stringify(docs, null, 2)};\n`;
232
+ // Watch each page file (not the directory) so editing frontmatter or
233
+ // body re-runs this load. A directory here is treated as an
234
+ // unresolvable import by vite:import-analysis; new/removed pages are
235
+ // handled by the watcher in configureServer.
236
+ if (id === VIRTUAL_CONTENT_ID) {
237
+ for (const file of listPageFiles(contentDir))
238
+ this.addWatchFile(file);
239
+ const docs = collectDocs(contentDir, routesDir);
240
+ return `export const docs = ${JSON.stringify(docs, null, 2)};\n`;
241
+ }
242
+ if (id === VIRTUAL_SEARCH_ID) {
243
+ for (const file of listPageFiles(contentDir))
244
+ this.addWatchFile(file);
245
+ const docs = collectSearchDocs(contentDir, routesDir);
246
+ return `export const docs = ${JSON.stringify(docs)};\n`;
247
+ }
160
248
  },
161
249
  configureServer(server) {
162
250
  server.watcher.add(contentDir);
163
251
  const onChange = (file) => {
164
252
  if (!isPageFile(file))
165
253
  return;
166
- const mod = server.moduleGraph.getModuleById(VIRTUAL_CONTENT_ID);
167
- if (!mod)
168
- return;
169
- server.moduleGraph.invalidateModule(mod);
170
- server.ws.send({ type: 'full-reload' });
254
+ let invalidated = false;
255
+ for (const virtualId of [VIRTUAL_CONTENT_ID, VIRTUAL_SEARCH_ID]) {
256
+ const mod = server.moduleGraph.getModuleById(virtualId);
257
+ if (!mod)
258
+ continue;
259
+ server.moduleGraph.invalidateModule(mod);
260
+ invalidated = true;
261
+ }
262
+ if (invalidated)
263
+ server.ws.send({ type: 'full-reload' });
171
264
  };
172
265
  server.watcher.on('add', onChange);
173
266
  server.watcher.on('unlink', onChange);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-docsmith",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "A framework for building beautiful documentation sites with Svelte.",
5
5
  "author": {
6
6
  "name": "George Daskalakis",
@@ -35,6 +35,10 @@
35
35
  "types": "./dist/content.d.ts",
36
36
  "default": "./dist/content.js"
37
37
  },
38
+ "./search": {
39
+ "types": "./dist/search.d.ts",
40
+ "default": "./dist/search.js"
41
+ },
38
42
  "./theme.css": "./dist/theme.css",
39
43
  "./themes/*.css": "./dist/themes/*.css",
40
44
  "./package.json": "./package.json"
@@ -77,12 +81,14 @@
77
81
  "dependencies": {
78
82
  "@fontsource-variable/inter": "^5.2.8",
79
83
  "@hbsnow/rehype-sectionize": "^1.0.7",
80
- "@lucide/svelte": "^1.23.0",
84
+ "@lucide/svelte": "^1.24.0",
81
85
  "@shikijs/transformers": "^3.3.0",
82
86
  "@tailwindcss/typography": "^0.5.16",
83
87
  "bits-ui": "^2.18.1",
84
88
  "clsx": "^2.1.1",
85
89
  "esm-env": "^1.2.2",
90
+ "flexsearch": "^0.8.212",
91
+ "github-slugger": "^2.0.0",
86
92
  "js-yaml": "^4.1.0",
87
93
  "mdsvex": "^0.12.3",
88
94
  "mode-watcher": "^1.0.2",