@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
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
- ```
@@ -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.