Skip to content

Commit 2fc298e

Browse files
committed
feat(history): can get all the selective keys (linear history)
1 parent 8a79df0 commit 2fc298e

4 files changed

Lines changed: 51 additions & 3 deletions

File tree

src/api/command/Selective.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ export function Selective(target: unknown, propertyName: string): void {
4949

5050
/**
5151
* Gets the selective entries (key/value) of the given object.
52-
* @param obj - The object to analyze.
52+
* @param obj - The object to analyze that may contain selective properties.
5353
* @returns `undefined` if the object is not selective. A set of entries (key/value) corresponding
5454
* to the selective keys and their values of the given object.
5555
*/
56-
function getSelectiveValue<T extends object>(obj: T): Partial<T> | undefined {
56+
export function getSelectiveValue<T extends object>(obj: T): Partial<T> | undefined {
5757
const keys: unknown = (obj.constructor as SelectiveMetadata)[INTERACTO_SELECTIVE];
5858

5959
if (keys instanceof Set) {

src/api/history/LinearHistory.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,11 @@ export abstract class LinearHistory implements LinearHistoryBase {
118118
* If not valid, the method does nothing.
119119
*/
120120
public abstract redoUpTo(index: number): void;
121+
122+
/**
123+
* Gets all the unique selective objects of this history.
124+
* @returns All the unique selective objects that used in the stored undoable objects.
125+
* This concerns both the undo and redo stacks.
126+
*/
127+
public abstract getAllSelectiveObjects(): ReadonlySet<unknown>;
121128
}

src/impl/history/LinearHistoryImpl.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {LinearHistory} from "../../api/history/LinearHistory";
1616
import {Subject} from "rxjs";
1717
import type {Undoable} from "../../api/history/Undoable";
1818
import type {Observable} from "rxjs";
19-
import {hasSelectiveValue} from "../../api/command/Selective";
19+
import {getSelectiveValue, hasSelectiveValue} from "../../api/command/Selective";
2020

2121
/**
2222
* Implementation of the linear history
@@ -233,4 +233,15 @@ export class LinearHistoryImpl extends LinearHistory {
233233
this.redo();
234234
}
235235
}
236+
237+
public getAllSelectiveObjects(): ReadonlySet<unknown> {
238+
// Considering both the undo and redo stacks
239+
// Using a set to remove duplicated values
240+
return new Set([...this.undos, ...this.redos]
241+
// Collecting the selective properties
242+
.map((undoable: Undoable) => getSelectiveValue(undoable))
243+
.filter(data => data !== undefined)
244+
// Collecting only the value of the selective properties
245+
.flatMap(data => Object.values(data)));
246+
}
236247
}

test/command/selective.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,36 @@ describe("using a selective command", () => {
218218
expect(res[0]).toStrictEqual([cmd2]);
219219
expect(res[1]).toHaveLength(0);
220220
});
221+
222+
test("getAllSelectiveObjects works with shared keys", () => {
223+
history.add(cmd2);
224+
history.add(cmd1);
225+
const res = [...history.getAllSelectiveObjects()];
226+
expect(res).toHaveLength(1);
227+
expect(res).toContain(cmd1.key);
228+
// expect(res).toContain(cmd2.otherKey);
229+
});
230+
231+
test("getAllSelectiveObjects works with several keys", () => {
232+
cmd2 = new CmdSelective2("foo");
233+
history.add(cmd2);
234+
history.add(cmd1);
235+
const res = [...history.getAllSelectiveObjects()];
236+
expect(res).toHaveLength(2);
237+
expect(res).toContain(cmd1.key);
238+
expect(res).toContain(cmd2.otherKey);
239+
});
240+
241+
test("getAllSelectiveObjects works by considering the redo stack", () => {
242+
cmd2 = new CmdSelective2("foo");
243+
history.add(cmd2);
244+
history.add(cmd1);
245+
history.undo();
246+
const res = [...history.getAllSelectiveObjects()];
247+
expect(res).toHaveLength(2);
248+
expect(res).toContain(cmd1.key);
249+
expect(res).toContain(cmd2.otherKey);
250+
});
221251
});
222252

223253
describe("and a linear history and specific key comparison function", () => {

0 commit comments

Comments
 (0)