@tnotesjs/core 0.5.0 → 0.6.1

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 (36) hide show
  1. package/dist/chunk-3R7QSABB.cjs +502 -0
  2. package/dist/chunk-56PKXCOX.js +176 -0
  3. package/dist/chunk-5F5RJ2HV.cjs +176 -0
  4. package/dist/chunk-CZXRQPFJ.js +11 -0
  5. package/dist/{chunk-XCWFZLER.js → chunk-DUTS75WQ.js} +27 -493
  6. package/dist/chunk-HXED7KVT.cjs +11 -0
  7. package/dist/chunk-MZIXIY2Y.cjs +216 -0
  8. package/dist/chunk-TJ4527KA.cjs +5264 -0
  9. package/dist/chunk-U6IBLREL.js +502 -0
  10. package/dist/cli/index.cjs +936 -0
  11. package/dist/cli/index.d.cts +2 -0
  12. package/dist/cli/index.d.ts +2 -0
  13. package/dist/cli/index.js +9 -6
  14. package/dist/index.cjs +8 -0
  15. package/dist/index.d.cts +56 -0
  16. package/dist/index.d.ts +56 -0
  17. package/dist/markdown/index.cjs +82 -0
  18. package/dist/markdown/index.d.cts +36 -0
  19. package/dist/markdown/index.d.ts +36 -0
  20. package/dist/markdown/index.js +82 -0
  21. package/dist/note-oGm44Rw8.d.cts +84 -0
  22. package/dist/note-oGm44Rw8.d.ts +84 -0
  23. package/dist/types-CpsEy8lA.d.cts +221 -0
  24. package/dist/types-CwBWwNVv.d.ts +221 -0
  25. package/dist/vitepress/config/index.cjs +1669 -0
  26. package/dist/vitepress/config/index.d.cts +12 -0
  27. package/dist/vitepress/config/index.d.ts +12 -0
  28. package/dist/vitepress/config/index.js +10 -4
  29. package/dist/workspace/index.cjs +1207 -0
  30. package/dist/workspace/index.d.cts +14 -0
  31. package/dist/workspace/index.d.ts +14 -0
  32. package/dist/workspace/index.js +1207 -0
  33. package/package.json +15 -2
  34. package/vitepress/components/Settings/Settings.vue +3 -3
  35. package/vitepress/components/SidebarCard/SidebarCard.vue +3 -3
  36. package/vitepress/plugins/localSearchReindexLogic.ts +11 -3
@@ -0,0 +1,1669 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+ var _chunkTJ4527KAcjs = require('../../chunk-TJ4527KA.cjs');
10
+
11
+
12
+ var _chunkMZIXIY2Ycjs = require('../../chunk-MZIXIY2Y.cjs');
13
+ require('../../chunk-3R7QSABB.cjs');
14
+
15
+
16
+ var _chunkHXED7KVTcjs = require('../../chunk-HXED7KVT.cjs');
17
+
18
+ // vitepress/config/index.ts
19
+ var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
20
+ var _path = require('path'); var _path2 = _interopRequireDefault(_path);
21
+ var _vitepress = require('vitepress');
22
+
23
+ // vitepress/config/dependencyOptimization.ts
24
+ var DEFAULT_OPTIMIZE_DEPS_INCLUDE = [
25
+ // VitePress 内部 CJS 依赖 —— 需要 Vite 预构建为 ESM
26
+ "vitepress > @vscode/markdown-it-katex",
27
+ "vitepress > @braintree/sanitize-url",
28
+ "vitepress > dayjs",
29
+ "vitepress > dayjs/plugin/utc",
30
+ "vitepress > dayjs/plugin/localizedFormat",
31
+ // Mermaid 11 的 ESM chunk 默认导入 CommonJS fastdom。pnpm 的严格
32
+ // 依赖布局下 Vite 无法从知识库根目录自动发现这条嵌套依赖,开发
33
+ // 模式会直接把 fastdom.js 当作 ESM 加载并导致整页白屏。
34
+ "@tnotesjs/core > mermaid > fastdom",
35
+ "@tnotesjs/core > mermaid > fastdom/extensions/fastdom-promised.js"
36
+ ];
37
+
38
+ // vitepress/configs/constants.ts
39
+ function getIgnoreList(config) {
40
+ return [...config.ignore_dirs.map((dir) => `**/${dir}/**`)];
41
+ }
42
+ function getGithubPageUrl(config) {
43
+ return "https://" + config.author.toLowerCase() + ".github.io/" + config.repoName + "/";
44
+ }
45
+
46
+ // vitepress/configs/head.config.ts
47
+ function getHeadConfig(config, githubPageUrl) {
48
+ const head = [
49
+ [
50
+ "meta",
51
+ {
52
+ name: "keywords",
53
+ content: config.keywords.join(", ")
54
+ }
55
+ ],
56
+ ["meta", { name: "author", content: config.author }],
57
+ ["link", { rel: "canonical", href: githubPageUrl }],
58
+ ["link", { rel: "icon", href: githubPageUrl + "favicon.ico" }],
59
+ ["link", { rel: "preconnect", href: "https://fonts.googleapis.com" }]
60
+ ];
61
+ return head;
62
+ }
63
+
64
+ // vitepress/configs/markdown.config.ts
65
+
66
+ var _markdownitcontainer = require('markdown-it-container'); var _markdownitcontainer2 = _interopRequireDefault(_markdownitcontainer);
67
+ var _markdownitlinkattributes = require('markdown-it-link-attributes'); var _markdownitlinkattributes2 = _interopRequireDefault(_markdownitlinkattributes);
68
+ var _markdownittasklists = require('markdown-it-task-lists'); var _markdownittasklists2 = _interopRequireDefault(_markdownittasklists);
69
+
70
+
71
+ // vitepress/components/MindmapPreview/markdown.ts
72
+ function cleanHeadingText(value) {
73
+ return value.trim().replace(/\s+#+\s*$/, "").trim();
74
+ }
75
+ function parseMindmapFence(openLine) {
76
+ const fenceBody = openLine.trim().replace(/^`+\s*/, "");
77
+ const nameMatch = fenceBody.match(/^mindmap(?=\s|\[|$)/);
78
+ if (!nameMatch) return null;
79
+ let rest = fenceBody.slice(nameMatch[0].length).trim();
80
+ const options = {};
81
+ const titleMatch = rest.match(/\[([^\]]+)\]/);
82
+ if (titleMatch) {
83
+ options.title = cleanHeadingText(titleMatch[1]) || void 0;
84
+ rest = `${rest.slice(0, titleMatch.index)} ${rest.slice((_nullishCoalesce(titleMatch.index, () => ( 0))) + titleMatch[0].length)}`.trim();
85
+ }
86
+ if (rest && !/^\d+$/.test(rest)) return null;
87
+ if (rest) {
88
+ options.initialExpandLevel = Math.max(1, Number(rest));
89
+ }
90
+ return options;
91
+ }
92
+ function parseMindmapReference(line) {
93
+ const match = line.trim().match(/^<<<\s+(.+?)\s*$/);
94
+ if (!match) return null;
95
+ let rest = match[1].trim();
96
+ let title;
97
+ const titleMatch = rest.match(/\s+\[([^\]]+)\]\s*$/);
98
+ if (titleMatch) {
99
+ title = cleanHeadingText(titleMatch[1]) || void 0;
100
+ rest = rest.slice(0, titleMatch.index).trim();
101
+ }
102
+ const path6 = rest.replace(/^(?:"([\s\S]*)"|'([\s\S]*)')$/, "$1$2").trim();
103
+ return path6 ? { path: path6, title } : null;
104
+ }
105
+ function normalizeMindmapMarkdown(source, options = {}) {
106
+ const lines = source.replace(/\r\n?/g, "\n").split("\n");
107
+ let existingTitle = "";
108
+ let rootIndex = -1;
109
+ for (let index = 0; index < lines.length; index++) {
110
+ const match = lines[index].match(/^\s{0,3}#(?!#)\s+(.+?)\s*$/);
111
+ if (!match) continue;
112
+ existingTitle = cleanHeadingText(match[1]);
113
+ rootIndex = index;
114
+ break;
115
+ }
116
+ const rootTitle = cleanHeadingText(options.title || existingTitle || options.defaultTitle || "root") || "root";
117
+ const body = lines.filter((_, index) => index !== rootIndex);
118
+ while (_optionalChain([body, 'access', _2 => _2[0], 'optionalAccess', _3 => _3.trim, 'call', _4 => _4()]) === "") body.shift();
119
+ while (_optionalChain([body, 'access', _5 => _5[body.length - 1], 'optionalAccess', _6 => _6.trim, 'call', _7 => _7()]) === "") body.pop();
120
+ return body.length > 0 ? `# ${rootTitle}
121
+
122
+ ${body.join("\n")}
123
+ ` : `# ${rootTitle}
124
+ `;
125
+ }
126
+
127
+ // vitepress/configs/markdown.config.ts
128
+ function esc(s = "") {
129
+ return s.replace(
130
+ /[&<>"']/g,
131
+ (ch) => ({
132
+ "&": "&amp;",
133
+ "<": "&lt;",
134
+ ">": "&gt;",
135
+ '"': "&quot;",
136
+ "'": "&#39;"
137
+ })[ch]
138
+ );
139
+ }
140
+ var simpleMermaidMarkdown = (md) => {
141
+ const fence = md.renderer.rules.fence ? md.renderer.rules.fence.bind(md.renderer.rules) : () => "";
142
+ md.renderer.rules.fence = (tokens, index, options, env, slf) => {
143
+ const token = tokens[index];
144
+ if (token.info.trim() === "mermaid") {
145
+ try {
146
+ const key = `mermaid-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
147
+ const content = token.content;
148
+ return `<Mermaid id="${key}" graph="${encodeURIComponent(content)}" />`;
149
+ } catch (err) {
150
+ return `<pre>${err}</pre>`;
151
+ }
152
+ }
153
+ if (token.info.trim() === "mmd") {
154
+ tokens[index].info = "mermaid";
155
+ }
156
+ return fence(tokens, index, options, env, slf);
157
+ };
158
+ };
159
+ function configureMindmapFence(md) {
160
+ const fence = md.renderer.rules.fence ? md.renderer.rules.fence.bind(md.renderer.rules) : () => "";
161
+ md.renderer.rules.fence = (tokens, index, options, env, slf) => {
162
+ const token = tokens[index];
163
+ const info = token.info.trim();
164
+ const fenceOptions = parseMindmapFence(info);
165
+ if (!fenceOptions) return fence(tokens, index, options, env, slf);
166
+ let content = token.content;
167
+ const firstNonEmptyLine = _nullishCoalesce(content.split("\n").find((line) => line.trim()), () => ( ""));
168
+ const reference = parseMindmapReference(firstNonEmptyLine);
169
+ if (reference) {
170
+ const possibleRel = _optionalChain([env, 'optionalAccess', _8 => _8.relativePath]) || _optionalChain([env, 'optionalAccess', _9 => _9.path]) || _optionalChain([env, 'optionalAccess', _10 => _10.filePath]) || _optionalChain([env, 'optionalAccess', _11 => _11.file]) || "";
171
+ const refFullPath = _path2.default.isAbsolute(reference.path) ? reference.path : _path2.default.resolve(process.cwd(), possibleRel ? _path2.default.dirname(possibleRel) : "", reference.path);
172
+ try {
173
+ content = _fs2.default.readFileSync(refFullPath, "utf8");
174
+ } catch (error) {
175
+ const message = error instanceof Error ? error.message : String(error);
176
+ content = `- Failed to load referenced file: ${reference.path}
177
+ - Error: ${message}`;
178
+ }
179
+ }
180
+ content = normalizeMindmapMarkdown(content, {
181
+ title: fenceOptions.title || _optionalChain([reference, 'optionalAccess', _12 => _12.title])
182
+ });
183
+ const props = [
184
+ `content="${encodeURIComponent(content.trim())}"`,
185
+ fenceOptions.initialExpandLevel === void 0 ? "" : `:initialExpandLevel="${fenceOptions.initialExpandLevel}"`
186
+ ].filter(Boolean).join(" ");
187
+ return `<MindmapPreview ${props}></MindmapPreview>
188
+ `;
189
+ };
190
+ }
191
+ function configureSwiperContainer(md) {
192
+ let __tn_swiper_uid = 0;
193
+ let __tn_rules_stack = [];
194
+ md.core.ruler.before("block", "tn_swiper_reset_uid", () => {
195
+ __tn_swiper_uid = 0;
196
+ __tn_rules_stack = [];
197
+ return true;
198
+ });
199
+ md.use(_markdownitcontainer2.default, "swiper", {
200
+ render: (tokens, idx) => {
201
+ if (tokens[idx].nesting === 1) {
202
+ __tn_rules_stack.push({
203
+ image: md.renderer.rules.image,
204
+ pOpen: md.renderer.rules.paragraph_open,
205
+ pClose: md.renderer.rules.paragraph_close
206
+ });
207
+ md.renderer.rules.paragraph_open = () => "";
208
+ md.renderer.rules.paragraph_close = () => "";
209
+ md.renderer.rules.image = (tokens2, i) => {
210
+ const token = tokens2[i];
211
+ const src = token.attrGet("src") || "";
212
+ const alt = token.content || "";
213
+ const title = alt && alt.trim() ? alt : "img";
214
+ return `<div class="swiper-slide" data-title="${esc(
215
+ title
216
+ )}"><img src="${esc(src)}" alt="${esc(alt)}"></div>`;
217
+ };
218
+ const id = `tn-swiper-${++__tn_swiper_uid}`;
219
+ return `
220
+ <div class="tn-swiper" data-swiper-id="${id}">
221
+ <div class="tn-swiper-tabs"></div>
222
+ <div class="swiper-container">
223
+ <div class="swiper-wrapper">
224
+ `;
225
+ } else {
226
+ const prev = __tn_rules_stack.pop() || {
227
+ image: null,
228
+ pOpen: null,
229
+ pClose: null
230
+ };
231
+ md.renderer.rules.image = prev.image;
232
+ md.renderer.rules.paragraph_open = prev.pOpen;
233
+ md.renderer.rules.paragraph_close = prev.pClose;
234
+ return `
235
+ </div>
236
+ <!-- \u4E0B\u4E00\u9875\u6309\u94AE -->
237
+ <!-- <div class="swiper-button-next"></div> -->
238
+ <!-- \u4E0A\u4E00\u9875\u6309\u94AE -->
239
+ <!-- <div class="swiper-button-prev"></div> -->
240
+ <!-- \u5206\u9875\u5BFC\u822A -->
241
+ <!-- <div class="swiper-pagination"></div> -->
242
+ </div>
243
+ </div>
244
+ `;
245
+ }
246
+ }
247
+ });
248
+ }
249
+ function getMarkdownConfig() {
250
+ const markdown = {
251
+ lineNumbers: true,
252
+ math: true,
253
+ config(md) {
254
+ md.core.ruler.before("normalize", "save-source", (state) => {
255
+ state.env.source = state.src;
256
+ return true;
257
+ });
258
+ simpleMermaidMarkdown(md);
259
+ configureMindmapFence(md);
260
+ md.use(_markdownittasklists2.default);
261
+ md.use(_markdownitlinkattributes2.default, {
262
+ attrs: {
263
+ target: "_self",
264
+ rel: "noopener"
265
+ }
266
+ });
267
+ configureSwiperContainer(md);
268
+ },
269
+ anchor: {
270
+ slugify: _chunkHXED7KVTcjs.generateAnchor
271
+ },
272
+ image: {
273
+ lazyLoading: true
274
+ }
275
+ };
276
+ return markdown;
277
+ }
278
+
279
+ // vitepress/configs/theme.config.ts
280
+ function getThemeConfig(config) {
281
+ const themeConfig = {
282
+ docFooter: {
283
+ prev: "\u4E0A\u4E00\u7BC7",
284
+ next: "\u4E0B\u4E00\u7BC7"
285
+ },
286
+ externalLinkIcon: true,
287
+ outline: {
288
+ level: [2, 3],
289
+ label: "\u76EE\u5F55"
290
+ },
291
+ nav: [
292
+ {
293
+ text: "\u{1F440} README",
294
+ link: "/README"
295
+ },
296
+ {
297
+ text: "Menus",
298
+ items: config.menuItems
299
+ }
300
+ ],
301
+ search: {
302
+ // 使用本地搜索(不依赖远程服务器)
303
+ provider: "local",
304
+ options: {
305
+ miniSearch: {
306
+ /**
307
+ * 控制如何对文档进行分词、字段提取等预处理
308
+ * @type {Pick<import('minisearch').Options, 'extractField' | 'tokenize' | 'processTerm'>}
309
+ */
310
+ options: {
311
+ // 自定义分词逻辑
312
+ tokenize: (text, language) => {
313
+ if (language === "zh") {
314
+ return text.match(/[\u4e00-\u9fa5]+|\S+/g) || [];
315
+ }
316
+ return text.split(/\s+/);
317
+ },
318
+ // 将所有词转为小写,确保大小写不敏感匹配
319
+ processTerm: (term) => term.toLowerCase()
320
+ },
321
+ /**
322
+ * 控制搜索时的行为(如模糊匹配、权重)
323
+ * @type {import('minisearch').SearchOptions}
324
+ * @default
325
+ * { fuzzy: 0.2, prefix: true, boost: { title: 4, text: 2, titles: 1 } }
326
+ */
327
+ searchOptions: {
328
+ fuzzy: 0.2,
329
+ // 模糊匹配阈值(0-1),允许拼写错误的阈值(数值越低越严格)
330
+ prefix: true,
331
+ // 是否启用前缀匹配(输入"jav"可匹配"javascript")
332
+ boost: {
333
+ title: 10,
334
+ // 文件名作为 h1 标题,权重最高
335
+ headings: 5,
336
+ // h2 - h6
337
+ text: 3,
338
+ // 正文内容索引
339
+ code: 1
340
+ // 代码块索引权重
341
+ }
342
+ }
343
+ },
344
+ /**
345
+ * 控制哪些 Markdown 内容参与本地搜索引擎索引
346
+ * @param {string} src 当前 Markdown 文件的原始内容(即 .md 文件中的文本)
347
+ * @param {import('vitepress').MarkdownEnv} env 包含当前页面环境信息的对象,比如 frontmatter、路径等
348
+ * @param {import('markdown-it-async')} md 一个 Markdown 渲染器实例,用来将 Markdown 转换为 HTML
349
+ */
350
+ async _render(src, env, md) {
351
+ const filePath = env.relativePath;
352
+ if (filePath.includes("TOC.md")) return "";
353
+ const notesIndex = filePath.indexOf("notes/");
354
+ let folderName = "";
355
+ if (notesIndex !== -1) {
356
+ const pathAfterNotes = filePath.slice(notesIndex + "notes/".length);
357
+ folderName = pathAfterNotes.split("/")[0];
358
+ }
359
+ const titleField = `# ${folderName}
360
+ `;
361
+ const html = md.render(titleField + "\n\n" + src, env);
362
+ return html;
363
+ }
364
+ }
365
+ },
366
+ // VitePress 只有 sidebar 非空才会渲染 sidebar 插槽,自定义侧边栏依赖这个外壳。
367
+ sidebar: [
368
+ {
369
+ text: "",
370
+ items: []
371
+ }
372
+ ],
373
+ socialLinks: config.socialLinks
374
+ };
375
+ return themeConfig;
376
+ }
377
+
378
+ // vitepress/plugins/buildProgressPlugin.ts
379
+
380
+
381
+
382
+
383
+
384
+
385
+
386
+ var CACHE_DIR = _path.join.call(void 0, process.cwd(), "node_modules", ".tnotes-progress");
387
+ var CACHE_FILE = _path.join.call(void 0, CACHE_DIR, "build-cache.json");
388
+ function getCacheData() {
389
+ try {
390
+ if (_fs.existsSync.call(void 0, CACHE_FILE)) {
391
+ return JSON.parse(_fs.readFileSync.call(void 0, CACHE_FILE, "utf-8"));
392
+ }
393
+ } catch (e) {
394
+ }
395
+ return { transformCount: 0, chunkCount: 0 };
396
+ }
397
+ function setCacheData(data) {
398
+ try {
399
+ if (!_fs.existsSync.call(void 0, CACHE_DIR)) {
400
+ _fs.mkdirSync.call(void 0, CACHE_DIR, { recursive: true });
401
+ }
402
+ _fs.writeFileSync.call(void 0, CACHE_FILE, JSON.stringify(data), "utf-8");
403
+ } catch (e2) {
404
+ }
405
+ }
406
+ var globalStartTime = 0;
407
+ var globalTransformCount = 0;
408
+ var globalChunkCount = 0;
409
+ var globalHasError = false;
410
+ var globalIsBuilding = false;
411
+ var globalOutDir = "";
412
+ var globalLastPercent = 0;
413
+ var globalLastLoggedPercent = -1;
414
+ var globalLastOutputTime = 0;
415
+ var globalTransformEndTime = 0;
416
+ var globalLastHookTime = 0;
417
+ var globalStallTimer = null;
418
+ var isTTY = !!(process.stdout.isTTY && process.stderr.isTTY);
419
+ var isCI = !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI || process.env.CIRCLECI || process.env.TRAVIS || process.env.JENKINS_URL);
420
+ var useSingleLineMode = isTTY && !isCI;
421
+ var originalStdoutWrite = null;
422
+ var originalStderrWrite = null;
423
+ function interceptOutput() {
424
+ if (originalStdoutWrite) return;
425
+ originalStdoutWrite = process.stdout.write.bind(process.stdout);
426
+ originalStderrWrite = process.stderr.write.bind(process.stderr);
427
+ const filter = (chunk) => {
428
+ const str = chunk.toString();
429
+ return str.includes("\u{1F528}") || str.includes("\u2705 \u6784\u5EFA\u6210\u529F") || str.includes("\u274C \u6784\u5EFA\u5931\u8D25") || str.includes("\u{1F4C1}") || str.includes("\u{1F4CA}") || str.includes("\u{1F4E6}") || str.includes("\u23F1\uFE0F") || str.includes("\x1B[2K");
430
+ };
431
+ process.stdout.write = ((chunk, encodingOrCallback, callback) => {
432
+ if (filter(chunk)) {
433
+ return originalStdoutWrite(chunk, encodingOrCallback, callback);
434
+ }
435
+ if (typeof encodingOrCallback === "function") encodingOrCallback();
436
+ else if (callback) callback();
437
+ return true;
438
+ });
439
+ process.stderr.write = ((chunk, encodingOrCallback, callback) => {
440
+ const str = chunk.toString();
441
+ if (filter(chunk) || str.toLowerCase().includes("error")) {
442
+ return originalStderrWrite(chunk, encodingOrCallback, callback);
443
+ }
444
+ if (typeof encodingOrCallback === "function") encodingOrCallback();
445
+ else if (callback) callback();
446
+ return true;
447
+ });
448
+ }
449
+ function restoreOutput() {
450
+ if (originalStdoutWrite) {
451
+ process.stdout.write = originalStdoutWrite;
452
+ originalStdoutWrite = null;
453
+ }
454
+ if (originalStderrWrite) {
455
+ process.stderr.write = originalStderrWrite;
456
+ originalStderrWrite = null;
457
+ }
458
+ }
459
+ function renderProgress(percent, transforms, chunks, width, complete, incomplete, isFinal = false) {
460
+ if (!originalStderrWrite) return;
461
+ if (!useSingleLineMode && !isFinal) {
462
+ const currentPercent = Math.floor(percent * 100);
463
+ const currentBucket = Math.floor(currentPercent / 10) * 10;
464
+ const now = Date.now();
465
+ if (currentBucket <= globalLastLoggedPercent || now - globalLastOutputTime < 500) {
466
+ return;
467
+ }
468
+ globalLastLoggedPercent = currentBucket;
469
+ globalLastOutputTime = now;
470
+ }
471
+ const filled = Math.floor(percent * width);
472
+ const empty = width - filled;
473
+ const bar = complete.repeat(filled) + incomplete.repeat(empty);
474
+ const percentStr = (percent * 100).toFixed(0).padStart(3, " ");
475
+ const elapsed = ((Date.now() - globalStartTime) / 1e3).toFixed(1);
476
+ const prefix = useSingleLineMode ? "\r\x1B[2K" : "";
477
+ const ending = isFinal || !useSingleLineMode ? "\n" : "";
478
+ const line = `${prefix}Building [${bar}] ${percentStr}% | Transforms: ${transforms} | Chunks: ${chunks} | Time: ${elapsed}s${ending}`;
479
+ originalStderrWrite(line);
480
+ }
481
+ function buildProgressPlugin(options = {}) {
482
+ const { width = 40, complete = "\u2588", incomplete = "\u2591" } = options;
483
+ const cache = getCacheData();
484
+ const hasCache = cache.transformCount > 0;
485
+ return {
486
+ name: "tnotes-build-progress",
487
+ enforce: "pre",
488
+ apply: "build",
489
+ config(config, { command }) {
490
+ if (command === "build") {
491
+ config.logLevel = "silent";
492
+ if (!globalIsBuilding) {
493
+ globalIsBuilding = true;
494
+ globalStartTime = Date.now();
495
+ globalTransformCount = 0;
496
+ globalChunkCount = 0;
497
+ globalHasError = false;
498
+ globalLastPercent = 0;
499
+ globalLastLoggedPercent = -1;
500
+ globalLastOutputTime = 0;
501
+ globalTransformEndTime = 0;
502
+ globalLastHookTime = Date.now();
503
+ globalOutDir = _optionalChain([config, 'access', _13 => _13.build, 'optionalAccess', _14 => _14.outDir]) || "dist";
504
+ interceptOutput();
505
+ globalStallTimer = setInterval(() => {
506
+ if (!globalIsBuilding || globalLastPercent <= 0 || globalLastPercent >= 0.98)
507
+ return;
508
+ const now = Date.now();
509
+ if (now - globalLastHookTime < 2e3) return;
510
+ const remaining = 0.98 - globalLastPercent;
511
+ globalLastPercent += remaining * 0.02;
512
+ const transformsStr = hasCache ? `${globalTransformCount}/${cache.transformCount * 2}` : `${globalTransformCount}`;
513
+ const chunksStr = hasCache ? `${globalChunkCount}/${cache.chunkCount * 2}` : `${globalChunkCount}`;
514
+ renderProgress(
515
+ globalLastPercent,
516
+ transformsStr,
517
+ chunksStr,
518
+ width,
519
+ complete,
520
+ incomplete
521
+ );
522
+ }, 1e3);
523
+ }
524
+ }
525
+ },
526
+ transform(_code, _id) {
527
+ globalTransformCount++;
528
+ globalLastHookTime = Date.now();
529
+ const transformWeight = hasCache && cache.transformEndRatio != null ? Math.max(0.1, Math.min(0.85, cache.transformEndRatio * 0.98)) : 0.85;
530
+ if (hasCache) {
531
+ const totalTransforms = cache.transformCount * 2;
532
+ globalLastPercent = Math.min(
533
+ transformWeight,
534
+ globalTransformCount / totalTransforms * transformWeight
535
+ );
536
+ } else {
537
+ const k = 500;
538
+ globalLastPercent = Math.min(
539
+ transformWeight,
540
+ transformWeight * globalTransformCount / (globalTransformCount + k)
541
+ );
542
+ }
543
+ const transformsStr = hasCache ? `${globalTransformCount}/${cache.transformCount * 2}` : `${globalTransformCount}`;
544
+ const chunksStr = hasCache ? `${globalChunkCount}/${cache.chunkCount * 2}` : `${globalChunkCount}`;
545
+ renderProgress(
546
+ globalLastPercent,
547
+ transformsStr,
548
+ chunksStr,
549
+ width,
550
+ complete,
551
+ incomplete
552
+ );
553
+ return null;
554
+ },
555
+ renderChunk() {
556
+ globalChunkCount++;
557
+ globalLastHookTime = Date.now();
558
+ if (!globalTransformEndTime) {
559
+ globalTransformEndTime = Date.now();
560
+ }
561
+ const transformWeight = hasCache && cache.transformEndRatio != null ? Math.max(0.1, Math.min(0.85, cache.transformEndRatio * 0.98)) : 0.85;
562
+ const chunkWeight = 0.98 - transformWeight;
563
+ if (hasCache) {
564
+ const totalChunks = cache.chunkCount * 2;
565
+ globalLastPercent = Math.min(
566
+ 0.98,
567
+ transformWeight + globalChunkCount / totalChunks * chunkWeight
568
+ );
569
+ } else {
570
+ globalLastPercent = Math.max(globalLastPercent, transformWeight);
571
+ globalLastPercent = Math.min(0.98, globalLastPercent + 5e-5);
572
+ }
573
+ const transformsStr = hasCache ? `${globalTransformCount}/${cache.transformCount * 2}` : `${globalTransformCount}`;
574
+ const chunksStr = hasCache ? `${globalChunkCount}/${cache.chunkCount * 2}` : `${globalChunkCount}`;
575
+ renderProgress(
576
+ globalLastPercent,
577
+ transformsStr,
578
+ chunksStr,
579
+ width,
580
+ complete,
581
+ incomplete
582
+ );
583
+ return null;
584
+ },
585
+ buildEnd(err) {
586
+ if (err) {
587
+ globalHasError = true;
588
+ }
589
+ },
590
+ closeBundle() {
591
+ setTimeout(() => {
592
+ if (!globalIsBuilding) return;
593
+ if (globalStallTimer) {
594
+ clearInterval(globalStallTimer);
595
+ globalStallTimer = null;
596
+ }
597
+ const elapsed = ((Date.now() - globalStartTime) / 1e3).toFixed(1);
598
+ const totalTransforms = hasCache ? cache.transformCount * 2 : globalTransformCount;
599
+ const totalChunks = hasCache ? cache.chunkCount * 2 : globalChunkCount;
600
+ const transformsStr = `${totalTransforms}/${totalTransforms}`;
601
+ const chunksStr = `${totalChunks}/${totalChunks}`;
602
+ renderProgress(
603
+ 1,
604
+ transformsStr,
605
+ chunksStr,
606
+ width,
607
+ complete,
608
+ incomplete,
609
+ true
610
+ );
611
+ restoreOutput();
612
+ if (!globalHasError) {
613
+ const totalTime = Date.now() - globalStartTime;
614
+ const transformTime = globalTransformEndTime ? globalTransformEndTime - globalStartTime : totalTime;
615
+ setCacheData({
616
+ transformCount: Math.floor(globalTransformCount / 2),
617
+ chunkCount: Math.floor(globalChunkCount / 2),
618
+ transformEndRatio: transformTime / totalTime
619
+ });
620
+ console.log(`\u{1F528} Rollup \u6253\u5305\u5B8C\u6210`);
621
+ console.log(` \u{1F4C1} \u8F93\u51FA\u76EE\u5F55: ${globalOutDir}`);
622
+ console.log(` \u23F1\uFE0F \u8017\u65F6: ${elapsed}s`);
623
+ console.log(` \u23F3 VitePress \u6B63\u5728\u6E32\u67D3\u9875\u9762...`);
624
+ } else {
625
+ console.log(`
626
+ \u274C \u6784\u5EFA\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u9519\u8BEF\u4FE1\u606F`);
627
+ }
628
+ globalIsBuilding = false;
629
+ }, 500);
630
+ }
631
+ };
632
+ }
633
+
634
+ // vitepress/plugins/fileWatcherBridgePlugin.ts
635
+ var RENAME_EVENT = "tnotes:note-renamed";
636
+ var BROADCAST_PATH = "/__tnotes_broadcast_rename";
637
+ function fileWatcherBridgePlugin() {
638
+ return {
639
+ name: "tnotes-file-watcher-bridge",
640
+ apply: "serve",
641
+ configureServer(server) {
642
+ server.middlewares.use((req, res, next) => {
643
+ const url = _nullishCoalesce(req.url, () => ( ""));
644
+ const isBroadcast = url === BROADCAST_PATH || url.endsWith(BROADCAST_PATH);
645
+ if (!isBroadcast || req.method !== "POST") {
646
+ return next();
647
+ }
648
+ let body = "";
649
+ req.on("data", (chunk) => {
650
+ body += chunk.toString();
651
+ });
652
+ req.on("end", () => {
653
+ try {
654
+ const data = JSON.parse(body || "{}");
655
+ server.ws.send({ type: "custom", event: RENAME_EVENT, data });
656
+ res.statusCode = 204;
657
+ res.end();
658
+ } catch (error) {
659
+ res.statusCode = 400;
660
+ res.end(
661
+ error instanceof Error ? error.message : "Bad rename payload"
662
+ );
663
+ }
664
+ });
665
+ });
666
+ }
667
+ };
668
+ }
669
+
670
+ // vitepress/plugins/getNoteByConfigIdPlugin.ts
671
+ function getNoteByConfigIdPlugin() {
672
+ return {
673
+ name: "tnotes-get-note-by-config-id",
674
+ configureServer(server) {
675
+ server.middlewares.use(async (req, res, next) => {
676
+ if (_optionalChain([req, 'access', _15 => _15.url, 'optionalAccess', _16 => _16.startsWith, 'call', _17 => _17("/__tnotes_get_note?")]) && req.method === "GET") {
677
+ try {
678
+ const url = new URL(req.url, `http://${req.headers.host}`);
679
+ const configId = url.searchParams.get("configId");
680
+ if (!configId) {
681
+ res.statusCode = 400;
682
+ res.setHeader("Content-Type", "application/json");
683
+ res.end(
684
+ JSON.stringify({
685
+ success: false,
686
+ error: "Missing configId parameter"
687
+ })
688
+ );
689
+ return;
690
+ }
691
+ const noteIndexCache = _chunkTJ4527KAcjs.NoteIndexCache.getInstance();
692
+ if (!noteIndexCache.isInitialized()) {
693
+ res.statusCode = 503;
694
+ res.setHeader("Content-Type", "application/json");
695
+ res.end(
696
+ JSON.stringify({
697
+ success: false,
698
+ error: "Service not initialized"
699
+ })
700
+ );
701
+ return;
702
+ }
703
+ const noteItem = noteIndexCache.getByConfigId(configId);
704
+ if (!noteItem) {
705
+ res.statusCode = 200;
706
+ res.setHeader("Content-Type", "application/json");
707
+ res.end(
708
+ JSON.stringify({
709
+ success: true,
710
+ found: false,
711
+ data: null
712
+ })
713
+ );
714
+ return;
715
+ }
716
+ res.statusCode = 200;
717
+ res.setHeader("Content-Type", "application/json");
718
+ res.end(
719
+ JSON.stringify({
720
+ success: true,
721
+ found: true,
722
+ data: {
723
+ noteIndex: noteItem.noteIndex,
724
+ folderName: noteItem.folderName,
725
+ // 构建笔记的完整 URL(包含 README)
726
+ url: `/notes/${encodeURIComponent(
727
+ noteItem.folderName
728
+ )}/README`
729
+ }
730
+ })
731
+ );
732
+ _chunkTJ4527KAcjs.logger.debug(
733
+ `\u67E5\u8BE2\u7B14\u8BB0: configId=${configId}, noteIndex=${noteItem.noteIndex}`
734
+ );
735
+ } catch (error) {
736
+ _chunkTJ4527KAcjs.logger.error("\u67E5\u8BE2\u7B14\u8BB0\u5931\u8D25:", error);
737
+ res.statusCode = 500;
738
+ res.setHeader("Content-Type", "application/json");
739
+ res.end(
740
+ JSON.stringify({
741
+ success: false,
742
+ error: error instanceof Error ? error.message : String(error)
743
+ })
744
+ );
745
+ }
746
+ } else {
747
+ next();
748
+ }
749
+ });
750
+ }
751
+ };
752
+ }
753
+
754
+ // vitepress/plugins/localSearchReindexPlugin.ts
755
+
756
+
757
+ // vitepress/plugins/localSearchIndexBuilder.ts
758
+ var _minisearch = require('minisearch'); var _minisearch2 = _interopRequireDefault(_minisearch);
759
+ var _promises = require('fs/promises'); var _promises2 = _interopRequireDefault(_promises);
760
+
761
+
762
+
763
+
764
+
765
+
766
+ // vitepress/plugins/localSearchReindexLogic.ts
767
+
768
+ function slash(value) {
769
+ return value.replace(/\\/g, "/");
770
+ }
771
+ var NOTE_README_RE = /(?:^|[\\/])notes[\\/](\d{4}\.[^\\/]+)[\\/]README\.md$/i;
772
+ function isNoteReadmePath(filePath, ignoreDirNames = []) {
773
+ const normalized = filePath.replace(/\\/g, "/");
774
+ const match = NOTE_README_RE.exec(normalized);
775
+ if (!match) return false;
776
+ const folderName = match[1];
777
+ if (!folderName) return false;
778
+ return !ignoreDirNames.some((dir) => folderName === dir);
779
+ }
780
+ function getDocIdFromFile(input) {
781
+ const pathApi = /^[a-zA-Z]:[\\/]/.test(
782
+ input.absoluteOrRelativeFile || input.srcDir
783
+ ) ? _path2.default.win32 : _path2.default;
784
+ const absoluteFile = pathApi.isAbsolute(input.absoluteOrRelativeFile) ? input.absoluteOrRelativeFile : pathApi.join(input.srcDir, input.absoluteOrRelativeFile);
785
+ let relFile = slash(pathApi.relative(input.srcDir, absoluteFile));
786
+ if (_optionalChain([input, 'access', _18 => _18.rewrites, 'optionalAccess', _19 => _19[relFile]])) {
787
+ relFile = input.rewrites[relFile];
788
+ }
789
+ let id = slash(_path2.default.posix.join(input.base, relFile));
790
+ id = id.replace(/(^|\/)index\.md$/, "$1");
791
+ id = id.replace(/\.md$/, input.cleanUrls ? "" : ".html");
792
+ return id;
793
+ }
794
+
795
+ // vitepress/plugins/localSearchIndexBuilder.ts
796
+ var headingRegex = /<h(\d*).*?>(.*?<a.*? href="#.*?".*?>.*?<\/a>)<\/h\1>/gi;
797
+ var headingContentRegex = /(.*?)<a.*? href="#(.*?)".*?>.*?<\/a>/i;
798
+ function slash2(value) {
799
+ return value.replace(/\\/g, "/");
800
+ }
801
+ function clearHtmlTags(str) {
802
+ return str.replace(/<[^>]*>/g, "");
803
+ }
804
+ function getSearchableText(content) {
805
+ return clearHtmlTags(content);
806
+ }
807
+ function* splitPageIntoSections(html) {
808
+ const result = html.split(headingRegex);
809
+ result.shift();
810
+ let parentTitles = [];
811
+ for (let i = 0; i < result.length; i += 3) {
812
+ const level = parseInt(result[i], 10) - 1;
813
+ const heading = result[i + 1];
814
+ const headingResult = headingContentRegex.exec(heading);
815
+ const title = clearHtmlTags(_nullishCoalesce(_optionalChain([headingResult, 'optionalAccess', _20 => _20[1]]), () => ( ""))).trim();
816
+ const anchor = _nullishCoalesce(_optionalChain([headingResult, 'optionalAccess', _21 => _21[2]]), () => ( ""));
817
+ const content = result[i + 2];
818
+ if (!title || !content) continue;
819
+ let titles = parentTitles.slice(0, level);
820
+ titles[level] = title;
821
+ titles = titles.filter(Boolean);
822
+ yield { anchor, titles, text: getSearchableText(content) };
823
+ if (level === 0) {
824
+ parentTitles = [title];
825
+ } else {
826
+ parentTitles[level] = title;
827
+ }
828
+ }
829
+ }
830
+ function getLocaleForPath(site, page) {
831
+ const normalizedPage = slash2(page);
832
+ for (const [localePath, localeConfig] of Object.entries(_nullishCoalesce(site.locales, () => ( {})))) {
833
+ const prefix = localePath.replace(/\\/g, "/");
834
+ if (prefix === "root") continue;
835
+ const normalizedPrefix = prefix.endsWith("/") ? prefix : `${prefix}/`;
836
+ if (normalizedPage.startsWith(normalizedPrefix)) {
837
+ return localePath;
838
+ }
839
+ if (_optionalChain([localeConfig, 'optionalAccess', _22 => _22.lang]) && normalizedPage === prefix.replace(/\/$/, "")) {
840
+ return localePath;
841
+ }
842
+ }
843
+ return "root";
844
+ }
845
+ async function createLocalSearchMarkdownRenderer(siteConfig) {
846
+ return _vitepress.createMarkdownRenderer.call(void 0,
847
+ siteConfig.srcDir,
848
+ siteConfig.markdown,
849
+ siteConfig.site.base,
850
+ siteConfig.logger
851
+ );
852
+ }
853
+ async function renderPageHtml(siteConfig, md, absoluteFile) {
854
+ if (!await _promises2.default.stat(absoluteFile).catch(() => null)) return "";
855
+ const srcDir = siteConfig.srcDir;
856
+ const relativePath = slash2(_path2.default.relative(srcDir, absoluteFile));
857
+ const env = {
858
+ path: absoluteFile,
859
+ relativePath,
860
+ cleanUrls: _nullishCoalesce(siteConfig.cleanUrls, () => ( false)),
861
+ frontmatter: {}
862
+ };
863
+ const options = _nullishCoalesce(_optionalChain([siteConfig, 'access', _23 => _23.site, 'access', _24 => _24.themeConfig, 'optionalAccess', _25 => _25.search, 'optionalAccess', _26 => _26.options]), () => ( {}));
864
+ const mdRaw = await _promises2.default.readFile(absoluteFile, "utf-8");
865
+ if (options._render) {
866
+ return await options._render(mdRaw, env, md);
867
+ }
868
+ const html = md.render(mdRaw, env);
869
+ return _optionalChain([env, 'access', _27 => _27.frontmatter, 'optionalAccess', _28 => _28.search]) === false ? "" : html;
870
+ }
871
+ async function indexPage(siteConfig, md, page, index) {
872
+ const absoluteFile = _path2.default.join(siteConfig.srcDir, page);
873
+ const fileId = getDocIdFromFile({
874
+ srcDir: siteConfig.srcDir,
875
+ base: siteConfig.site.base,
876
+ cleanUrls: _nullishCoalesce(siteConfig.cleanUrls, () => ( false)),
877
+ rewrites: siteConfig.rewrites.map,
878
+ absoluteOrRelativeFile: absoluteFile
879
+ });
880
+ const html = await renderPageHtml(siteConfig, md, absoluteFile);
881
+ const sections = splitPageIntoSections(html);
882
+ for (const section of sections) {
883
+ if (!section || !(section.text || section.titles)) break;
884
+ const { anchor, text, titles } = section;
885
+ const id = anchor ? [fileId, anchor].join("#") : fileId;
886
+ if (index.has(id)) index.discard(id);
887
+ index.add({
888
+ id,
889
+ text,
890
+ title: titles[titles.length - 1],
891
+ titles: titles.slice(0, -1)
892
+ });
893
+ }
894
+ }
895
+ async function buildLocalSearchIndexSnapshot(siteConfig, md) {
896
+ const { pages } = await _vitepress.resolvePages.call(void 0,
897
+ siteConfig.srcDir,
898
+ siteConfig.userConfig,
899
+ siteConfig.logger
900
+ );
901
+ const options = _nullishCoalesce(_optionalChain([siteConfig, 'access', _29 => _29.site, 'access', _30 => _30.themeConfig, 'optionalAccess', _31 => _31.search, 'optionalAccess', _32 => _32.options]), () => ( {}));
902
+ const indexByLocale = /* @__PURE__ */ new Map();
903
+ for (const page of pages) {
904
+ const locale = getLocaleForPath(siteConfig.site, page);
905
+ let index = indexByLocale.get(locale);
906
+ if (!index) {
907
+ index = new (0, _minisearch2.default)({
908
+ fields: ["title", "titles", "text"],
909
+ storeFields: ["title", "titles"],
910
+ ..._optionalChain([options, 'access', _33 => _33.miniSearch, 'optionalAccess', _34 => _34.options])
911
+ });
912
+ indexByLocale.set(locale, index);
913
+ }
914
+ await indexPage(siteConfig, md, page, index);
915
+ }
916
+ const snapshot = /* @__PURE__ */ new Map();
917
+ for (const [locale, index] of indexByLocale) {
918
+ snapshot.set(locale, JSON.stringify(JSON.stringify(index)));
919
+ }
920
+ return { snapshot, pageCount: pages.length };
921
+ }
922
+
923
+ // vitepress/plugins/localSearchReindexPatch.ts
924
+ function patchVPNavBarSearch(code) {
925
+ if (code.includes("localSearchIndexBridge")) return null;
926
+ if (!code.includes("VPLocalSearchBox")) return null;
927
+ let next = code.replace(
928
+ /<script lang="ts" setup>\r?\n/,
929
+ `<script lang="ts" setup>
930
+ import { searchBoxRemountKey } from '@tnotesjs/core/vitepress/client/localSearchIndexBridge'
931
+ `
932
+ );
933
+ next = next.replace(
934
+ /<VPLocalSearchBox\r?\n\s+v-if="showSearch"\r?\n\s+@close="showSearch = false"\r?\n\s+\/>/,
935
+ `<VPLocalSearchBox
936
+ v-if="showSearch"
937
+ :key="searchBoxRemountKey"
938
+ @close="showSearch = false"
939
+ />`
940
+ );
941
+ return next === code ? null : next;
942
+ }
943
+
944
+ // vitepress/plugins/localSearchReindexPlugin.ts
945
+ var LOCAL_SEARCH_INDEX_REQUEST_PATH = "/@localSearchIndex";
946
+ var LOCAL_SEARCH_INDEX_ID = "@localSearchIndex";
947
+ var SEARCH_REINDEX_HTTP_PATH = "/__tnotes_search_reindex";
948
+ var SEARCH_INDEX_HMR_EVENT = "tnotes:search-index-updated";
949
+ var REBUILD_DEBOUNCE_MS = 400;
950
+ var VP_NAV_BAR_SEARCH = /vitepress[/\\]dist[/\\]client[/\\]theme-default[/\\]components[/\\]VPNavBarSearch\.vue$/;
951
+ var reindexController = null;
952
+ var indexSnapshot = null;
953
+ var snapshotRevision = 0;
954
+ var DEBUG = process.env.TNOTES_DEBUG_SEARCH_REINDEX === "1";
955
+ function debugLog(message, detail) {
956
+ if (!DEBUG) return;
957
+ if (detail === void 0) {
958
+ console.log(`[tnotes:search-reindex] ${message}`);
959
+ return;
960
+ }
961
+ console.log(`[tnotes:search-reindex] ${message}`, detail);
962
+ }
963
+ function logInfo(message) {
964
+ console.warn(`[tnotes:search-reindex] ${message}`);
965
+ }
966
+ function normalizeId(id) {
967
+ return id.replace(/\\/g, "/");
968
+ }
969
+ function getVitePressSiteConfig(server) {
970
+ return _nullishCoalesce(server.config.vitepress, () => ( null));
971
+ }
972
+ function isLocalSearchEnabled(server) {
973
+ return server.config.plugins.some(
974
+ (entry) => entry.name === "vitepress:local-search" && typeof entry.load === "function"
975
+ );
976
+ }
977
+ function normalizeLocalSearchModuleId(id) {
978
+ return id.split("?")[0];
979
+ }
980
+ function getLocaleFromIndexModuleId(id) {
981
+ const normalized = normalizeLocalSearchModuleId(id);
982
+ if (normalized === LOCAL_SEARCH_INDEX_REQUEST_PATH) return null;
983
+ if (!normalized.startsWith(LOCAL_SEARCH_INDEX_REQUEST_PATH)) return null;
984
+ return normalized.slice(LOCAL_SEARCH_INDEX_REQUEST_PATH.length) || null;
985
+ }
986
+ function getSearchIndexModuleIds(snapshot) {
987
+ const ids = [LOCAL_SEARCH_INDEX_REQUEST_PATH];
988
+ for (const locale of snapshot.keys()) {
989
+ ids.push(`${LOCAL_SEARCH_INDEX_REQUEST_PATH}${locale}`);
990
+ }
991
+ return ids;
992
+ }
993
+ function notifySearchIndexUpdated(server, snapshot, revision) {
994
+ const moduleIds = getSearchIndexModuleIds(snapshot);
995
+ const updates = [];
996
+ for (const moduleId of moduleIds) {
997
+ server.moduleGraph.onFileChange(moduleId);
998
+ const mod = server.moduleGraph.getModuleById(moduleId);
999
+ if (mod) {
1000
+ server.moduleGraph.invalidateModule(mod);
1001
+ updates.push({
1002
+ acceptedPath: mod.url,
1003
+ path: mod.url,
1004
+ timestamp: Date.now(),
1005
+ type: "js-update"
1006
+ });
1007
+ continue;
1008
+ }
1009
+ debugLog(`HMR module not loaded yet: ${moduleId}`);
1010
+ }
1011
+ if (updates.length > 0) {
1012
+ server.ws.send({ type: "update", updates });
1013
+ debugLog("HMR pushed", updates.map((item) => item.path));
1014
+ } else {
1015
+ debugLog("HMR skipped: no loaded search index modules");
1016
+ }
1017
+ server.ws.send({
1018
+ type: "custom",
1019
+ event: SEARCH_INDEX_HMR_EVENT,
1020
+ data: { revision }
1021
+ });
1022
+ debugLog("custom HMR event sent", { revision });
1023
+ }
1024
+ function renderSnapshotLoad(id, snapshot) {
1025
+ const normalizedId = normalizeLocalSearchModuleId(id);
1026
+ if (normalizedId === LOCAL_SEARCH_INDEX_REQUEST_PATH) {
1027
+ const records = [];
1028
+ for (const locale2 of snapshot.keys()) {
1029
+ records.push(
1030
+ `${JSON.stringify(locale2)}: () => import('${LOCAL_SEARCH_INDEX_ID}${locale2}')`
1031
+ );
1032
+ }
1033
+ return `export default {${records.join(",")}}`;
1034
+ }
1035
+ const locale = getLocaleFromIndexModuleId(id);
1036
+ if (locale !== null) {
1037
+ const payload = _nullishCoalesce(snapshot.get(locale), () => ( JSON.stringify({})));
1038
+ return `export default ${payload}`;
1039
+ }
1040
+ return null;
1041
+ }
1042
+ function createDebouncer(delayMs) {
1043
+ let timer = null;
1044
+ let pendingReason = "";
1045
+ return (reason, task) => {
1046
+ pendingReason = reason;
1047
+ if (timer) clearTimeout(timer);
1048
+ timer = setTimeout(async () => {
1049
+ timer = null;
1050
+ const reasonToRun = pendingReason;
1051
+ pendingReason = "";
1052
+ try {
1053
+ await task();
1054
+ } catch (error) {
1055
+ console.error(
1056
+ `[tnotes:search-reindex] rebuild failed (${reasonToRun})`,
1057
+ error
1058
+ );
1059
+ }
1060
+ }, delayMs);
1061
+ };
1062
+ }
1063
+ function matchesSearchReindexPath(url) {
1064
+ return url === SEARCH_REINDEX_HTTP_PATH || url.endsWith(SEARCH_REINDEX_HTTP_PATH);
1065
+ }
1066
+ function scheduleNoteSearchReindex(reason = "external") {
1067
+ if (!reindexController) {
1068
+ logInfo(`schedule ignored (plugin not ready): ${reason}`);
1069
+ return;
1070
+ }
1071
+ reindexController.schedule(reason);
1072
+ }
1073
+ function localSearchReindexPlugin() {
1074
+ return {
1075
+ name: "tnotes-local-search-reindex",
1076
+ apply: "serve",
1077
+ enforce: "pre",
1078
+ resolveId(source) {
1079
+ if (!source.startsWith(LOCAL_SEARCH_INDEX_ID)) return null;
1080
+ const clean = source.split("?")[0];
1081
+ if (clean === source) return null;
1082
+ return `/${clean}`;
1083
+ },
1084
+ transform(code, id) {
1085
+ const normalizedId = normalizeId(id);
1086
+ if (VP_NAV_BAR_SEARCH.test(normalizedId)) {
1087
+ return patchVPNavBarSearch(code);
1088
+ }
1089
+ return null;
1090
+ },
1091
+ load(id) {
1092
+ if (!indexSnapshot || !id.startsWith(LOCAL_SEARCH_INDEX_REQUEST_PATH)) {
1093
+ return null;
1094
+ }
1095
+ return renderSnapshotLoad(id, indexSnapshot);
1096
+ },
1097
+ configureServer(server) {
1098
+ server.middlewares.use((req, res, next) => {
1099
+ const url = _nullishCoalesce(req.url, () => ( ""));
1100
+ if (!matchesSearchReindexPath(url) || req.method !== "POST") {
1101
+ return next();
1102
+ }
1103
+ let body = "";
1104
+ req.on("data", (chunk) => {
1105
+ body += chunk.toString();
1106
+ });
1107
+ req.on("end", () => {
1108
+ try {
1109
+ const data = JSON.parse(body || "{}");
1110
+ scheduleNoteSearchReindex(data.reason || "bridge:http");
1111
+ res.statusCode = 204;
1112
+ res.end();
1113
+ } catch (error) {
1114
+ res.statusCode = 400;
1115
+ res.end(
1116
+ error instanceof Error ? error.message : "Bad search reindex payload"
1117
+ );
1118
+ }
1119
+ });
1120
+ });
1121
+ return async () => {
1122
+ indexSnapshot = null;
1123
+ snapshotRevision = 0;
1124
+ if (!isLocalSearchEnabled(server)) {
1125
+ reindexController = null;
1126
+ logInfo("vitepress:local-search not found, reindex disabled");
1127
+ return;
1128
+ }
1129
+ const siteConfig = getVitePressSiteConfig(server);
1130
+ if (!siteConfig) {
1131
+ reindexController = null;
1132
+ logInfo("server.config.vitepress missing, reindex disabled");
1133
+ return;
1134
+ }
1135
+ _chunkMZIXIY2Ycjs.ConfigManager.init({ rootPath: process.cwd() });
1136
+ const ignoreDirNames = _nullishCoalesce(_chunkMZIXIY2Ycjs.ConfigManager.getInstance().getAll().ignore_dirs, () => ( []));
1137
+ const md = await createLocalSearchMarkdownRenderer(siteConfig);
1138
+ const debouncedRebuild = createDebouncer(REBUILD_DEBOUNCE_MS);
1139
+ async function rebuildFullIndex(reason) {
1140
+ const startedAt = Date.now();
1141
+ snapshotRevision += 1;
1142
+ debugLog(`rebuild start (${reason}) rev=${snapshotRevision}`);
1143
+ const { snapshot, pageCount } = await buildLocalSearchIndexSnapshot(
1144
+ siteConfig,
1145
+ md
1146
+ );
1147
+ indexSnapshot = snapshot;
1148
+ notifySearchIndexUpdated(server, indexSnapshot, snapshotRevision);
1149
+ logInfo(
1150
+ `rebuild done (${reason}) rev=${snapshotRevision} pages=${pageCount} locales=${indexSnapshot.size} elapsed=${Date.now() - startedAt}ms`
1151
+ );
1152
+ }
1153
+ reindexController = {
1154
+ schedule(reason) {
1155
+ debugLog(`scheduled (${reason})`);
1156
+ debouncedRebuild(reason, () => rebuildFullIndex(reason));
1157
+ }
1158
+ };
1159
+ const onWatcherEvent = (absoluteFile, event) => {
1160
+ if (!isNoteReadmePath(absoluteFile, ignoreDirNames)) return;
1161
+ scheduleNoteSearchReindex(
1162
+ `watcher:${event}:${_path2.default.basename(absoluteFile)}`
1163
+ );
1164
+ };
1165
+ server.watcher.on("add", (file) => onWatcherEvent(file, "add"));
1166
+ server.watcher.on("change", (file) => onWatcherEvent(file, "change"));
1167
+ server.watcher.on("unlink", (file) => onWatcherEvent(file, "unlink"));
1168
+ };
1169
+ }
1170
+ };
1171
+ }
1172
+
1173
+ // vitepress/plugins/renameNotePlugin.ts
1174
+ function renameNotePlugin() {
1175
+ const renameCommand = new (0, _chunkTJ4527KAcjs.RenameNoteCommand)();
1176
+ return {
1177
+ name: "tnotes-rename-note",
1178
+ configureServer(server) {
1179
+ server.middlewares.use(async (req, res, next) => {
1180
+ if (req.url === "/__tnotes_rename_note" && req.method === "POST") {
1181
+ let body = "";
1182
+ req.on("data", (chunk) => {
1183
+ body += chunk.toString();
1184
+ });
1185
+ req.on("end", async () => {
1186
+ try {
1187
+ const { noteIndex, newTitle } = JSON.parse(body);
1188
+ if (!noteIndex || !newTitle) {
1189
+ res.statusCode = 400;
1190
+ res.end("Missing noteIndex or newTitle");
1191
+ return;
1192
+ }
1193
+ const startTime = Date.now();
1194
+ await renameCommand.renameNote({ noteIndex, newTitle });
1195
+ const duration = Date.now() - startTime;
1196
+ const newFolderName = `${noteIndex}. ${newTitle.trim()}`;
1197
+ const newUrl = `/notes/${encodeURIComponent(
1198
+ newFolderName
1199
+ )}/README`;
1200
+ res.statusCode = 200;
1201
+ res.setHeader("Content-Type", "application/json");
1202
+ res.end(
1203
+ JSON.stringify({
1204
+ success: true,
1205
+ duration,
1206
+ newTitle,
1207
+ newFolderName,
1208
+ newUrl,
1209
+ message: "\u91CD\u547D\u540D\u5B8C\u6210"
1210
+ })
1211
+ );
1212
+ } catch (error) {
1213
+ res.statusCode = 500;
1214
+ res.end(error instanceof Error ? error.message : "Rename failed");
1215
+ }
1216
+ });
1217
+ } else {
1218
+ next();
1219
+ }
1220
+ });
1221
+ }
1222
+ };
1223
+ }
1224
+
1225
+ // vitepress/plugins/sidebarStructurePlugin.ts
1226
+ async function readJsonBody(req) {
1227
+ let body = "";
1228
+ await new Promise((resolve, reject) => {
1229
+ req.on("data", (chunk) => {
1230
+ body += chunk.toString();
1231
+ });
1232
+ req.on("end", resolve);
1233
+ req.on("error", reject);
1234
+ });
1235
+ return body ? JSON.parse(body) : {};
1236
+ }
1237
+ function sendJson(res, statusCode, payload) {
1238
+ res.statusCode = statusCode;
1239
+ res.setHeader("Content-Type", "application/json");
1240
+ res.end(JSON.stringify(payload));
1241
+ }
1242
+ function normalizePathname(url) {
1243
+ return (url || "").split("?")[0];
1244
+ }
1245
+ function normalizeCount(value) {
1246
+ const count = Number(_nullishCoalesce(value, () => ( 1)));
1247
+ if (!Number.isInteger(count) || count < 1 || count > 100) {
1248
+ throw new Error("count must be an integer between 1 and 100");
1249
+ }
1250
+ return count;
1251
+ }
1252
+ function getCreatedNotePayload(notes) {
1253
+ return notes.map((note) => ({
1254
+ index: note.index,
1255
+ dirName: note.dirName,
1256
+ link: `/notes/${encodeURIComponent(note.dirName)}/README`
1257
+ }));
1258
+ }
1259
+ function buildNoteReadmeLink(note) {
1260
+ return `/notes/${encodeURIComponent(note.dirName)}/README`;
1261
+ }
1262
+ function resolveDeleteRedirectUrl(noteService, previousNoteIndex) {
1263
+ if (!previousNoteIndex) return "/";
1264
+ const previousNote = noteService.getNoteByIndex(previousNoteIndex);
1265
+ if (!previousNote) return "/";
1266
+ return buildNoteReadmeLink(previousNote);
1267
+ }
1268
+ async function withSuspendedWatcher(task) {
1269
+ const watcher = _chunkTJ4527KAcjs.FileWatcherService.getInstance();
1270
+ try {
1271
+ _optionalChain([watcher, 'optionalAccess', _35 => _35.suspend, 'call', _36 => _36()]);
1272
+ return await task();
1273
+ } finally {
1274
+ _optionalChain([watcher, 'optionalAccess', _37 => _37.unsuspend, 'call', _38 => _38()]);
1275
+ }
1276
+ }
1277
+ function sidebarStructurePlugin() {
1278
+ const noteService = _chunkTJ4527KAcjs.NoteService.getInstance();
1279
+ const tocService = _chunkTJ4527KAcjs.TocService.getInstance();
1280
+ async function createNotes(count) {
1281
+ const notes = [];
1282
+ const usedIndexes = /* @__PURE__ */ new Set();
1283
+ for (const note of noteService.getAllNotes()) {
1284
+ const index = parseInt(note.index, 10);
1285
+ if (!isNaN(index)) {
1286
+ usedIndexes.add(index);
1287
+ }
1288
+ }
1289
+ for (let i = 0; i < count; i++) {
1290
+ const note = await noteService.createNote({
1291
+ title: "new",
1292
+ usedIndexes
1293
+ });
1294
+ const index = parseInt(note.index, 10);
1295
+ if (!isNaN(index)) {
1296
+ usedIndexes.add(index);
1297
+ }
1298
+ notes.push(note);
1299
+ }
1300
+ return notes;
1301
+ }
1302
+ async function refreshTocAndSidebar() {
1303
+ await tocService.regenerateSidebar();
1304
+ }
1305
+ return {
1306
+ name: "tnotes-sidebar-structure",
1307
+ configureServer(server) {
1308
+ server.middlewares.use(async (req, res, next) => {
1309
+ const pathname = normalizePathname(req.url);
1310
+ const handledPaths = /* @__PURE__ */ new Set([
1311
+ "/__tnotes_sidebar_create_note",
1312
+ "/__tnotes_sidebar_create_notes",
1313
+ "/__tnotes_sidebar_create_folder",
1314
+ "/__tnotes_sidebar_delete_note",
1315
+ "/__tnotes_sidebar_delete_entry",
1316
+ "/__tnotes_sidebar_rename_folder",
1317
+ "/__tnotes_sidebar_reorder"
1318
+ ]);
1319
+ if (!handledPaths.has(pathname)) {
1320
+ next();
1321
+ return;
1322
+ }
1323
+ if (req.method !== "POST") {
1324
+ sendJson(res, 405, { success: false, message: "Method Not Allowed" });
1325
+ return;
1326
+ }
1327
+ try {
1328
+ const data = await readJsonBody(req);
1329
+ const result = await withSuspendedWatcher(async () => {
1330
+ if (pathname === "/__tnotes_sidebar_delete_note") {
1331
+ const noteIndex = String(data.noteIndex || "");
1332
+ if (!noteIndex) throw new Error("Missing noteIndex");
1333
+ const previousNoteIndex = await tocService.getPreviousNoteIndexBeforeDelete(noteIndex);
1334
+ await tocService.deleteNoteFromToc(noteIndex);
1335
+ await noteService.deleteNote(noteIndex);
1336
+ await refreshTocAndSidebar();
1337
+ scheduleNoteSearchReindex("api:delete-note");
1338
+ return {
1339
+ success: true,
1340
+ sidebarChanged: true,
1341
+ redirectUrl: resolveDeleteRedirectUrl(
1342
+ noteService,
1343
+ previousNoteIndex
1344
+ ),
1345
+ redirectNoteIndex: previousNoteIndex,
1346
+ deletedNoteIndexes: [noteIndex],
1347
+ message: "\u7B14\u8BB0\u5DF2\u5220\u9664"
1348
+ };
1349
+ }
1350
+ if (pathname === "/__tnotes_sidebar_delete_entry") {
1351
+ const tocLineIndex = Number(data.tocLineIndex);
1352
+ if (!Number.isInteger(tocLineIndex) || tocLineIndex < 0) {
1353
+ throw new Error("Missing tocLineIndex");
1354
+ }
1355
+ const currentNoteIndex = String(data.currentNoteIndex || "");
1356
+ const previousNoteIndex = await tocService.getPreviousNoteIndexBeforeEntryDelete(
1357
+ tocLineIndex
1358
+ );
1359
+ const inSubtree = currentNoteIndex && await tocService.isNoteInTocEntrySubtree(
1360
+ tocLineIndex,
1361
+ currentNoteIndex
1362
+ );
1363
+ const deletedNoteIndexes = await tocService.deleteTocEntryCascade(tocLineIndex);
1364
+ await refreshTocAndSidebar();
1365
+ scheduleNoteSearchReindex("api:delete-entry");
1366
+ return {
1367
+ success: true,
1368
+ sidebarChanged: true,
1369
+ redirectUrl: inSubtree ? resolveDeleteRedirectUrl(noteService, previousNoteIndex) : void 0,
1370
+ redirectNoteIndex: inSubtree ? previousNoteIndex : null,
1371
+ deletedNoteIndexes,
1372
+ message: "\u5DF2\u5220\u9664"
1373
+ };
1374
+ }
1375
+ if (pathname === "/__tnotes_sidebar_rename_folder") {
1376
+ const tocLineIndex = Number(data.tocLineIndex);
1377
+ const newTitle = String(data.newTitle || "");
1378
+ if (!Number.isInteger(tocLineIndex) || tocLineIndex < 0) {
1379
+ throw new Error("Missing tocLineIndex");
1380
+ }
1381
+ await tocService.renameFolderInToc(tocLineIndex, newTitle);
1382
+ await refreshTocAndSidebar();
1383
+ return {
1384
+ success: true,
1385
+ sidebarChanged: true,
1386
+ message: "\u76EE\u5F55\u5DF2\u91CD\u547D\u540D"
1387
+ };
1388
+ }
1389
+ if (pathname === "/__tnotes_sidebar_reorder") {
1390
+ if (data.node_uuid && data.action === "prependChild" && !data.target_uuid) {
1391
+ await tocService.prependToRootByNodeId(String(data.node_uuid));
1392
+ await refreshTocAndSidebar();
1393
+ return {
1394
+ success: true,
1395
+ sidebarChanged: true,
1396
+ message: "\u6392\u5E8F\u5DF2\u66F4\u65B0"
1397
+ };
1398
+ }
1399
+ if (data.node_uuid && data.target_uuid && (data.action === "moveAfter" || data.action === "prependChild")) {
1400
+ if (data.action === "moveAfter") {
1401
+ await tocService.moveAfterByNodeId(
1402
+ String(data.node_uuid),
1403
+ String(data.target_uuid)
1404
+ );
1405
+ } else {
1406
+ await tocService.prependChildByNodeId(
1407
+ String(data.node_uuid),
1408
+ String(data.target_uuid)
1409
+ );
1410
+ }
1411
+ await refreshTocAndSidebar();
1412
+ return {
1413
+ success: true,
1414
+ sidebarChanged: true,
1415
+ message: "\u6392\u5E8F\u5DF2\u66F4\u65B0"
1416
+ };
1417
+ }
1418
+ const dragTocLineIndex = Number(data.dragTocLineIndex);
1419
+ if (!Number.isInteger(dragTocLineIndex) || dragTocLineIndex < 0) {
1420
+ throw new Error("Missing dragTocLineIndex");
1421
+ }
1422
+ const placement = data.targetType === "group" || data.placement === "inside" ? "inside" : data.placement === "after" ? "after" : "before";
1423
+ if (data.targetTocLineIndex !== void 0 && data.targetTocLineIndex !== null) {
1424
+ await tocService.moveTocEntryByLineIndex(dragTocLineIndex, {
1425
+ targetTocLineIndex: Number(data.targetTocLineIndex),
1426
+ placement
1427
+ });
1428
+ } else if (Array.isArray(data.targetFolderPath) && data.targetFolderPath.length > 0) {
1429
+ await tocService.moveTocEntryByLineIndex(dragTocLineIndex, {
1430
+ targetType: "folder",
1431
+ targetFolderPath: data.targetFolderPath.map(String),
1432
+ placement
1433
+ });
1434
+ } else {
1435
+ const targetNoteIndex = String(
1436
+ data.targetNoteIndex || data.targetGroupNoteIndex || ""
1437
+ );
1438
+ if (!targetNoteIndex) throw new Error("Missing targetNoteIndex");
1439
+ await tocService.moveTocEntryByLineIndex(dragTocLineIndex, {
1440
+ targetType: "note",
1441
+ targetNoteIndex,
1442
+ placement
1443
+ });
1444
+ }
1445
+ await refreshTocAndSidebar();
1446
+ return {
1447
+ success: true,
1448
+ sidebarChanged: true,
1449
+ message: "\u6392\u5E8F\u5DF2\u66F4\u65B0"
1450
+ };
1451
+ }
1452
+ if (pathname === "/__tnotes_sidebar_create_folder") {
1453
+ const parentTocLineIndex = Number(data.parentTocLineIndex);
1454
+ const title = String(data.title || "");
1455
+ if (!Number.isInteger(parentTocLineIndex) || parentTocLineIndex < 0) {
1456
+ throw new Error("Missing parentTocLineIndex");
1457
+ }
1458
+ await tocService.insertFolderUnderParent(
1459
+ parentTocLineIndex,
1460
+ title
1461
+ );
1462
+ await refreshTocAndSidebar();
1463
+ return {
1464
+ success: true,
1465
+ sidebarChanged: true,
1466
+ message: "\u76EE\u5F55\u5DF2\u521B\u5EFA"
1467
+ };
1468
+ }
1469
+ const count = normalizeCount(data.count);
1470
+ const notes = await createNotes(count);
1471
+ if (data.targetNoteIndex) {
1472
+ const placement = data.placement === "after" ? "after" : "before";
1473
+ await tocService.insertNotesAroundNote(
1474
+ String(data.targetNoteIndex),
1475
+ notes,
1476
+ placement
1477
+ );
1478
+ } else if (data.parentTocLineIndex !== void 0 && data.parentTocLineIndex !== null) {
1479
+ await tocService.insertNotesUnderTocLine(
1480
+ Number(data.parentTocLineIndex),
1481
+ notes
1482
+ );
1483
+ } else if (Array.isArray(data.parentFolderPath) && data.parentFolderPath.length > 0) {
1484
+ await tocService.insertNotesUnderFolder(
1485
+ data.parentFolderPath.map(String),
1486
+ notes
1487
+ );
1488
+ } else if (data.parentNoteIndex) {
1489
+ await tocService.insertNotesUnderParent(
1490
+ String(data.parentNoteIndex),
1491
+ notes
1492
+ );
1493
+ } else {
1494
+ for (const note of notes) {
1495
+ await tocService.appendNoteToToc(note.index);
1496
+ }
1497
+ }
1498
+ await refreshTocAndSidebar();
1499
+ scheduleNoteSearchReindex("api:create-notes");
1500
+ return {
1501
+ success: true,
1502
+ sidebarChanged: true,
1503
+ createdNotes: getCreatedNotePayload(notes),
1504
+ message: "\u7B14\u8BB0\u5DF2\u521B\u5EFA"
1505
+ };
1506
+ });
1507
+ sendJson(res, 200, result);
1508
+ } catch (error) {
1509
+ console.error("\u4FA7\u8FB9\u680F\u7ED3\u6784\u64CD\u4F5C\u5931\u8D25:", error);
1510
+ sendJson(res, 500, {
1511
+ success: false,
1512
+ message: error instanceof Error ? error.message : String(error)
1513
+ });
1514
+ }
1515
+ });
1516
+ }
1517
+ };
1518
+ }
1519
+
1520
+ // vitepress/plugins/updateConfigPlugin.ts
1521
+ function updateConfigPlugin() {
1522
+ let updateCommand;
1523
+ return {
1524
+ name: "tnotes-update-config",
1525
+ configureServer(server) {
1526
+ updateCommand = new (0, _chunkTJ4527KAcjs.UpdateNoteConfigCommand)();
1527
+ server.middlewares.use(async (req, res, next) => {
1528
+ if (req.url === "/__tnotes_update_config" && req.method === "POST") {
1529
+ let body = "";
1530
+ req.on("data", (chunk) => {
1531
+ body += chunk.toString();
1532
+ });
1533
+ req.on("end", async () => {
1534
+ try {
1535
+ const data = JSON.parse(body);
1536
+ const { noteIndex, config } = data;
1537
+ if (!noteIndex || !config) {
1538
+ res.statusCode = 400;
1539
+ res.end("Missing noteIndex or config");
1540
+ return;
1541
+ }
1542
+ await updateCommand.updateConfig({
1543
+ noteIndex,
1544
+ config: {
1545
+ done: config.done,
1546
+ enableDiscussions: config.enableDiscussions,
1547
+ description: config.description
1548
+ }
1549
+ });
1550
+ res.statusCode = 200;
1551
+ res.setHeader("Content-Type", "application/json");
1552
+ res.end(JSON.stringify({ success: true }));
1553
+ } catch (error) {
1554
+ console.error("\u66F4\u65B0\u914D\u7F6E\u5931\u8D25:", error);
1555
+ res.statusCode = 500;
1556
+ res.end(error instanceof Error ? error.message : String(error));
1557
+ }
1558
+ });
1559
+ } else {
1560
+ next();
1561
+ }
1562
+ });
1563
+ }
1564
+ };
1565
+ }
1566
+
1567
+ // vitepress/config/index.ts
1568
+ function defineNotesConfig(overrides = {}) {
1569
+ const rootPath = process.cwd();
1570
+ _chunkMZIXIY2Ycjs.ConfigManager.init({ rootPath });
1571
+ const config = _chunkMZIXIY2Ycjs.ConfigManager.getInstance().getAll();
1572
+ const { repoName } = config;
1573
+ const IGNORE_LIST = getIgnoreList(config);
1574
+ const GITHUB_PAGE_URL = getGithubPageUrl(config);
1575
+ const {
1576
+ transformPageData: overrideTransformPageData,
1577
+ vite: overrideVite,
1578
+ ...restOverrides
1579
+ } = overrides;
1580
+ return _vitepress.defineConfig.call(void 0, {
1581
+ appearance: "dark",
1582
+ base: "/" + repoName + "/",
1583
+ cleanUrls: true,
1584
+ description: repoName,
1585
+ head: getHeadConfig(config, GITHUB_PAGE_URL),
1586
+ ignoreDeadLinks: true,
1587
+ lang: "zh-Hans",
1588
+ lastUpdated: false,
1589
+ markdown: getMarkdownConfig(),
1590
+ sitemap: {
1591
+ hostname: GITHUB_PAGE_URL,
1592
+ lastmodDateOnly: false
1593
+ },
1594
+ themeConfig: getThemeConfig(config),
1595
+ title: repoName,
1596
+ srcExclude: IGNORE_LIST,
1597
+ vite: {
1598
+ plugins: [
1599
+ buildProgressPlugin(),
1600
+ updateConfigPlugin(),
1601
+ renameNotePlugin(),
1602
+ sidebarStructurePlugin(),
1603
+ getNoteByConfigIdPlugin(),
1604
+ fileWatcherBridgePlugin(),
1605
+ localSearchReindexPlugin(),
1606
+ ..._optionalChain([overrideVite, 'optionalAccess', _39 => _39.plugins]) || []
1607
+ ],
1608
+ server: {
1609
+ // 显式同时监听 IPv4 / IPv6,避免 Node 18+ 在 Windows 下偶发只绑定 ::1
1610
+ // 导致 Chrome 解析 localhost → 127.0.0.1 时连接被拒、页面一直 pending。
1611
+ // host: true,
1612
+ watch: {
1613
+ ignored: IGNORE_LIST
1614
+ },
1615
+ ..._optionalChain([overrideVite, 'optionalAccess', _40 => _40.server])
1616
+ },
1617
+ css: {
1618
+ preprocessorOptions: {
1619
+ scss: {
1620
+ silenceDeprecations: ["legacy-js-api"]
1621
+ }
1622
+ },
1623
+ ..._optionalChain([overrideVite, 'optionalAccess', _41 => _41.css])
1624
+ },
1625
+ build: {
1626
+ chunkSizeWarningLimit: 1e3,
1627
+ ..._optionalChain([overrideVite, 'optionalAccess', _42 => _42.build])
1628
+ },
1629
+ define: {
1630
+ __TNOTES_REPO_NAME__: JSON.stringify(config.repoName),
1631
+ __TNOTES_AUTHOR__: JSON.stringify(config.author),
1632
+ __TNOTES_IGNORE_DIRS__: JSON.stringify(config.ignore_dirs),
1633
+ __TNOTES_ROOT_ITEM__: JSON.stringify(config.root_item),
1634
+ ..._optionalChain([overrideVite, 'optionalAccess', _43 => _43.define])
1635
+ },
1636
+ resolve: {
1637
+ dedupe: ["vue", "vitepress"],
1638
+ ..._optionalChain([overrideVite, 'optionalAccess', _44 => _44.resolve])
1639
+ },
1640
+ optimizeDeps: {
1641
+ include: [...DEFAULT_OPTIMIZE_DEPS_INCLUDE],
1642
+ ..._optionalChain([overrideVite, 'optionalAccess', _45 => _45.optimizeDeps])
1643
+ }
1644
+ },
1645
+ transformPageData(pageData, ctx) {
1646
+ if (/^notes\/\d{4}/.test(pageData.relativePath)) {
1647
+ const fullPath = _path2.default.resolve(rootPath, pageData.relativePath);
1648
+ try {
1649
+ const raw = _fs2.default.readFileSync(fullPath, "utf-8");
1650
+ pageData.frontmatter.rawContent = Buffer.from(raw, "utf-8").toString(
1651
+ "base64"
1652
+ );
1653
+ } catch (e3) {
1654
+ pageData.frontmatter.rawContent = null;
1655
+ }
1656
+ }
1657
+ if (typeof overrideTransformPageData === "function") {
1658
+ return overrideTransformPageData(pageData, ctx);
1659
+ }
1660
+ },
1661
+ router: {
1662
+ prefetchLinks: false
1663
+ },
1664
+ ...restOverrides
1665
+ });
1666
+ }
1667
+
1668
+
1669
+ exports.defineNotesConfig = defineNotesConfig;