@@ -24,6 +24,8 @@ import {
2424} from '@/application/types' ;
2525import { Log } from '@/utils/log' ;
2626
27+ const RUST_NANOID_SAFE_ALPHABET = '_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ;
28+ const DEFAULT_ID_LEN = 10 ;
2729// UUID namespace OID (same as Rust's Uuid::NAMESPACE_OID)
2830// Note: 6ba7b812 (not 6ba7b810 which is NAMESPACE_DNS)
2931const UUID_NAMESPACE_OID = '6ba7b812-9dad-11d1-80b4-00c04fd430c8' ;
@@ -60,6 +62,25 @@ export function pageIdFromDocumentId(documentId: string): string {
6062 return pageId ;
6163}
6264
65+ function idFromDocumentId ( documentId : string , role : string ) : string {
66+ const docUuid = uuidValidate ( documentId ) ? documentId : uuidv5 ( documentId , UUID_NAMESPACE_OID ) ;
67+
68+ return uuidv5 ( role , docUuid ) ;
69+ }
70+
71+ function nanoidFromDocumentId ( documentId : string , role : string ) : string {
72+ const uuid = idFromDocumentId ( documentId , role ) . replace ( / - / g, '' ) ;
73+ let id = '' ;
74+
75+ for ( let i = 0 ; i < DEFAULT_ID_LEN ; i += 1 ) {
76+ const byte = parseInt ( uuid . slice ( i * 2 , i * 2 + 2 ) , 16 ) ;
77+
78+ id += RUST_NANOID_SAFE_ALPHABET [ byte & 0x3f ] ;
79+ }
80+
81+ return id ;
82+ }
83+
6384export function getTextMap ( sharedRoot : YSharedRoot ) {
6485 const document = sharedRoot . get ( YjsEditorKey . document ) ;
6586 const meta = document . get ( YjsEditorKey . meta ) as YMeta ;
@@ -355,21 +376,23 @@ export function initializeDocumentStructure(doc: YDoc, includeInitialParagraph =
355376 if ( includeInitialParagraph ) {
356377 // Create an empty paragraph block as child of page
357378 // The Slate editor requires at least one text block to render properly
358- const paragraphId = nanoid ( 8 ) ;
379+ const paragraphId = documentId ? nanoidFromDocumentId ( documentId , 'block' ) : nanoid ( 8 ) ;
380+ const paragraphChildrenId = documentId ? nanoidFromDocumentId ( documentId , 'children' ) : paragraphId ;
381+ const paragraphTextId = documentId ? nanoidFromDocumentId ( documentId , 'text' ) : paragraphId ;
359382 const paragraphBlock = new Y . Map ( ) ;
360383
361384 paragraphBlock . set ( YjsEditorKey . block_id , paragraphId ) ;
362385 paragraphBlock . set ( YjsEditorKey . block_type , BlockType . Paragraph ) ;
363- paragraphBlock . set ( YjsEditorKey . block_children , paragraphId ) ;
364- paragraphBlock . set ( YjsEditorKey . block_external_id , paragraphId ) ;
386+ paragraphBlock . set ( YjsEditorKey . block_children , paragraphChildrenId ) ;
387+ paragraphBlock . set ( YjsEditorKey . block_external_id , paragraphTextId ) ;
365388 paragraphBlock . set ( YjsEditorKey . block_external_type , YjsEditorKey . text ) ;
366389 paragraphBlock . set ( YjsEditorKey . block_data , '{}' ) ;
367390 paragraphBlock . set ( YjsEditorKey . block_parent , pageId ) ;
368391 blocks . set ( paragraphId , paragraphBlock ) ;
369392
370393 pageChildren . push ( [ paragraphId ] ) ;
371- childrenMap . set ( paragraphId , new Y . Array ( ) ) ;
372- textMap . set ( paragraphId , new Y . Text ( ) ) ;
394+ childrenMap . set ( paragraphChildrenId , new Y . Array ( ) ) ;
395+ textMap . set ( paragraphTextId , new Y . Text ( ) ) ;
373396 }
374397
375398 childrenMap . set ( pageId , pageChildren ) ;
@@ -448,6 +471,8 @@ export function deleteBlock(sharedRoot: YSharedRoot, blockId: string) {
448471 const meta = document . get ( YjsEditorKey . meta ) as YMeta ;
449472 const childrenMap = meta . get ( YjsEditorKey . children_map ) as YChildrenMap ;
450473 const textMap = meta . get ( YjsEditorKey . text_map ) as YTextMap ;
474+ const blockChildrenId = block . get ( YjsEditorKey . block_children ) ;
475+ const blockExternalId = block . get ( YjsEditorKey . block_external_id ) ;
451476
452477 const parent = getBlock ( parentId , sharedRoot ) ;
453478
@@ -465,8 +490,8 @@ export function deleteBlock(sharedRoot: YSharedRoot, blockId: string) {
465490 }
466491
467492 blocks . delete ( blockId ) ;
468- childrenMap . delete ( blockId ) ;
469- textMap . delete ( blockId ) ;
493+ childrenMap . delete ( blockChildrenId ) ;
494+ textMap . delete ( blockExternalId ) ;
470495
471496 // delete parent if it's empty column block
472497 if ( parentType === BlockType . ColumnBlock && afterDeletedLength === 0 ) {
0 commit comments