@tnotesjs/core 0.6.1 → 0.7.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 (42) hide show
  1. package/config/templates.ts +0 -5
  2. package/dist/{chunk-5F5RJ2HV.cjs → chunk-7FEANCT6.cjs} +16 -7
  3. package/dist/chunk-AGVER5MX.cjs +1746 -0
  4. package/dist/{chunk-TJ4527KA.cjs → chunk-BL22KD4V.cjs} +324 -950
  5. package/dist/{chunk-56PKXCOX.js → chunk-GWG75A5M.js} +13 -4
  6. package/dist/{chunk-DUTS75WQ.js → chunk-XNO3PCEH.js} +374 -1000
  7. package/dist/chunk-ZEQS64PE.js +1746 -0
  8. package/dist/cli/index.cjs +76 -155
  9. package/dist/cli/index.js +10 -89
  10. package/dist/markdown/index.cjs +2 -3
  11. package/dist/markdown/index.d.cts +1 -1
  12. package/dist/markdown/index.d.ts +1 -1
  13. package/dist/markdown/index.js +1 -2
  14. package/dist/{types-CwBWwNVv.d.ts → types-C_d0fFeD.d.ts} +8 -1
  15. package/dist/{types-CpsEy8lA.d.cts → types-MRBGgJTX.d.cts} +8 -1
  16. package/dist/vitepress/config/index.cjs +200 -132
  17. package/dist/vitepress/config/index.js +187 -119
  18. package/dist/workspace/index.cjs +4 -1202
  19. package/dist/workspace/index.d.cts +2 -2
  20. package/dist/workspace/index.d.ts +2 -2
  21. package/dist/workspace/index.js +4 -1202
  22. package/package.json +1 -1
  23. package/services/file-watcher/folderChangeHandler.ts +19 -15
  24. package/services/file-watcher/globalUpdateCoordinator.ts +21 -27
  25. package/services/file-watcher/service.ts +1 -6
  26. package/services/index.ts +0 -1
  27. package/services/note/service.ts +4 -6
  28. package/services/readme/service.ts +11 -18
  29. package/services/reconcileToc.ts +20 -0
  30. package/utils/index.ts +0 -9
  31. package/{services/toc → utils}/moveTocInside.test.ts +1 -1
  32. package/vitepress/components/constants.ts +2 -2
  33. package/vitepress/components/sidebar.data.ts +8 -5
  34. package/vitepress/plugins/sidebarStructurePlugin.ts +242 -145
  35. package/dist/chunk-3R7QSABB.cjs +0 -502
  36. package/dist/chunk-CZXRQPFJ.js +0 -11
  37. package/dist/chunk-HXED7KVT.cjs +0 -11
  38. package/dist/chunk-U6IBLREL.js +0 -502
  39. package/services/toc/index.ts +0 -5
  40. package/services/toc/service.ts +0 -759
  41. package/utils/migrateReadmeToToc.test.ts +0 -111
  42. package/utils/migrateReadmeToToc.ts +0 -135
@@ -1,19 +1,20 @@
1
1
  import {
2
2
  FileWatcherService,
3
3
  NoteIndexCache,
4
- NoteService,
4
+ ROOT_DIR_PATH,
5
5
  RenameNoteCommand,
6
- TocService,
7
6
  UpdateNoteConfigCommand,
8
7
  logger
9
- } from "../../chunk-DUTS75WQ.js";
8
+ } from "../../chunk-XNO3PCEH.js";
10
9
  import {
11
10
  ConfigManager
12
11
  } from "../../chunk-UJG3UU5X.js";
13
- import "../../chunk-U6IBLREL.js";
12
+ import {
13
+ createWorkspace
14
+ } from "../../chunk-ZEQS64PE.js";
14
15
  import {
15
16
  generateAnchor
16
- } from "../../chunk-CZXRQPFJ.js";
17
+ } from "../../chunk-GWG75A5M.js";
17
18
 
18
19
  // vitepress/config/index.ts
19
20
  import fs3 from "fs";
@@ -1249,21 +1250,8 @@ function normalizeCount(value) {
1249
1250
  }
1250
1251
  return count;
1251
1252
  }
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);
1253
+ function buildNoteReadmeLink(dirName) {
1254
+ return `/notes/${encodeURIComponent(dirName)}/README`;
1267
1255
  }
1268
1256
  async function withSuspendedWatcher(task) {
1269
1257
  const watcher = FileWatcherService.getInstance();
@@ -1274,33 +1262,78 @@ async function withSuspendedWatcher(task) {
1274
1262
  watcher?.unsuspend();
1275
1263
  }
1276
1264
  }
1277
- function sidebarStructurePlugin() {
1278
- const noteService = NoteService.getInstance();
1279
- const tocService = 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);
1265
+ function collectRefs(snapshot) {
1266
+ const byLine = /* @__PURE__ */ new Map();
1267
+ const orderedIndexes = [];
1268
+ let order = 0;
1269
+ const walk = (nodes) => {
1270
+ for (const node of nodes) {
1271
+ if (node.kind === "folder") {
1272
+ walk(node.children);
1273
+ continue;
1287
1274
  }
1288
- }
1289
- for (let i = 0; i < count; i++) {
1290
- const note = await noteService.createNote({
1291
- title: "new",
1292
- usedIndexes
1275
+ const subtree = [];
1276
+ const collect = (n) => {
1277
+ if (n.kind === "note") subtree.push(n.noteIndex);
1278
+ for (const child of n.children) collect(child);
1279
+ };
1280
+ collect(node);
1281
+ byLine.set(node.tocLineIndex, {
1282
+ tocLineIndex: node.tocLineIndex,
1283
+ ref: { type: "note", noteUuid: "" },
1284
+ subtreeIndexes: subtree,
1285
+ orderIndex: order
1293
1286
  });
1294
- const index = parseInt(note.index, 10);
1295
- if (!isNaN(index)) {
1296
- usedIndexes.add(index);
1297
- }
1298
- notes.push(note);
1287
+ orderedIndexes.push(...subtree);
1288
+ order += 1;
1299
1289
  }
1300
- return notes;
1290
+ };
1291
+ walk(snapshot.toc);
1292
+ return { byLine, orderedIndexes };
1293
+ }
1294
+ function noteUuidForIndex(snapshot, index) {
1295
+ const note = snapshot.notes.find((item) => item.index === index);
1296
+ if (!note) throw new Error(`\u672A\u627E\u5230\u7B14\u8BB0: ${index}`);
1297
+ return note.uuid;
1298
+ }
1299
+ function previousNoteIndex(snapshot, entry) {
1300
+ if (!entry) return null;
1301
+ const entries = [...collectRefs(snapshot).byLine.values()].sort(
1302
+ (a, b) => a.orderIndex - b.orderIndex
1303
+ );
1304
+ let cursor = 0;
1305
+ for (const item of entries) {
1306
+ if (item === entry) return cursor > 0 ? collectRefs(snapshot).orderedIndexes[cursor - 1] : null;
1307
+ cursor += item.subtreeIndexes.length;
1301
1308
  }
1309
+ return null;
1310
+ }
1311
+ function isNoteInSubtree(snapshot, lineIndex, noteIndex) {
1312
+ const entry = collectRefs(snapshot).byLine.get(lineIndex);
1313
+ return entry ? entry.subtreeIndexes.includes(noteIndex) : false;
1314
+ }
1315
+ function folderPathAtLine(snapshot, lineIndex) {
1316
+ const result = [];
1317
+ const walk = (nodes, path6) => {
1318
+ for (const node of nodes) {
1319
+ if (node.kind === "folder") {
1320
+ if (node.tocLineIndex === lineIndex) {
1321
+ result.push(...[...path6, node.title]);
1322
+ return true;
1323
+ }
1324
+ if (walk(node.children, [...path6, node.title])) return true;
1325
+ }
1326
+ }
1327
+ return false;
1328
+ };
1329
+ walk(snapshot.toc, []);
1330
+ if (result.length === 0) throw new Error(`\u672A\u627E\u5230\u76EE\u5F55\u884C: ${lineIndex}`);
1331
+ return result;
1332
+ }
1333
+ function sidebarStructurePlugin() {
1334
+ const workspace = createWorkspace({ rootPath: ROOT_DIR_PATH });
1302
1335
  async function refreshTocAndSidebar() {
1303
- await tocService.regenerateSidebar();
1336
+ await workspace.toc.reconcileFromFiles();
1304
1337
  }
1305
1338
  return {
1306
1339
  name: "tnotes-sidebar-structure",
@@ -1327,22 +1360,27 @@ function sidebarStructurePlugin() {
1327
1360
  try {
1328
1361
  const data = await readJsonBody(req);
1329
1362
  const result = await withSuspendedWatcher(async () => {
1363
+ const snapshot = await workspace.inspect();
1330
1364
  if (pathname === "/__tnotes_sidebar_delete_note") {
1331
1365
  const noteIndex = String(data.noteIndex || "");
1332
1366
  if (!noteIndex) throw new Error("Missing noteIndex");
1333
- const previousNoteIndex = await tocService.getPreviousNoteIndexBeforeDelete(noteIndex);
1334
- await tocService.deleteNoteFromToc(noteIndex);
1335
- await noteService.deleteNote(noteIndex);
1367
+ const refs = collectRefs(snapshot);
1368
+ const deletedRef = [...refs.byLine.values()].find(
1369
+ (item) => item.subtreeIndexes.includes(noteIndex)
1370
+ );
1371
+ const previous = previousNoteIndex(snapshot, deletedRef);
1372
+ await workspace.toc.deleteEntry({
1373
+ entry: { type: "note", noteUuid: noteUuidForIndex(snapshot, noteIndex) },
1374
+ expectedSnapshotRevision: snapshot.revision
1375
+ });
1336
1376
  await refreshTocAndSidebar();
1337
1377
  scheduleNoteSearchReindex("api:delete-note");
1378
+ const redirectDir = previous ? snapshot.notes.find((item) => item.index === previous)?.dirName : void 0;
1338
1379
  return {
1339
1380
  success: true,
1340
1381
  sidebarChanged: true,
1341
- redirectUrl: resolveDeleteRedirectUrl(
1342
- noteService,
1343
- previousNoteIndex
1344
- ),
1345
- redirectNoteIndex: previousNoteIndex,
1382
+ redirectUrl: redirectDir ? buildNoteReadmeLink(redirectDir) : "/",
1383
+ redirectNoteIndex: previous,
1346
1384
  deletedNoteIndexes: [noteIndex],
1347
1385
  message: "\u7B14\u8BB0\u5DF2\u5220\u9664"
1348
1386
  };
@@ -1353,22 +1391,26 @@ function sidebarStructurePlugin() {
1353
1391
  throw new Error("Missing tocLineIndex");
1354
1392
  }
1355
1393
  const currentNoteIndex = String(data.currentNoteIndex || "");
1356
- const previousNoteIndex = await tocService.getPreviousNoteIndexBeforeEntryDelete(
1394
+ const inSubtree = currentNoteIndex ? isNoteInSubtree(snapshot, tocLineIndex, currentNoteIndex) : false;
1395
+ const entry = collectRefs(snapshot).byLine.get(tocLineIndex);
1396
+ const previous = previousNoteIndex(snapshot, entry);
1397
+ const preview = await workspace.toc.previewDelete({
1398
+ type: "line",
1357
1399
  tocLineIndex
1358
- );
1359
- const inSubtree = currentNoteIndex && await tocService.isNoteInTocEntrySubtree(
1360
- tocLineIndex,
1361
- currentNoteIndex
1362
- );
1363
- const deletedNoteIndexes = await tocService.deleteTocEntryCascade(tocLineIndex);
1400
+ });
1401
+ await workspace.toc.deleteEntry({
1402
+ entry: { type: "line", tocLineIndex },
1403
+ expectedSnapshotRevision: snapshot.revision
1404
+ });
1364
1405
  await refreshTocAndSidebar();
1365
1406
  scheduleNoteSearchReindex("api:delete-entry");
1407
+ const redirectDir = inSubtree && previous ? snapshot.notes.find((item) => item.index === previous)?.dirName : void 0;
1366
1408
  return {
1367
1409
  success: true,
1368
1410
  sidebarChanged: true,
1369
- redirectUrl: inSubtree ? resolveDeleteRedirectUrl(noteService, previousNoteIndex) : void 0,
1370
- redirectNoteIndex: inSubtree ? previousNoteIndex : null,
1371
- deletedNoteIndexes,
1411
+ redirectUrl: redirectDir ? buildNoteReadmeLink(redirectDir) : void 0,
1412
+ redirectNoteIndex: inSubtree ? previous : null,
1413
+ deletedNoteIndexes: preview.notes.map((note) => note.index),
1372
1414
  message: "\u5DF2\u5220\u9664"
1373
1415
  };
1374
1416
  }
@@ -1378,7 +1420,11 @@ function sidebarStructurePlugin() {
1378
1420
  if (!Number.isInteger(tocLineIndex) || tocLineIndex < 0) {
1379
1421
  throw new Error("Missing tocLineIndex");
1380
1422
  }
1381
- await tocService.renameFolderInToc(tocLineIndex, newTitle);
1423
+ await workspace.toc.renameGroup({
1424
+ folderPath: folderPathAtLine(snapshot, tocLineIndex),
1425
+ title: newTitle,
1426
+ expectedSnapshotRevision: snapshot.revision
1427
+ });
1382
1428
  await refreshTocAndSidebar();
1383
1429
  return {
1384
1430
  success: true,
@@ -1387,8 +1433,20 @@ function sidebarStructurePlugin() {
1387
1433
  };
1388
1434
  }
1389
1435
  if (pathname === "/__tnotes_sidebar_reorder") {
1390
- if (data.node_uuid && data.action === "prependChild" && !data.target_uuid) {
1391
- await tocService.prependToRootByNodeId(String(data.node_uuid));
1436
+ const awaitMove = async (source2, target, placement2) => {
1437
+ await workspace.toc.move({
1438
+ source: source2,
1439
+ target,
1440
+ placement: placement2,
1441
+ expectedSnapshotRevision: snapshot.revision
1442
+ });
1443
+ };
1444
+ if (typeof data.node_uuid === "string" && data.action === "prependChild" && !data.target_uuid) {
1445
+ await awaitMove(
1446
+ { type: "note", noteUuid: data.node_uuid },
1447
+ { type: "line", tocLineIndex: 0 },
1448
+ data.placement === "after" ? "after" : "before"
1449
+ );
1392
1450
  await refreshTocAndSidebar();
1393
1451
  return {
1394
1452
  success: true,
@@ -1396,18 +1454,12 @@ function sidebarStructurePlugin() {
1396
1454
  message: "\u6392\u5E8F\u5DF2\u66F4\u65B0"
1397
1455
  };
1398
1456
  }
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
- }
1457
+ if (typeof data.node_uuid === "string" && typeof data.target_uuid === "string" && (data.action === "moveAfter" || data.action === "prependChild")) {
1458
+ await awaitMove(
1459
+ { type: "note", noteUuid: data.node_uuid },
1460
+ { type: "note", noteUuid: data.target_uuid },
1461
+ data.action === "prependChild" ? "inside" : "after"
1462
+ );
1411
1463
  await refreshTocAndSidebar();
1412
1464
  return {
1413
1465
  success: true,
@@ -1420,27 +1472,32 @@ function sidebarStructurePlugin() {
1420
1472
  throw new Error("Missing dragTocLineIndex");
1421
1473
  }
1422
1474
  const placement = data.targetType === "group" || data.placement === "inside" ? "inside" : data.placement === "after" ? "after" : "before";
1475
+ const source = { type: "line", tocLineIndex: dragTocLineIndex };
1423
1476
  if (data.targetTocLineIndex !== void 0 && data.targetTocLineIndex !== null) {
1424
- await tocService.moveTocEntryByLineIndex(dragTocLineIndex, {
1425
- targetTocLineIndex: Number(data.targetTocLineIndex),
1477
+ await awaitMove(
1478
+ source,
1479
+ { type: "line", tocLineIndex: Number(data.targetTocLineIndex) },
1426
1480
  placement
1427
- });
1481
+ );
1428
1482
  } else if (Array.isArray(data.targetFolderPath) && data.targetFolderPath.length > 0) {
1429
- await tocService.moveTocEntryByLineIndex(dragTocLineIndex, {
1430
- targetType: "folder",
1431
- targetFolderPath: data.targetFolderPath.map(String),
1483
+ await awaitMove(
1484
+ source,
1485
+ {
1486
+ type: "folder",
1487
+ folderPath: data.targetFolderPath.map(String)
1488
+ },
1432
1489
  placement
1433
- });
1490
+ );
1434
1491
  } else {
1435
- const targetNoteIndex = String(
1492
+ const targetNoteIndex2 = String(
1436
1493
  data.targetNoteIndex || data.targetGroupNoteIndex || ""
1437
1494
  );
1438
- if (!targetNoteIndex) throw new Error("Missing targetNoteIndex");
1439
- await tocService.moveTocEntryByLineIndex(dragTocLineIndex, {
1440
- targetType: "note",
1441
- targetNoteIndex,
1495
+ if (!targetNoteIndex2) throw new Error("Missing targetNoteIndex");
1496
+ await awaitMove(
1497
+ source,
1498
+ { type: "note", noteUuid: noteUuidForIndex(snapshot, targetNoteIndex2) },
1442
1499
  placement
1443
- });
1500
+ );
1444
1501
  }
1445
1502
  await refreshTocAndSidebar();
1446
1503
  return {
@@ -1455,10 +1512,13 @@ function sidebarStructurePlugin() {
1455
1512
  if (!Number.isInteger(parentTocLineIndex) || parentTocLineIndex < 0) {
1456
1513
  throw new Error("Missing parentTocLineIndex");
1457
1514
  }
1458
- await tocService.insertFolderUnderParent(
1459
- parentTocLineIndex,
1460
- title
1461
- );
1515
+ const sibling = collectRefs(snapshot).byLine.get(parentTocLineIndex);
1516
+ if (!sibling) throw new Error("\u672A\u627E\u5230\u76EE\u5F55\u884C");
1517
+ await workspace.toc.createGroup({
1518
+ title,
1519
+ placement: sibling.ref.type === "note" ? { type: "note", targetNoteUuid: sibling.ref.noteUuid, placement: "inside" } : { type: "root", placement: "end" },
1520
+ expectedSnapshotRevision: snapshot.revision
1521
+ });
1462
1522
  await refreshTocAndSidebar();
1463
1523
  return {
1464
1524
  success: true,
@@ -1467,40 +1527,48 @@ function sidebarStructurePlugin() {
1467
1527
  };
1468
1528
  }
1469
1529
  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);
1530
+ const targetNoteIndex = String(
1531
+ data.targetNoteIndex || data.targetGroupNoteIndex || ""
1532
+ );
1533
+ const parentLine = data.parentTocLineIndex !== void 0 && data.parentTocLineIndex !== null ? Number(data.parentTocLineIndex) : null;
1534
+ const created = [];
1535
+ for (let i = 0; i < count; i++) {
1536
+ let placement;
1537
+ if (targetNoteIndex) {
1538
+ placement = {
1539
+ type: "note",
1540
+ targetNoteUuid: noteUuidForIndex(snapshot, targetNoteIndex),
1541
+ placement: data.placement === "after" ? "after" : "before"
1542
+ };
1543
+ } else if (parentLine !== null) {
1544
+ const sibling = collectRefs(snapshot).byLine.get(parentLine);
1545
+ if (sibling && sibling.ref.type === "note") {
1546
+ placement = {
1547
+ type: "note",
1548
+ targetNoteUuid: sibling.ref.noteUuid,
1549
+ placement: "inside"
1550
+ };
1551
+ }
1496
1552
  }
1553
+ const result2 = await workspace.notes.create({
1554
+ title: "new",
1555
+ placement,
1556
+ expectedSnapshotRevision: snapshot.revision
1557
+ });
1558
+ created.push({
1559
+ index: result2.value.index,
1560
+ dirName: result2.value.dirName
1561
+ });
1497
1562
  }
1498
1563
  await refreshTocAndSidebar();
1499
1564
  scheduleNoteSearchReindex("api:create-notes");
1500
1565
  return {
1501
1566
  success: true,
1502
1567
  sidebarChanged: true,
1503
- createdNotes: getCreatedNotePayload(notes),
1568
+ createdNotes: created.map((note) => ({
1569
+ ...note,
1570
+ link: buildNoteReadmeLink(note.dirName)
1571
+ })),
1504
1572
  message: "\u7B14\u8BB0\u5DF2\u521B\u5EFA"
1505
1573
  };
1506
1574
  });