Skip to content

Commit af5b47f

Browse files
committed
example and optimized none handling
1 parent 4567f3c commit af5b47f

2 files changed

Lines changed: 33 additions & 10 deletions

File tree

core/src/TeaCup/UpdatePiped.test.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,35 @@
2323
*
2424
*/
2525

26-
import { genericUpdatePiped } from "./UpdatePiped";
26+
import { Cmd } from './Cmd';
27+
import { genericUpdatePiped, updatePiped } from './UpdatePiped';
2728

2829
describe('UpdatePiped', () => {
2930
type MyModel = number;
30-
type MyCmd = string[];
31+
type MyCmd = readonly string[];
3132

3233
test('generic', () => {
33-
const model0 : MyModel = 6;
34+
const model0: MyModel = 6;
3435
const [model, cmd] = genericUpdatePiped(
35-
(cmds: readonly MyCmd[]) => new Array().concat(...cmds),
36+
(cmd1: MyCmd, cmd2: MyCmd) => new Array().concat(...cmd1, ...cmd2),
37+
[],
3638
model0,
3739
(model) => [model + 1, ['add 1']],
3840
(model) => [model * 6, ['multiply by 6']],
3941
);
4042
expect(model).toBe(42);
4143
expect(cmd).toEqual(['add 1', 'multiply by 6']);
4244
});
43-
});
4445

46+
test('example with none handling', () => {
47+
type MyMsg = string;
48+
const model0: MyModel = 6;
49+
const [model, cmd] = updatePiped(
50+
model0,
51+
(model) => [model + 1, Cmd.none()],
52+
(model) => [model * 6, Cmd.none()],
53+
);
54+
expect(model).toBe(42);
55+
expect(cmd).toEqual(Cmd.none());
56+
});
57+
});

core/src/TeaCup/UpdatePiped.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,17 @@ export function updatePiped<Model, Msg>(
3535
model: Model,
3636
...updates: readonly UpdateFunction<Model, Msg>[]
3737
): [Model, Cmd<Msg>] {
38-
return genericUpdatePiped(Cmd.batch, model, ...updates);
38+
const none: Cmd<Msg> = Cmd.none();
39+
const combine = (cmd1: Cmd<Msg>, cmd2: Cmd<Msg>) => {
40+
const none1 = isNone(cmd1);
41+
const none2 = isNone(cmd2);
42+
return none1 && none2 ? cmd1 : none1 ? cmd2 : none2 ? cmd1 : Cmd.batch([cmd1, cmd2]);
43+
};
44+
return genericUpdatePiped(combine, none, model, ...updates);
45+
}
46+
47+
function isNone<Msg>(cmd: Cmd<Msg>): boolean {
48+
return cmd.constructor.name === 'CmdNone';
3949
}
4050

4151
export type GenericUpdateFunction<Model, Cmd> = (model: Model) => [Model, Cmd];
@@ -45,17 +55,17 @@ export type GenericUpdateFunction<Model, Cmd> = (model: Model) => [Model, Cmd];
4555
* See updatePiped().
4656
*/
4757
export function genericUpdatePiped<Model, Cmd>(
48-
batch: (cmds: readonly Cmd[]) => Cmd,
58+
combine: (cmd1: Cmd, cmd2: Cmd) => Cmd,
59+
none: Cmd,
4960
model: Model,
5061
...updates: readonly GenericUpdateFunction<Model, Cmd>[]
5162
): [Model, Cmd] {
52-
const cmd0: Cmd = batch([]);
5363
return updates.reduce<[Model, Cmd]>(
5464
(acc: [Model, Cmd], update: GenericUpdateFunction<Model, Cmd>) => {
5565
const [model0, cmd0] = acc;
5666
const [model1, cmd1] = update(model0);
57-
return [model1, batch([cmd0, cmd1])];
67+
return [model1, combine(cmd0, cmd1)];
5868
},
59-
[model, cmd0],
69+
[model, none],
6070
);
6171
}

0 commit comments

Comments
 (0)