Skip to content

Commit 4567f3c

Browse files
committed
introduce updatePiped
1 parent 1432fef commit 4567f3c

2 files changed

Lines changed: 105 additions & 0 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2019 Rémi Van Keisbelck
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*
24+
*/
25+
26+
import { genericUpdatePiped } from "./UpdatePiped";
27+
28+
describe('UpdatePiped', () => {
29+
type MyModel = number;
30+
type MyCmd = string[];
31+
32+
test('generic', () => {
33+
const model0 : MyModel = 6;
34+
const [model, cmd] = genericUpdatePiped(
35+
(cmds: readonly MyCmd[]) => new Array().concat(...cmds),
36+
model0,
37+
(model) => [model + 1, ['add 1']],
38+
(model) => [model * 6, ['multiply by 6']],
39+
);
40+
expect(model).toBe(42);
41+
expect(cmd).toEqual(['add 1', 'multiply by 6']);
42+
});
43+
});
44+

core/src/TeaCup/UpdatePiped.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2019 Rémi Van Keisbelck
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*
24+
*/
25+
26+
import { Cmd } from './Cmd';
27+
28+
export type UpdateFunction<Model, Msg> = GenericUpdateFunction<Model, Cmd<Msg>>;
29+
30+
/**
31+
* Piped updates.
32+
* Useful for chaining building blocks making up the update loop.
33+
*/
34+
export function updatePiped<Model, Msg>(
35+
model: Model,
36+
...updates: readonly UpdateFunction<Model, Msg>[]
37+
): [Model, Cmd<Msg>] {
38+
return genericUpdatePiped(Cmd.batch, model, ...updates);
39+
}
40+
41+
export type GenericUpdateFunction<Model, Cmd> = (model: Model) => [Model, Cmd];
42+
43+
/**
44+
* Generic implementation of chained updates.
45+
* See updatePiped().
46+
*/
47+
export function genericUpdatePiped<Model, Cmd>(
48+
batch: (cmds: readonly Cmd[]) => Cmd,
49+
model: Model,
50+
...updates: readonly GenericUpdateFunction<Model, Cmd>[]
51+
): [Model, Cmd] {
52+
const cmd0: Cmd = batch([]);
53+
return updates.reduce<[Model, Cmd]>(
54+
(acc: [Model, Cmd], update: GenericUpdateFunction<Model, Cmd>) => {
55+
const [model0, cmd0] = acc;
56+
const [model1, cmd1] = update(model0);
57+
return [model1, batch([cmd0, cmd1])];
58+
},
59+
[model, cmd0],
60+
);
61+
}

0 commit comments

Comments
 (0)