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.
- package/dist/mcp.js +79 -24
- package/package.json +2 -1
- package/server/client/dist/assets/{Calendar-DbPut8EU.js → Calendar-B2_OJcHD.js} +1 -1
- package/server/client/dist/assets/{Callout-DfX-gIUB.js → Callout-BvXAlA5k.js} +1 -1
- package/server/client/dist/assets/{Graph-yHE9m5fy.js → Graph-DO35UCPM.js} +1 -1
- package/server/client/dist/assets/{Image.es-CtMc7BW4.js → Image.es-DLqLiGdW.js} +1 -1
- package/server/client/dist/assets/Note-AaTlS352.js +22 -0
- package/server/client/dist/assets/{Plus.es-BGVIIQtM.js → Plus.es-I7xuoJ9B.js} +1 -1
- package/server/client/dist/assets/{Reminders-CvEJf0eQ.js → Reminders-B0LJeSlu.js} +1 -1
- package/server/client/dist/assets/{Search-CKZhztuV.js → Search-xbDSlNOT.js} +1 -1
- package/server/client/dist/assets/{SurfaceCard-Bnfo5EOl.js → SurfaceCard-Brd1cMxi.js} +1 -1
- package/server/client/dist/assets/{Tag-C4oAwjs0.js → Tag-2PlhkjwY.js} +1 -1
- package/server/client/dist/assets/{TagNotes-Rl1ZSJP6.js → TagNotes-1yUBLqhX.js} +1 -1
- package/server/client/dist/assets/{Trash.es-BcwUz2yM.js → Trash.es-B-7U25B6.js} +1 -1
- package/server/client/dist/assets/{ViewNotes-B9Yc0A87.js → ViewNotes-D4X-MCTk.js} +1 -1
- package/server/client/dist/assets/{ViewSectionTableRenderer-C5yJBO7C.js → ViewSectionTableRenderer-FuqBpQts.js} +1 -1
- package/server/client/dist/assets/{Views-Bqq0pUEE.js → Views-CBEimWY8.js} +1 -1
- package/server/client/dist/assets/{image.api-CuGTgzyQ.js → image.api-BtadKO98.js} +1 -1
- package/server/client/dist/assets/{index-CDjYEIVf.css → index-BFkZTZ6v.css} +1 -1
- package/server/client/dist/assets/{index-B43ulIPo.js → index-BgnmVjeF.js} +45 -11
- package/server/client/dist/assets/{index-BQDR6hIA.js → index-sGhvnErO.js} +1 -1
- package/server/client/dist/assets/{manage-image-Bs4Kmevx.js → manage-image-B4UZ-ZQx.js} +1 -1
- package/server/client/dist/assets/{manage-image-detail-WARala-v.js → manage-image-detail-ejAh3nCL.js} +1 -1
- package/server/client/dist/assets/{mcp-C0Z3vKBa.js → mcp-aIwuouT9.js} +1 -1
- package/server/client/dist/assets/{placeholder-D080guzn.js → placeholder-B_9Hnm7h.js} +4 -4
- package/server/client/dist/assets/{properties-DbnmfbT5.js → properties-D8oLyTCD.js} +1 -1
- package/server/client/dist/assets/{trash-D5ZiZfTk.js → trash-w7Hhxckg.js} +1 -1
- package/server/client/dist/assets/{useReminderMutate-h7d_S_X2.js → useReminderMutate--RlAj_Gg.js} +1 -1
- package/server/client/dist/index.html +2 -2
- package/server/dist/features/note/graphql/note.query.resolver.js +88 -47
- package/server/dist/features/note/graphql/note.query.resolver.js.map +1 -1
- package/server/dist/features/note/graphql/note.type-defs.js +32 -0
- package/server/dist/features/note/graphql/note.type-defs.js.map +1 -1
- package/server/dist/features/note/http/mcp.js +32 -0
- package/server/dist/features/note/http/mcp.js.map +1 -1
- package/server/dist/features/note/services/markdown-intent-write.js +3 -3
- package/server/dist/features/note/services/markdown-intent-write.js.map +1 -1
- package/server/dist/features/note/services/markdown-patch.js +34 -4
- package/server/dist/features/note/services/markdown-patch.js.map +1 -1
- package/server/dist/features/note/services/snapshot.js +159 -0
- package/server/dist/features/note/services/snapshot.js.map +1 -1
- package/server/dist/modules/blocknote.js +274 -24
- package/server/dist/modules/blocknote.js.map +1 -1
- package/server/dist/routes/mcp.js +5 -0
- package/server/dist/routes/mcp.js.map +1 -1
- 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: `[[${
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
862
|
+
hardBreakProtectedMarkdown.markdown,
|
|
620
863
|
deps,
|
|
621
864
|
preprocessedMarkdown.placeholderToTag,
|
|
622
|
-
|
|
865
|
+
preprocessedReferenceMarkdown.placeholderToReference,
|
|
866
|
+
basePlaceholderToToken
|
|
623
867
|
);
|
|
624
|
-
if (extractLiteralAngleBracketTextTokens(
|
|
868
|
+
if (extractLiteralAngleBracketTextTokens(preprocessedReferenceMarkdown.markdown).length === 0) {
|
|
625
869
|
return contentJson;
|
|
626
870
|
}
|
|
627
|
-
if (!hasLiteralAngleBracketTextTokenLoss(
|
|
871
|
+
if (!hasLiteralAngleBracketTextTokenLoss(
|
|
872
|
+
preprocessedReferenceMarkdown.markdown,
|
|
873
|
+
await blocksToMarkdown(contentJson)
|
|
874
|
+
)) {
|
|
628
875
|
return contentJson;
|
|
629
876
|
}
|
|
630
|
-
const protectedMarkdown = protectMarkdownTextAngleBrackets(
|
|
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(
|
|
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,
|