Skip to content

Commit ad11ef3

Browse files
committed
[checkpoints] Add forEachCheckpoints method
1 parent 9151a25 commit ad11ef3

File tree

3 files changed

+74
-1
lines changed

3 files changed

+74
-1
lines changed

src/checkpoints.d.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ import {Store} from './store.d';
3333
*/
3434
export type CheckpointIds = [Ids, Id | undefined, Ids];
3535

36+
/**
37+
* The CheckpointCallback type describes a function that takes a Checkpoint's
38+
* Id.
39+
*
40+
* A CheckpointCallback is provided when using the forEachCheckpoint method,
41+
* so that you can do something based on every Checkpoint in the Checkpoints
42+
* object. See that method for specific examples.
43+
*
44+
* @param checkpointId The Id of the Checkpoint that the callback can operate
45+
* on.
46+
* @category Callback
47+
*/
48+
export type CheckpointCallback = (checkpointId: Id, label?: string) => void;
49+
3650
/**
3751
* The CheckpointIdsListener type describes a function that is used to listen to
3852
* changes to the checkpoint Ids in a Checkpoints object.
@@ -353,6 +367,36 @@ export interface Checkpoints {
353367
*/
354368
getCheckpointIds(): CheckpointIds;
355369

370+
/**
371+
* The forEachCheckpoint method takes a function that it will then call for
372+
* each Checkpoint in a specified Checkpoints object.
373+
*
374+
* This method is useful for iterating over the structure of the Checkpoints
375+
* object in a functional style. The `checkpointCallback` parameter is a
376+
* CheckpointCallback function that will be called with the Id of each
377+
* Checkpoint.
378+
*
379+
* @param checkpointCallback The function that should be called for every
380+
* Checkpoint.
381+
* @example
382+
* This example iterates over each Checkpoint in a Checkpoints object.
383+
*
384+
* ```js
385+
* const store = createStore().setTables({pets: {fido: {sold: false}}});
386+
* const checkpoints = createCheckpoints(store);
387+
* store.setCell('pets', 'fido', 'sold', true);
388+
* checkpoints.addCheckpoint('sale');
389+
*
390+
* checkpoints.forEachCheckpoint((checkpointId, label) => {
391+
* console.log(`${checkpointId}:${label}`);
392+
* });
393+
* // -> '0:'
394+
* // -> '1:sale'
395+
* ```
396+
* @category Iterator
397+
*/
398+
forEachCheckpoint(checkpointCallback: CheckpointCallback): void;
399+
356400
/**
357401
* The hasCheckpoint method returns a boolean indicating whether a given
358402
* Checkpoint exists in the Checkpoints object.

src/checkpoints.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {Cell, Store} from './store.d';
22
import {
3+
CheckpointCallback,
34
CheckpointIds,
45
CheckpointIdsListener,
56
CheckpointListener,
@@ -9,7 +10,14 @@ import {
910
} from './checkpoints.d';
1011
import {DEBUG, ifNotUndefined, isUndefined} from './common/other';
1112
import {Id, IdOrNull, Ids} from './common.d';
12-
import {IdMap, mapEnsure, mapGet, mapNew, mapSet} from './common/map';
13+
import {
14+
IdMap,
15+
mapEnsure,
16+
mapForEach,
17+
mapGet,
18+
mapNew,
19+
mapSet,
20+
} from './common/map';
1321
import {IdSet, IdSet2, setNew} from './common/set';
1422
import {
1523
arrayClear,
@@ -193,6 +201,9 @@ export const createCheckpoints: typeof createCheckpointsDecl =
193201
[...forwardIds],
194202
];
195203

204+
const forEachCheckpoint = (checkpointCallback: CheckpointCallback) =>
205+
mapForEach(labels, checkpointCallback);
206+
196207
const hasCheckpoint = (checkpointId: Id) => collHas(deltas, checkpointId);
197208

198209
const getCheckpoint = (checkpointId: Id): string | undefined =>
@@ -267,6 +278,7 @@ export const createCheckpoints: typeof createCheckpointsDecl =
267278

268279
getStore,
269280
getCheckpointIds,
281+
forEachCheckpoint,
270282
hasCheckpoint,
271283
getCheckpoint,
272284

test/unit/checkpoints.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,23 @@ describe('Miscellaneous', () => {
500500
expectNoChanges(listener);
501501
});
502502

503+
test('forEachCheckpoint', () => {
504+
setCells();
505+
checkpoints.setCheckpoint('2', 'two');
506+
checkpoints.setCheckpoint('3', 'three');
507+
const eachCheckpoint: any = {};
508+
checkpoints.forEachCheckpoint(
509+
(checkpointId, label) => (eachCheckpoint[checkpointId] = label),
510+
);
511+
expect(eachCheckpoint).toEqual({
512+
'0': '',
513+
'1': '',
514+
'2': 'two',
515+
'3': 'three',
516+
'4': '',
517+
});
518+
});
519+
503520
test('getStore', () => {
504521
expect(checkpoints.getStore()).toEqual(store);
505522
});

0 commit comments

Comments
 (0)