{
  "version": 3,
  "sources": ["../src/index.ts"],
  "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { isShallowEqual } from '@wordpress/is-shallow-equal';\n\n/**\n * Internal dependencies\n */\nimport type {\n\tHistoryChange as _HistoryChange,\n\tHistoryChanges as _HistoryChanges,\n\tHistoryRecord as _HistoryRecord,\n\tUndoManager as _UndoManager,\n} from './types';\n\n/**\n * Represents a single change in history.\n */\nexport type HistoryChange< T = unknown > = _HistoryChange< T >;\n\n/**\n * Represents changes for a single item.\n */\nexport type HistoryChanges< T = unknown > = _HistoryChanges< T >;\n\n/**\n * Represents a record of history changes.\n */\nexport type HistoryRecord< T = unknown > = _HistoryRecord< T >;\n\n/**\n * The undo manager interface.\n */\nexport type UndoManager< T = unknown > = _UndoManager< T >;\n\n/**\n * Merge changes for a single item into a record of changes.\n *\n * @param changes1 Previous changes\n * @param changes2 Next changes\n *\n * @return Merged changes\n */\nfunction mergeHistoryChanges< T >(\n\tchanges1: Record< string, HistoryChange< T > >,\n\tchanges2: Record< string, HistoryChange< T > >\n): Record< string, HistoryChange< T > > {\n\tconst newChanges: Record< string, HistoryChange< T > > = { ...changes1 };\n\tObject.entries( changes2 ).forEach( ( [ key, value ] ) => {\n\t\tif ( newChanges[ key ] ) {\n\t\t\tnewChanges[ key ] = { ...newChanges[ key ], to: value.to };\n\t\t} else {\n\t\t\tnewChanges[ key ] = value;\n\t\t}\n\t} );\n\n\treturn newChanges;\n}\n\n/**\n * Adds history changes for a single item into a record of changes.\n *\n * @param record  The record to merge into.\n * @param changes The changes to merge.\n */\nconst addHistoryChangesIntoRecord = < T >(\n\trecord: HistoryRecord< T >,\n\tchanges: HistoryChanges< T >\n): HistoryRecord< T > => {\n\tconst existingChangesIndex = record?.findIndex(\n\t\t( { id: recordIdentifier } ) => {\n\t\t\treturn typeof recordIdentifier === 'string'\n\t\t\t\t? recordIdentifier === changes.id\n\t\t\t\t: isShallowEqual( recordIdentifier, changes.id );\n\t\t}\n\t);\n\tconst nextRecord = [ ...record ];\n\n\tif ( existingChangesIndex !== -1 ) {\n\t\t// If the edit is already in the stack leave the initial \"from\" value.\n\t\tnextRecord[ existingChangesIndex ] = {\n\t\t\tid: changes.id,\n\t\t\tchanges: mergeHistoryChanges(\n\t\t\t\tnextRecord[ existingChangesIndex ].changes,\n\t\t\t\tchanges.changes\n\t\t\t),\n\t\t};\n\t} else {\n\t\tnextRecord.push( changes );\n\t}\n\treturn nextRecord;\n};\n\n/**\n * Creates an undo manager.\n *\n * @return Undo manager.\n */\nexport function createUndoManager< T = unknown >(): UndoManager< T > {\n\tlet history: HistoryRecord< T >[] = [];\n\tlet stagedRecord: HistoryRecord< T > = [];\n\tlet offset = 0;\n\n\tconst dropPendingRedos = (): void => {\n\t\thistory = history.slice( 0, offset || undefined );\n\t\toffset = 0;\n\t};\n\n\tconst appendStagedRecordToLatestHistoryRecord = (): void => {\n\t\tconst index = history.length === 0 ? 0 : history.length - 1;\n\t\tlet latestRecord = history[ index ] ?? [];\n\t\tstagedRecord.forEach( ( changes ) => {\n\t\t\tlatestRecord = addHistoryChangesIntoRecord( latestRecord, changes );\n\t\t} );\n\t\tstagedRecord = [];\n\t\thistory[ index ] = latestRecord;\n\t};\n\n\t/**\n\t * Checks whether a record is empty.\n\t * A record is considered empty if it the changes keep the same values.\n\t * Also updates to function values are ignored.\n\t *\n\t * @param record The record to check.\n\t * @return Whether the record is empty.\n\t */\n\tconst isRecordEmpty = ( record: HistoryRecord< T > ): boolean => {\n\t\tconst filteredRecord = record.filter( ( { changes } ) => {\n\t\t\treturn Object.values( changes ).some(\n\t\t\t\t( { from, to } ) =>\n\t\t\t\t\ttypeof from !== 'function' &&\n\t\t\t\t\ttypeof to !== 'function' &&\n\t\t\t\t\t! isShallowEqual( from, to )\n\t\t\t);\n\t\t} );\n\t\treturn ! filteredRecord.length;\n\t};\n\n\treturn {\n\t\taddRecord( record?: HistoryRecord< T >, isStaged = false ): void {\n\t\t\tconst isEmpty = ! record || isRecordEmpty( record );\n\t\t\tif ( isStaged ) {\n\t\t\t\tif ( isEmpty ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trecord.forEach( ( changes ) => {\n\t\t\t\t\tstagedRecord = addHistoryChangesIntoRecord(\n\t\t\t\t\t\tstagedRecord,\n\t\t\t\t\t\tchanges\n\t\t\t\t\t);\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tdropPendingRedos();\n\t\t\t\tif ( stagedRecord.length ) {\n\t\t\t\t\tappendStagedRecordToLatestHistoryRecord();\n\t\t\t\t}\n\t\t\t\tif ( isEmpty ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\thistory.push( record );\n\t\t\t}\n\t\t},\n\n\t\tundo(): HistoryRecord< T > | undefined {\n\t\t\tif ( stagedRecord.length ) {\n\t\t\t\tdropPendingRedos();\n\t\t\t\tappendStagedRecordToLatestHistoryRecord();\n\t\t\t}\n\t\t\tconst undoRecord = history[ history.length - 1 + offset ];\n\t\t\tif ( ! undoRecord ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\toffset -= 1;\n\t\t\treturn undoRecord;\n\t\t},\n\n\t\tredo(): HistoryRecord< T > | undefined {\n\t\t\tconst redoRecord = history[ history.length + offset ];\n\t\t\tif ( ! redoRecord ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\toffset += 1;\n\t\t\treturn redoRecord;\n\t\t},\n\n\t\thasUndo(): boolean {\n\t\t\treturn !! history[ history.length - 1 + offset ];\n\t\t},\n\n\t\thasRedo(): boolean {\n\t\t\treturn !! history[ history.length + offset ];\n\t\t},\n\t};\n}\n"],
  "mappings": "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",
  "names": []
}
