{
  "version": 3,
  "sources": ["../../src/utils/crdt-blocks.ts"],
  "sourcesContent": ["/**\n * External dependencies\n */\nimport { v4 as uuidv4 } from 'uuid';\nimport fastDeepEqual from 'fast-deep-equal/es6/index.js';\n\n/**\n * WordPress dependencies\n */\nimport { getBlockTypes } from '@wordpress/blocks';\nimport { RichTextData } from '@wordpress/rich-text';\nimport { Y } from '@wordpress/sync';\n\n/**\n * Internal dependencies\n */\nimport { createYMap, type YMapRecord, type YMapWrap } from './crdt-utils';\nimport { getCachedRichTextData } from './crdt-text';\nimport { Delta } from '../sync';\n\ninterface BlockAttributes {\n\t[ key: string ]: unknown;\n}\n\ninterface BlockAttributeSchema {\n\trole?: string;\n\ttype?: string;\n\tquery?: Record< string, BlockAttributeSchema >;\n}\n\ninterface BlockType {\n\tattributes?: Record< string, BlockAttributeSchema >;\n\tname: string;\n}\n\n// A block as represented in Gutenberg's data store.\nexport interface Block {\n\tattributes: BlockAttributes;\n\tclientId?: string;\n\tinnerBlocks: Block[];\n\tisValid?: boolean;\n\tname: string;\n\toriginalContent?: string;\n\tvalidationIssues?: string[]; // unserializable\n}\n\n// A block as represented in the CRDT document (Y.Map).\nexport interface YBlockRecord extends YMapRecord {\n\tattributes: YBlockAttributes;\n\tclientId: string;\n\tinnerBlocks: YBlocks;\n\tisValid?: boolean;\n\toriginalContent?: string;\n\tname: string;\n}\n\nexport type YBlock = YMapWrap< YBlockRecord >;\nexport type YBlocks = Y.Array< YBlock >;\n\n// Block attribute schema cannot be known at compile time, so we use Y.Map.\n// Attribute values will be typed as the union of `Y.Text` and `unknown`.\nexport type YBlockAttributes = Y.Map< Y.Text | unknown >;\n\nconst serializableBlocksCache = new WeakMap< WeakKey, Block[] >();\n\n/**\n * Recursively walk an attribute value and convert any RichTextData instances\n * to their string (HTML) representation. This is necessary for array-type and\n * object-type attributes, which can contain nested RichTextData.\n *\n * @param value The attribute value to serialize.\n * @return The value with all RichTextData instances replaced by strings.\n */\nfunction serializeAttributeValue( value: unknown ): unknown {\n\tif ( value instanceof RichTextData ) {\n\t\treturn value.valueOf();\n\t}\n\n\t// e.g. core/table `body`: [ { cells: [ { content: RichTextData } ] } ]\n\tif ( Array.isArray( value ) ) {\n\t\treturn value.map( serializeAttributeValue );\n\t}\n\n\t// e.g. a single row inside core/table `body`: { cells: [ ... ] }\n\tif ( value && typeof value === 'object' ) {\n\t\tconst result: Record< string, unknown > = {};\n\n\t\tfor ( const [ k, v ] of Object.entries( value ) ) {\n\t\t\tresult[ k ] = serializeAttributeValue( v );\n\t\t}\n\t\treturn result;\n\t}\n\n\treturn value;\n}\n\nfunction makeBlockAttributesSerializable(\n\tblockName: string,\n\tattributes: BlockAttributes\n): BlockAttributes {\n\tconst newAttributes = { ...attributes };\n\tfor ( const [ key, value ] of Object.entries( attributes ) ) {\n\t\tif ( isLocalAttribute( blockName, key ) ) {\n\t\t\tdelete newAttributes[ key ];\n\t\t\tcontinue;\n\t\t}\n\n\t\tnewAttributes[ key ] = serializeAttributeValue( value );\n\t}\n\treturn newAttributes;\n}\n\nfunction makeBlocksSerializable( blocks: Block[] ): Block[] {\n\treturn blocks.map( ( block: Block ) => {\n\t\tconst { name, innerBlocks, attributes, ...rest } = block;\n\t\tdelete rest.validationIssues;\n\t\treturn {\n\t\t\t...rest,\n\t\t\tname,\n\t\t\tattributes: makeBlockAttributesSerializable( name, attributes ),\n\t\t\tinnerBlocks: makeBlocksSerializable( innerBlocks ),\n\t\t};\n\t} );\n}\n\n/**\n * Recursively walk an attribute value and convert any strings that correspond\n * to rich-text schema nodes into RichTextData instances. This is the inverse\n * of serializeAttributeValue and handles nested structures like table cells.\n *\n * @param schema The attribute type definition for this value.\n * @param value  The attribute value from CRDT (toJSON).\n * @return The value with rich-text strings replaced by RichTextData.\n */\nfunction deserializeAttributeValue(\n\tschema: BlockAttributeSchema | undefined,\n\tvalue: unknown\n): unknown {\n\tif ( schema?.type === 'rich-text' && typeof value === 'string' ) {\n\t\treturn getCachedRichTextData( value );\n\t}\n\n\t// e.g. core/table `body`: [ { cells: [ { content: RichTextData } ] } ]\n\tif ( Array.isArray( value ) ) {\n\t\treturn value.map( ( item ) =>\n\t\t\tdeserializeAttributeValue( schema, item )\n\t\t);\n\t}\n\n\t// e.g. a single row inside core/table `body`: { cells: [ ... ] }\n\tif ( value && typeof value === 'object' ) {\n\t\tconst result: Record< string, unknown > = {};\n\n\t\tfor ( const [ key, innerValue ] of Object.entries(\n\t\t\tvalue as Record< string, unknown >\n\t\t) ) {\n\t\t\tresult[ key ] = deserializeAttributeValue(\n\t\t\t\tschema?.query?.[ key ],\n\t\t\t\tinnerValue\n\t\t\t);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\treturn value;\n}\n\n/**\n * Convert blocks from their CRDT-serialized form back to the runtime form\n * expected by the block editor. Rich-text attributes are stored as Y.Text in\n * the CRDT document, which serializes to plain strings via toJSON(). This\n * function restores them to RichTextData instances so that block edit\n * components that rely on RichTextData methods (e.g. `.text`) work correctly.\n *\n * @param blocks Blocks as extracted from the CRDT document via toJSON().\n * @return Blocks with rich-text attributes restored to RichTextData.\n */\nexport function deserializeBlockAttributes( blocks: Block[] ): Block[] {\n\treturn blocks.map( ( block: Block ) => {\n\t\tconst { name, innerBlocks, attributes, ...rest } = block;\n\n\t\tconst newAttributes = { ...attributes };\n\n\t\tfor ( const [ key, value ] of Object.entries( attributes ) ) {\n\t\t\tconst schema = getBlockAttributeSchema( name, key );\n\n\t\t\tif ( schema ) {\n\t\t\t\tnewAttributes[ key ] = deserializeAttributeValue(\n\t\t\t\t\tschema,\n\t\t\t\t\tvalue\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\t...rest,\n\t\t\tname,\n\t\t\tattributes: newAttributes,\n\t\t\tinnerBlocks: deserializeBlockAttributes( innerBlocks ?? [] ),\n\t\t};\n\t} );\n}\n\n/**\n * @param {any}   gblock\n * @param {Y.Map} yblock\n */\nfunction areBlocksEqual( gblock: Block, yblock: YBlock ): boolean {\n\tconst yblockAsJson = yblock.toJSON();\n\n\t// we must not sync clientId, as this can't be generated consistently and\n\t// hence will lead to merge conflicts.\n\tconst overwrites = {\n\t\tinnerBlocks: null,\n\t\tclientId: null,\n\t};\n\tconst res = fastDeepEqual(\n\t\tObject.assign( {}, gblock, overwrites ),\n\t\tObject.assign( {}, yblockAsJson, overwrites )\n\t);\n\tconst inners = gblock.innerBlocks || [];\n\tconst yinners = yblock.get( 'innerBlocks' );\n\treturn (\n\t\tres &&\n\t\tinners.length === yinners?.length &&\n\t\tinners.every( ( block: Block, i: number ) =>\n\t\t\tareBlocksEqual( block, yinners.get( i ) )\n\t\t)\n\t);\n}\n\nfunction createNewYAttributeMap(\n\tblockName: string,\n\tattributes: BlockAttributes\n): YBlockAttributes {\n\treturn new Y.Map(\n\t\tObject.entries( attributes ).map(\n\t\t\t( [ attributeName, attributeValue ] ) => {\n\t\t\t\treturn [\n\t\t\t\t\tattributeName,\n\t\t\t\t\tcreateNewYAttributeValue(\n\t\t\t\t\t\tblockName,\n\t\t\t\t\t\tattributeName,\n\t\t\t\t\t\tattributeValue\n\t\t\t\t\t),\n\t\t\t\t];\n\t\t\t}\n\t\t)\n\t);\n}\n\nfunction createNewYAttributeValue(\n\tblockName: string,\n\tattributeName: string,\n\tattributeValue: unknown\n): Y.Text | Y.Array< unknown > | Y.Map< unknown > | unknown {\n\tconst schema = getBlockAttributeSchema( blockName, attributeName );\n\treturn createYValueFromSchema( schema, attributeValue );\n}\n\n/**\n * Recursively create the appropriate Y.js type for a value based on its\n * block-attribute schema.\n *\n * - `rich-text`          -> Y.Text\n * - `array`  with query  -> Y.Array of Y.Maps\n * - `object` with query  -> Y.Map\n * - anything else        -> plain value (unchanged)\n *\n * @param schema The attribute type definition.\n * @param value  The plain JS value to convert.\n * @return A Y.js type or the original value.\n */\nfunction createYValueFromSchema(\n\tschema: BlockAttributeSchema | undefined,\n\tvalue: unknown\n): Y.Text | Y.Array< unknown > | Y.Map< unknown > | unknown {\n\tif ( ! schema ) {\n\t\treturn value;\n\t}\n\n\tif ( schema.type === 'rich-text' ) {\n\t\treturn new Y.Text( value?.toString() ?? '' );\n\t}\n\n\tif ( schema.type === 'array' && schema.query && Array.isArray( value ) ) {\n\t\tconst query = schema.query;\n\t\tconst yArray = new Y.Array< Y.Map< unknown > >();\n\n\t\tyArray.insert(\n\t\t\t0,\n\t\t\tvalue.map( ( item ) => createYMapFromQuery( query, item ) )\n\t\t);\n\n\t\treturn yArray;\n\t}\n\n\tif ( schema.type === 'object' && schema.query && isRecord( value ) ) {\n\t\treturn createYMapFromQuery( schema.query, value );\n\t}\n\n\treturn value;\n}\n\n/**\n * Type guard that narrows `unknown` to `Record< string, unknown >`.\n *\n * @param value Value to check.\n * @return True if `value` is a non-null, non-array object.\n */\nfunction isRecord( value: unknown ): value is Record< string, unknown > {\n\treturn !! value && typeof value === 'object' && ! Array.isArray( value );\n}\n\n/**\n * Create a Y.Map from a plain object, using a query schema to decide which\n * properties should become nested Y.js types (Y.Text, Y.Array, Y.Map).\n *\n * @param query The query schema defining the properties.\n * @param obj   The plain object to convert.\n * @return A Y.Map with typed values.\n */\nfunction createYMapFromQuery(\n\tquery: Record< string, BlockAttributeSchema >,\n\tobj: unknown\n): Y.Map< unknown > {\n\tif ( ! isRecord( obj ) ) {\n\t\treturn new Y.Map();\n\t}\n\n\tconst entries: [ string, unknown ][] = Object.entries( obj ).map(\n\t\t( [ key, val ] ): [ string, unknown ] => {\n\t\t\tconst subSchema = query[ key ];\n\t\t\treturn [ key, createYValueFromSchema( subSchema, val ) ];\n\t\t}\n\t);\n\n\treturn new Y.Map( entries );\n}\n\nfunction createNewYBlock( block: Block ): YBlock {\n\treturn createYMap< YBlockRecord >(\n\t\tObject.fromEntries(\n\t\t\tObject.entries( block ).map( ( [ key, value ] ) => {\n\t\t\t\tswitch ( key ) {\n\t\t\t\t\tcase 'attributes': {\n\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\tcreateNewYAttributeMap( block.name, value ),\n\t\t\t\t\t\t];\n\t\t\t\t\t}\n\n\t\t\t\t\tcase 'innerBlocks': {\n\t\t\t\t\t\tconst innerBlocks = new Y.Array();\n\n\t\t\t\t\t\t// If not an array, set to empty Y.Array.\n\t\t\t\t\t\tif ( ! Array.isArray( value ) ) {\n\t\t\t\t\t\t\treturn [ key, innerBlocks ];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tinnerBlocks.insert(\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\tvalue.map( ( innerBlock: Block ) =>\n\t\t\t\t\t\t\t\tcreateNewYBlock( innerBlock )\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\treturn [ key, innerBlocks ];\n\t\t\t\t\t}\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn [ key, value ];\n\t\t\t\t}\n\t\t\t} )\n\t\t)\n\t);\n}\n\n/**\n * Merge incoming block data into the local Y.Doc.\n * This function is called to sync local block changes to a shared Y.Doc.\n *\n * @param yblocks        The blocks in the local Y.Doc.\n * @param incomingBlocks Gutenberg blocks being synced.\n * @param cursorPosition The position of the cursor after the change occurs.\n */\nexport function mergeCrdtBlocks(\n\tyblocks: YBlocks,\n\tincomingBlocks: Block[],\n\tcursorPosition: number | null\n): void {\n\t// Ensure we are working with serializable block data.\n\tif ( ! serializableBlocksCache.has( incomingBlocks ) ) {\n\t\tserializableBlocksCache.set(\n\t\t\tincomingBlocks,\n\t\t\tmakeBlocksSerializable( incomingBlocks )\n\t\t);\n\t}\n\tconst blocksToSync = serializableBlocksCache.get( incomingBlocks ) ?? [];\n\n\t// This is a rudimentary diff implementation similar to the y-prosemirror diffing\n\t// approach.\n\t// A better implementation would also diff the textual content and represent it\n\t// using a Y.Text type.\n\t// However, at this time it makes more sense to keep this algorithm generic to\n\t// support all kinds of block types.\n\t// Ideally, we ensure that block data structure have a consistent data format.\n\t// E.g.:\n\t//   - textual content (using rich-text formatting?) may always be stored under `block.text`\n\t//   - local information that shouldn't be shared (e.g. clientId or isDragging) is stored under `block.private`\n\t//\n\t// @credit Kevin Jahns (dmonad)\n\t// @link https://github.com/WordPress/gutenberg/pull/68483\n\tconst numOfCommonEntries = Math.min(\n\t\tblocksToSync.length ?? 0,\n\t\tyblocks.length\n\t);\n\n\tlet left = 0;\n\tlet right = 0;\n\n\t// skip equal blocks from left\n\tfor (\n\t\t;\n\t\tleft < numOfCommonEntries &&\n\t\tareBlocksEqual( blocksToSync[ left ], yblocks.get( left ) );\n\t\tleft++\n\t) {\n\t\t/* nop */\n\t}\n\n\t// skip equal blocks from right\n\tfor (\n\t\t;\n\t\tright < numOfCommonEntries - left &&\n\t\tareBlocksEqual(\n\t\t\tblocksToSync[ blocksToSync.length - right - 1 ],\n\t\t\tyblocks.get( yblocks.length - right - 1 )\n\t\t);\n\t\tright++\n\t) {\n\t\t/* nop */\n\t}\n\n\tconst numOfUpdatesNeeded = numOfCommonEntries - left - right;\n\tconst numOfInsertionsNeeded = Math.max(\n\t\t0,\n\t\tblocksToSync.length - yblocks.length\n\t);\n\tconst numOfDeletionsNeeded = Math.max(\n\t\t0,\n\t\tyblocks.length - blocksToSync.length\n\t);\n\n\t// updates\n\tfor ( let i = 0; i < numOfUpdatesNeeded; i++, left++ ) {\n\t\tconst block = blocksToSync[ left ];\n\t\tconst yblock = yblocks.get( left );\n\n\t\tObject.entries( block ).forEach( ( [ key, value ] ) => {\n\t\t\tswitch ( key ) {\n\t\t\t\tcase 'attributes': {\n\t\t\t\t\tconst currentAttributes = yblock.get( key );\n\n\t\t\t\t\t// If attributes are not set on the yblock, use the new values.\n\t\t\t\t\tif ( ! currentAttributes ) {\n\t\t\t\t\t\tyblock.set(\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\tcreateNewYAttributeMap( block.name, value )\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tObject.entries( value ).forEach(\n\t\t\t\t\t\t( [ attributeName, attributeValue ] ) => {\n\t\t\t\t\t\t\tconst currentAttribute =\n\t\t\t\t\t\t\t\tcurrentAttributes?.get( attributeName );\n\n\t\t\t\t\t\t\tconst isExpectedType = isExpectedAttributeType(\n\t\t\t\t\t\t\t\tblock.name,\n\t\t\t\t\t\t\t\tattributeName,\n\t\t\t\t\t\t\t\tcurrentAttribute\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t// Y types (Y.Text, Y.Array, Y.Map) cannot be\n\t\t\t\t\t\t\t// compared with fastDeepEqual against plain values.\n\t\t\t\t\t\t\t// Delegate to mergeYValue which handles no-op\n\t\t\t\t\t\t\t// detection at the edges.\n\t\t\t\t\t\t\tconst isYType =\n\t\t\t\t\t\t\t\tcurrentAttribute instanceof Y.AbstractType;\n\n\t\t\t\t\t\t\tconst isAttributeChanged =\n\t\t\t\t\t\t\t\t! isExpectedType ||\n\t\t\t\t\t\t\t\tisYType ||\n\t\t\t\t\t\t\t\t! fastDeepEqual(\n\t\t\t\t\t\t\t\t\tcurrentAttribute,\n\t\t\t\t\t\t\t\t\tattributeValue\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif ( isAttributeChanged ) {\n\t\t\t\t\t\t\t\tupdateYBlockAttribute(\n\t\t\t\t\t\t\t\t\tblock.name,\n\t\t\t\t\t\t\t\t\tattributeName,\n\t\t\t\t\t\t\t\t\tattributeValue,\n\t\t\t\t\t\t\t\t\tcurrentAttributes,\n\t\t\t\t\t\t\t\t\tcursorPosition\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\n\t\t\t\t\t// Delete any attributes that are no longer present.\n\t\t\t\t\tcurrentAttributes.forEach(\n\t\t\t\t\t\t( _attrValue: unknown, attrName: string ) => {\n\t\t\t\t\t\t\tif ( ! value.hasOwnProperty( attrName ) ) {\n\t\t\t\t\t\t\t\tcurrentAttributes.delete( attrName );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase 'innerBlocks': {\n\t\t\t\t\t// Recursively merge innerBlocks\n\t\t\t\t\tlet yInnerBlocks = yblock.get( key );\n\n\t\t\t\t\tif ( ! ( yInnerBlocks instanceof Y.Array ) ) {\n\t\t\t\t\t\tyInnerBlocks = new Y.Array< YBlock >();\n\t\t\t\t\t\tyblock.set( key, yInnerBlocks );\n\t\t\t\t\t}\n\n\t\t\t\t\tmergeCrdtBlocks(\n\t\t\t\t\t\tyInnerBlocks,\n\t\t\t\t\t\tvalue ?? [],\n\t\t\t\t\t\tcursorPosition\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault:\n\t\t\t\t\tif ( ! fastDeepEqual( block[ key ], yblock.get( key ) ) ) {\n\t\t\t\t\t\tyblock.set( key, value );\n\t\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t\tyblock.forEach( ( _v, k ) => {\n\t\t\tif ( ! block.hasOwnProperty( k ) ) {\n\t\t\t\tyblock.delete( k );\n\t\t\t}\n\t\t} );\n\t}\n\n\t// deletes\n\tyblocks.delete( left, numOfDeletionsNeeded );\n\n\t// inserts\n\tfor ( let i = 0; i < numOfInsertionsNeeded; i++, left++ ) {\n\t\tconst newBlock = [ createNewYBlock( blocksToSync[ left ] ) ];\n\n\t\tyblocks.insert( left, newBlock );\n\t}\n\n\t// remove duplicate clientids\n\tconst knownClientIds = new Set< string >();\n\tfor ( let j = 0; j < yblocks.length; j++ ) {\n\t\tconst yblock: YBlock = yblocks.get( j );\n\n\t\tlet clientId = yblock.get( 'clientId' );\n\n\t\tif ( ! clientId ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ( knownClientIds.has( clientId ) ) {\n\t\t\tclientId = uuidv4();\n\t\t\tyblock.set( 'clientId', clientId );\n\t\t}\n\t\tknownClientIds.add( clientId );\n\t}\n}\n\n/**\n * Compare a plain array element against a Y.Map element for equality.\n * Used by the left-right sweep diff in mergeYArray.\n *\n * @param newElement The plain object from the incoming array.\n * @param yElement   The Y.Map element from the existing Y.Array.\n * @return True if the elements are deeply equal.\n */\nfunction areArrayElementsEqual(\n\tnewElement: unknown,\n\tyElement: unknown\n): boolean {\n\tif ( yElement instanceof Y.Map && isRecord( newElement ) ) {\n\t\treturn fastDeepEqual( newElement, yElement.toJSON() );\n\t}\n\n\treturn fastDeepEqual( newElement, yElement );\n}\n\n/**\n * Merge an incoming plain array into an existing Y.Array in-place.\n *\n * Uses the same left-right sweep diff approach as mergeCrdtBlocks:\n * equal elements are skipped from both ends, then the middle section\n * is updated, deleted, or inserted as needed. This preserves existing\n * Y.Map/Y.Text objects for unchanged elements, so concurrent edits\n * to those elements are not lost.\n *\n * @param yArray         The existing Y.Array to update.\n * @param newValue       The new plain array to merge into the Y.Array.\n * @param schema         The attribute schema (must have `query`).\n * @param cursorPosition The local cursor position for rich-text delta merges.\n */\nfunction mergeYArray(\n\tyArray: Y.Array< unknown >,\n\tnewValue: unknown[],\n\tschema: BlockAttributeSchema,\n\tcursorPosition: number | null\n): void {\n\tif ( ! schema.query ) {\n\t\treturn;\n\t}\n\n\tconst query = schema.query;\n\tconst numOfCommonEntries = Math.min( newValue.length, yArray.length );\n\n\tlet left = 0;\n\tlet right = 0;\n\n\t// Skip equal elements from left.\n\tfor (\n\t\t;\n\t\tleft < numOfCommonEntries &&\n\t\tareArrayElementsEqual( newValue[ left ], yArray.get( left ) );\n\t\tleft++\n\t) {\n\t\t/* nop */\n\t}\n\n\t// Skip equal elements from right.\n\tfor (\n\t\t;\n\t\tright < numOfCommonEntries - left &&\n\t\tareArrayElementsEqual(\n\t\t\tnewValue[ newValue.length - right - 1 ],\n\t\t\tyArray.get( yArray.length - right - 1 )\n\t\t);\n\t\tright++\n\t) {\n\t\t/* nop */\n\t}\n\n\t// Updates: merge changed elements in-place.\n\tconst numOfUpdatesNeeded = numOfCommonEntries - left - right;\n\n\tfor ( let i = 0; i < numOfUpdatesNeeded; i++ ) {\n\t\tconst currentElement = yArray.get( left + i );\n\t\tconst newElement = newValue[ left + i ];\n\n\t\tif ( currentElement instanceof Y.Map && isRecord( newElement ) ) {\n\t\t\tmergeYMapValues(\n\t\t\t\tcurrentElement,\n\t\t\t\tnewElement,\n\t\t\t\tquery,\n\t\t\t\tcursorPosition\n\t\t\t);\n\t\t} else {\n\t\t\t// Element is the wrong type (e.g. partial migration) or the\n\t\t\t// incoming value is not an object. Rebuild the entire array.\n\t\t\tyArray.delete( 0, yArray.length );\n\t\t\tyArray.insert(\n\t\t\t\t0,\n\t\t\t\tnewValue.map( ( item ) => createYMapFromQuery( query, item ) )\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Deletes.\n\tconst numOfDeletionsNeeded = Math.max( 0, yArray.length - newValue.length );\n\n\tif ( numOfDeletionsNeeded > 0 ) {\n\t\tyArray.delete( left + numOfUpdatesNeeded, numOfDeletionsNeeded );\n\t}\n\n\t// Inserts.\n\tconst numOfInsertionsNeeded = Math.max(\n\t\t0,\n\t\tnewValue.length - yArray.length\n\t);\n\n\tif ( numOfInsertionsNeeded > 0 ) {\n\t\tconst insertAt = left + numOfUpdatesNeeded;\n\t\tconst itemsToInsert: Y.Map< unknown >[] = new Array(\n\t\t\tnumOfInsertionsNeeded\n\t\t);\n\n\t\tfor ( let i = 0; i < numOfInsertionsNeeded; i++ ) {\n\t\t\titemsToInsert[ i ] = createYMapFromQuery(\n\t\t\t\tquery,\n\t\t\t\tnewValue[ insertAt + i ]\n\t\t\t);\n\t\t}\n\n\t\tyArray.insert( insertAt, itemsToInsert );\n\t}\n}\n\n/**\n * Merge a single value into a Y.Map entry, using the attribute schema to\n * decide how to merge.\n *\n * If the current value is already a matching Y.js type (Y.Text, Y.Array,\n * Y.Map), the update is merged in-place so concurrent edits are preserved.\n * Otherwise the value is replaced wholesale.\n *\n * @param schema         The attribute type definition for this value.\n * @param newVal         The new value to merge into the Y.Map entry.\n * @param yMap           The Y.Map that owns this entry.\n * @param key            The key of this entry in the Y.Map.\n * @param cursorPosition The local cursor position for rich-text delta merges.\n */\nfunction mergeYValue(\n\tschema: BlockAttributeSchema | undefined,\n\tnewVal: unknown,\n\tyMap: Y.Map< unknown >,\n\tkey: string,\n\tcursorPosition: number | null\n): void {\n\tconst currentVal = yMap.get( key );\n\tif (\n\t\tschema?.type === 'rich-text' &&\n\t\ttypeof newVal === 'string' &&\n\t\tcurrentVal instanceof Y.Text\n\t) {\n\t\tmergeRichTextUpdate( currentVal, newVal, cursorPosition );\n\t} else if (\n\t\tschema?.type === 'array' &&\n\t\tschema.query &&\n\t\tArray.isArray( newVal ) &&\n\t\tcurrentVal instanceof Y.Array\n\t) {\n\t\tmergeYArray( currentVal, newVal, schema, cursorPosition );\n\t} else if (\n\t\tschema?.type === 'object' &&\n\t\tschema.query &&\n\t\tisRecord( newVal ) &&\n\t\tcurrentVal instanceof Y.Map\n\t) {\n\t\tmergeYMapValues( currentVal, newVal, schema.query, cursorPosition );\n\t} else {\n\t\tconst newYValue = createYValueFromSchema( schema, newVal );\n\n\t\t// If createYValueFromSchema wrapped the value into a Y type, the\n\t\t// current value is the wrong type and needs upgrading. Otherwise,\n\t\t// only replace if the raw value actually changed.\n\t\tif ( newYValue !== newVal || ! fastDeepEqual( currentVal, newVal ) ) {\n\t\t\tyMap.set( key, newYValue );\n\t\t}\n\t}\n}\n\n/**\n * Merge an incoming plain object into an existing Y.Map in-place, using\n * the query schema to decide how each property should be merged.\n *\n * Properties present in the Y.Map but absent from `newObj` are deleted.\n *\n * @param yMap           The existing Y.Map to update.\n * @param newObj         The new plain object to merge into the Y.Map.\n * @param query          The query schema defining property types.\n * @param cursorPosition The local cursor position for rich-text delta merges.\n */\nfunction mergeYMapValues(\n\tyMap: Y.Map< unknown >,\n\tnewObj: Record< string, unknown >,\n\tquery: Record< string, BlockAttributeSchema >,\n\tcursorPosition: number | null\n): void {\n\tfor ( const [ key, newVal ] of Object.entries( newObj ) ) {\n\t\tmergeYValue( query[ key ], newVal, yMap, key, cursorPosition );\n\t}\n\n\t// Delete properties absent from the incoming object.\n\tfor ( const key of yMap.keys() ) {\n\t\tif ( ! Object.hasOwn( newObj, key ) ) {\n\t\t\tyMap.delete( key );\n\t\t}\n\t}\n}\n\n/**\n * Update a single attribute on a Yjs block attributes map (currentAttributes).\n *\n * @param blockName         The block type name, e.g. 'core/paragraph'.\n * @param attributeName     The name of the attribute to update, e.g. 'content'.\n * @param attributeValue    The new value for the attribute.\n * @param currentAttributes The Y.Map holding the block's current attributes.\n * @param cursorPosition    The local cursor position, used when merging rich-text deltas.\n */\nfunction updateYBlockAttribute(\n\tblockName: string,\n\tattributeName: string,\n\tattributeValue: unknown,\n\tcurrentAttributes: YBlockAttributes,\n\tcursorPosition: number | null\n): void {\n\tconst schema = getBlockAttributeSchema( blockName, attributeName );\n\n\tmergeYValue(\n\t\tschema,\n\t\tattributeValue,\n\t\tcurrentAttributes,\n\t\tattributeName,\n\t\tcursorPosition\n\t);\n}\n\n// Cached block attribute types, populated once from getBlockTypes().\nlet cachedBlockAttributeSchemas: Map<\n\tstring,\n\tMap< string, BlockAttributeSchema >\n>;\n\n/**\n * Get the attribute type definition for a block attribute.\n *\n * @param blockName     The name of the block, e.g. 'core/paragraph'.\n * @param attributeName The name of the attribute, e.g. 'content'.\n * @return The type definition of the attribute.\n */\nfunction getBlockAttributeSchema(\n\tblockName: string,\n\tattributeName: string\n): BlockAttributeSchema | undefined {\n\tif ( ! cachedBlockAttributeSchemas ) {\n\t\t// Parse the attributes for all blocks once.\n\t\tcachedBlockAttributeSchemas = new Map();\n\n\t\tfor ( const blockType of getBlockTypes() as BlockType[] ) {\n\t\t\tcachedBlockAttributeSchemas.set(\n\t\t\t\tblockType.name,\n\t\t\t\tnew Map< string, BlockAttributeSchema >(\n\t\t\t\t\tObject.entries( blockType.attributes ?? {} ).map(\n\t\t\t\t\t\t( [ name, definition ] ) => {\n\t\t\t\t\t\t\tconst { role, type, query } = definition;\n\t\t\t\t\t\t\treturn [ name, { role, type, query } ];\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\t}\n\n\treturn cachedBlockAttributeSchemas.get( blockName )?.get( attributeName );\n}\n\n/**\n * Check if an attribute value is the expected type.\n *\n * @param blockName      The name of the block, e.g. 'core/paragraph'.\n * @param attributeName  The name of the attribute, e.g. 'content'.\n * @param attributeValue The current attribute value.\n * @return True if the attribute type is expected, false otherwise.\n */\nfunction isExpectedAttributeType(\n\tblockName: string,\n\tattributeName: string,\n\tattributeValue: unknown\n): boolean {\n\tconst schema = getBlockAttributeSchema( blockName, attributeName );\n\n\tif ( schema?.type === 'rich-text' ) {\n\t\treturn attributeValue instanceof Y.Text;\n\t}\n\n\tif ( schema?.type === 'string' ) {\n\t\treturn typeof attributeValue === 'string';\n\t}\n\n\tif ( schema?.type === 'array' && schema.query ) {\n\t\treturn attributeValue instanceof Y.Array;\n\t}\n\n\tif ( schema?.type === 'object' && schema.query ) {\n\t\treturn attributeValue instanceof Y.Map;\n\t}\n\n\treturn true;\n}\n\n/**\n * Given a block name and attribute key, return true if the attribute is local\n * and should not be synced.\n *\n * @param blockName     The name of the block, e.g. 'core/image'.\n * @param attributeName The name of the attribute to check, e.g. 'blob'.\n * @return True if the attribute is local, false otherwise.\n */\nfunction isLocalAttribute( blockName: string, attributeName: string ): boolean {\n\treturn (\n\t\t'local' === getBlockAttributeSchema( blockName, attributeName )?.role\n\t);\n}\n\nlet localDoc: Y.Doc;\n\n/**\n * Given a Y.Text object and an updated string value, diff the new value and\n * apply the delta to the Y.Text.\n *\n * @param blockYText     The Y.Text to update.\n * @param updatedValue   The updated value.\n * @param cursorPosition The position of the cursor after the change occurs.\n */\nexport function mergeRichTextUpdate(\n\tblockYText: Y.Text,\n\tupdatedValue: string,\n\tcursorPosition: number | null = null\n): void {\n\t// Gutenberg does not use Yjs shared types natively, so we can only subscribe\n\t// to changes from store and apply them to Yjs types that we create and\n\t// manage. Crucially, for rich-text attributes, we do not receive granular\n\t// string updates; we get the new full string value on each change, even when\n\t// only a single character changed.\n\t//\n\t// The code below allows us to compute a delta between the current and new\n\t// value, then apply it to the Y.Text.\n\n\tif ( ! localDoc ) {\n\t\t// Y.Text must be attached to a Y.Doc to be able to do operations on it.\n\t\t// Create a temporary Y.Text attached to a local Y.Doc for delta computation.\n\t\tlocalDoc = new Y.Doc();\n\t}\n\n\tconst localYText = localDoc.getText( 'temporary-text' );\n\tlocalYText.delete( 0, localYText.length );\n\tlocalYText.insert( 0, updatedValue );\n\n\tconst currentValueAsDelta = new Delta( blockYText.toDelta() );\n\tconst updatedValueAsDelta = new Delta( localYText.toDelta() );\n\tconst deltaDiff = currentValueAsDelta.diffWithCursor(\n\t\tupdatedValueAsDelta,\n\t\tcursorPosition\n\t);\n\n\tblockYText.applyDelta( deltaDiff.ops );\n}\n"],
  "mappings": "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",
  "names": ["import_sync", "fastDeepEqual", "uuidv4"]
}
