@mp-lb/mdkit 0.3.2 → 0.3.4

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 (160) hide show
  1. package/README.md +8 -2
  2. package/dist/collaboration/useMdKitCollaboration.d.ts +5 -0
  3. package/dist/collaboration/useMdKitCollaboration.d.ts.map +1 -0
  4. package/dist/collaboration/useMdKitCollaboration.js +4 -0
  5. package/dist/core/checkpointPolicy.d.ts +10 -0
  6. package/dist/core/checkpointPolicy.d.ts.map +1 -0
  7. package/dist/core/checkpointPolicy.js +9 -0
  8. package/dist/core/documentEngine.d.ts +1 -0
  9. package/dist/core/documentEngine.d.ts.map +1 -0
  10. package/dist/core/index.d.ts +1 -0
  11. package/dist/core/index.d.ts.map +1 -0
  12. package/dist/document/MdKitConflictPanel.d.ts +5 -0
  13. package/dist/document/MdKitConflictPanel.d.ts.map +1 -0
  14. package/dist/document/MdKitConflictPanel.js +4 -0
  15. package/dist/document/MdKitDocumentToolbar.d.ts +6 -0
  16. package/dist/document/MdKitDocumentToolbar.d.ts.map +1 -0
  17. package/dist/document/MdKitDocumentToolbar.js +5 -0
  18. package/dist/document/documentTypes.d.ts +6 -0
  19. package/dist/document/documentTypes.d.ts.map +1 -0
  20. package/dist/document/useMdKitDocument.d.ts +5 -0
  21. package/dist/document/useMdKitDocument.d.ts.map +1 -0
  22. package/dist/document/useMdKitDocument.js +4 -0
  23. package/dist/fastify.d.ts +1 -0
  24. package/dist/fastify.d.ts.map +1 -0
  25. package/dist/index.d.ts +4 -1
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/markdown/MarkdownBubbleMenu.d.ts +1 -0
  28. package/dist/markdown/MarkdownBubbleMenu.d.ts.map +1 -0
  29. package/dist/markdown/MarkdownPasteExtension.d.ts +1 -0
  30. package/dist/markdown/MarkdownPasteExtension.d.ts.map +1 -0
  31. package/dist/markdown/MarkdownSearchExtension.d.ts +1 -0
  32. package/dist/markdown/MarkdownSearchExtension.d.ts.map +1 -0
  33. package/dist/markdown/MarkdownSearchPanel.d.ts +1 -0
  34. package/dist/markdown/MarkdownSearchPanel.d.ts.map +1 -0
  35. package/dist/markdown/MdKitEditor.d.ts +11 -0
  36. package/dist/markdown/MdKitEditor.d.ts.map +1 -0
  37. package/dist/markdown/MdKitEditor.js +10 -2
  38. package/dist/markdown/MdKitView.d.ts +9 -1
  39. package/dist/markdown/MdKitView.d.ts.map +1 -0
  40. package/dist/markdown/MdKitView.js +7 -2
  41. package/dist/markdown/TiptapMarkdownSurface.d.ts +1 -0
  42. package/dist/markdown/TiptapMarkdownSurface.d.ts.map +1 -0
  43. package/dist/markdown/TiptapMarkdownSurface.js +3 -22
  44. package/dist/markdown/createMdKitTiptapExtensions.d.ts +1 -0
  45. package/dist/markdown/createMdKitTiptapExtensions.d.ts.map +1 -0
  46. package/dist/markdown/editorDebug.d.ts +1 -0
  47. package/dist/markdown/editorDebug.d.ts.map +1 -0
  48. package/dist/markdown/markdownFenceRanges.d.ts +1 -0
  49. package/dist/markdown/markdownFenceRanges.d.ts.map +1 -0
  50. package/dist/markdown/normalizeMarkdownSerialization.d.ts +1 -0
  51. package/dist/markdown/normalizeMarkdownSerialization.d.ts.map +1 -0
  52. package/dist/markdown/prepareMarkdownForEditorHydration.d.ts +1 -0
  53. package/dist/markdown/prepareMarkdownForEditorHydration.d.ts.map +1 -0
  54. package/dist/markdown/preserveMarkdownWhitespace.d.ts +1 -0
  55. package/dist/markdown/preserveMarkdownWhitespace.d.ts.map +1 -0
  56. package/dist/markdown/yamlFrontMatter.d.ts +1 -0
  57. package/dist/markdown/yamlFrontMatter.d.ts.map +1 -0
  58. package/dist/server.d.ts +1 -0
  59. package/dist/server.d.ts.map +1 -0
  60. package/dist/theme/MdKitThemeEditor.d.ts +5 -0
  61. package/dist/theme/MdKitThemeEditor.d.ts.map +1 -0
  62. package/dist/theme/MdKitThemeEditor.js +4 -0
  63. package/dist/theme/editorTheme.d.ts +1 -0
  64. package/dist/theme/editorTheme.d.ts.map +1 -0
  65. package/dist/theme/editorTheme.js +8 -8
  66. package/dist/transport/backend.d.ts +13 -0
  67. package/dist/transport/backend.d.ts.map +1 -0
  68. package/dist/transport/backend.js +6 -0
  69. package/dist/transport/fastify.d.ts +5 -0
  70. package/dist/transport/fastify.d.ts.map +1 -0
  71. package/dist/transport/fastify.js +4 -0
  72. package/dist/transport/http.d.ts +1 -0
  73. package/dist/transport/http.d.ts.map +1 -0
  74. package/dist/transport/index.d.ts +1 -0
  75. package/dist/transport/index.d.ts.map +1 -0
  76. package/dist/transport/rest.d.ts +6 -0
  77. package/dist/transport/rest.d.ts.map +1 -0
  78. package/dist/transport/rest.js +5 -0
  79. package/dist/transport/store.d.ts +1 -0
  80. package/dist/transport/store.d.ts.map +1 -0
  81. package/dist/transport/trpcClient.d.ts +8 -0
  82. package/dist/transport/trpcClient.d.ts.map +1 -0
  83. package/dist/transport/trpcClient.js +7 -0
  84. package/dist/transport/trpcServer.d.ts +6 -0
  85. package/dist/transport/trpcServer.d.ts.map +1 -0
  86. package/dist/transport/trpcServer.js +5 -0
  87. package/dist/trpc/client.d.ts +1 -0
  88. package/dist/trpc/client.d.ts.map +1 -0
  89. package/dist/trpc/server.d.ts +1 -0
  90. package/dist/trpc/server.d.ts.map +1 -0
  91. package/dist/trpc.d.ts +1 -0
  92. package/dist/trpc.d.ts.map +1 -0
  93. package/dist/ui/joinClassNames.d.ts +1 -0
  94. package/dist/ui/joinClassNames.d.ts.map +1 -0
  95. package/dist/versioning/VersionHistoryPanel.d.ts +5 -0
  96. package/dist/versioning/VersionHistoryPanel.d.ts.map +1 -0
  97. package/dist/versioning/VersionHistoryPanel.js +4 -0
  98. package/dist/versioning/useMdKitDocumentVersions.d.ts +5 -0
  99. package/dist/versioning/useMdKitDocumentVersions.d.ts.map +1 -0
  100. package/dist/versioning/useMdKitDocumentVersions.js +4 -0
  101. package/dist/yjs/MdKitMarkdownYjs.d.ts +1 -0
  102. package/dist/yjs/MdKitMarkdownYjs.d.ts.map +1 -0
  103. package/dist/yjs/index.d.ts +1 -0
  104. package/dist/yjs/index.d.ts.map +1 -0
  105. package/package.json +10 -12
  106. package/src/collaboration/useMdKitCollaboration.ts +528 -0
  107. package/src/core/checkpointPolicy.ts +107 -0
  108. package/src/core/documentEngine.ts +175 -0
  109. package/src/core/index.ts +33 -0
  110. package/src/document/MdKitConflictPanel.tsx +129 -0
  111. package/src/document/MdKitDocumentToolbar.tsx +141 -0
  112. package/src/document/documentTypes.ts +89 -0
  113. package/src/document/useMdKitDocument.ts +543 -0
  114. package/src/fastify.ts +6 -0
  115. package/src/index.ts +89 -0
  116. package/src/markdown/MarkdownBubbleMenu.tsx +271 -0
  117. package/src/markdown/MarkdownPasteExtension.ts +81 -0
  118. package/src/markdown/MarkdownSearchExtension.ts +77 -0
  119. package/src/markdown/MarkdownSearchPanel.tsx +98 -0
  120. package/src/markdown/MdKitEditor.tsx +75 -0
  121. package/src/markdown/MdKitView.tsx +80 -0
  122. package/src/markdown/TiptapMarkdownSurface.tsx +923 -0
  123. package/src/markdown/createMdKitTiptapExtensions.ts +42 -0
  124. package/src/markdown/editorDebug.ts +5 -0
  125. package/src/markdown/markdownFenceRanges.ts +68 -0
  126. package/src/markdown/normalizeMarkdownSerialization.ts +55 -0
  127. package/src/markdown/prepareMarkdownForEditorHydration.ts +23 -0
  128. package/src/markdown/preserveMarkdownWhitespace.ts +143 -0
  129. package/src/markdown/yamlFrontMatter.ts +135 -0
  130. package/src/server.ts +6 -0
  131. package/src/styles.css +132 -53
  132. package/src/theme/MdKitThemeEditor.tsx +134 -0
  133. package/src/theme/editorTheme.ts +72 -0
  134. package/src/transport/backend.ts +220 -0
  135. package/src/transport/fastify.ts +57 -0
  136. package/src/transport/http.ts +126 -0
  137. package/src/transport/index.ts +12 -0
  138. package/src/transport/rest.ts +80 -0
  139. package/src/transport/store.ts +45 -0
  140. package/src/transport/trpcClient.ts +90 -0
  141. package/src/transport/trpcServer.ts +66 -0
  142. package/src/trpc/client.ts +11 -0
  143. package/src/trpc/server.ts +12 -0
  144. package/src/trpc.ts +11 -0
  145. package/src/ui/joinClassNames.ts +3 -0
  146. package/src/versioning/VersionHistoryPanel.tsx +146 -0
  147. package/src/versioning/useMdKitDocumentVersions.ts +146 -0
  148. package/src/yjs/MdKitMarkdownYjs.ts +111 -0
  149. package/src/yjs/index.ts +8 -0
  150. package/docs/.vitepress/config.ts +0 -47
  151. package/docs/api.md +0 -512
  152. package/docs/architecture.md +0 -96
  153. package/docs/collaboration-persistence.md +0 -147
  154. package/docs/index.md +0 -341
  155. package/docs/permissions.md +0 -139
  156. package/docs/plain-text.md +0 -131
  157. package/docs/rest.md +0 -98
  158. package/docs/shadcn.md +0 -125
  159. package/docs/styling.md +0 -373
  160. package/docs/use-cases.md +0 -148
@@ -0,0 +1,146 @@
1
+ import { useCallback, useEffect, useMemo, useState } from "react";
2
+ import type {
3
+ MdKitDocumentAdapter,
4
+ MdKitDocumentVersionDetail,
5
+ MdKitDocumentVersionSummary,
6
+ } from "../document/documentTypes";
7
+
8
+ export type UseMdKitDocumentVersionsOptions = {
9
+ adapter: Pick<
10
+ MdKitDocumentAdapter,
11
+ "listDocumentVersions" | "readDocumentVersion"
12
+ >;
13
+ documentId: string | null;
14
+ enabled?: boolean;
15
+ };
16
+
17
+ export type MdKitDocumentVersionsController = {
18
+ error: string | null;
19
+ hasVersioning: boolean;
20
+ isLoading: boolean;
21
+ openVersion: (versionId: string) => Promise<void>;
22
+ refresh: () => Promise<void>;
23
+ selectedVersion: MdKitDocumentVersionDetail | null;
24
+ selectedVersionId: string | null;
25
+ versions: MdKitDocumentVersionSummary[];
26
+ };
27
+
28
+ /**
29
+ * Lists a document's checkpoints and lazily reads checkpoint detail, tracking
30
+ * loading state for checkpoint-history UI.
31
+ */
32
+ export const useMdKitDocumentVersions = (
33
+ options: UseMdKitDocumentVersionsOptions,
34
+ ): MdKitDocumentVersionsController => {
35
+ const { adapter, documentId, enabled = true } = options;
36
+ const [versions, setVersions] = useState<MdKitDocumentVersionSummary[]>([]);
37
+
38
+ const [selectedVersionId, setSelectedVersionId] = useState<string | null>(
39
+ null,
40
+ );
41
+
42
+ const [selectedVersion, setSelectedVersion] =
43
+ useState<MdKitDocumentVersionDetail | null>(null);
44
+
45
+ const [isLoading, setIsLoading] = useState(false);
46
+ const [error, setError] = useState<string | null>(null);
47
+
48
+ const hasVersioning =
49
+ enabled && !!adapter.listDocumentVersions && !!adapter.readDocumentVersion;
50
+
51
+ const refresh = useCallback(async () => {
52
+ if (!hasVersioning || !documentId || !adapter.listDocumentVersions) {
53
+ setVersions([]);
54
+ setSelectedVersionId(null);
55
+ setSelectedVersion(null);
56
+ setError(null);
57
+ return;
58
+ }
59
+
60
+ setIsLoading(true);
61
+ setError(null);
62
+
63
+ try {
64
+ const nextVersions = await adapter.listDocumentVersions(documentId);
65
+ setVersions(nextVersions);
66
+
67
+ setSelectedVersionId((currentSelectedVersionId) => {
68
+ if (
69
+ !nextVersions.some(
70
+ (version) => version.id === currentSelectedVersionId,
71
+ )
72
+ ) {
73
+ setSelectedVersion(null);
74
+ return null;
75
+ }
76
+
77
+ return currentSelectedVersionId;
78
+ });
79
+ } catch (err) {
80
+ setError(`Failed to load versions: ${String(err)}`);
81
+ } finally {
82
+ setIsLoading(false);
83
+ }
84
+ }, [adapter, documentId, hasVersioning]);
85
+
86
+ const openVersion = useCallback(
87
+ async (versionId: string) => {
88
+ if (!hasVersioning || !documentId || !adapter.readDocumentVersion) {
89
+ return;
90
+ }
91
+
92
+ setSelectedVersionId(versionId);
93
+ setIsLoading(true);
94
+ setError(null);
95
+
96
+ try {
97
+ const nextVersion = await adapter.readDocumentVersion({
98
+ documentId,
99
+ versionId,
100
+ });
101
+
102
+ if (!nextVersion) {
103
+ setSelectedVersion(null);
104
+ setError("That version is no longer available.");
105
+ return;
106
+ }
107
+
108
+ setSelectedVersion(nextVersion);
109
+ } catch (err) {
110
+ setError(`Failed to load version: ${String(err)}`);
111
+ } finally {
112
+ setIsLoading(false);
113
+ }
114
+ },
115
+ [adapter, documentId, hasVersioning],
116
+ );
117
+
118
+ useEffect(() => {
119
+ setSelectedVersionId(null);
120
+ setSelectedVersion(null);
121
+ void refresh();
122
+ }, [documentId, refresh]);
123
+
124
+ return useMemo(
125
+ () => ({
126
+ error,
127
+ hasVersioning,
128
+ isLoading,
129
+ openVersion,
130
+ refresh,
131
+ selectedVersion,
132
+ selectedVersionId,
133
+ versions,
134
+ }),
135
+ [
136
+ error,
137
+ hasVersioning,
138
+ isLoading,
139
+ openVersion,
140
+ refresh,
141
+ selectedVersion,
142
+ selectedVersionId,
143
+ versions,
144
+ ],
145
+ );
146
+ };
@@ -0,0 +1,111 @@
1
+ import { getSchema } from "@tiptap/core";
2
+ import { MarkdownManager } from "@tiptap/markdown";
3
+ import {
4
+ prosemirrorJSONToYXmlFragment,
5
+ yXmlFragmentToProsemirrorJSON,
6
+ } from "@tiptap/y-tiptap";
7
+ import * as Y from "yjs";
8
+ import { createMdKitTiptapExtensions } from "../markdown/createMdKitTiptapExtensions";
9
+ import {
10
+ extractYamlFrontMatter,
11
+ prependYamlFrontMatter,
12
+ } from "../markdown/yamlFrontMatter";
13
+ import { normalizeMarkdownSerialization } from "../markdown/normalizeMarkdownSerialization";
14
+ import { prepareMarkdownForEditorHydration } from "../markdown/prepareMarkdownForEditorHydration";
15
+
16
+ export type MdKitMarkdownYjsOptions = {
17
+ fragmentName?: string;
18
+ ignoreYamlFrontMatter?: boolean;
19
+ };
20
+
21
+ const defaultMdKitYjsFragmentName = "default";
22
+ const mdKitYjsMetadataMapName = "__mdkit";
23
+ const frontMatterPrefixMetadataKey = "frontMatterPrefix";
24
+
25
+ const getMdKitYjsFragmentName = (options?: MdKitMarkdownYjsOptions) =>
26
+ options?.fragmentName ?? defaultMdKitYjsFragmentName;
27
+
28
+ const getFrontMatterPrefixMetadataKey = (fragmentName: string) =>
29
+ `${fragmentName}:${frontMatterPrefixMetadataKey}`;
30
+
31
+ const createMdKitMarkdownManager = () =>
32
+ new MarkdownManager({
33
+ extensions: createMdKitTiptapExtensions(),
34
+ markedOptions: {
35
+ gfm: true,
36
+ },
37
+ });
38
+
39
+ const createMdKitProseMirrorSchema = () =>
40
+ getSchema(createMdKitTiptapExtensions());
41
+
42
+ const markdownToProseMirrorJson = (markdown: string) =>
43
+ createMdKitMarkdownManager().parse(
44
+ prepareMarkdownForEditorHydration(markdown),
45
+ );
46
+
47
+ const proseMirrorJsonToMarkdown = (json: Record<string, any>) =>
48
+ normalizeMarkdownSerialization(createMdKitMarkdownManager().serialize(json));
49
+
50
+ export const replaceMdKitYjsMarkdown = (
51
+ ydoc: Y.Doc,
52
+ markdown: string,
53
+ options?: MdKitMarkdownYjsOptions,
54
+ ): Uint8Array => {
55
+ const fragmentName = getMdKitYjsFragmentName(options);
56
+ const fragment = ydoc.getXmlFragment(fragmentName);
57
+ const metadata = ydoc.getMap<string>(mdKitYjsMetadataMapName);
58
+ const schema = createMdKitProseMirrorSchema();
59
+ const frontMatter = options?.ignoreYamlFrontMatter
60
+ ? extractYamlFrontMatter(markdown)
61
+ : null;
62
+ const json = markdownToProseMirrorJson(frontMatter?.body ?? markdown);
63
+ const metadataKey = getFrontMatterPrefixMetadataKey(fragmentName);
64
+
65
+ prosemirrorJSONToYXmlFragment(schema, json, fragment);
66
+
67
+ if (frontMatter?.frontMatter) {
68
+ metadata.set(metadataKey, frontMatter.frontMatter.raw);
69
+ } else {
70
+ metadata.delete(metadataKey);
71
+ }
72
+
73
+ return Y.encodeStateAsUpdate(ydoc);
74
+ };
75
+
76
+ export const markdownToMdKitYjs = (
77
+ markdown: string,
78
+ options?: MdKitMarkdownYjsOptions,
79
+ ): Uint8Array => {
80
+ const ydoc = new Y.Doc();
81
+
82
+ return replaceMdKitYjsMarkdown(ydoc, markdown, options);
83
+ };
84
+
85
+ export const mdKitYjsToMarkdown = (
86
+ yjsState: Uint8Array,
87
+ options?: MdKitMarkdownYjsOptions,
88
+ ): string => {
89
+ const ydoc = new Y.Doc();
90
+
91
+ Y.applyUpdate(ydoc, yjsState);
92
+
93
+ const fragmentName = getMdKitYjsFragmentName(options);
94
+ const json = yXmlFragmentToProsemirrorJSON(
95
+ ydoc.getXmlFragment(fragmentName),
96
+ );
97
+ const metadata = ydoc.getMap<string>(mdKitYjsMetadataMapName);
98
+ const frontMatterRaw =
99
+ metadata.get(getFrontMatterPrefixMetadataKey(fragmentName)) ?? "";
100
+
101
+ return prependYamlFrontMatter(
102
+ frontMatterRaw,
103
+ proseMirrorJsonToMarkdown(json),
104
+ );
105
+ };
106
+
107
+ export const yjs = {
108
+ markdownToMdKitYjs,
109
+ mdKitYjsToMarkdown,
110
+ replaceMdKitYjsMarkdown,
111
+ };
@@ -0,0 +1,8 @@
1
+ export {
2
+ markdownToMdKitYjs,
3
+ mdKitYjsToMarkdown,
4
+ replaceMdKitYjsMarkdown,
5
+ yjs,
6
+ } from "./MdKitMarkdownYjs";
7
+
8
+ export type { MdKitMarkdownYjsOptions } from "./MdKitMarkdownYjs";
@@ -1,47 +0,0 @@
1
- import { defineConfig } from "vitepress";
2
-
3
- export default defineConfig({
4
- title: "Markdown Editor Kit",
5
- description: "Docs for the mdkit markdown editor package",
6
- cleanUrls: true,
7
- themeConfig: {
8
- nav: [
9
- { text: "Quick Start", link: "/" },
10
- { text: "Plain Text", link: "/plain-text" },
11
- { text: "Styling", link: "/styling" },
12
- { text: "Shadcn", link: "/shadcn" },
13
- { text: "REST", link: "/rest" },
14
- { text: "Use Cases", link: "/use-cases" },
15
- { text: "Permissions", link: "/permissions" },
16
- { text: "Collaboration Persistence", link: "/collaboration-persistence" },
17
- { text: "API", link: "/api" },
18
- { text: "Architecture", link: "/architecture" },
19
- ],
20
- sidebar: [
21
- {
22
- text: "Guide",
23
- items: [
24
- { text: "Quick Start", link: "/" },
25
- { text: "Plain Text Editors", link: "/plain-text" },
26
- { text: "Styling", link: "/styling" },
27
- { text: "Shadcn Plugin", link: "/shadcn" },
28
- { text: "REST Backend", link: "/rest" },
29
- { text: "Use Cases", link: "/use-cases" },
30
- { text: "Permissions", link: "/permissions" },
31
- {
32
- text: "Collaboration Persistence",
33
- link: "/collaboration-persistence",
34
- },
35
- { text: "API Reference", link: "/api" },
36
- { text: "Architecture", link: "/architecture" },
37
- ],
38
- },
39
- ],
40
- socialLinks: [
41
- {
42
- icon: "github",
43
- link: "https://github.com/mp-lb/mdkit",
44
- },
45
- ],
46
- },
47
- });