@mp-lb/mdkit 0.3.2 → 0.3.3
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.
- package/README.md +8 -2
- package/dist/collaboration/useMdKitCollaboration.d.ts +5 -0
- package/dist/collaboration/useMdKitCollaboration.d.ts.map +1 -0
- package/dist/collaboration/useMdKitCollaboration.js +4 -0
- package/dist/core/checkpointPolicy.d.ts +10 -0
- package/dist/core/checkpointPolicy.d.ts.map +1 -0
- package/dist/core/checkpointPolicy.js +9 -0
- package/dist/core/documentEngine.d.ts +1 -0
- package/dist/core/documentEngine.d.ts.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/document/MdKitConflictPanel.d.ts +5 -0
- package/dist/document/MdKitConflictPanel.d.ts.map +1 -0
- package/dist/document/MdKitConflictPanel.js +4 -0
- package/dist/document/MdKitDocumentToolbar.d.ts +6 -0
- package/dist/document/MdKitDocumentToolbar.d.ts.map +1 -0
- package/dist/document/MdKitDocumentToolbar.js +5 -0
- package/dist/document/documentTypes.d.ts +6 -0
- package/dist/document/documentTypes.d.ts.map +1 -0
- package/dist/document/useMdKitDocument.d.ts +5 -0
- package/dist/document/useMdKitDocument.d.ts.map +1 -0
- package/dist/document/useMdKitDocument.js +4 -0
- package/dist/fastify.d.ts +1 -0
- package/dist/fastify.d.ts.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/markdown/MarkdownBubbleMenu.d.ts +1 -0
- package/dist/markdown/MarkdownBubbleMenu.d.ts.map +1 -0
- package/dist/markdown/MarkdownPasteExtension.d.ts +1 -0
- package/dist/markdown/MarkdownPasteExtension.d.ts.map +1 -0
- package/dist/markdown/MarkdownSearchExtension.d.ts +1 -0
- package/dist/markdown/MarkdownSearchExtension.d.ts.map +1 -0
- package/dist/markdown/MarkdownSearchPanel.d.ts +1 -0
- package/dist/markdown/MarkdownSearchPanel.d.ts.map +1 -0
- package/dist/markdown/MdKitEditor.d.ts +11 -0
- package/dist/markdown/MdKitEditor.d.ts.map +1 -0
- package/dist/markdown/MdKitEditor.js +10 -2
- package/dist/markdown/MdKitView.d.ts +9 -1
- package/dist/markdown/MdKitView.d.ts.map +1 -0
- package/dist/markdown/MdKitView.js +7 -2
- package/dist/markdown/TiptapMarkdownSurface.d.ts +1 -0
- package/dist/markdown/TiptapMarkdownSurface.d.ts.map +1 -0
- package/dist/markdown/TiptapMarkdownSurface.js +3 -22
- package/dist/markdown/createMdKitTiptapExtensions.d.ts +1 -0
- package/dist/markdown/createMdKitTiptapExtensions.d.ts.map +1 -0
- package/dist/markdown/editorDebug.d.ts +1 -0
- package/dist/markdown/editorDebug.d.ts.map +1 -0
- package/dist/markdown/markdownFenceRanges.d.ts +1 -0
- package/dist/markdown/markdownFenceRanges.d.ts.map +1 -0
- package/dist/markdown/normalizeMarkdownSerialization.d.ts +1 -0
- package/dist/markdown/normalizeMarkdownSerialization.d.ts.map +1 -0
- package/dist/markdown/prepareMarkdownForEditorHydration.d.ts +1 -0
- package/dist/markdown/prepareMarkdownForEditorHydration.d.ts.map +1 -0
- package/dist/markdown/preserveMarkdownWhitespace.d.ts +1 -0
- package/dist/markdown/preserveMarkdownWhitespace.d.ts.map +1 -0
- package/dist/markdown/yamlFrontMatter.d.ts +1 -0
- package/dist/markdown/yamlFrontMatter.d.ts.map +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/theme/MdKitThemeEditor.d.ts +5 -0
- package/dist/theme/MdKitThemeEditor.d.ts.map +1 -0
- package/dist/theme/MdKitThemeEditor.js +4 -0
- package/dist/theme/editorTheme.d.ts +1 -0
- package/dist/theme/editorTheme.d.ts.map +1 -0
- package/dist/theme/editorTheme.js +8 -8
- package/dist/transport/backend.d.ts +13 -0
- package/dist/transport/backend.d.ts.map +1 -0
- package/dist/transport/backend.js +6 -0
- package/dist/transport/fastify.d.ts +5 -0
- package/dist/transport/fastify.d.ts.map +1 -0
- package/dist/transport/fastify.js +4 -0
- package/dist/transport/http.d.ts +1 -0
- package/dist/transport/http.d.ts.map +1 -0
- package/dist/transport/index.d.ts +1 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/rest.d.ts +6 -0
- package/dist/transport/rest.d.ts.map +1 -0
- package/dist/transport/rest.js +5 -0
- package/dist/transport/store.d.ts +1 -0
- package/dist/transport/store.d.ts.map +1 -0
- package/dist/transport/trpcClient.d.ts +8 -0
- package/dist/transport/trpcClient.d.ts.map +1 -0
- package/dist/transport/trpcClient.js +7 -0
- package/dist/transport/trpcServer.d.ts +6 -0
- package/dist/transport/trpcServer.d.ts.map +1 -0
- package/dist/transport/trpcServer.js +5 -0
- package/dist/trpc/client.d.ts +1 -0
- package/dist/trpc/client.d.ts.map +1 -0
- package/dist/trpc/server.d.ts +1 -0
- package/dist/trpc/server.d.ts.map +1 -0
- package/dist/trpc.d.ts +1 -0
- package/dist/trpc.d.ts.map +1 -0
- package/dist/ui/joinClassNames.d.ts +1 -0
- package/dist/ui/joinClassNames.d.ts.map +1 -0
- package/dist/versioning/VersionHistoryPanel.d.ts +5 -0
- package/dist/versioning/VersionHistoryPanel.d.ts.map +1 -0
- package/dist/versioning/VersionHistoryPanel.js +4 -0
- package/dist/versioning/useMdKitDocumentVersions.d.ts +5 -0
- package/dist/versioning/useMdKitDocumentVersions.d.ts.map +1 -0
- package/dist/versioning/useMdKitDocumentVersions.js +4 -0
- package/dist/yjs/MdKitMarkdownYjs.d.ts +1 -0
- package/dist/yjs/MdKitMarkdownYjs.d.ts.map +1 -0
- package/dist/yjs/index.d.ts +1 -0
- package/dist/yjs/index.d.ts.map +1 -0
- package/package.json +10 -12
- package/src/collaboration/useMdKitCollaboration.ts +528 -0
- package/src/core/checkpointPolicy.ts +107 -0
- package/src/core/documentEngine.ts +175 -0
- package/src/core/index.ts +33 -0
- package/src/document/MdKitConflictPanel.tsx +129 -0
- package/src/document/MdKitDocumentToolbar.tsx +141 -0
- package/src/document/documentTypes.ts +89 -0
- package/src/document/useMdKitDocument.ts +543 -0
- package/src/fastify.ts +6 -0
- package/src/index.ts +89 -0
- package/src/markdown/MarkdownBubbleMenu.tsx +271 -0
- package/src/markdown/MarkdownPasteExtension.ts +81 -0
- package/src/markdown/MarkdownSearchExtension.ts +77 -0
- package/src/markdown/MarkdownSearchPanel.tsx +98 -0
- package/src/markdown/MdKitEditor.tsx +75 -0
- package/src/markdown/MdKitView.tsx +80 -0
- package/src/markdown/TiptapMarkdownSurface.tsx +923 -0
- package/src/markdown/createMdKitTiptapExtensions.ts +42 -0
- package/src/markdown/editorDebug.ts +5 -0
- package/src/markdown/markdownFenceRanges.ts +68 -0
- package/src/markdown/normalizeMarkdownSerialization.ts +55 -0
- package/src/markdown/prepareMarkdownForEditorHydration.ts +23 -0
- package/src/markdown/preserveMarkdownWhitespace.ts +143 -0
- package/src/markdown/yamlFrontMatter.ts +135 -0
- package/src/server.ts +6 -0
- package/src/styles.css +125 -53
- package/src/theme/MdKitThemeEditor.tsx +134 -0
- package/src/theme/editorTheme.ts +72 -0
- package/src/transport/backend.ts +220 -0
- package/src/transport/fastify.ts +57 -0
- package/src/transport/http.ts +126 -0
- package/src/transport/index.ts +12 -0
- package/src/transport/rest.ts +80 -0
- package/src/transport/store.ts +45 -0
- package/src/transport/trpcClient.ts +90 -0
- package/src/transport/trpcServer.ts +66 -0
- package/src/trpc/client.ts +11 -0
- package/src/trpc/server.ts +12 -0
- package/src/trpc.ts +11 -0
- package/src/ui/joinClassNames.ts +3 -0
- package/src/versioning/VersionHistoryPanel.tsx +146 -0
- package/src/versioning/useMdKitDocumentVersions.ts +146 -0
- package/src/yjs/MdKitMarkdownYjs.ts +111 -0
- package/src/yjs/index.ts +8 -0
- package/docs/.vitepress/config.ts +0 -47
- package/docs/api.md +0 -512
- package/docs/architecture.md +0 -96
- package/docs/collaboration-persistence.md +0 -147
- package/docs/index.md +0 -341
- package/docs/permissions.md +0 -139
- package/docs/plain-text.md +0 -131
- package/docs/rest.md +0 -98
- package/docs/shadcn.md +0 -125
- package/docs/styling.md +0 -373
- package/docs/use-cases.md +0 -148
package/docs/api.md
DELETED
|
@@ -1,512 +0,0 @@
|
|
|
1
|
-
# API Reference
|
|
2
|
-
|
|
3
|
-
This page lists the current public exports from
|
|
4
|
-
`@mp-lb/mdkit`. It is hand-written for now; a generated API
|
|
5
|
-
reference from JSDoc/TypeScript declarations is a good follow-up once the public
|
|
6
|
-
surface settles.
|
|
7
|
-
|
|
8
|
-
## Editor
|
|
9
|
-
|
|
10
|
-
### `MdKitEditor`
|
|
11
|
-
|
|
12
|
-
Primary editor component.
|
|
13
|
-
|
|
14
|
-
Local mode:
|
|
15
|
-
|
|
16
|
-
```tsx
|
|
17
|
-
<MdKitEditor value={markdown} onChange={setMarkdown} />
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Collaborative mode:
|
|
21
|
-
|
|
22
|
-
```tsx
|
|
23
|
-
<MdKitEditor collaboration={collaboration} />
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
In collaborative mode the Yjs document in `collaboration.document` is the editor
|
|
27
|
-
content source. `value` may be passed for API symmetry with connected examples,
|
|
28
|
-
but external `value` changes are not applied into the collaborative document.
|
|
29
|
-
Use your Hocuspocus/MDKit collaboration persistence bridge to seed or replace
|
|
30
|
-
collaborative content.
|
|
31
|
-
|
|
32
|
-
### `MdKitEditorProps`
|
|
33
|
-
|
|
34
|
-
Props for `MdKitEditor`.
|
|
35
|
-
|
|
36
|
-
Local editing props:
|
|
37
|
-
|
|
38
|
-
- `value: string`
|
|
39
|
-
- `onChange?: (markdown: string) => void`
|
|
40
|
-
- `onFocusChange?: (focused: boolean) => void`
|
|
41
|
-
- `fillHeight?: boolean`
|
|
42
|
-
- `search?: boolean`
|
|
43
|
-
- `instanceKey?: string | number`
|
|
44
|
-
- `className?: string`
|
|
45
|
-
- `style?: CSSProperties`
|
|
46
|
-
|
|
47
|
-
Collaborative editing props:
|
|
48
|
-
|
|
49
|
-
- `collaboration: MdKitCollaborationSession`
|
|
50
|
-
- `value?: string`
|
|
51
|
-
- `onChange?: (markdown: string) => void`
|
|
52
|
-
- `onFocusChange?: (focused: boolean) => void`
|
|
53
|
-
- `fillHeight?: boolean`
|
|
54
|
-
- `search?: boolean`
|
|
55
|
-
- `className?: string`
|
|
56
|
-
- `style?: CSSProperties`
|
|
57
|
-
|
|
58
|
-
`fillHeight` makes the editor fill its parent height, own its scroll area, and
|
|
59
|
-
keep blank space below the last line clickable so it focuses the cursor at the
|
|
60
|
-
end. Leave it off when the host application owns sizing and scrolling.
|
|
61
|
-
|
|
62
|
-
`search` opts the editor into the built-in document search panel. The panel is
|
|
63
|
-
not rendered by default; when enabled, users open it with `Cmd+F` on macOS or
|
|
64
|
-
`Ctrl+F` on Windows/Linux.
|
|
65
|
-
|
|
66
|
-
The package stylesheet includes reset-resistant markdown rules for headings,
|
|
67
|
-
lists, code blocks, blockquotes, and links. Styling is controlled with CSS
|
|
68
|
-
variables on `.mp-lb-mdkit-markdown-editor`. See [Styling](./styling.md) for setup,
|
|
69
|
-
dark mode, fonts, sizing, and theme customization.
|
|
70
|
-
|
|
71
|
-
### `MdKitView`
|
|
72
|
-
|
|
73
|
-
Read-only markdown view that uses the same shell, sizing, and markdown styling
|
|
74
|
-
as `MdKitEditor`, but renders with `react-markdown` instead of Tiptap.
|
|
75
|
-
|
|
76
|
-
```tsx
|
|
77
|
-
<MdKitView value={markdown} />
|
|
78
|
-
<MdKitView fillHeight value={markdown} />
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Props:
|
|
82
|
-
|
|
83
|
-
- `value: string`
|
|
84
|
-
- `placeholder?: string`
|
|
85
|
-
- `fillHeight?: boolean`
|
|
86
|
-
- `className?: string`
|
|
87
|
-
- `style?: CSSProperties`
|
|
88
|
-
|
|
89
|
-
`fillHeight` uses the same full-pane sizing contract as `MdKitEditor`.
|
|
90
|
-
|
|
91
|
-
## Document Persistence
|
|
92
|
-
|
|
93
|
-
### `useMdKitDocument`
|
|
94
|
-
|
|
95
|
-
Hook for loading, editing, saving, autosaving, and resyncing a markdown document
|
|
96
|
-
through a storage adapter.
|
|
97
|
-
|
|
98
|
-
### `MdKitDocumentController`
|
|
99
|
-
|
|
100
|
-
Return type for `useMdKitDocument`. It contains the current markdown value,
|
|
101
|
-
status flags, save actions, resync actions, conflict details, and state setters
|
|
102
|
-
used by editor UI.
|
|
103
|
-
|
|
104
|
-
### `MdKitDocumentToolbar`
|
|
105
|
-
|
|
106
|
-
Unstyled workflow controls for a connected markdown document. Render this above
|
|
107
|
-
or near `MdKitEditor` when you want mdkit to handle common document actions
|
|
108
|
-
without adopting a design system.
|
|
109
|
-
|
|
110
|
-
```tsx
|
|
111
|
-
<MdKitDocumentToolbar
|
|
112
|
-
document={document}
|
|
113
|
-
versions={versions}
|
|
114
|
-
collaboration={collaboration}
|
|
115
|
-
onOpenConflict={() => setConflictDialogOpen(true)}
|
|
116
|
-
onOpenVersionHistory={() => setVersionPanelOpen(true)}
|
|
117
|
-
/>
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
It renders save status, collaboration status, an optional checkpoint-history
|
|
121
|
-
entry point labelled with the current revision token, and a conflict entry via
|
|
122
|
-
`onOpenConflict`.
|
|
123
|
-
|
|
124
|
-
Related type:
|
|
125
|
-
|
|
126
|
-
- `MdKitDocumentToolbarProps`
|
|
127
|
-
|
|
128
|
-
### `MdKitConflictPanel`
|
|
129
|
-
|
|
130
|
-
Base panel for conflict resolution. It renders inline semantic HTML, previews the
|
|
131
|
-
remote and local content snapshots, and uses the document controller actions to
|
|
132
|
-
keep the remote document or keep the local editor content.
|
|
133
|
-
|
|
134
|
-
```tsx
|
|
135
|
-
<MdKitConflictPanel document={document} />
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
It returns `null` when `document.conflict` is false. Use it next to
|
|
139
|
-
`MdKitDocumentToolbar` when you want the base-panel workflow. If your app uses a
|
|
140
|
-
modal, drawer, or editor-replacement view, put this panel inside your own shell.
|
|
141
|
-
|
|
142
|
-
Related type:
|
|
143
|
-
|
|
144
|
-
- `MdKitConflictPanelProps`
|
|
145
|
-
|
|
146
|
-
### `MdKitDocumentAdapter`
|
|
147
|
-
|
|
148
|
-
Storage adapter contract. Implement this to connect document persistence to your
|
|
149
|
-
backend.
|
|
150
|
-
|
|
151
|
-
```ts
|
|
152
|
-
type MdKitDocumentAdapter = {
|
|
153
|
-
readDocument(documentId: string): Promise<MdKitDocumentSnapshot>;
|
|
154
|
-
writeDocument(
|
|
155
|
-
input: MdKitDocumentWriteInput,
|
|
156
|
-
): Promise<MdKitDocumentWriteResult>;
|
|
157
|
-
resyncDocument?(documentId: string): Promise<MdKitDocumentSnapshot>;
|
|
158
|
-
listDocumentVersions?(
|
|
159
|
-
documentId: string,
|
|
160
|
-
): Promise<MdKitDocumentVersionSummary[]>;
|
|
161
|
-
readDocumentVersion?(input: {
|
|
162
|
-
documentId: string;
|
|
163
|
-
versionId: string;
|
|
164
|
-
}): Promise<MdKitDocumentVersionDetail | null>;
|
|
165
|
-
};
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
Required storage methods:
|
|
169
|
-
|
|
170
|
-
- `readDocument` returns the current markdown snapshot.
|
|
171
|
-
- `writeDocument` persists markdown with the caller's base version.
|
|
172
|
-
- `resyncDocument` is optional and can force a fresh read from the canonical
|
|
173
|
-
source.
|
|
174
|
-
|
|
175
|
-
Optional checkpoint-history methods:
|
|
176
|
-
|
|
177
|
-
- `listDocumentVersions` returns available checkpoints for the document.
|
|
178
|
-
- `readDocumentVersion` returns a saved markdown snapshot for one checkpoint.
|
|
179
|
-
|
|
180
|
-
The current public names still use `Version` because that is the existing API.
|
|
181
|
-
Conceptually these records are checkpoints. `MdKitDocumentSnapshot.version` is
|
|
182
|
-
an opaque current-document revision token, not necessarily a user-facing
|
|
183
|
-
checkpoint id.
|
|
184
|
-
|
|
185
|
-
Related storage types:
|
|
186
|
-
|
|
187
|
-
- `MdKitDocumentSnapshot`
|
|
188
|
-
- `MdKitDocumentWriteInput`
|
|
189
|
-
- `MdKitDocumentWriteResult`
|
|
190
|
-
|
|
191
|
-
```ts
|
|
192
|
-
type MdKitDocumentSnapshot = {
|
|
193
|
-
content: string;
|
|
194
|
-
version: MdKitDocumentVersionToken;
|
|
195
|
-
updatedAt?: string | null;
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
type MdKitDocumentWriteInput = {
|
|
199
|
-
documentId: string;
|
|
200
|
-
content: string;
|
|
201
|
-
baseVersion: MdKitDocumentVersionToken;
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
type MdKitDocumentWriteResult =
|
|
205
|
-
| {
|
|
206
|
-
version: MdKitDocumentVersionToken;
|
|
207
|
-
updatedAt?: string | null;
|
|
208
|
-
}
|
|
209
|
-
| {
|
|
210
|
-
conflict: true;
|
|
211
|
-
version?: MdKitDocumentVersionToken;
|
|
212
|
-
updatedAt?: string | null;
|
|
213
|
-
};
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
## Styling
|
|
217
|
-
|
|
218
|
-
### `MdKitThemeEditor`
|
|
219
|
-
|
|
220
|
-
Reusable controls for editing an `MdKitEditorTheme`. This component is optional
|
|
221
|
-
and mainly intended for theme builders, documentation, and debug tools.
|
|
222
|
-
|
|
223
|
-
```tsx
|
|
224
|
-
const [theme, setTheme] = useState(darkMdKitEditorTheme);
|
|
225
|
-
const style = createMdKitEditorThemeStyle(theme);
|
|
226
|
-
|
|
227
|
-
<MdKitThemeEditor theme={theme} onChange={setTheme} />
|
|
228
|
-
<MdKitEditor style={style} value={markdown} onChange={setMarkdown} />
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
Related exports:
|
|
232
|
-
|
|
233
|
-
- `MdKitEditorTheme`
|
|
234
|
-
- `MdKitEditorThemeStyle`
|
|
235
|
-
- `createMdKitEditorThemeStyle`
|
|
236
|
-
- `defaultMdKitEditorTheme`
|
|
237
|
-
- `darkMdKitEditorTheme`
|
|
238
|
-
|
|
239
|
-
`MdKitThemeEditor` also relies on the optional package stylesheet for its own
|
|
240
|
-
layout. Without that stylesheet, it still renders normal form controls.
|
|
241
|
-
|
|
242
|
-
## Checkpoint History
|
|
243
|
-
|
|
244
|
-
### `useMdKitDocumentVersions`
|
|
245
|
-
|
|
246
|
-
Hook for listing checkpoints, reading a checkpoint detail, and tracking
|
|
247
|
-
checkpoint-history loading state.
|
|
248
|
-
|
|
249
|
-
### `VersionHistoryPanel`
|
|
250
|
-
|
|
251
|
-
UI component for rendering checkpoint history from `useMdKitDocumentVersions`.
|
|
252
|
-
|
|
253
|
-
Related types:
|
|
254
|
-
|
|
255
|
-
- `MdKitDocumentVersionSummary`
|
|
256
|
-
- `MdKitDocumentVersionDetail`
|
|
257
|
-
- `MdKitDocumentVersionToken`
|
|
258
|
-
- `MdKitDocumentVersionsController`
|
|
259
|
-
- `UseMdKitDocumentVersionsOptions`
|
|
260
|
-
- `VersionHistoryPanelProps`
|
|
261
|
-
|
|
262
|
-
```ts
|
|
263
|
-
type MdKitDocumentVersionToken = string | number | null;
|
|
264
|
-
|
|
265
|
-
type MdKitDocumentVersionSummary = {
|
|
266
|
-
id: string;
|
|
267
|
-
label?: string;
|
|
268
|
-
createdAt: string;
|
|
269
|
-
authorLabel?: string | null;
|
|
270
|
-
version?: MdKitDocumentVersionToken;
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
type MdKitDocumentVersionDetail = MdKitDocumentVersionSummary & {
|
|
274
|
-
content: string;
|
|
275
|
-
};
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
The `Version` type names are retained for compatibility with the current public
|
|
279
|
-
API. The data model should be understood as checkpoint history.
|
|
280
|
-
|
|
281
|
-
### `CheckpointPolicy`
|
|
282
|
-
|
|
283
|
-
Backend helper for deciding when saved content should become checkpoint
|
|
284
|
-
history. Pass the policy to mdkit's backend helper, not to your application
|
|
285
|
-
store. Your store exposes database operations; mdkit evaluates the policy after
|
|
286
|
-
writes and calls your checkpoint storage when the policy triggers.
|
|
287
|
-
|
|
288
|
-
```ts
|
|
289
|
-
import { CheckpointPolicy } from "@mp-lb/mdkit/core";
|
|
290
|
-
|
|
291
|
-
const never = CheckpointPolicy.never();
|
|
292
|
-
const always = CheckpointPolicy.always();
|
|
293
|
-
const smart = CheckpointPolicy.smart();
|
|
294
|
-
const tunedSmart = CheckpointPolicy.smart({
|
|
295
|
-
minEditDistance: 250,
|
|
296
|
-
minIntervalMs: 5 * 60_000,
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
const custom = CheckpointPolicy.function(
|
|
300
|
-
({
|
|
301
|
-
currentContent,
|
|
302
|
-
editDistance,
|
|
303
|
-
previousCheckpointContent,
|
|
304
|
-
timeSinceLastCheckpointMs,
|
|
305
|
-
}) =>
|
|
306
|
-
editDistance > 500 ||
|
|
307
|
-
timeSinceLastCheckpointMs > 10 * 60_000 ||
|
|
308
|
-
currentContent.startsWith("# Published") !==
|
|
309
|
-
previousCheckpointContent?.startsWith("# Published"),
|
|
310
|
-
);
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
`smart()` without options uses mdkit's default autosave-friendly policy.
|
|
314
|
-
`function()` receives both mdkit's computed edit distance and the raw document
|
|
315
|
-
content, so products can use the built-in comparison or replace it with their
|
|
316
|
-
own.
|
|
317
|
-
|
|
318
|
-
### `createMdKitBackend`
|
|
319
|
-
|
|
320
|
-
Creates the mdkit backend surface from your application store and checkpoint
|
|
321
|
-
policy. This is the layer that owns checkpoint orchestration.
|
|
322
|
-
|
|
323
|
-
```ts
|
|
324
|
-
import { CheckpointPolicy } from "@mp-lb/mdkit/core";
|
|
325
|
-
import {
|
|
326
|
-
createMdKitBackend,
|
|
327
|
-
type MdKitBackendStore,
|
|
328
|
-
} from "@mp-lb/mdkit/server";
|
|
329
|
-
import { createMdKitTrpcRouter } from "@mp-lb/mdkit/trpc/server";
|
|
330
|
-
|
|
331
|
-
const store: MdKitBackendStore = createYourDocumentStore();
|
|
332
|
-
|
|
333
|
-
const mdkit = createMdKitBackend({
|
|
334
|
-
store,
|
|
335
|
-
checkpointPolicy: CheckpointPolicy.smart(),
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
const router = createMdKitTrpcRouter(mdkit);
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
On a document write, the helper should:
|
|
342
|
-
|
|
343
|
-
- write the canonical current document
|
|
344
|
-
- compare the current content with the latest checkpoint
|
|
345
|
-
- evaluate the configured `CheckpointPolicy`
|
|
346
|
-
- call the store's checkpoint creation method when the policy triggers
|
|
347
|
-
- return the write result to the transport layer
|
|
348
|
-
|
|
349
|
-
Exported from `@mp-lb/mdkit/server`.
|
|
350
|
-
|
|
351
|
-
### `MdKitBackendStore`
|
|
352
|
-
|
|
353
|
-
Application-owned persistence contract consumed by `createMdKitBackend`.
|
|
354
|
-
Implement this with your database. The checkpoint policy is not interpreted by
|
|
355
|
-
this store; mdkit calls `createCheckpoint` when the configured policy triggers.
|
|
356
|
-
|
|
357
|
-
```ts
|
|
358
|
-
type MdKitBackendStore = {
|
|
359
|
-
readDocument(documentId: string): Promise<MdKitDocumentSnapshot>;
|
|
360
|
-
writeDocument(
|
|
361
|
-
input: MdKitDocumentWriteInput,
|
|
362
|
-
): Promise<MdKitDocumentWriteResult>;
|
|
363
|
-
getLatestCheckpoint?(
|
|
364
|
-
documentId: string,
|
|
365
|
-
): Promise<MdKitDocumentVersionDetail | null>;
|
|
366
|
-
createCheckpoint?(input: {
|
|
367
|
-
documentId: string;
|
|
368
|
-
content: string;
|
|
369
|
-
sourceRevision: MdKitDocumentVersionToken;
|
|
370
|
-
metadata?: unknown;
|
|
371
|
-
}): Promise<MdKitDocumentVersionSummary>;
|
|
372
|
-
listDocumentVersions?(
|
|
373
|
-
documentId: string,
|
|
374
|
-
): Promise<MdKitDocumentVersionSummary[]>;
|
|
375
|
-
readDocumentVersion?(input: {
|
|
376
|
-
documentId: string;
|
|
377
|
-
versionId: string;
|
|
378
|
-
}): Promise<MdKitDocumentVersionDetail | null>;
|
|
379
|
-
restoreDocumentVersion?(input: {
|
|
380
|
-
documentId: string;
|
|
381
|
-
versionId: string;
|
|
382
|
-
}): Promise<MdKitDocumentWriteResult>;
|
|
383
|
-
readCollaborationState?(documentName: string): Promise<Uint8Array | null>;
|
|
384
|
-
writeCollaborationState?(
|
|
385
|
-
documentName: string,
|
|
386
|
-
state: Uint8Array,
|
|
387
|
-
): Promise<void>;
|
|
388
|
-
};
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
## Collaboration
|
|
392
|
-
|
|
393
|
-
### `useMdKitCollaboration`
|
|
394
|
-
|
|
395
|
-
Hook for creating a Hocuspocus/Yjs collaboration session for `MdKitEditor`.
|
|
396
|
-
|
|
397
|
-
Related types:
|
|
398
|
-
|
|
399
|
-
- `MdKitCollaborationParticipant`
|
|
400
|
-
- `MdKitCollaborationSession`
|
|
401
|
-
- `MdKitCollaborationStatus`
|
|
402
|
-
|
|
403
|
-
```ts
|
|
404
|
-
type MdKitCollaborationSession = {
|
|
405
|
-
collaborator: MdKitCollaborationParticipant;
|
|
406
|
-
document: Y.Doc;
|
|
407
|
-
provider: HocuspocusProvider | null;
|
|
408
|
-
roomName: string;
|
|
409
|
-
status: MdKitCollaborationStatus;
|
|
410
|
-
};
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
## Transport Helpers
|
|
414
|
-
|
|
415
|
-
### `createMdKitRestAdapter`
|
|
416
|
-
|
|
417
|
-
Creates an `MdKitDocumentAdapter` that talks to the mdkit REST endpoint shape.
|
|
418
|
-
Restore is not part of `MdKitDocumentAdapter` yet, so REST restore needs a
|
|
419
|
-
separate `POST /versions/:versionId/restore` call from application code. See
|
|
420
|
-
[REST Backend](./rest.md).
|
|
421
|
-
|
|
422
|
-
```ts
|
|
423
|
-
const adapter = createMdKitRestAdapter({
|
|
424
|
-
baseUrl: "https://api.example.com/mdkit",
|
|
425
|
-
});
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
Exported from `@mp-lb/mdkit`.
|
|
429
|
-
|
|
430
|
-
### `registerMdKitFastify`
|
|
431
|
-
|
|
432
|
-
Registers the matching REST endpoints on a Fastify app.
|
|
433
|
-
|
|
434
|
-
```ts
|
|
435
|
-
await registerMdKitFastify(app, {
|
|
436
|
-
prefix: "/mdkit",
|
|
437
|
-
store: mdkit,
|
|
438
|
-
});
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
Exported from `@mp-lb/mdkit/fastify`.
|
|
442
|
-
|
|
443
|
-
### `createMdKitTrpcRouter`
|
|
444
|
-
|
|
445
|
-
Creates a tRPC router for document reads, writes, resync, checkpoint list/read,
|
|
446
|
-
and restore. The current API names still use `Version`, but these methods model
|
|
447
|
-
checkpoint history.
|
|
448
|
-
|
|
449
|
-
```ts
|
|
450
|
-
const appRouter = t.router({
|
|
451
|
-
mdkit: createMdKitTrpcRouter(mdkit),
|
|
452
|
-
// otherRouters: ...
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
const server = createHTTPServer({
|
|
456
|
-
basePath: "/trpc",
|
|
457
|
-
router: appRouter,
|
|
458
|
-
});
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
Exported from `@mp-lb/mdkit/trpc/server`.
|
|
462
|
-
|
|
463
|
-
### `createMdKitTrpcClient` and `createMdKitTrpcAdapter`
|
|
464
|
-
|
|
465
|
-
Creates a typed tRPC client and turns it into an `MdKitDocumentAdapter`.
|
|
466
|
-
|
|
467
|
-
```ts
|
|
468
|
-
const client = createMdKitTrpcClient({ url: `${apiUrl}/trpc` });
|
|
469
|
-
const adapter = createMdKitTrpcAdapter({ client });
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
If the mdkit router is nested inside your app router, create your normal app
|
|
473
|
-
client and pass the mdkit sub-client:
|
|
474
|
-
|
|
475
|
-
```ts
|
|
476
|
-
const adapter = createMdKitTrpcAdapter({ client: trpc.mdkit });
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
Exported from `@mp-lb/mdkit/trpc/client`.
|
|
480
|
-
|
|
481
|
-
### `MdKitTransportStore`
|
|
482
|
-
|
|
483
|
-
Transport-ready backend surface used by the Fastify and tRPC helpers. You can
|
|
484
|
-
implement this directly for full control, but the opinionated path is to create
|
|
485
|
-
it with `createMdKitBackend({ store, checkpointPolicy })` so mdkit owns
|
|
486
|
-
checkpoint policy orchestration.
|
|
487
|
-
|
|
488
|
-
```ts
|
|
489
|
-
type MdKitTransportStore = {
|
|
490
|
-
readDocument(documentId: string): Promise<MdKitDocumentSnapshot>;
|
|
491
|
-
writeDocument(
|
|
492
|
-
input: MdKitDocumentWriteInput,
|
|
493
|
-
): Promise<MdKitDocumentWriteResult>;
|
|
494
|
-
resyncDocument?(documentId: string): Promise<MdKitDocumentSnapshot>;
|
|
495
|
-
listDocumentVersions?(
|
|
496
|
-
documentId: string,
|
|
497
|
-
): Promise<MdKitDocumentVersionSummary[]>;
|
|
498
|
-
readDocumentVersion?(input: {
|
|
499
|
-
documentId: string;
|
|
500
|
-
versionId: string;
|
|
501
|
-
}): Promise<MdKitDocumentVersionDetail | null>;
|
|
502
|
-
restoreDocumentVersion?(input: {
|
|
503
|
-
documentId: string;
|
|
504
|
-
versionId: string;
|
|
505
|
-
}): Promise<MdKitDocumentWriteResult>;
|
|
506
|
-
readCollaborationState?(documentName: string): Promise<Uint8Array | null>;
|
|
507
|
-
writeCollaborationState?(
|
|
508
|
-
documentName: string,
|
|
509
|
-
state: Uint8Array,
|
|
510
|
-
): Promise<void>;
|
|
511
|
-
};
|
|
512
|
-
```
|
package/docs/architecture.md
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
# Architecture
|
|
2
|
-
|
|
3
|
-
The editor package should keep UI concerns separate from persistence,
|
|
4
|
-
checkpoint history, permissions, and collaboration infrastructure.
|
|
5
|
-
|
|
6
|
-
## Layers
|
|
7
|
-
|
|
8
|
-
### Editor
|
|
9
|
-
|
|
10
|
-
`MdKitEditor` is the public editor component.
|
|
11
|
-
|
|
12
|
-
For local editing, it accepts:
|
|
13
|
-
|
|
14
|
-
- `value: string`
|
|
15
|
-
- `onChange?: (markdown: string) => void`
|
|
16
|
-
- `onFocusChange?: (focused: boolean) => void`
|
|
17
|
-
- `instanceKey?: string | number`
|
|
18
|
-
|
|
19
|
-
It should behave like a fancy textarea from the consumer's point of view. It
|
|
20
|
-
must not know about storage, checkpoints, auth, servers, Hocuspocus, MongoDB,
|
|
21
|
-
or the host application.
|
|
22
|
-
|
|
23
|
-
For collaborative editing, the same component accepts:
|
|
24
|
-
|
|
25
|
-
- `collaboration: MdKitCollaborationSession`
|
|
26
|
-
- `value?: string`
|
|
27
|
-
- `onChange?: (markdown: string) => void`
|
|
28
|
-
- `onFocusChange?: (focused: boolean) => void`
|
|
29
|
-
|
|
30
|
-
Collaboration needs a different editor engine internally because it is backed by
|
|
31
|
-
Yjs state and remote cursors, but consumers should not need a separate editor
|
|
32
|
-
component.
|
|
33
|
-
|
|
34
|
-
In collaborative mode, Yjs is the live content source. The editor must not apply
|
|
35
|
-
late React `value` updates into the collaborative document because a host app may
|
|
36
|
-
load the durable markdown snapshot after Hocuspocus has already hydrated the
|
|
37
|
-
same document. Applying that snapshot as editor content can duplicate blocks in
|
|
38
|
-
the shared CRDT state.
|
|
39
|
-
|
|
40
|
-
`MdKitView` is the read-only companion surface. It accepts a markdown `value`
|
|
41
|
-
and uses the same package styling and full-height layout contract as
|
|
42
|
-
`MdKitEditor`, but it renders markdown without Tiptap or ProseMirror. Use it
|
|
43
|
-
when consumers need previews, checkpoint snapshots, or readonly document views
|
|
44
|
-
that visually match the editor without paying the editor runtime cost.
|
|
45
|
-
|
|
46
|
-
### Headless Hooks
|
|
47
|
-
|
|
48
|
-
Storage, checkpoint history, and collaboration controls should come from hooks and
|
|
49
|
-
consumer-owned UI. A product can render those controls in a header, toolbar,
|
|
50
|
-
side panel, command menu, or nowhere at all.
|
|
51
|
-
|
|
52
|
-
Hooks should expose enough state for consumers to decide which UI features are
|
|
53
|
-
visible based on available adapters:
|
|
54
|
-
|
|
55
|
-
- storage adapter present: load/save UI and autosave can exist
|
|
56
|
-
- checkpoint adapter present: checkpoint history UI can exist
|
|
57
|
-
- collaboration adapter present: collaborative state and presence can exist
|
|
58
|
-
|
|
59
|
-
Missing adapters should remove functionality, not break the editor.
|
|
60
|
-
|
|
61
|
-
### Reference Integrations
|
|
62
|
-
|
|
63
|
-
Reference integrations should provide plug-and-play adapters for supported
|
|
64
|
-
backends. The editor UI should depend on adapter interfaces, not implementation
|
|
65
|
-
details.
|
|
66
|
-
|
|
67
|
-
Examples:
|
|
68
|
-
|
|
69
|
-
- JSON document storage
|
|
70
|
-
- MongoDB-backed document storage
|
|
71
|
-
- JSON or MongoDB checkpoint history
|
|
72
|
-
- Hocuspocus/Yjs collaboration
|
|
73
|
-
|
|
74
|
-
### Backend Helpers
|
|
75
|
-
|
|
76
|
-
The opinionated backend helper should provide structure, not own application
|
|
77
|
-
data. Applications still own storage, metadata, auth, permissions, tenancy, and
|
|
78
|
-
infrastructure. MDKit should own the workflow shape: current-document writes,
|
|
79
|
-
checkpoint policy, restore ordering, collaboration authorization hooks, and
|
|
80
|
-
markdown/Yjs bridging.
|
|
81
|
-
|
|
82
|
-
## Ownership Rule
|
|
83
|
-
|
|
84
|
-
The frontend editor owns rendering and local editing state. Adapters own
|
|
85
|
-
durable state and transport. The editor should never import database clients,
|
|
86
|
-
server framework code, or backend-specific SDKs.
|
|
87
|
-
|
|
88
|
-
## Package Boundaries
|
|
89
|
-
|
|
90
|
-
Packages should expose:
|
|
91
|
-
|
|
92
|
-
- pure types for adapter contracts
|
|
93
|
-
- React hooks/components for UI behavior
|
|
94
|
-
- optional adapter factories in separate entrypoints when we add reference integrations
|
|
95
|
-
|
|
96
|
-
Reference adapters should be optional dependencies or split entrypoints so a basic consumer does not install server-only or backend-specific code.
|