ocean-brain 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/mcp.js +79 -24
  2. package/package.json +2 -1
  3. package/server/client/dist/assets/{Calendar-DbPut8EU.js → Calendar-B2_OJcHD.js} +1 -1
  4. package/server/client/dist/assets/{Callout-DfX-gIUB.js → Callout-BvXAlA5k.js} +1 -1
  5. package/server/client/dist/assets/{Graph-yHE9m5fy.js → Graph-DO35UCPM.js} +1 -1
  6. package/server/client/dist/assets/{Image.es-CtMc7BW4.js → Image.es-DLqLiGdW.js} +1 -1
  7. package/server/client/dist/assets/Note-AaTlS352.js +22 -0
  8. package/server/client/dist/assets/{Plus.es-BGVIIQtM.js → Plus.es-I7xuoJ9B.js} +1 -1
  9. package/server/client/dist/assets/{Reminders-CvEJf0eQ.js → Reminders-B0LJeSlu.js} +1 -1
  10. package/server/client/dist/assets/{Search-CKZhztuV.js → Search-xbDSlNOT.js} +1 -1
  11. package/server/client/dist/assets/{SurfaceCard-Bnfo5EOl.js → SurfaceCard-Brd1cMxi.js} +1 -1
  12. package/server/client/dist/assets/{Tag-C4oAwjs0.js → Tag-2PlhkjwY.js} +1 -1
  13. package/server/client/dist/assets/{TagNotes-Rl1ZSJP6.js → TagNotes-1yUBLqhX.js} +1 -1
  14. package/server/client/dist/assets/{Trash.es-BcwUz2yM.js → Trash.es-B-7U25B6.js} +1 -1
  15. package/server/client/dist/assets/{ViewNotes-B9Yc0A87.js → ViewNotes-D4X-MCTk.js} +1 -1
  16. package/server/client/dist/assets/{ViewSectionTableRenderer-C5yJBO7C.js → ViewSectionTableRenderer-FuqBpQts.js} +1 -1
  17. package/server/client/dist/assets/{Views-Bqq0pUEE.js → Views-CBEimWY8.js} +1 -1
  18. package/server/client/dist/assets/{image.api-CuGTgzyQ.js → image.api-BtadKO98.js} +1 -1
  19. package/server/client/dist/assets/{index-CDjYEIVf.css → index-BFkZTZ6v.css} +1 -1
  20. package/server/client/dist/assets/{index-B43ulIPo.js → index-BgnmVjeF.js} +45 -11
  21. package/server/client/dist/assets/{index-BQDR6hIA.js → index-sGhvnErO.js} +1 -1
  22. package/server/client/dist/assets/{manage-image-Bs4Kmevx.js → manage-image-B4UZ-ZQx.js} +1 -1
  23. package/server/client/dist/assets/{manage-image-detail-WARala-v.js → manage-image-detail-ejAh3nCL.js} +1 -1
  24. package/server/client/dist/assets/{mcp-C0Z3vKBa.js → mcp-aIwuouT9.js} +1 -1
  25. package/server/client/dist/assets/{placeholder-D080guzn.js → placeholder-B_9Hnm7h.js} +4 -4
  26. package/server/client/dist/assets/{properties-DbnmfbT5.js → properties-D8oLyTCD.js} +1 -1
  27. package/server/client/dist/assets/{trash-D5ZiZfTk.js → trash-w7Hhxckg.js} +1 -1
  28. package/server/client/dist/assets/{useReminderMutate-h7d_S_X2.js → useReminderMutate--RlAj_Gg.js} +1 -1
  29. package/server/client/dist/index.html +2 -2
  30. package/server/dist/features/note/graphql/note.query.resolver.js +88 -47
  31. package/server/dist/features/note/graphql/note.query.resolver.js.map +1 -1
  32. package/server/dist/features/note/graphql/note.type-defs.js +32 -0
  33. package/server/dist/features/note/graphql/note.type-defs.js.map +1 -1
  34. package/server/dist/features/note/http/mcp.js +32 -0
  35. package/server/dist/features/note/http/mcp.js.map +1 -1
  36. package/server/dist/features/note/services/markdown-intent-write.js +3 -3
  37. package/server/dist/features/note/services/markdown-intent-write.js.map +1 -1
  38. package/server/dist/features/note/services/markdown-patch.js +34 -4
  39. package/server/dist/features/note/services/markdown-patch.js.map +1 -1
  40. package/server/dist/features/note/services/snapshot.js +159 -0
  41. package/server/dist/features/note/services/snapshot.js.map +1 -1
  42. package/server/dist/modules/blocknote.js +274 -24
  43. package/server/dist/modules/blocknote.js.map +1 -1
  44. package/server/dist/routes/mcp.js +5 -0
  45. package/server/dist/routes/mcp.js.map +1 -1
  46. package/server/client/dist/assets/Note-BECn-AoI.js +0 -21
@@ -4,6 +4,8 @@ import models from "../models.js";
4
4
  const UNSUPPORTED_MARKDOWN_BLOCK_TYPES = /* @__PURE__ */ new Set(["tableOfContents"]);
5
5
  const TAG_PLACEHOLDER_PREFIX = "OCEAN_BRAIN_TAG_";
6
6
  const TAG_PLACEHOLDER_SUFFIX = "_TOKEN";
7
+ const REFERENCE_PLACEHOLDER_PREFIX = "OCEAN_BRAIN_REFERENCE_";
8
+ const REFERENCE_PLACEHOLDER_SUFFIX = "_TOKEN";
7
9
  const defaultMarkdownImportDeps = {
8
10
  ensureTag: async (name) => ensureTagByName(name),
9
11
  findNotesByTitle: async (title) => {
@@ -20,6 +22,23 @@ const defaultMarkdownImportDeps = {
20
22
  id: String(note.id),
21
23
  title: note.title
22
24
  }));
25
+ },
26
+ findNoteById: async (id) => {
27
+ if (!isValidNoteIdString(id)) {
28
+ return null;
29
+ }
30
+ const numericId = Number(id);
31
+ const note = await models.note.findUnique({
32
+ select: {
33
+ id: true,
34
+ title: true
35
+ },
36
+ where: { id: numericId }
37
+ });
38
+ return note ? {
39
+ id: String(note.id),
40
+ title: note.title
41
+ } : null;
23
42
  }
24
43
  };
25
44
  function stripUnsupportedMarkdownBlocks(blocks) {
@@ -46,6 +65,16 @@ function visitBlocks(blocks, visit) {
46
65
  function createTagPlaceholder(index) {
47
66
  return `${TAG_PLACEHOLDER_PREFIX}${index}${TAG_PLACEHOLDER_SUFFIX}`;
48
67
  }
68
+ function createReferencePlaceholder(index) {
69
+ return `${REFERENCE_PLACEHOLDER_PREFIX}${index}${REFERENCE_PLACEHOLDER_SUFFIX}`;
70
+ }
71
+ function isValidNoteIdString(id) {
72
+ if (!/^[1-9]\d*$/.test(id)) {
73
+ return false;
74
+ }
75
+ const numericId = Number(id);
76
+ return Number.isSafeInteger(numericId) && numericId <= MAX_SQLITE_INT_ID;
77
+ }
49
78
  function isTableContent(content) {
50
79
  return !Array.isArray(content) && content?.type === "tableContent";
51
80
  }
@@ -114,23 +143,16 @@ function mapBlocks(blocks, mapContent) {
114
143
  children: block.children?.length ? mapBlocks(block.children, mapContent) : []
115
144
  }));
116
145
  }
117
- async function mapBlocksAsync(blocks, mapContent) {
118
- return Promise.all(
119
- blocks.map(async (block) => ({
120
- ...block,
121
- content: await mapContent(block.content),
122
- children: block.children?.length ? await mapBlocksAsync(block.children, mapContent) : []
123
- }))
124
- );
125
- }
126
146
  function preprocessCustomInlineContent(blocks, placeholderToTag, nextPlaceholderIndex) {
127
147
  return mapBlocks(
128
148
  blocks,
129
149
  (content) => mapBlockContent(content, (inline) => {
130
150
  if (inline.type === "reference") {
151
+ const id = String(inline.props?.id || "");
152
+ const title = String(inline.props?.title || inline.props?.id || "");
131
153
  return {
132
154
  type: "text",
133
- text: `[[${inline.props?.title || inline.props?.id || ""}]]`,
155
+ text: isValidNoteIdString(id) ? `[[${title}]](note:${id})` : `[[${title}]]`,
134
156
  styles: {}
135
157
  };
136
158
  }
@@ -168,6 +190,57 @@ function preprocessMarkdownExplicitTags(markdown) {
168
190
  placeholderToTag
169
191
  };
170
192
  }
193
+ function preprocessMarkdownExplicitReferences(markdown) {
194
+ const placeholderToReference = /* @__PURE__ */ new Map();
195
+ let activeFence = null;
196
+ const preprocessedLines = markdown.split(/(?<=\n)/).map((line) => {
197
+ const { body: lineBody, lineEnding } = splitMarkdownLineEnding(line);
198
+ const fenceMatch = lineBody.match(MARKDOWN_FENCED_CODE_PATTERN);
199
+ if (activeFence) {
200
+ if (isClosingFenceLine(lineBody, activeFence)) {
201
+ activeFence = null;
202
+ }
203
+ return line;
204
+ }
205
+ if (fenceMatch?.[1]) {
206
+ activeFence = {
207
+ marker: fenceMatch[1][0],
208
+ length: fenceMatch[1].length
209
+ };
210
+ return line;
211
+ }
212
+ if (/^(?: {4,}|\t)/.test(lineBody)) {
213
+ return line;
214
+ }
215
+ return `${replaceMarkdownLineExplicitReferences(lineBody, placeholderToReference)}${lineEnding}`;
216
+ });
217
+ return {
218
+ markdown: preprocessedLines.join(""),
219
+ placeholderToReference
220
+ };
221
+ }
222
+ function replaceMarkdownLineExplicitReferences(line, placeholderToReference) {
223
+ let result = "";
224
+ let cursor = 0;
225
+ while (cursor < line.length) {
226
+ const codeSpan = findNextInlineCodeSpan(line, cursor);
227
+ if (!codeSpan) {
228
+ result += replaceExplicitReferenceTokens(line.slice(cursor), placeholderToReference);
229
+ break;
230
+ }
231
+ result += replaceExplicitReferenceTokens(line.slice(cursor, codeSpan.start), placeholderToReference);
232
+ result += line.slice(codeSpan.start, codeSpan.end);
233
+ cursor = codeSpan.end;
234
+ }
235
+ return result;
236
+ }
237
+ function replaceExplicitReferenceTokens(text, placeholderToReference) {
238
+ return text.replace(/\[\[([^\]\n]+)\]\]\(note:([^)\s]+)\)/g, (token, title, id) => {
239
+ const placeholder = createReferencePlaceholder(placeholderToReference.size);
240
+ placeholderToReference.set(placeholder, { id, title, token });
241
+ return placeholder;
242
+ });
243
+ }
171
244
  const MARKDOWN_ANGLE_BRACKET_TOKEN_PATTERN = /<([^<>\n]+)>/g;
172
245
  const MARKDOWN_NUMERIC_TILDE_RANGE_PATTERN = /(\d)~(?=\d)/g;
173
246
  const MARKDOWN_FENCED_CODE_PATTERN = /^ {0,3}(`{3,}|~{3,})/;
@@ -175,6 +248,9 @@ const ANGLE_BRACKET_PLACEHOLDER_PREFIX = "\uE000OBANGLE";
175
248
  const ANGLE_BRACKET_PLACEHOLDER_SUFFIX = "\uE001";
176
249
  const NUMERIC_TILDE_RANGE_PLACEHOLDER_PREFIX = "\uE000OBTILDE";
177
250
  const NUMERIC_TILDE_RANGE_PLACEHOLDER_SUFFIX = "\uE001";
251
+ const HARD_BREAK_PLACEHOLDER_PREFIX = "\uE000OBHARDBREAK";
252
+ const HARD_BREAK_PLACEHOLDER_SUFFIX = "\uE001";
253
+ const MAX_SQLITE_INT_ID = 2147483647;
178
254
  function isMarkdownAutolinkAngleBracketText(innerText) {
179
255
  if (innerText !== innerText.trim()) {
180
256
  return false;
@@ -253,6 +329,49 @@ function protectMarkdownNumericTildeRanges(markdown) {
253
329
  placeholderToToken
254
330
  };
255
331
  }
332
+ function protectMarkdownLineEndHardBreakMarkers(markdown) {
333
+ const protectedLines = [];
334
+ const placeholderToToken = /* @__PURE__ */ new Map();
335
+ let activeFence = null;
336
+ const lines = markdown.split(/(?<=\n)/);
337
+ for (const [index, line] of lines.entries()) {
338
+ const { body: lineBody, lineEnding } = splitMarkdownLineEnding(line);
339
+ const fenceMatch = lineBody.match(MARKDOWN_FENCED_CODE_PATTERN);
340
+ if (activeFence) {
341
+ protectedLines.push(line);
342
+ if (isClosingFenceLine(lineBody, activeFence)) {
343
+ activeFence = null;
344
+ }
345
+ continue;
346
+ }
347
+ if (fenceMatch?.[1]) {
348
+ const marker = fenceMatch[1][0];
349
+ activeFence = {
350
+ marker,
351
+ length: fenceMatch[1].length
352
+ };
353
+ protectedLines.push(line);
354
+ continue;
355
+ }
356
+ if (/^(?: {4,}|\t)/.test(lineBody)) {
357
+ protectedLines.push(line);
358
+ continue;
359
+ }
360
+ const nextLineBody = splitMarkdownLineEnding(lines[index + 1] ?? "").body;
361
+ protectedLines.push(
362
+ `${protectMarkdownLineEndHardBreakMarker(
363
+ lineBody,
364
+ lineEnding,
365
+ isMarkdownHardBreakContinuationLine(nextLineBody),
366
+ placeholderToToken
367
+ )}${lineEnding}`
368
+ );
369
+ }
370
+ return {
371
+ markdown: protectedLines.join(""),
372
+ placeholderToToken
373
+ };
374
+ }
256
375
  function protectMarkdownTextAngleBrackets(markdown) {
257
376
  const protectedLines = [];
258
377
  const placeholderToToken = /* @__PURE__ */ new Map();
@@ -404,12 +523,61 @@ function replaceNumericTildeRangeMarkers(text, placeholderToToken) {
404
523
  return `${leadingDigit}${placeholder}`;
405
524
  });
406
525
  }
526
+ function protectMarkdownLineEndHardBreakMarker(line, lineEnding, hasContinuationLine, placeholderToToken) {
527
+ if (!lineEnding || !line.endsWith("\\")) {
528
+ return line;
529
+ }
530
+ const placeholder = createHardBreakPlaceholder(placeholderToToken.size);
531
+ const shouldPreserveAsHardBreak = hasContinuationLine && !hasUnclosedInlineCodeSpanAtLineEnd(line);
532
+ placeholderToToken.set(placeholder, shouldPreserveAsHardBreak ? "" : "\\");
533
+ return `${line.slice(0, -1)}${placeholder}`;
534
+ }
535
+ function isMarkdownHardBreakContinuationLine(line) {
536
+ if (!line.trim()) {
537
+ return false;
538
+ }
539
+ const trimmedLine = line.trimStart();
540
+ if (trimmedLine.match(MARKDOWN_FENCED_CODE_PATTERN)) {
541
+ return false;
542
+ }
543
+ if (/^(?:#{1,6})(?:\s|$)/.test(trimmedLine)) {
544
+ return false;
545
+ }
546
+ if (/^>/.test(trimmedLine)) {
547
+ return false;
548
+ }
549
+ if (/^(?:[-+*])(?:\s|$)/.test(trimmedLine) || /^\d{1,9}[.)](?:\s|$)/.test(trimmedLine)) {
550
+ return false;
551
+ }
552
+ if (/^(?:-{3,}|\*{3,}|_{3,})\s*$/.test(trimmedLine)) {
553
+ return false;
554
+ }
555
+ return true;
556
+ }
557
+ function hasUnclosedInlineCodeSpanAtLineEnd(line) {
558
+ let cursor = 0;
559
+ let openDelimiter = null;
560
+ while (cursor < line.length) {
561
+ const codeStart = line.indexOf("`", cursor);
562
+ if (codeStart === -1) {
563
+ break;
564
+ }
565
+ const delimiterLength = countRepeatedCharacter(line, codeStart, "`");
566
+ const delimiter = "`".repeat(delimiterLength);
567
+ openDelimiter = openDelimiter === delimiter ? null : delimiter;
568
+ cursor = codeStart + delimiterLength;
569
+ }
570
+ return openDelimiter !== null;
571
+ }
407
572
  function createAngleBracketPlaceholder(index) {
408
573
  return `${ANGLE_BRACKET_PLACEHOLDER_PREFIX}${index}${ANGLE_BRACKET_PLACEHOLDER_SUFFIX}`;
409
574
  }
410
575
  function createNumericTildeRangePlaceholder(index) {
411
576
  return `${NUMERIC_TILDE_RANGE_PLACEHOLDER_PREFIX}${index}${NUMERIC_TILDE_RANGE_PLACEHOLDER_SUFFIX}`;
412
577
  }
578
+ function createHardBreakPlaceholder(index) {
579
+ return `${HARD_BREAK_PLACEHOLDER_PREFIX}${index}${HARD_BREAK_PLACEHOLDER_SUFFIX}`;
580
+ }
413
581
  function countRepeatedCharacter(value, start, character) {
414
582
  let cursor = start;
415
583
  while (value[cursor] === character) {
@@ -428,6 +596,17 @@ function findTagPlaceholderAtCursor(text, cursor, placeholderToTag) {
428
596
  }
429
597
  return null;
430
598
  }
599
+ function findReferencePlaceholderAtCursor(text, cursor, placeholderToReference) {
600
+ for (const [placeholder, reference] of placeholderToReference.entries()) {
601
+ if (text.startsWith(placeholder, cursor)) {
602
+ return {
603
+ placeholder,
604
+ reference
605
+ };
606
+ }
607
+ }
608
+ return null;
609
+ }
431
610
  function restoreRemainingTagPlaceholders(blocks, placeholderToTag) {
432
611
  return mapBlocks(
433
612
  blocks,
@@ -494,9 +673,10 @@ function appendInline(target, inline) {
494
673
  }
495
674
  target.push(inline);
496
675
  }
497
- async function restoreCustomInlineContent(blocks, deps, placeholderToTag) {
676
+ async function restoreCustomInlineContent(blocks, deps, placeholderToTag, placeholderToReference = /* @__PURE__ */ new Map()) {
498
677
  const tagCache = /* @__PURE__ */ new Map();
499
678
  const noteCache = /* @__PURE__ */ new Map();
679
+ const noteByIdCache = /* @__PURE__ */ new Map();
500
680
  const getTag = (token) => {
501
681
  const normalizedToken = token.startsWith("#") ? `@${token.slice(1)}` : token;
502
682
  let existing = tagCache.get(normalizedToken);
@@ -517,6 +697,14 @@ async function restoreCustomInlineContent(blocks, deps, placeholderToTag) {
517
697
  }
518
698
  return existing;
519
699
  };
700
+ const getNoteById = (id) => {
701
+ let existing = noteByIdCache.get(id);
702
+ if (!existing) {
703
+ existing = deps.findNoteById ? deps.findNoteById(id) : Promise.resolve(null);
704
+ noteByIdCache.set(id, existing);
705
+ }
706
+ return existing;
707
+ };
520
708
  const restoreTextInline = async (inline) => {
521
709
  if (inline.type !== "text" || typeof inline.text !== "string" || !inline.text || inline.styles?.code === true) {
522
710
  return [inline];
@@ -525,6 +713,32 @@ async function restoreCustomInlineContent(blocks, deps, placeholderToTag) {
525
713
  const styles = inline.styles ?? {};
526
714
  let cursor = 0;
527
715
  while (cursor < inline.text.length) {
716
+ const referencePlaceholderMatch = findReferencePlaceholderAtCursor(
717
+ inline.text,
718
+ cursor,
719
+ placeholderToReference
720
+ );
721
+ if (referencePlaceholderMatch) {
722
+ if (!isValidNoteIdString(referencePlaceholderMatch.reference.id)) {
723
+ appendInline(restored, createTextInline(referencePlaceholderMatch.reference.token, styles));
724
+ cursor += referencePlaceholderMatch.placeholder.length;
725
+ continue;
726
+ }
727
+ const note = await getNoteById(referencePlaceholderMatch.reference.id);
728
+ if (note) {
729
+ appendInline(restored, {
730
+ type: "reference",
731
+ props: {
732
+ id: note.id,
733
+ title: note.title
734
+ }
735
+ });
736
+ } else {
737
+ appendInline(restored, createTextInline(referencePlaceholderMatch.reference.token, styles));
738
+ }
739
+ cursor += referencePlaceholderMatch.placeholder.length;
740
+ continue;
741
+ }
528
742
  if (inline.text.startsWith("[[", cursor)) {
529
743
  const closeIndex = inline.text.indexOf("]]", cursor + 2);
530
744
  if (closeIndex !== -1) {
@@ -564,12 +778,35 @@ async function restoreCustomInlineContent(blocks, deps, placeholderToTag) {
564
778
  nextCursor = Math.min(nextCursor, nextPlaceholderCursor);
565
779
  }
566
780
  }
781
+ for (const placeholder of placeholderToReference.keys()) {
782
+ const nextPlaceholderCursor = inline.text.indexOf(placeholder, cursor + 1);
783
+ if (nextPlaceholderCursor !== -1) {
784
+ nextCursor = Math.min(nextCursor, nextPlaceholderCursor);
785
+ }
786
+ }
567
787
  appendInline(restored, createTextInline(inline.text.slice(cursor, nextCursor), styles));
568
788
  cursor = nextCursor;
569
789
  }
570
790
  return restored;
571
791
  };
572
- return mapBlocksAsync(blocks, (content) => mapBlockContentAsync(content, restoreTextInline));
792
+ const restoreBlocks = async (items) => {
793
+ return Promise.all(
794
+ items.map(async (block) => {
795
+ if (block.type === "codeBlock") {
796
+ return {
797
+ ...block,
798
+ children: block.children?.length ? await restoreBlocks(block.children) : []
799
+ };
800
+ }
801
+ return {
802
+ ...block,
803
+ content: await mapBlockContentAsync(block.content, restoreTextInline),
804
+ children: block.children?.length ? await restoreBlocks(block.children) : []
805
+ };
806
+ })
807
+ );
808
+ };
809
+ return restoreBlocks(blocks);
573
810
  }
574
811
  function collectTagIds(blocks) {
575
812
  const tagIds = /* @__PURE__ */ new Set();
@@ -613,36 +850,49 @@ async function blocksToMarkdown(contentJson) {
613
850
  async function markdownToBlocksJson(markdown, deps = defaultMarkdownImportDeps) {
614
851
  const editor = getEditor();
615
852
  const preprocessedMarkdown = preprocessMarkdownExplicitTags(markdown);
616
- const tildeProtectedMarkdown = protectMarkdownNumericTildeRanges(preprocessedMarkdown.markdown);
853
+ const preprocessedReferenceMarkdown = preprocessMarkdownExplicitReferences(preprocessedMarkdown.markdown);
854
+ const tildeProtectedMarkdown = protectMarkdownNumericTildeRanges(preprocessedReferenceMarkdown.markdown);
855
+ const hardBreakProtectedMarkdown = protectMarkdownLineEndHardBreakMarkers(tildeProtectedMarkdown.markdown);
856
+ const basePlaceholderToToken = new Map([
857
+ ...tildeProtectedMarkdown.placeholderToToken,
858
+ ...hardBreakProtectedMarkdown.placeholderToToken
859
+ ]);
617
860
  const contentJson = await parseMarkdownToContentJson(
618
861
  editor,
619
- tildeProtectedMarkdown.markdown,
862
+ hardBreakProtectedMarkdown.markdown,
620
863
  deps,
621
864
  preprocessedMarkdown.placeholderToTag,
622
- tildeProtectedMarkdown.placeholderToToken
865
+ preprocessedReferenceMarkdown.placeholderToReference,
866
+ basePlaceholderToToken
623
867
  );
624
- if (extractLiteralAngleBracketTextTokens(preprocessedMarkdown.markdown).length === 0) {
868
+ if (extractLiteralAngleBracketTextTokens(preprocessedReferenceMarkdown.markdown).length === 0) {
625
869
  return contentJson;
626
870
  }
627
- if (!hasLiteralAngleBracketTextTokenLoss(preprocessedMarkdown.markdown, await blocksToMarkdown(contentJson))) {
871
+ if (!hasLiteralAngleBracketTextTokenLoss(
872
+ preprocessedReferenceMarkdown.markdown,
873
+ await blocksToMarkdown(contentJson)
874
+ )) {
628
875
  return contentJson;
629
876
  }
630
- const protectedMarkdown = protectMarkdownTextAngleBrackets(tildeProtectedMarkdown.markdown);
631
- const placeholderToToken = new Map([
632
- ...tildeProtectedMarkdown.placeholderToToken,
633
- ...protectedMarkdown.placeholderToToken
634
- ]);
877
+ const protectedMarkdown = protectMarkdownTextAngleBrackets(hardBreakProtectedMarkdown.markdown);
878
+ const placeholderToToken = new Map([...basePlaceholderToToken, ...protectedMarkdown.placeholderToToken]);
635
879
  return parseMarkdownToContentJson(
636
880
  editor,
637
881
  protectedMarkdown.markdown,
638
882
  deps,
639
883
  preprocessedMarkdown.placeholderToTag,
884
+ preprocessedReferenceMarkdown.placeholderToReference,
640
885
  placeholderToToken
641
886
  );
642
887
  }
643
- async function parseMarkdownToContentJson(editor, markdown, deps, placeholderToTag, placeholderToProtectedTextToken = /* @__PURE__ */ new Map()) {
888
+ async function parseMarkdownToContentJson(editor, markdown, deps, placeholderToTag, placeholderToReference = /* @__PURE__ */ new Map(), placeholderToProtectedTextToken = /* @__PURE__ */ new Map()) {
644
889
  const blocks = await editor.tryParseMarkdownToBlocks(markdown);
645
- const restoredBlocks = await restoreCustomInlineContent(blocks, deps, placeholderToTag);
890
+ const restoredBlocks = await restoreCustomInlineContent(
891
+ blocks,
892
+ deps,
893
+ placeholderToTag,
894
+ placeholderToReference
895
+ );
646
896
  const restoredTagBlocks = restoreRemainingTagPlaceholders(restoredBlocks, placeholderToTag);
647
897
  const restoredProtectedTextBlocks = restoreProtectedTextPlaceholders(
648
898
  restoredTagBlocks,