Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v0.1.5 #213

Merged
merged 32 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7925b64
fix(movex-react-improve-api): :bug: fix compiling issue by adding a q…
GabrielCTroia Apr 4, 2024
85ff54e
chore(lib versions): :hammer: bump to v0.1.3 for all packages
GabrielCTroia Apr 4, 2024
200b2b2
chore(package version): :hammer: bump to 0.1.4 actually out of some s…
GabrielCTroia Apr 4, 2024
e8088b9
feat(movex-master): :sparkles: add onResourceSubscriberRemoved & onRe…
GabrielCTroia Apr 1, 2024
556af28
Refactor the MovexResourceObseravble State to support subscribers as …
GabrielCTroia Apr 3, 2024
fd12804
refactor(movex-core-util): :recycle: refactor the "setClientIt" event…
GabrielCTroia Apr 3, 2024
3f614fe
feat(movex-server): :sparkles: add an api route to GET individual res…
GabrielCTroia Apr 3, 2024
a120dd1
refactor(movex-react): :recycle: fixed typos
GabrielCTroia Apr 3, 2024
74c77a5
refactor(movex-core-util/observable): :recycle: take out uneeded code
GabrielCTroia Apr 3, 2024
9cca1aa
docs(movex): :memo: fix the README - take out hacktoberfest
GabrielCTroia Apr 4, 2024
cebb16a
test(movex-master): :white_check_mark: fix tests after adding the sub…
GabrielCTroia Apr 4, 2024
ae3a5d7
chore(version): :hammer: bump to v0.1.5-0
GabrielCTroia Apr 4, 2024
016ecbf
refactor(movex, movex-core-util, movex-master): :recycle: take out co…
GabrielCTroia Apr 4, 2024
bfbe7ba
Remove unneded code
GabrielCTroia Apr 6, 2024
ded030c
fix(movex-react-local-master): :bug: fix the bndResource
GabrielCTroia Apr 6, 2024
c1a9809
feat(movex-demo): :sparkles: add an RPS game using the movex-react-lo…
GabrielCTroia Apr 7, 2024
f8a80dc
refactor(all): :recycle: make Logsy an Event Emitter and expose in mo…
GabrielCTroia Apr 7, 2024
96b19ae
feat(rps-v2): :sparkles: hookup a logger to the MovexLocalProvider
GabrielCTroia Apr 7, 2024
a29a6ed
ci(libs version): :ferris_wheel: bump to 0.1.5-1
GabrielCTroia Apr 11, 2024
cb30fc1
fix(movex-react): :bug: add the logger to MovexProviderClass as well
GabrielCTroia Apr 11, 2024
0af75b0
ci(movex-react): :ferris_wheel: bump version to 0.1.5-1
GabrielCTroia Apr 11, 2024
358dd78
fix(movex-react): :bug: remove unneded "test" prop from movex-provider
GabrielCTroia Apr 11, 2024
9660c76
ci(movex-react): :ferris_wheel: bump to 0.1.5-3
GabrielCTroia Apr 11, 2024
0ab9a6b
feat(all-libs): :sparkles: add ability to pass in Client Info Object …
GabrielCTroia Apr 17, 2024
2bf6e50
Merge pull request #210 from movesthatmatter/improve-logs
GabrielCTroia Apr 17, 2024
92ad4cf
ci(libs): :ferris_wheel: bump the version to 0.1.5-4
GabrielCTroia Apr 17, 2024
df7e945
Merge pull request #211 from movesthatmatter/improve-subscribers-object
GabrielCTroia Jul 11, 2024
3cfc405
Merge pull request #208 from movesthatmatter/feature-add-access-to-su…
GabrielCTroia Jul 11, 2024
396706f
Merge branch 'dev'
GabrielCTroia Jul 11, 2024
f38a499
fix([movex-master]): :bug: fix the tests after adding subscriber clie…
GabrielCTroia Jul 11, 2024
a6dcd7e
[libs] Add a "version-publishable-libs" script to push all the script…
GabrielCTroia Jul 11, 2024
de0a132
ci(libs): :ferris_wheel: bump all libs version to 0.1.5
GabrielCTroia Jul 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions apps/movex-demo/pages/local/rps-v2/Game.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import * as React from 'react';
import { MovexBoundResource } from 'movex-react';
import movexConfig from './movex.config';
import { initialState } from './movex';
import { useState } from 'react';
import { ResourceIdentifier, toResourceIdentifierStr } from 'movex-core-util';
import { GameUI } from './GameUI';
// import { MovexStoreItem } from "movex";
import { MovexLocalInstance } from 'movex-react-local-master';
import { MovexStoreItem } from 'movex-store';

type Props = {
masterStore?: MovexStoreItem<any>;
};

export function Game(props: Props) {
const [rpsRid, setRpsRid] = useState<ResourceIdentifier<'rps'>>();
const [masterStateUpdated, setMasterStateUpdated] = useState(false);

return (
<div className="h-screen flex flex-1 flex-col md:flex-row bg-gradient-to-bl from-blue-400 via-indigo-500 to-purple-500">
<MovexLocalInstance
clientId="playerA"
movexDefinition={movexConfig}
onConnected={(movex) => {
const reg = movex.register('rps');

reg.create(initialState).map(({ rid }) => {
setRpsRid(rid);

setTimeout(() => {
// HACK. Fake the Maser State Update in order to fix a current issue with working with
// master state values, instead of local ones.
// See https://github.com/movesthatmatter/movex/issues/9 for more info.
// This feature witll be added in the close future
setMasterStateUpdated(true);
}, 10);
});
}}
>
{rpsRid && (
<MovexBoundResource
rid={rpsRid}
movexDefinition={movexConfig}
render={({ boundResource, clientId }) => (
<div className="w-full flex-1">
<GameUI boundResource={boundResource} userId={clientId} />
</div>
)}
/>
)}
</MovexLocalInstance>
<div className="flex-1 flex flex-col h-full">
<div className="flex-1 flex justify-center items-center">
<span role="img" aria-label="versus" className="text-5xl">
🆚
</span>
</div>
{props.masterStore && (
<div
className="hidden md:block bg-red-100 bg-opacity-10 text-center pb-2 pt-2 pl-2 pr-2 overflow-scroll flex flex-col justify-center"
style={{
flex: 0.55,
}}
>
<div className="flex flex-col flex-1 nbg-green-100 h-full">
<p className="font-bold pb-4 capitalize text-white">
Master Movex State
</p>
<pre
className="text-xs text-left text-white flex flex-1 justify-center items-center nbg-red-100"
lang="json"
>
<code>
{JSON.stringify(
{
submissions: props.masterStore.state[0].submissions,
winner: props.masterStore.state[0].winner,
},
null,
1
)}
</code>
</pre>
</div>
</div>
)}
</div>
{rpsRid && masterStateUpdated && (
<MovexLocalInstance clientId="playerB" movexDefinition={movexConfig}>
<MovexBoundResource
rid={rpsRid}
movexDefinition={movexConfig}
render={({ boundResource, clientId }) => (
<div className="w-full flex-1">
<GameUI boundResource={boundResource} userId={clientId} />
</div>
)}
/>
</MovexLocalInstance>
)}
</div>
);
}
263 changes: 263 additions & 0 deletions apps/movex-demo/pages/local/rps-v2/GameUI.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
import React from "react";
import { MovexBoundResourceFromConfig } from "movex-react";
import { useCallback, useEffect, useMemo } from "react";
import { globalLogsy } from "movex-core-util";
import movexConfig from "./movex.config";
import {
PlayerLabel,
toOppositeLabel,
RPS,
selectAvailableLabels
} from "./movex";

type Props = {
boundResource: MovexBoundResourceFromConfig<
typeof movexConfig["resources"],
"rps"
>;
userId: string;
buttonClassName?: string;
containerClassName?: string;
backgroundColor?: string;
};

export const GameUI: React.FC<Props> = ({
boundResource,
userId,
...props
}) => {
const { state, dispatch, dispatchPrivate } = boundResource;
const { players } = state;

const myPlayerLabel = useMemo((): PlayerLabel | undefined => {
if (!(players.playerA && players.playerB)) {
return undefined;
}

if (players.playerA.id === userId) {
return "playerA";
}

if (players.playerB.id === userId) {
return "playerB";
}

return undefined;
}, [players, userId]);

const oppnentPlayerLabel = useMemo(() => {
return myPlayerLabel ? toOppositeLabel(myPlayerLabel) : undefined;
}, [myPlayerLabel]);

// Add Player
useEffect(() => {
// TODO: here there is a major issue, as selectAvailableLables works with local state
// but it needs to check on the actual (master) state. How to solve this?
// add an api to be able to read master state seperately?

// Or in this case change the strategy altogether, and work with master generated values, in which case
// the local optimistic state udate gets turned off by default, so that means it will wait for the real state to update.
// Kinda like a dispatchAndWait
const availableLabels = selectAvailableLabels(state);

if (
state.players.playerA?.id === userId ||
state.players.playerB?.id === userId
) {
return;
}

if (availableLabels.length === 0) {
globalLogsy.warn("Player Slots taken");

return;
}

dispatch({
type: "addPlayer",
payload: {
id: userId,
playerLabel: availableLabels[0],
atTimestamp: new Date().getTime()
}
});
}, [userId, state, dispatch]);

const submit = useCallback(
(play: RPS) => {
if (!myPlayerLabel) {
console.warn("Not A Player");
return;
}

dispatchPrivate(
{
type: "submit",
payload: {
playerLabel: myPlayerLabel,
rps: play
},
isPrivate: true
},
{
type: "setReadySubmission",
payload: {
playerLabel: myPlayerLabel
}
}
);
},
[dispatchPrivate, myPlayerLabel]
);

const winner = useMemo(() => {
if (!state.winner) {
return undefined;
}

if (state.winner === "1/2") {
return "1/2";
}

const {
submissions: { playerA }
} = state;

if (playerA.play === state.winner) {
return state.players.playerA.label;
}

return state.players.playerB.label;
}, [state.winner]);

return (
<div
className="w-full flex h-full flex-col text-white"
style={{
...(props.backgroundColor
? {
background: props.backgroundColor
}
: {
// background: "#afd8fa"
})
}}
>
<div className="flex flex-1 w-full h-full flex-col justify-center items-center content-center">
<div className="p-10 pb-20 text-xl font-bold capitalize">{userId}</div>
{state.winner ? (
<>
<h3 className="text-7xl text-center">
{winner === "1/2"
? "Draw 😫"
: winner === myPlayerLabel
? "You Won 🎉"
: "You Lost 😢"}
</h3>
<button
className="text-2xl font-bold mt-10 hover:text-3xl"
onClick={() => dispatch({ type: "playAgain" })}
>
Play Again
</button>
</>
) : (
<>
<div className="flex">
<div>
<button
style={{
animationDelay: "200ms",
animationDuration: "3s"
}}
className={`animate-bounce text-7xl hover:bg-red-500 p-6 rounded-xl ${
myPlayerLabel &&
state.submissions[myPlayerLabel]?.play === "rock" &&
"bg-red-500"
}`}
onClick={() => submit("rock")}
>
<span role="img" aria-label="rock">
👊
</span>
</button>
</div>
<div>
<button
style={{
animationDelay: "500ms",
animationDuration: "3s"
}}
className={`animate-bounce text-7xl hover:bg-red-500 p-6 rounded-xl ${
myPlayerLabel &&
state.submissions[myPlayerLabel]?.play === "paper" &&
"bg-red-500"
}`}
onClick={() => submit("paper")}
>
<span role="img" aria-label="paper">
</span>
</button>
</div>
<div>
<button
style={{
animationDelay: "0ms",
animationDuration: "3s"
}}
className={`animate-bounce text-7xl hover:bg-red-500 p-6 rounded-xl ${
myPlayerLabel &&
state.submissions[myPlayerLabel]?.play === "scissors" &&
"bg-red-500"
}`}
onClick={() => submit("scissors")}
>
<span role="img" aria-label="scrissors">
✌️
</span>
</button>
</div>
</div>
<div className="text-center">
{oppnentPlayerLabel &&
state.submissions[oppnentPlayerLabel]?.play && (
<h5 className="text-lg italic">
Opponent Submitted{" "}
<span role="img" aria-label="time ticking">
⌛️⏰
</span>
</h5>
)}
</div>
</>
)}
</div>
<div
className="hidden md:block bg-red-100 bg-opacity-10 text-center pb-2 pt-2 pl-2 pr-2 overflow-scroll flex flex-col justify-center"
style={{
flex: 0.55
}}
>
<div className="flex flex-col flex-1 nbg-green-100 h-full">
<p className="font-bold pb-4 capitalize">{userId} Movex State</p>
<pre
className="text-xs text-left text-white flex flex-1 justify-center items-center nbg-red-100"
lang="json"
>
<code>
{JSON.stringify(
{
submissions: state.submissions,
winner: state.winner
},
null,
1
)}
</code>
</pre>
</div>
</div>
</div>
);
};
28 changes: 28 additions & 0 deletions apps/movex-demo/pages/local/rps-v2/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useState } from 'react';
import movexConfig from './movex.config';
import { Game } from './Game';
import { MovexLocalMasterProvider } from 'movex-react-local-master';
import { MovexStoreItem } from 'movex-store';

export default function App() {
const [masterStore, setMasterStore] = useState<MovexStoreItem<any>>();

return (
/**
* This is using the Local Provider in order to simulate
* multiple players in the same browser instance
*/
<MovexLocalMasterProvider
movexDefinition={movexConfig}
onMasterResourceUpdated={setMasterStore}
logger={{
onLog: ({ method, prefix, message, payload }) => {
// console.log('event', method, prefix, message, payload)
console[method](prefix + ' ' + message, payload);
},
}}
>
<Game masterStore={masterStore} />
</MovexLocalMasterProvider>
);
}
Loading
Loading