Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:vankeisb/react-tea-cup into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
vankeisb committed Dec 1, 2020
2 parents 7307e97 + 28c7f22 commit e2f8a77
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 68 deletions.
1 change: 1 addition & 0 deletions core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"test": "jest",
"test-watch": "jest --watch",
"prettify": "prettier --write .",
"tsc": "tsc",
"compile": "rimraf dist && tsc"
}
}
25 changes: 25 additions & 0 deletions core/src/TeaCup/ObjectSerializer.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
/*
* MIT License
*
* Copyright (c) 2019 Rémi Van Keisbelck
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/

import { Dict } from './Dict';
import { Tuple } from './Tuple';
import { Just, Maybe, Nothing } from './Maybe';
Expand Down
66 changes: 66 additions & 0 deletions core/src/TeaCup/Port.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* MIT License
*
* Copyright (c) 2019 Rémi Van Keisbelck
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/

import {Sub} from "./Sub";

export class Port<T> {
private subs: PortSub<T, any>[] = [];

send(t: T): void {
this.subs.forEach((s) => s.notify(t));
}

subscribe<M>(f: (t: T) => M): Sub<M> {
return new PortSub(
f,
(p) => this.subs.push(p),
(p) => {
this.subs = this.subs.filter((x) => x !== p);
},
);
}
}

class PortSub<T, M> extends Sub<M> {
constructor(
private readonly f: (t: T) => M,
private readonly _onInit: (p: PortSub<T, M>) => void,
private readonly _onRelease: (p: PortSub<T, M>) => void,
) {
super();
}

protected onInit() {
this._onInit(this);
}

protected onRelease() {
this._onRelease(this);
}

notify(t: T): void {
this.dispatch(this.f(t));
}
}
1 change: 1 addition & 0 deletions core/src/TeaCup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ export * from './ListWithSelection';
export * from './ObjectSerializer';
export * from './Try';
export * from './UUID';
export * from './Port';
27 changes: 26 additions & 1 deletion samples/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ import * as ClassMsgs from './Samples/ClassMsgs';
import * as Sful from './Samples/StatefulInView';
import * as Rest from './Samples/Rest';
import * as TimeSample from './Samples/TimeSample';
import * as PortsSample from './Samples/PortsSample';
import {appSamplePorts} from "./Samples/PortsSample";

enum Tab {
All,
Expand Down Expand Up @@ -160,6 +162,7 @@ interface Samples {
readonly sful: Sful.Model;
readonly rest: Rest.Model;
readonly time: TimeSample.Model;
readonly ports: PortsSample.Model;
}

type Msg =
Expand All @@ -172,6 +175,7 @@ type Msg =
| { type: 'sful'; child: Sful.Msg }
| { type: 'rest'; child: Rest.Msg }
| { type: 'timeSample'; child: TimeSample.Msg }
| { type: 'portsSample'; child: PortsSample.Msg }
| { type: 'urlChange'; location: Location }
| { type: 'newUrl'; url: string }
| { type: 'noop' }
Expand All @@ -189,6 +193,7 @@ function initSamples(): [Model, Cmd<Msg>] {
const sful = Sful.init();
const rest = Rest.init();
const time = TimeSample.init();
const ports = PortsSample.init();
return [
{
tag: 'samples',
Expand All @@ -202,6 +207,7 @@ function initSamples(): [Model, Cmd<Msg>] {
sful: sful[0],
rest: rest[0],
time: time[0],
ports: ports[0],
},
},
Cmd.batch([
Expand All @@ -214,6 +220,7 @@ function initSamples(): [Model, Cmd<Msg>] {
sful[1].map(mapSful),
rest[1].map(mapRest),
time[1].map(mapTimeSample),
ports[1].map(mapPortsSample),
]),
];
}
Expand Down Expand Up @@ -328,6 +335,13 @@ function mapTimeSample(m: TimeSample.Msg): Msg {
};
}

function mapPortsSample(m: PortsSample.Msg): Msg {
return {
type: 'portsSample',
child: m,
}
}

function view(dispatch: Dispatcher<Msg>, model: Model) {
switch (model.tag) {
case 'home':
Expand Down Expand Up @@ -545,6 +559,12 @@ function viewSamples(dispatch: Dispatcher<Msg>, samples: Samples) {
{Rest.view(map(dispatch, mapRest), samples.rest)}
<h2>Time</h2>
{TimeSample.view(map(dispatch, mapTimeSample), samples.time)}
<h2>Ports</h2>
{PortsSample.view(map(dispatch, mapPortsSample), samples.ports)}
<button onClick={() => {
// call ports without going through any update loop
appSamplePorts.setCounter.send(0)
}}>Reset using port</button>
</div>
);
}
Expand Down Expand Up @@ -603,12 +623,16 @@ function update(msg: Msg, model: Model): [Model, Cmd<Msg>] {
const macRest = Rest.update(msg.child, s.rest);
return [{ ...s, rest: macRest[0] }, macRest[1].map(mapRest)];
});

case 'timeSample':
return mapSample((s: Samples) => {
const macTime = TimeSample.update(msg.child, s.time);
return [{ ...s, time: macTime[0] }, macTime[1].map(mapTimeSample)];
});
case "portsSample":
return mapSample((s: Samples) => {
const mac = PortsSample.update(msg.child, s.ports);
return [{ ...s, ports: mac[0]}, mac[1].map(mapPortsSample)];
});

case 'urlChange':
return init(msg.location);
Expand All @@ -631,6 +655,7 @@ function subscriptions(model: Model): Sub<Msg> {
ParentChild.subscriptions(parentChild).map(mapParentChild),
Raf.subscriptions(raf).map(mapRaf),
TimeSample.subscriptions(time).map(mapTimeSample),
PortsSample.subscriptions().map(mapPortsSample),
]);
default:
return Sub.none();
Expand Down
77 changes: 77 additions & 0 deletions samples/src/Samples/PortsSample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* MIT License
*
* Copyright (c) 2019 Rémi Van Keisbelck
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/

import * as React from 'react';
import { Cmd, Dispatcher, noCmd, Port, Sub } from 'tea-cup-core';

export type Model = number;

export type Msg = { tag: 'inc' } | { tag: 'set-value'; value: number };

function onSetValue(value: number): Msg {
return {
tag: 'set-value',
value,
};
}

// the ports allow to send Msgs to the update loop from the outside
export const appSamplePorts = {
setCounter: new Port<number>(),
};

// export as a global to play in dev tools
// @ts-ignore
window['appSamplePorts'] = appSamplePorts;

export function init(): [Model, Cmd<Msg>] {
return noCmd(0);
}

export function view(dispatch: Dispatcher<Msg>, model: Model) {
return (
<div>
<h2>Counter with ports</h2>
<span>Value = {model}</span>
<button onClick={() => dispatch({ tag: 'inc' })}>+</button>
</div>
);
}

export function update(msg: Msg, model: Model): [Model, Cmd<Msg>] {
switch (msg.tag) {
case 'inc': {
return noCmd(model + 1);
}
case 'set-value': {
return noCmd(msg.value);
}
}
}

export function subscriptions(): Sub<Msg> {
// wire ports to get Msgs into our update func
return appSamplePorts.setCounter.subscribe(onSetValue);
}
1 change: 1 addition & 0 deletions tea-cup/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"test": "jest",
"test-watch": "jest --watch",
"prettify": "prettier --write .",
"tsc": "tsc",
"compile": "rimraf dist && tsc",
"samples": "tsc --outFile ./dist/Samples/index.js && cp ./src/Samples/index.html ./dist/Samples"
},
Expand Down
Loading

0 comments on commit e2f8a77

Please sign in to comment.