cooking with sqlite
This commit is contained in:
2
Makefile
2
Makefile
@@ -10,4 +10,4 @@ build:
|
|||||||
|
|
||||||
|
|
||||||
start:
|
start:
|
||||||
sudo docker run -p $(PORT):3000 -t games
|
sudo docker run -p $(PORT):3000 -p 5555:5555 -t games
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
../sources/Card_back_01.svg
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../sources/Vector-Cards-Version-3.2/FACES (BORDERED)/STANDARD BORDERED/Single Cards (One Per FIle)/
|
|
||||||
@@ -3,10 +3,11 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.0.2",
|
"version": "0.0.2",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "concurrently 'vinxi dev' 'pnpm dlx prisma studio --browser none'",
|
"dev": "concurrently 'vinxi dev' 'pnpm run dbstudio'",
|
||||||
"build": "vinxi build",
|
"build": "vinxi build",
|
||||||
"start": "vinxi start",
|
"start": "concurrently 'vinxi start' 'pnpm run dbstudio'",
|
||||||
"sync_db": "concurrently 'pnpm dlx prisma generate' 'pnpm dlx prisma migrate dev'"
|
"dbstudio": "pnpm dlx prisma studio --browser none",
|
||||||
|
"dbsync": "concurrently 'pnpm dlx prisma generate' 'pnpm dlx prisma migrate dev'"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "6.13.0",
|
"@prisma/client": "6.13.0",
|
||||||
|
|||||||
1
public/views/back.svg
Symbolic link
1
public/views/back.svg
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../assets/sources/Card_back_01.svg
|
||||||
1
public/views/cards
Symbolic link
1
public/views/cards
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../assets/sources/Vector-Cards-Version-3.2/FACES (BORDERED)/STANDARD BORDERED/Single Cards (One Per FIle)/
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Component, createResource, JSX, Suspense } from "solid-js";
|
import { Component, createResource, JSX, Suspense } from "solid-js";
|
||||||
import { Card } from "../types/cards";
|
import { Card, newDeck } from "../types/cards";
|
||||||
import { Clickable, Stylable } from "./toolbox";
|
import { Clickable, Stylable } from "./toolbox";
|
||||||
|
|
||||||
const cardToSvgFilename = (card: Card) => {
|
const cardToSvgFilename = (card: Card) => {
|
||||||
@@ -17,17 +17,6 @@ const cardToSvgFilename = (card: Card) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default ((props) => {
|
export default ((props) => {
|
||||||
const [svgPath] = createResource(() =>
|
|
||||||
props.face == "down"
|
|
||||||
? // @ts-ignore
|
|
||||||
import("~/../assets/views/back.svg")
|
|
||||||
: import(
|
|
||||||
`~/../assets/views/cards/${cardToSvgFilename(
|
|
||||||
props.card
|
|
||||||
)}.svg`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<img
|
<img
|
||||||
@@ -39,7 +28,11 @@ export default ((props) => {
|
|||||||
...props.style,
|
...props.style,
|
||||||
}}
|
}}
|
||||||
width="100px"
|
width="100px"
|
||||||
src={svgPath()?.default}
|
src={
|
||||||
|
props.face == "down"
|
||||||
|
? "/views/back.svg"
|
||||||
|
: `/views/cards/${cardToSvgFilename(props.card)}.svg`
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,22 +1,33 @@
|
|||||||
import { createContext, JSX } from "solid-js";
|
import {
|
||||||
|
Accessor,
|
||||||
|
createContext,
|
||||||
|
createResource,
|
||||||
|
JSX,
|
||||||
|
Show,
|
||||||
|
Suspense,
|
||||||
|
} from "solid-js";
|
||||||
import Card from "./Card";
|
import Card from "./Card";
|
||||||
import Hand from "./Hand";
|
import Hand from "./Hand";
|
||||||
import Pile from "./Pile";
|
import Pile from "./Pile";
|
||||||
import { GameState, newDeck, shuffle, Hand as THand } from "../types/cards";
|
import { GameState, newDeck, shuffle, Hand as THand } from "../types/cards";
|
||||||
import { createStore, produce, SetStoreFunction, Store } from "solid-js/store";
|
import { createStore, produce, SetStoreFunction, Store } from "solid-js/store";
|
||||||
|
import { getGameState, updateGameState } from "../db/Instances";
|
||||||
|
|
||||||
export const GameContext = createContext<{
|
export const GameContext = createContext<{
|
||||||
gameState: Store<GameState>;
|
gameState: Accessor<GameState | undefined>;
|
||||||
setGameState: SetStoreFunction<GameState>;
|
setGameState: (state: GameState) => Promise<any>;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
export default (props: { initialState: GameState }) => {
|
export default (props: { instanceId: number }) => {
|
||||||
const [gameState, setGameState] = createStore<GameState>(
|
const [gameState, { refetch }] = createResource(() =>
|
||||||
props.initialState
|
getGameState(props.instanceId)
|
||||||
);
|
);
|
||||||
|
const setGameState = (state: GameState) =>
|
||||||
|
updateGameState(props.instanceId, state).then(refetch);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GameContext.Provider value={{ gameState, setGameState }}>
|
<GameContext.Provider value={{ gameState, setGameState }}>
|
||||||
|
<Show when={gameState() != undefined}>
|
||||||
<div
|
<div
|
||||||
onClick={() => {}}
|
onClick={() => {}}
|
||||||
class="full column center"
|
class="full column center"
|
||||||
@@ -24,19 +35,20 @@ export default (props: { initialState: GameState }) => {
|
|||||||
>
|
>
|
||||||
<div class="full center">
|
<div class="full center">
|
||||||
<Pile
|
<Pile
|
||||||
pile={gameState.deck}
|
pile={gameState()!.deck}
|
||||||
style={{ cursor: "pointer" }}
|
style={{ cursor: "pointer" }}
|
||||||
onClick={() =>
|
onClick={() => {
|
||||||
setGameState(
|
const [drawn, ...rest] = gameState()!.deck;
|
||||||
produce((state) => {
|
setGameState({
|
||||||
state.hand.push(state.deck.pop()!);
|
deck: rest,
|
||||||
})
|
hand: [drawn, ...gameState()!.hand],
|
||||||
)
|
});
|
||||||
}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Hand hand={gameState.hand} />
|
<Hand hand={gameState()!.hand} />
|
||||||
</div>
|
</div>
|
||||||
|
</Show>
|
||||||
</GameContext.Provider>
|
</GameContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { GameContext } from "./Game";
|
|||||||
import { produce } from "solid-js/store";
|
import { produce } from "solid-js/store";
|
||||||
|
|
||||||
export default ((props) => {
|
export default ((props) => {
|
||||||
const { setGameState } = useContext(GameContext)!;
|
const { setGameState, gameState } = useContext(GameContext)!;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -33,20 +33,16 @@ export default ((props) => {
|
|||||||
style={{
|
style={{
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
}}
|
}}
|
||||||
onClick={() =>
|
onClick={() => {
|
||||||
setGameState(
|
const index = gameState()!.hand.indexOf(card);
|
||||||
produce((state) => {
|
setGameState({
|
||||||
const index = state.hand.indexOf(card);
|
deck: [card, ...gameState()!.deck],
|
||||||
console.log(index);
|
hand: [
|
||||||
state.deck.push(
|
...gameState()!.hand.slice(0, index),
|
||||||
state.hand.splice(
|
...gameState()!.hand.slice(index + 1),
|
||||||
props.hand.indexOf(card),
|
],
|
||||||
1
|
});
|
||||||
)[0]!
|
}}
|
||||||
);
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
|
|||||||
@@ -1,6 +1,25 @@
|
|||||||
"use server";
|
"use server";
|
||||||
|
|
||||||
|
import { GameState, newDeck, shuffle } from "../types/cards";
|
||||||
import { prisma } from "./db";
|
import { prisma } from "./db";
|
||||||
|
|
||||||
export const queryInstances = async (gameName: string) =>
|
export const queryInstances = async (gameName: string) =>
|
||||||
await prisma.instance.findMany({ where: { game: { name: gameName } } });
|
prisma.instance.findMany({ where: { game: { name: gameName } } });
|
||||||
|
|
||||||
|
export const createInstance = (gameName: string) =>
|
||||||
|
prisma.instance.create({
|
||||||
|
data: {
|
||||||
|
gameState: { deck: shuffle(newDeck()), hand: [] } as GameState,
|
||||||
|
game: { connect: { name: gameName } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const getGameState = (instanceId: number) =>
|
||||||
|
prisma.instance
|
||||||
|
.findUnique({ where: { id: instanceId } })
|
||||||
|
.then((i) => i?.gameState as GameState | undefined);
|
||||||
|
|
||||||
|
export const updateGameState = async (
|
||||||
|
instanceId: number,
|
||||||
|
gameState: GameState
|
||||||
|
) => prisma.instance.update({ where: { id: instanceId }, data: { gameState } });
|
||||||
|
|||||||
@@ -1,19 +1,30 @@
|
|||||||
import { useParams } from "@solidjs/router";
|
import { A, useParams } from "@solidjs/router";
|
||||||
|
|
||||||
import { createEffect, createResource, Show, Suspense } from "solid-js";
|
import { createEffect, createResource, Show, Suspense } from "solid-js";
|
||||||
import Game from "../../components/Game";
|
import Game from "../../components/Game";
|
||||||
import { aql } from "arangojs";
|
import { getGameState } from "../../db/Instances";
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const params = useParams();
|
const params = useParams<{ game: string; instance: string }>();
|
||||||
|
|
||||||
const [instance] = createResource(async () => {
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Show when={instance() != null}>
|
<>
|
||||||
<Game state={instance()!} />
|
<Game instanceId={Number.parseInt(params.instance)} />
|
||||||
</Show>
|
<A
|
||||||
|
href={`/${params.game}`}
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
padding: "10px",
|
||||||
|
top: "0",
|
||||||
|
left: "0",
|
||||||
|
margin: "20px",
|
||||||
|
"background-color": "white",
|
||||||
|
"border-radius": "8px",
|
||||||
|
border: "2px solid black",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</A>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,26 +5,31 @@ import * as Instance from "../../db/Instances";
|
|||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const params = useParams<{ game: string }>();
|
const params = useParams<{ game: string }>();
|
||||||
createEffect(() => {
|
|
||||||
console.log(">>", params.game);
|
const [instances, { refetch }] = createResource(
|
||||||
});
|
|
||||||
const [instances] = createResource(
|
|
||||||
() => params.game,
|
() => params.game,
|
||||||
() => Instance.queryInstances(params.game)
|
() => Instance.queryInstances(params.game)
|
||||||
);
|
);
|
||||||
|
|
||||||
createEffect(() => console.log(instances()));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<div style={{ padding: "20px" }}>
|
<div style={{ padding: "20px" }}>
|
||||||
<h1 style={{ margin: 0 }}>{params.game}</h1>
|
<h1 style={{ margin: 0 }}>{params.game}</h1>
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
Instance.createInstance(params.game).then(refetch)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
New Game
|
||||||
|
</button>
|
||||||
<ul>
|
<ul>
|
||||||
<For each={instances() ?? []}>
|
<For each={instances() ?? []}>
|
||||||
{(instance) => (
|
{(instance) => (
|
||||||
<A href={`/${params.game}/${instance._id}`}>
|
<li>
|
||||||
{instance._id}
|
<A href={`/${params.game}/${instance.id}`}>
|
||||||
|
{instance.id}
|
||||||
</A>
|
</A>
|
||||||
|
</li>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { A } from "@solidjs/router";
|
import { A } from "@solidjs/router";
|
||||||
import { createResource, For } from "solid-js";
|
import { createResource, For } from "solid-js";
|
||||||
import * as Games from "../db/games";
|
import * as Games from "../db/Games";
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [games] = createResource(() => Games.queryAll());
|
const [games] = createResource(() => Games.queryAll());
|
||||||
|
|||||||
Reference in New Issue
Block a user