@tnotesjs/core 0.6.1 → 0.8.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 (92) hide show
  1. package/commands/BaseCommand.ts +58 -0
  2. package/commands/build/BuildCommand.ts +25 -0
  3. package/commands/build/PreviewCommand.ts +29 -0
  4. package/commands/build/index.ts +8 -0
  5. package/commands/dev/DevCommand.ts +75 -0
  6. package/commands/dev/index.ts +7 -0
  7. package/commands/git/PullCommand.ts +25 -0
  8. package/commands/git/PushCommand.ts +64 -0
  9. package/commands/git/index.ts +8 -0
  10. package/commands/index.ts +11 -0
  11. package/commands/init-sub-repo/InitSubRepoCommand.ts +206 -0
  12. package/commands/init-sub-repo/index.ts +1 -0
  13. package/commands/misc/HelpCommand.ts +104 -0
  14. package/commands/misc/index.ts +7 -0
  15. package/commands/models.ts +87 -0
  16. package/commands/note/CreateNoteCommand.ts +160 -0
  17. package/commands/note/RenameNoteCommand.ts +147 -0
  18. package/commands/note/UpdateNoteConfigCommand.ts +78 -0
  19. package/commands/note/index.ts +9 -0
  20. package/commands/registry.ts +47 -0
  21. package/commands/update/UpdateCommand.ts +219 -0
  22. package/commands/update/index.ts +7 -0
  23. package/commands/update-completed-count/UpdateCompletedCountCommand.ts +208 -0
  24. package/commands/update-completed-count/index.ts +5 -0
  25. package/config/templates.ts +0 -5
  26. package/dist/{chunk-5F5RJ2HV.cjs → chunk-7FEANCT6.cjs} +16 -7
  27. package/dist/chunk-AGVER5MX.cjs +1746 -0
  28. package/dist/{chunk-TJ4527KA.cjs → chunk-BL22KD4V.cjs} +324 -950
  29. package/dist/{chunk-56PKXCOX.js → chunk-GWG75A5M.js} +13 -4
  30. package/dist/{chunk-DUTS75WQ.js → chunk-XNO3PCEH.js} +374 -1000
  31. package/dist/chunk-ZEQS64PE.js +1746 -0
  32. package/dist/cli/index.cjs +76 -155
  33. package/dist/cli/index.js +10 -89
  34. package/dist/markdown/index.cjs +8 -12
  35. package/dist/markdown/index.d.cts +1 -1
  36. package/dist/markdown/index.d.ts +1 -1
  37. package/dist/markdown/index.js +7 -11
  38. package/dist/{types-CwBWwNVv.d.ts → types-C_d0fFeD.d.ts} +8 -1
  39. package/dist/{types-CpsEy8lA.d.cts → types-MRBGgJTX.d.cts} +8 -1
  40. package/dist/vitepress/config/index.cjs +402 -178
  41. package/dist/vitepress/config/index.js +392 -168
  42. package/dist/workspace/index.cjs +4 -1202
  43. package/dist/workspace/index.d.cts +2 -2
  44. package/dist/workspace/index.d.ts +2 -2
  45. package/dist/workspace/index.js +4 -1202
  46. package/markdown/components.ts +86 -0
  47. package/markdown/index.ts +17 -0
  48. package/markdown/noteFormatter.test.ts +44 -0
  49. package/markdown/noteFormatter.ts +237 -0
  50. package/package.json +7 -3
  51. package/services/file-watcher/folderChangeHandler.ts +19 -15
  52. package/services/file-watcher/globalUpdateCoordinator.ts +21 -27
  53. package/services/file-watcher/service.ts +1 -6
  54. package/services/index.ts +0 -1
  55. package/services/note/service.ts +4 -6
  56. package/services/readme/service.ts +11 -18
  57. package/services/reconcileToc.ts +20 -0
  58. package/utils/index.ts +0 -9
  59. package/{services/toc → utils}/moveTocInside.test.ts +1 -1
  60. package/vitepress/components/BilibiliOutsidePlayer/BilibiliOutsidePlayer.vue +9 -18
  61. package/vitepress/components/EnWordList/EnWordList.vue +16 -662
  62. package/vitepress/components/Footprints/Footprints.vue +15 -537
  63. package/vitepress/components/Mermaid/Mermaid.vue +13 -588
  64. package/vitepress/components/MindmapPreview/MindmapPreview.vue +12 -434
  65. package/vitepress/components/MindmapPreview/markdown.ts +1 -1
  66. package/vitepress/components/NotesTable/NotesTable.vue +11 -130
  67. package/vitepress/components/constants.ts +2 -2
  68. package/vitepress/components/sidebar.data.ts +8 -5
  69. package/vitepress/configs/markdown.config.ts +170 -26
  70. package/vitepress/plugins/sidebarStructurePlugin.ts +242 -145
  71. package/vitepress/theme/index.ts +9 -13
  72. package/vitepress/theme/styles/base.scss +15 -0
  73. package/workspace/atomic.ts +113 -0
  74. package/workspace/errors.ts +27 -0
  75. package/workspace/index.ts +40 -0
  76. package/workspace/mutationQueue.ts +28 -0
  77. package/workspace/paths.ts +64 -0
  78. package/workspace/reconcile.test.ts +300 -0
  79. package/workspace/reconcile.ts +95 -0
  80. package/workspace/scanner.ts +292 -0
  81. package/workspace/types.ts +224 -0
  82. package/workspace/workspace.test.ts +333 -0
  83. package/workspace/workspace.ts +1020 -0
  84. package/dist/chunk-3R7QSABB.cjs +0 -502
  85. package/dist/chunk-CZXRQPFJ.js +0 -11
  86. package/dist/chunk-HXED7KVT.cjs +0 -11
  87. package/dist/chunk-U6IBLREL.js +0 -502
  88. package/services/toc/index.ts +0 -5
  89. package/services/toc/service.ts +0 -759
  90. package/utils/migrateReadmeToToc.test.ts +0 -111
  91. package/utils/migrateReadmeToToc.ts +0 -135
  92. package/vitepress/components/EnWordList/RightClickMenu.vue +0 -93
@@ -1,111 +0,0 @@
1
- /**
2
- * utils/migrateReadmeToToc.test.ts
3
- */
4
-
5
- import { describe, it, expect } from 'vitest'
6
-
7
- import {
8
- extractReadmeBodyAfterToc,
9
- migrateReadmeToToc,
10
- README_TOC_END_TAG,
11
- } from './migrateReadmeToToc'
12
-
13
- const TOC_REGION = `<!-- region:toc -->
14
-
15
- - [1. Alpha](#1-alpha)
16
-
17
- ${README_TOC_END_TAG}`
18
-
19
- describe('extractReadmeBodyAfterToc', () => {
20
- it('returns lines after endregion:toc', () => {
21
- const content = `${TOC_REGION}\n\n## 1. Alpha\n- [x] [0001. A](url)`
22
- const lines = extractReadmeBodyAfterToc(content)
23
- expect(lines.some((l) => l.includes('## 1. Alpha'))).toBe(true)
24
- expect(lines.some((l) => l.includes('#1-alpha'))).toBe(false)
25
- })
26
-
27
- it('throws when endregion:toc is missing', () => {
28
- expect(() => extractReadmeBodyAfterToc('# no toc')).toThrow(
29
- README_TOC_END_TAG,
30
- )
31
- })
32
- })
33
-
34
- describe('migrateReadmeToToc', () => {
35
- it('outputs folder + nested notes for heading sections', () => {
36
- const content = `${TOC_REGION}
37
-
38
- ## 1. One
39
- - [x] [0001. Alpha](https://github.com/a/b)
40
- - [ ] [0002. Beta](https://github.com/a/b)
41
- `
42
- const { entries } = migrateReadmeToToc(content)
43
- expect(entries).toEqual([
44
- { kind: 'folder', folderTitle: '1. One', indent: 0 },
45
- { kind: 'note', noteIndex: '0001', indent: 1, completed: true },
46
- { kind: 'note', noteIndex: '0002', indent: 1, completed: false },
47
- ])
48
- })
49
-
50
- it('handles single note section with folder', () => {
51
- const content = `${TOC_REGION}
52
-
53
- ## 7. Solo
54
- - [ ] [0036. Only](https://github.com/a/b)
55
- `
56
- const { entries } = migrateReadmeToToc(content)
57
- expect(entries).toEqual([
58
- { kind: 'folder', folderTitle: '7. Solo', indent: 0 },
59
- { kind: 'note', noteIndex: '0036', indent: 1, completed: false },
60
- ])
61
- })
62
-
63
- it('treats ## and ### as separate groups', () => {
64
- const content = `${TOC_REGION}
65
-
66
- ## 1. A
67
- - [x] [0001. Alpha](url)
68
- - [ ] [0002. Beta](url)
69
- ### 1.1 B
70
- - [x] [0003. Gamma](url)
71
- - [ ] [0004. Delta](url)
72
- `
73
- const { entries } = migrateReadmeToToc(content)
74
- expect(entries).toEqual([
75
- { kind: 'folder', folderTitle: '1. A', indent: 0 },
76
- { kind: 'note', noteIndex: '0001', indent: 1, completed: true },
77
- { kind: 'note', noteIndex: '0002', indent: 1, completed: false },
78
- { kind: 'folder', folderTitle: '1.1 B', indent: 0 },
79
- { kind: 'note', noteIndex: '0003', indent: 1, completed: true },
80
- { kind: 'note', noteIndex: '0004', indent: 1, completed: false },
81
- ])
82
- })
83
-
84
- it('deduplicates note indexes with warnings', () => {
85
- const content = `${TOC_REGION}
86
-
87
- ## 1. A
88
- - [x] [0001. Alpha](url)
89
- ## 2. B
90
- - [ ] [0001. Alpha again](url)
91
- `
92
- const { entries, warnings } = migrateReadmeToToc(content)
93
- expect(entries).toHaveLength(2)
94
- expect(warnings.some((w) => w.includes('0001'))).toBe(true)
95
- })
96
-
97
- it('skips empty sections', () => {
98
- const content = `${TOC_REGION}
99
-
100
- ## Empty
101
-
102
- ## 2. B
103
- - [x] [0002. Beta](url)
104
- `
105
- const { entries } = migrateReadmeToToc(content)
106
- expect(entries).toEqual([
107
- { kind: 'folder', folderTitle: '2. B', indent: 0 },
108
- { kind: 'note', noteIndex: '0002', indent: 1, completed: true },
109
- ])
110
- })
111
- })
@@ -1,135 +0,0 @@
1
- /**
2
- * utils/migrateReadmeToToc.ts
3
- *
4
- * 从 v0.1.x 根目录 README.md 解析笔记分区,生成 TOC.md 条目(init-toc 过渡命令)
5
- */
6
-
7
- import { parseTocLine } from './tocHelpers'
8
-
9
- /** 与 TocGenerator 保持一致 */
10
- export const README_TOC_END_TAG = '<!-- endregion:toc -->'
11
-
12
- /** 迁移后的 flat TOC 条目 */
13
- export type MigratedTocEntry =
14
- | {
15
- kind: 'folder'
16
- folderTitle: string
17
- indent: number
18
- }
19
- | {
20
- kind: 'note'
21
- noteIndex: string
22
- indent: number
23
- completed: boolean
24
- }
25
-
26
- /** migrateReadmeToToc 返回结果 */
27
- export interface MigrateReadmeToTocResult {
28
- entries: MigratedTocEntry[]
29
- warnings: string[]
30
- }
31
-
32
- interface NoteGroupItem {
33
- noteIndex: string
34
- completed: boolean
35
- }
36
-
37
- interface ReadmeSection {
38
- heading: string | null
39
- items: NoteGroupItem[]
40
- }
41
-
42
- /**
43
- * 取 `<!-- endregion:toc -->` 之后的 README 正文行
44
- */
45
- export function extractReadmeBodyAfterToc(content: string): string[] {
46
- const endTagIndex = content.indexOf(README_TOC_END_TAG)
47
- if (endTagIndex === -1) {
48
- throw new Error(
49
- `README.md 中未找到 ${README_TOC_END_TAG},无法执行 init-toc 迁移`,
50
- )
51
- }
52
-
53
- const afterTag = content.slice(endTagIndex + README_TOC_END_TAG.length)
54
- return afterTag.split('\n')
55
- }
56
-
57
- /**
58
- * 从 v0.1.x README 正文解析 TOC 条目。
59
- *
60
- * 规则:
61
- * - 每个 #{2,} 标题独立成组,输出为 folder 行
62
- * - 组内笔记统一为 folder 下 indent 1 的 note 行
63
- * - 无标题组内笔记为根级 note 行
64
- */
65
- export function migrateReadmeToToc(content: string): MigrateReadmeToTocResult {
66
- const lines = extractReadmeBodyAfterToc(content)
67
- const warnings: string[] = []
68
- const seenIndexes = new Set<string>()
69
- const sections: ReadmeSection[] = []
70
- let currentHeading: string | null = null
71
- let currentGroup: NoteGroupItem[] = []
72
-
73
- const flushGroup = () => {
74
- if (currentGroup.length > 0) {
75
- sections.push({ heading: currentHeading, items: currentGroup })
76
- }
77
- currentGroup = []
78
- }
79
-
80
- for (const line of lines) {
81
- const headingMatch = line.match(/^(#{2,})\s+(.+)$/)
82
- if (headingMatch) {
83
- flushGroup()
84
- currentHeading = headingMatch[2].trim()
85
- continue
86
- }
87
-
88
- const parsed = parseTocLine(line)
89
- if (!parsed.isMatch || !parsed.noteIndex) continue
90
-
91
- if (seenIndexes.has(parsed.noteIndex)) {
92
- warnings.push(`跳过重复笔记索引: ${parsed.noteIndex}`)
93
- continue
94
- }
95
-
96
- seenIndexes.add(parsed.noteIndex)
97
- currentGroup.push({
98
- noteIndex: parsed.noteIndex,
99
- completed: parsed.completed,
100
- })
101
- }
102
-
103
- flushGroup()
104
-
105
- const entries: MigratedTocEntry[] = []
106
- for (const section of sections) {
107
- if (section.heading) {
108
- entries.push({
109
- kind: 'folder',
110
- folderTitle: section.heading,
111
- indent: 0,
112
- })
113
- for (const item of section.items) {
114
- entries.push({
115
- kind: 'note',
116
- noteIndex: item.noteIndex,
117
- indent: 1,
118
- completed: item.completed,
119
- })
120
- }
121
- continue
122
- }
123
-
124
- for (const item of section.items) {
125
- entries.push({
126
- kind: 'note',
127
- noteIndex: item.noteIndex,
128
- indent: 0,
129
- completed: item.completed,
130
- })
131
- }
132
- }
133
-
134
- return { entries, warnings }
135
- }
@@ -1,93 +0,0 @@
1
- <!--
2
- vitepress/components/EnWordList/RightClickMenu.vue
3
- -->
4
-
5
- <template>
6
- <div
7
- v-if="show"
8
- class="rightClickMenu"
9
- :style="{ left: x + 'px', top: y + 'px' }"
10
- >
11
- <div class="menuItem" @click="handlePin">📌 Pin</div>
12
- <div class="menuItem" @click="(e) => handlePronounce(e, 'en-GB')">
13
- 📢 Pronounce(英)
14
- </div>
15
- <div class="menuItem" @click="(e) => handlePronounce(e, 'en-US')">
16
- 📢 Pronounce(美)
17
- </div>
18
- <div
19
- class="menuItem"
20
- @click="(e) => handlePronounceAll(e, 'en-GB')"
21
- >
22
- 📢 Pronounce All(英)
23
- </div>
24
- <div
25
- class="menuItem"
26
- @click="(e) => handlePronounceAll(e, 'en-US')"
27
- >
28
- 📢 Pronounce All(美)
29
- </div>
30
- <div class="menuItem" @click="handleAutoShowCard">
31
- 🔍 Auto Show Card({{ isAutoShowCard ? '关' : '开' }})
32
- </div>
33
- <div class="menuItem" @click="handleCheckAll">✅ Check All</div>
34
- <div class="menuItem" @click="handleReset">❌ Reset</div>
35
- </div>
36
- </template>
37
-
38
- <script setup>
39
- const props = defineProps({
40
- show: Boolean,
41
- isAutoShowCard: Boolean,
42
- x: Number,
43
- y: Number,
44
- })
45
-
46
- const emit = defineEmits(['pin', 'pronounce'])
47
- const handlePin = (e) => {
48
- emit('pin')
49
- e.preventDefault()
50
- }
51
- const handleAutoShowCard = () => {
52
- emit('autoShowCard')
53
- }
54
- const handlePronounce = (e, lang) => {
55
- emit('pronounce', lang)
56
- e.preventDefault()
57
- }
58
- const handlePronounceAll = (e, lang) => {
59
- emit('pronounceAll', lang)
60
- e.preventDefault()
61
- }
62
- const handleCheckAll = () => {
63
- emit('checkAll')
64
- }
65
- const handleReset = () => {
66
- emit('reset')
67
- }
68
- </script>
69
-
70
- <style scoped lang="scss">
71
- // RightClickMenu 组件样式
72
-
73
- .rightClickMenu {
74
- position: fixed;
75
- z-index: 99999;
76
- background: #2c2c2c;
77
- border: 1px solid #444;
78
- border-radius: 6px;
79
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
80
- font-size: 13px;
81
- color: #eee;
82
- cursor: pointer;
83
- user-select: none;
84
- }
85
-
86
- .menuItem {
87
- padding: 8px 16px;
88
-
89
- &:hover {
90
- background-color: #444;
91
- }
92
- }
93
- </style>