@supernova-studio/client 0.32.0 → 0.34.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/index.d.mts +233 -183
- package/dist/index.d.ts +233 -183
- package/dist/index.js +417 -284
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +408 -275
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/api/dto/elements/documentation/group.ts +1 -1
- package/src/yjs/docs-editor/blocks-to-prosemirror.ts +19 -7
- package/src/yjs/docs-editor/index.ts +1 -0
- package/src/yjs/docs-editor/list-tree-builder.ts +23 -82
- package/src/yjs/docs-editor/mock.ts +304 -147
- package/src/yjs/docs-editor/prosemirror-to-blocks.ts +109 -68
|
@@ -73,6 +73,12 @@ export function prosemirrorDocToPage(
|
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
export function prosemirrorNodeToBlock(prosemirrorNode: ProsemirrorNode, definitions: PageBlockDefinition[]) {
|
|
77
|
+
const definitionsById = mapByUnique(definitions, d => d.id);
|
|
78
|
+
const block = internalProsemirrorNodeToBlock(prosemirrorNode, definitionsById, 0);
|
|
79
|
+
return block[0] ?? null;
|
|
80
|
+
}
|
|
81
|
+
|
|
76
82
|
//
|
|
77
83
|
// Sections
|
|
78
84
|
//
|
|
@@ -134,7 +140,7 @@ function prosemirrorNodeToSectionColumns(
|
|
|
134
140
|
|
|
135
141
|
return {
|
|
136
142
|
id: id,
|
|
137
|
-
blocks: internalProsemirrorNodesToBlocks(prosemirrorNode.content ?? [], definitionsMap),
|
|
143
|
+
blocks: internalProsemirrorNodesToBlocks(prosemirrorNode.content ?? [], definitionsMap, 0),
|
|
138
144
|
};
|
|
139
145
|
}
|
|
140
146
|
|
|
@@ -144,49 +150,49 @@ function prosemirrorNodeToSectionColumns(
|
|
|
144
150
|
|
|
145
151
|
export function prosemirrorNodesToBlocks(prosemirrorNodes: ProsemirrorNode[], definitions: PageBlockDefinition[]) {
|
|
146
152
|
const definitionsById = mapByUnique(definitions, d => d.id);
|
|
147
|
-
return internalProsemirrorNodesToBlocks(prosemirrorNodes, definitionsById);
|
|
153
|
+
return internalProsemirrorNodesToBlocks(prosemirrorNodes, definitionsById, 0);
|
|
148
154
|
}
|
|
149
155
|
|
|
150
156
|
function internalProsemirrorNodesToPageItems(
|
|
151
157
|
prosemirrorNodes: ProsemirrorNode[],
|
|
152
158
|
definitionsMap: Map<string, PageBlockDefinition>
|
|
153
159
|
): (PageBlockEditorModel | PageSectionEditorModel)[] {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
|
|
160
|
+
const result: (PageBlockEditorModel | PageSectionEditorModel)[] = [];
|
|
161
|
+
|
|
162
|
+
for (const prosemirrorNode of prosemirrorNodes) {
|
|
163
|
+
if (prosemirrorNode.type === "tabsSection") {
|
|
164
|
+
// Section
|
|
165
|
+
const section = prosemirrorNodeToSection(prosemirrorNode, Array.from(definitionsMap.values()));
|
|
166
|
+
section && result.push(section);
|
|
167
|
+
} else {
|
|
168
|
+
// Block
|
|
169
|
+
result.push(...internalProsemirrorNodeToBlock(prosemirrorNode, definitionsMap, 0));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return result;
|
|
163
174
|
}
|
|
164
175
|
|
|
165
176
|
function internalProsemirrorNodesToBlocks(
|
|
166
177
|
prosemirrorNodes: ProsemirrorNode[],
|
|
167
|
-
definitionsMap: Map<string, PageBlockDefinition
|
|
178
|
+
definitionsMap: Map<string, PageBlockDefinition>,
|
|
179
|
+
depth: number
|
|
168
180
|
): PageBlockEditorModel[] {
|
|
169
|
-
return prosemirrorNodes
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
})
|
|
173
|
-
.filter(nonNullFilter);
|
|
181
|
+
return prosemirrorNodes.flatMap(prosemirrorNode => {
|
|
182
|
+
return internalProsemirrorNodeToBlock(prosemirrorNode, definitionsMap, depth);
|
|
183
|
+
});
|
|
174
184
|
}
|
|
175
185
|
|
|
176
186
|
function internalProsemirrorNodeToBlock(
|
|
177
187
|
prosemirrorNode: ProsemirrorNode,
|
|
178
|
-
definitionsMap: Map<string, PageBlockDefinition
|
|
179
|
-
|
|
180
|
-
|
|
188
|
+
definitionsMap: Map<string, PageBlockDefinition>,
|
|
189
|
+
depth: number
|
|
190
|
+
): PageBlockEditorModel[] {
|
|
191
|
+
const definitionId = getProsemirrorAttribute(prosemirrorNode, "definitionId", z.string());
|
|
181
192
|
if (!definitionId) {
|
|
182
193
|
console.warn(`definitionId on ${prosemirrorNode.type} is required to be interpreted as a block, skipping node`);
|
|
183
194
|
|
|
184
|
-
return
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// TODO: remove
|
|
188
|
-
if (definitionId === "io.supernova.block.token-detail") {
|
|
189
|
-
definitionId = "io.supernova.block.token-list";
|
|
195
|
+
return [];
|
|
190
196
|
}
|
|
191
197
|
|
|
192
198
|
const definition = definitionsMap.get(definitionId);
|
|
@@ -195,36 +201,42 @@ function internalProsemirrorNodeToBlock(
|
|
|
195
201
|
`Block definitionId "${definitionId}" (prosemirror node ${prosemirrorNode.type}) is not among available definitions`
|
|
196
202
|
);
|
|
197
203
|
console.warn(prosemirrorNode);
|
|
198
|
-
return
|
|
204
|
+
return [];
|
|
199
205
|
}
|
|
200
206
|
|
|
201
|
-
return
|
|
207
|
+
return prosemirrorNodeAndDefinitionToBlock(prosemirrorNode, definition, definitionsMap, depth);
|
|
202
208
|
}
|
|
203
209
|
|
|
204
|
-
|
|
210
|
+
function prosemirrorNodeAndDefinitionToBlock(
|
|
205
211
|
prosemirrorNode: ProsemirrorNode,
|
|
206
|
-
definition: PageBlockDefinition
|
|
207
|
-
|
|
212
|
+
definition: PageBlockDefinition,
|
|
213
|
+
definitionsMap: Map<string, PageBlockDefinition>,
|
|
214
|
+
depth: number
|
|
215
|
+
): PageBlockEditorModel[] {
|
|
208
216
|
const richTextProperty = BlockDefinitionUtils.firstRichTextProperty(definition);
|
|
209
217
|
if (richTextProperty) {
|
|
210
|
-
|
|
218
|
+
const block = parseAsRichText(prosemirrorNode, definition, richTextProperty);
|
|
219
|
+
return block ? [block] : [];
|
|
211
220
|
}
|
|
212
221
|
|
|
213
222
|
const multiRichTextProperty = BlockDefinitionUtils.firstMultiRichTextProperty(definition);
|
|
214
223
|
if (multiRichTextProperty) {
|
|
215
|
-
return parseAsMultiRichText(prosemirrorNode, definition, multiRichTextProperty);
|
|
224
|
+
return parseAsMultiRichText(prosemirrorNode, definition, multiRichTextProperty, definitionsMap, depth);
|
|
216
225
|
}
|
|
217
226
|
|
|
218
227
|
const tableProperty = BlockDefinitionUtils.firstTableProperty(definition);
|
|
219
228
|
if (tableProperty) {
|
|
220
|
-
|
|
229
|
+
const block = parseAsTable(prosemirrorNode, definition, tableProperty);
|
|
230
|
+
return block ? [block] : [];
|
|
221
231
|
}
|
|
222
232
|
|
|
223
233
|
if (definition.id === "io.supernova.block.divider") {
|
|
224
|
-
|
|
234
|
+
const block = parseAsDivider(prosemirrorNode, definition);
|
|
235
|
+
return block ? [block] : [];
|
|
225
236
|
}
|
|
226
237
|
|
|
227
|
-
|
|
238
|
+
const block = parseAsCustomBlock(prosemirrorNode, definition);
|
|
239
|
+
return block ? [block] : [];
|
|
228
240
|
}
|
|
229
241
|
|
|
230
242
|
//
|
|
@@ -294,46 +306,75 @@ function parseCalloutType(prosemirrorCalloutType: unknown): PageBlockCalloutType
|
|
|
294
306
|
function parseAsMultiRichText(
|
|
295
307
|
prosemirrorNode: ProsemirrorNode,
|
|
296
308
|
definition: PageBlockDefinition,
|
|
297
|
-
property: PageBlockDefinitionProperty
|
|
298
|
-
|
|
309
|
+
property: PageBlockDefinitionProperty,
|
|
310
|
+
definitionsMap: Map<string, PageBlockDefinition>,
|
|
311
|
+
depth: number
|
|
312
|
+
): PageBlockEditorModel[] {
|
|
299
313
|
const id = getProsemirrorBlockId(prosemirrorNode);
|
|
300
|
-
if (!id) return
|
|
314
|
+
if (!id) return [];
|
|
301
315
|
|
|
302
316
|
const variantId = getProsemirrorBlockVariantId(prosemirrorNode);
|
|
317
|
+
const result: PageBlockEditorModel[] = [];
|
|
303
318
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
packageId: definition.id,
|
|
310
|
-
indentLevel: 0,
|
|
311
|
-
|
|
312
|
-
...(variantId && { variantId: variantId }),
|
|
319
|
+
// Flatten items
|
|
320
|
+
const listItems: ProsemirrorNode[] = [];
|
|
321
|
+
prosemirrorNode.content?.forEach(c => {
|
|
322
|
+
// Illegal child of a list
|
|
323
|
+
if (c.type !== "listItem") return;
|
|
313
324
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
[property.id]: {
|
|
319
|
-
// Required
|
|
320
|
-
value: (prosemirrorNode.content ?? [])
|
|
321
|
-
.map(listItem => {
|
|
322
|
-
if (listItem.type !== "listItem") return null;
|
|
323
|
-
if (!listItem.content?.length) return parseRichText([]);
|
|
324
|
-
|
|
325
|
-
const paragraph = listItem.content[0];
|
|
326
|
-
if (paragraph.type !== "paragraph") return parseRichText([]);
|
|
325
|
+
c.content?.forEach(cc => {
|
|
326
|
+
listItems.push(cc);
|
|
327
|
+
});
|
|
328
|
+
});
|
|
327
329
|
|
|
330
|
+
// Text list items buffering
|
|
331
|
+
let bufferedTextItems: ProsemirrorNode[] = [];
|
|
332
|
+
function flushBufferedTextItems() {
|
|
333
|
+
if (!bufferedTextItems.length) return;
|
|
334
|
+
|
|
335
|
+
const idSuffix = result.length ? `-${result.length}` : "";
|
|
336
|
+
|
|
337
|
+
result.push({
|
|
338
|
+
id: id + idSuffix,
|
|
339
|
+
type: "Block",
|
|
340
|
+
data: {
|
|
341
|
+
packageId: definition.id,
|
|
342
|
+
indentLevel: depth,
|
|
343
|
+
...(variantId && { variantId: variantId }),
|
|
344
|
+
items: [
|
|
345
|
+
{
|
|
346
|
+
id: id + idSuffix,
|
|
347
|
+
props: {
|
|
348
|
+
[property.id]: {
|
|
349
|
+
value: bufferedTextItems.map(paragraph => {
|
|
328
350
|
return parseRichText(paragraph.content ?? []);
|
|
329
|
-
})
|
|
330
|
-
|
|
331
|
-
}
|
|
351
|
+
}),
|
|
352
|
+
} satisfies PageBlockItemMultiRichTextValue,
|
|
353
|
+
},
|
|
332
354
|
},
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}
|
|
336
|
-
|
|
355
|
+
],
|
|
356
|
+
},
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
bufferedTextItems = [];
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
listItems.forEach(item => {
|
|
363
|
+
if (item.type === "paragraph") {
|
|
364
|
+
bufferedTextItems.push(item);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// This is not a paragraph, flush text items first
|
|
369
|
+
flushBufferedTextItems();
|
|
370
|
+
|
|
371
|
+
result.push(...internalProsemirrorNodeToBlock(item, definitionsMap, depth + 1));
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
// Flush text items at the end
|
|
375
|
+
flushBufferedTextItems();
|
|
376
|
+
|
|
377
|
+
return result;
|
|
337
378
|
}
|
|
338
379
|
|
|
339
380
|
//
|