feat: use cloudflare kv
This commit is contained in:
parent
8ae9355ec9
commit
c2e36adc6a
8 changed files with 35 additions and 13 deletions
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
|
@ -16,6 +16,7 @@
|
||||||
"leaflet-defaulticon-compatibility": "^0.1.2"
|
"leaflet-defaulticon-compatibility": "^0.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@cloudflare/workers-types": "^4.20241022.0",
|
||||||
"@sveltejs/adapter-cloudflare": "^4.7.4",
|
"@sveltejs/adapter-cloudflare": "^4.7.4",
|
||||||
"@sveltejs/kit": "^2.7.3",
|
"@sveltejs/kit": "^2.7.3",
|
||||||
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
||||||
|
|
6
src/app.d.ts
vendored
6
src/app.d.ts
vendored
|
@ -6,7 +6,11 @@ declare global {
|
||||||
// interface Locals {}
|
// interface Locals {}
|
||||||
// interface PageData {}
|
// interface PageData {}
|
||||||
// interface PageState {}
|
// interface PageState {}
|
||||||
// interface Platform {}
|
interface Platform {
|
||||||
|
env?: {
|
||||||
|
TCL_GUESSR_KV: KVNamespace;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,17 +35,22 @@ let lazyMetro: [GeoJSON.Feature, string][] | null = null;
|
||||||
let lazyTram: [GeoJSON.Feature, string][] | null = null;
|
let lazyTram: [GeoJSON.Feature, string][] | null = null;
|
||||||
let lazyStops: GeoJSON.Feature[] | null = null;
|
let lazyStops: GeoJSON.Feature[] | null = null;
|
||||||
|
|
||||||
const games: Record<string, GeoJSON.Feature> = {};
|
export async function createGame(stop: GeoJSON.Feature, kv: KVNamespace<string>): Promise<string> {
|
||||||
|
|
||||||
export function createGame(stop: GeoJSON.Feature): string {
|
|
||||||
const uuid = crypto.randomUUID();
|
const uuid = crypto.randomUUID();
|
||||||
games[uuid] = stop;
|
|
||||||
|
await kv.put(`game:${uuid}`, JSON.stringify(stop), { expirationTtl: 600 });
|
||||||
|
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stopGame(uuid: string): GeoJSON.Feature | null {
|
export async function stopGame(
|
||||||
const stop = games[uuid];
|
uuid: string,
|
||||||
delete games[uuid];
|
kv: KVNamespace<string>,
|
||||||
|
): Promise<GeoJSON.Feature | null> {
|
||||||
|
const stop: GeoJSON.Feature | null = await kv.get(`game:${uuid}`, "json");
|
||||||
|
|
||||||
|
if (stop) await kv.delete(`game:${uuid}`);
|
||||||
|
|
||||||
return stop;
|
return stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
import { stopGame, type CheckData, type CheckResponse } from "$lib";
|
import { stopGame, type CheckData, type CheckResponse } from "$lib";
|
||||||
|
import { error } from "@sveltejs/kit";
|
||||||
import type { RequestHandler } from "./$types";
|
import type { RequestHandler } from "./$types";
|
||||||
|
|
||||||
export const POST: RequestHandler = async ({ request }) => {
|
export const POST: RequestHandler = async ({ request, platform }) => {
|
||||||
|
const kv = platform?.env?.TCL_GUESSR_KV;
|
||||||
|
if (!kv) return error(500, "could not connect to kv");
|
||||||
|
|
||||||
const data: CheckData = await request.json();
|
const data: CheckData = await request.json();
|
||||||
const stop = stopGame(data.gameId);
|
const stop = await stopGame(data.gameId, kv);
|
||||||
|
|
||||||
if (stop) {
|
if (stop) {
|
||||||
// GeoJSON data is LonLat, not LatLon
|
// GeoJSON data is LonLat, not LatLon
|
||||||
|
|
|
@ -2,7 +2,10 @@ import type { PageServerLoad } from "./$types";
|
||||||
import { createGame, getMetro, getStops, getTram, type GameData, type GameOptions } from "$lib";
|
import { createGame, getMetro, getStops, getTram, type GameData, type GameOptions } from "$lib";
|
||||||
import { error } from "@sveltejs/kit";
|
import { error } from "@sveltejs/kit";
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ fetch, url }) => {
|
export const load: PageServerLoad = async ({ fetch, url, platform }) => {
|
||||||
|
const kv = platform?.env?.TCL_GUESSR_KV;
|
||||||
|
if (!kv) return error(500, "could not connect to kv");
|
||||||
|
|
||||||
const stops = await getStops(fetch);
|
const stops = await getStops(fetch);
|
||||||
|
|
||||||
const mode = url.searchParams.get("mode");
|
const mode = url.searchParams.get("mode");
|
||||||
|
@ -40,7 +43,7 @@ export const load: PageServerLoad = async ({ fetch, url }) => {
|
||||||
return error(400, "could not select random stop");
|
return error(400, "could not select random stop");
|
||||||
}
|
}
|
||||||
|
|
||||||
const gameId = createGame(randomStop);
|
const gameId = await createGame(randomStop, kv);
|
||||||
const gameData: GameData = {
|
const gameData: GameData = {
|
||||||
lines: options.mode === "easy" || options.mode === "hard" ? lineColors : [],
|
lines: options.mode === "easy" || options.mode === "hard" ? lineColors : [],
|
||||||
stops: options.mode === "easy" ? crossingStops : [],
|
stops: options.mode === "easy" ? crossingStops : [],
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"moduleResolution": "bundler"
|
"moduleResolution": "bundler",
|
||||||
|
"types": ["@cloudflare/workers-types"]
|
||||||
}
|
}
|
||||||
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
|
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
|
||||||
// except $lib which is handled by https://kit.svelte.dev/docs/configuration#files
|
// except $lib which is handled by https://kit.svelte.dev/docs/configuration#files
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
name = "tcl-guessr"
|
name = "tcl-guessr"
|
||||||
compatibility_date = "2024-09-25"
|
compatibility_date = "2024-09-25"
|
||||||
pages_build_output_dir = ".svelte-kit/cloudflare"
|
pages_build_output_dir = ".svelte-kit/cloudflare"
|
||||||
|
|
||||||
|
[[kv_namespaces]]
|
||||||
|
binding = "TCL_GUESSR_KV"
|
||||||
|
id = "b2d8980ac3a74a80854c35bf9569dbf8"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue