bug fixes
This commit is contained in:
@@ -1,10 +1,20 @@
|
|||||||
import { Accessor, createContext, For, onCleanup, Show } from "solid-js";
|
import {
|
||||||
|
Accessor,
|
||||||
|
createContext,
|
||||||
|
createEffect,
|
||||||
|
createResource,
|
||||||
|
createSignal,
|
||||||
|
For,
|
||||||
|
onCleanup,
|
||||||
|
Show,
|
||||||
|
} from "solid-js";
|
||||||
import { TWsIn, TWsOut } from "../../../server/src/table";
|
import { TWsIn, TWsOut } from "../../../server/src/table";
|
||||||
import api, { fromWebsocket } from "../api";
|
import api, { fromWebsocket } from "../api";
|
||||||
import { createObservable, createObservableWithInit, cx } from "../fn";
|
import { createObservable, createObservableWithInit, cx } from "../fn";
|
||||||
import { me } from "../profile";
|
import { me } from "../profile";
|
||||||
import Game from "./Game";
|
import Game from "./Game";
|
||||||
import Player from "./Player";
|
import Player from "./Player";
|
||||||
|
import { fromPromise } from "kefir";
|
||||||
|
|
||||||
export const TableContext = createContext<{
|
export const TableContext = createContext<{
|
||||||
players: Accessor<string[]>;
|
players: Accessor<string[]>;
|
||||||
@@ -13,9 +23,20 @@ export const TableContext = createContext<{
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
export default (props: { tableKey: string }) => {
|
export default (props: { tableKey: string }) => {
|
||||||
|
const wsPromise = new Promise<
|
||||||
|
ReturnType<ReturnType<typeof api.ws>["subscribe"]>
|
||||||
|
>((res) => {
|
||||||
const ws = api.ws(props).subscribe();
|
const ws = api.ws(props).subscribe();
|
||||||
const wsEvents = fromWebsocket<TWsOut>(ws);
|
ws.on("open", () => res(ws));
|
||||||
onCleanup(() => ws.close());
|
ws.on("error", () => res(ws));
|
||||||
|
ws.on("close", () => res(ws));
|
||||||
|
});
|
||||||
|
|
||||||
|
const sendWs = (msg: TWsIn) => wsPromise.then((ws) => ws.send(msg));
|
||||||
|
const wsEvents = fromPromise(wsPromise).flatMap((ws) =>
|
||||||
|
fromWebsocket<TWsOut>(ws)
|
||||||
|
);
|
||||||
|
onCleanup(() => wsPromise.then((ws) => ws.close()));
|
||||||
|
|
||||||
const presenceEvents = wsEvents.filter((evt) => evt.players != null);
|
const presenceEvents = wsEvents.filter((evt) => evt.players != null);
|
||||||
|
|
||||||
@@ -26,12 +47,14 @@ export default (props: { tableKey: string }) => {
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [ready, setReady] = createSignal(false);
|
||||||
|
createEffect(() => sendWs({ ready: ready() }));
|
||||||
const view = createObservable(gameEvents.map((evt) => evt.view));
|
const view = createObservable(gameEvents.map((evt) => evt.view));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableContext.Provider
|
<TableContext.Provider
|
||||||
value={{
|
value={{
|
||||||
sendWs: (evt) => ws.send(evt),
|
sendWs,
|
||||||
view,
|
view,
|
||||||
players,
|
players,
|
||||||
}}
|
}}
|
||||||
@@ -83,10 +106,10 @@ export default (props: { tableKey: string }) => {
|
|||||||
<Show when={view() == null}>
|
<Show when={view() == null}>
|
||||||
<div class="absolute center">
|
<div class="absolute center">
|
||||||
<button
|
<button
|
||||||
onClick={() => ws.send({ ready: true })}
|
onClick={() => setReady((prev) => !prev)}
|
||||||
class="button p-1 "
|
class="button p-1 "
|
||||||
>
|
>
|
||||||
Ready
|
{ready() ? "Not Ready" : "Ready"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import { A, useParams } from "@solidjs/router";
|
import { A, useParams } from "@solidjs/router";
|
||||||
|
|
||||||
import Table from "../components/Table";
|
import Table from "../components/Table";
|
||||||
|
import { Show } from "solid-js";
|
||||||
|
import { me } from "../profile";
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const { tableKey } = useParams();
|
const { tableKey } = useParams();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Show when={me() != null}>
|
||||||
<Table tableKey={tableKey} />
|
<Table tableKey={tableKey} />
|
||||||
<A href={"/"} class="fixed tl m-4 px-2 py-1.5 button">
|
<A href={"/"} class="fixed tl m-4 px-2 py-1.5 button">
|
||||||
Back
|
Back
|
||||||
</A>
|
</A>
|
||||||
</>
|
</Show>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ const api = new Elysia({ prefix: "/api" })
|
|||||||
},
|
},
|
||||||
send,
|
send,
|
||||||
}) {
|
}) {
|
||||||
|
console.log(humanKey, "connected");
|
||||||
|
try {
|
||||||
const table = liveTable<
|
const table = liveTable<
|
||||||
SimpleConfiguration,
|
SimpleConfiguration,
|
||||||
SimpleGameState,
|
SimpleGameState,
|
||||||
@@ -101,6 +103,9 @@ const api = new Elysia({ prefix: "/api" })
|
|||||||
humanKey,
|
humanKey,
|
||||||
presence: "joined",
|
presence: "joined",
|
||||||
});
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
response: WsOut,
|
response: WsOut,
|
||||||
@@ -139,6 +144,10 @@ const api = new Elysia({ prefix: "/api" })
|
|||||||
presence: "left",
|
presence: "left",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// error(err) {
|
||||||
|
// console.error("ERROR IN WEBSOCKET", JSON.stringify(err, null, 2));
|
||||||
|
// },
|
||||||
});
|
});
|
||||||
|
|
||||||
export default api;
|
export default api;
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ const app = new Elysia()
|
|||||||
origin: ["http://localhost:3000", "https://games.drm.dev"],
|
origin: ["http://localhost:3000", "https://games.drm.dev"],
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.onRequest(({ request }) => {
|
// .onRequest(({ request }) => {
|
||||||
console.log(request.method, request.url);
|
// console.log(request.method, request.url);
|
||||||
})
|
// })
|
||||||
.onError(({ error }) => {
|
.onError(({ error }) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return error;
|
return error;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { transform } from "./kefir-extension";
|
|||||||
|
|
||||||
export const WsOut = t.Object({
|
export const WsOut = t.Object({
|
||||||
players: t.Optional(t.Array(t.String())),
|
players: t.Optional(t.Array(t.String())),
|
||||||
playersReady: t.Optional(t.Record(t.String(), t.String())),
|
playersReady: t.Optional(t.Record(t.String(), t.Boolean())),
|
||||||
view: t.Optional(t.Any()),
|
view: t.Optional(t.Any()),
|
||||||
});
|
});
|
||||||
export type TWsOut = typeof WsOut.static;
|
export type TWsOut = typeof WsOut.static;
|
||||||
@@ -60,7 +60,6 @@ export const liveTable = <GameConfig, GameState, GameAction>(key: string) => {
|
|||||||
quits: Bus(),
|
quits: Bus(),
|
||||||
};
|
};
|
||||||
const { connectionChanges, readys, actions, quits } = inputs;
|
const { connectionChanges, readys, actions, quits } = inputs;
|
||||||
|
|
||||||
// =======
|
// =======
|
||||||
|
|
||||||
const playersPresent = connectionChanges
|
const playersPresent = connectionChanges
|
||||||
@@ -97,7 +96,11 @@ export const liveTable = <GameConfig, GameState, GameAction>(key: string) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const gameStarts = playersReady
|
const gameStarts = playersReady
|
||||||
.filter((pr) => Object.values(pr).every((ready) => ready))
|
.filter(
|
||||||
|
(pr) =>
|
||||||
|
Object.values(pr).length > 0 &&
|
||||||
|
Object.values(pr).every((ready) => ready)
|
||||||
|
)
|
||||||
.map((_) => null);
|
.map((_) => null);
|
||||||
|
|
||||||
const gameConfig = playersPresent.map((players) => ({
|
const gameConfig = playersPresent.map((players) => ({
|
||||||
@@ -147,9 +150,11 @@ export const liveTable = <GameConfig, GameState, GameAction>(key: string) => {
|
|||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
tables[key].outputs.playersPresent
|
tables[key].outputs.playersPresent
|
||||||
.debounce(30000)
|
.debounce(30000, { immediate: false })
|
||||||
.filter((players) => players.length === 0)
|
.filter((players) => players.length === 0)
|
||||||
|
.skip(1)
|
||||||
.onValue((_) => {
|
.onValue((_) => {
|
||||||
|
console.log("DELETING LIVE TABLE");
|
||||||
delete tables[key];
|
delete tables[key];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user