33 */
44import isShallowEqual from '@wordpress/is-shallow-equal' ;
55
6- /** @typedef {import('./types').HistoryRecord } HistoryRecord */
7- /** @typedef {import('./types').HistoryChange } HistoryChange */
8- /** @typedef {import('./types').HistoryChanges } HistoryChanges */
9- /** @typedef {import('./types').UndoManager } UndoManager */
6+ /**
7+ * Internal dependencies
8+ */
9+ import type {
10+ HistoryChange as _HistoryChange ,
11+ HistoryChanges as _HistoryChanges ,
12+ HistoryRecord as _HistoryRecord ,
13+ UndoManager as _UndoManager ,
14+ } from './types' ;
15+
16+ /**
17+ * Represents a single change in history.
18+ */
19+ export type HistoryChange < T = unknown > = _HistoryChange < T > ;
20+
21+ /**
22+ * Represents changes for a single item.
23+ */
24+ export type HistoryChanges < T = unknown > = _HistoryChanges < T > ;
25+
26+ /**
27+ * Represents a record of history changes.
28+ */
29+ export type HistoryRecord < T = unknown > = _HistoryRecord < T > ;
30+
31+ /**
32+ * The undo manager interface.
33+ */
34+ export type UndoManager < T = unknown > = _UndoManager < T > ;
1035
1136/**
1237 * Merge changes for a single item into a record of changes.
1338 *
14- * @param { Record< string, HistoryChange > } changes1 Previous changes
15- * @param { Record< string, HistoryChange > } changes2 NextChanges
39+ * @param changes1 Previous changes
40+ * @param changes2 Next changes
1641 *
17- * @return { Record< string, HistoryChange > } Merged changes
42+ * @return Merged changes
1843 */
19- function mergeHistoryChanges ( changes1 , changes2 ) {
20- /**
21- * @type { Record< string, HistoryChange > }
22- */
23- const newChanges = { ...changes1 } ;
44+ function mergeHistoryChanges < T > (
45+ changes1 : Record < string , HistoryChange < T > > ,
46+ changes2 : Record < string , HistoryChange < T > >
47+ ) : Record < string , HistoryChange < T > > {
48+ const newChanges : Record < string , HistoryChange < T > > = { ...changes1 } ;
2449 Object . entries ( changes2 ) . forEach ( ( [ key , value ] ) => {
2550 if ( newChanges [ key ] ) {
2651 newChanges [ key ] = { ...newChanges [ key ] , to : value . to } ;
@@ -35,10 +60,13 @@ function mergeHistoryChanges( changes1, changes2 ) {
3560/**
3661 * Adds history changes for a single item into a record of changes.
3762 *
38- * @param { HistoryRecord } record The record to merge into.
39- * @param { HistoryChanges } changes The changes to merge.
63+ * @param record The record to merge into.
64+ * @param changes The changes to merge.
4065 */
41- const addHistoryChangesIntoRecord = ( record , changes ) => {
66+ const addHistoryChangesIntoRecord = < T > (
67+ record : HistoryRecord < T > ,
68+ changes : HistoryChanges < T >
69+ ) : HistoryRecord < T > => {
4270 const existingChangesIndex = record ?. findIndex (
4371 ( { id : recordIdentifier } ) => {
4472 return typeof recordIdentifier === 'string'
@@ -66,28 +94,19 @@ const addHistoryChangesIntoRecord = ( record, changes ) => {
6694/**
6795 * Creates an undo manager.
6896 *
69- * @return { UndoManager } Undo manager.
97+ * @return Undo manager.
7098 */
71- export function createUndoManager ( ) {
72- /**
73- * @type {HistoryRecord[] }
74- */
75- let history = [ ] ;
76- /**
77- * @type {HistoryRecord }
78- */
79- let stagedRecord = [ ] ;
80- /**
81- * @type {number }
82- */
99+ export function createUndoManager < T = unknown > ( ) : UndoManager < T > {
100+ let history : HistoryRecord < T > [ ] = [ ] ;
101+ let stagedRecord : HistoryRecord < T > = [ ] ;
83102 let offset = 0 ;
84103
85- const dropPendingRedos = ( ) => {
104+ const dropPendingRedos = ( ) : void => {
86105 history = history . slice ( 0 , offset || undefined ) ;
87106 offset = 0 ;
88107 } ;
89108
90- const appendStagedRecordToLatestHistoryRecord = ( ) => {
109+ const appendStagedRecordToLatestHistoryRecord = ( ) : void => {
91110 const index = history . length === 0 ? 0 : history . length - 1 ;
92111 let latestRecord = history [ index ] ?? [ ] ;
93112 stagedRecord . forEach ( ( changes ) => {
@@ -102,10 +121,10 @@ export function createUndoManager() {
102121 * A record is considered empty if it the changes keep the same values.
103122 * Also updates to function values are ignored.
104123 *
105- * @param { HistoryRecord } record
106- * @return { boolean } Whether the record is empty.
124+ * @param record The record to check.
125+ * @return Whether the record is empty.
107126 */
108- const isRecordEmpty = ( record ) => {
127+ const isRecordEmpty = ( record : HistoryRecord < T > ) : boolean => {
109128 const filteredRecord = record . filter ( ( { changes } ) => {
110129 return Object . values ( changes ) . some (
111130 ( { from, to } ) =>
@@ -118,13 +137,7 @@ export function createUndoManager() {
118137 } ;
119138
120139 return {
121- /**
122- * Record changes into the history.
123- *
124- * @param {HistoryRecord= } record A record of changes to record.
125- * @param {boolean } isStaged Whether to immediately create an undo point or not.
126- */
127- addRecord ( record , isStaged = false ) {
140+ addRecord ( record ?: HistoryRecord < T > , isStaged = false ) : void {
128141 const isEmpty = ! record || isRecordEmpty ( record ) ;
129142 if ( isStaged ) {
130143 if ( isEmpty ) {
@@ -148,7 +161,7 @@ export function createUndoManager() {
148161 }
149162 } ,
150163
151- undo ( ) {
164+ undo ( ) : HistoryRecord < T > | undefined {
152165 if ( stagedRecord . length ) {
153166 dropPendingRedos ( ) ;
154167 appendStagedRecordToLatestHistoryRecord ( ) ;
@@ -161,7 +174,7 @@ export function createUndoManager() {
161174 return undoRecord ;
162175 } ,
163176
164- redo ( ) {
177+ redo ( ) : HistoryRecord < T > | undefined {
165178 const redoRecord = history [ history . length + offset ] ;
166179 if ( ! redoRecord ) {
167180 return ;
@@ -170,11 +183,11 @@ export function createUndoManager() {
170183 return redoRecord ;
171184 } ,
172185
173- hasUndo ( ) {
186+ hasUndo ( ) : boolean {
174187 return ! ! history [ history . length - 1 + offset ] ;
175188 } ,
176189
177- hasRedo ( ) {
190+ hasRedo ( ) : boolean {
178191 return ! ! history [ history . length + offset ] ;
179192 } ,
180193 } ;
0 commit comments