From e78c755799cf29195292086d31204681fe59abac Mon Sep 17 00:00:00 2001 From: cannorin Date: Sat, 22 Feb 2025 13:11:22 +0900 Subject: [PATCH] kripke: add history --- apps/web/src/lib/global.d.ts | 4 -- apps/web/src/routes/kripke/+page.svelte | 2 +- .../kripke/components/formula-input.svelte | 16 ++++++ apps/web/src/routes/kripke/lib/multiset.ts | 54 +++++++++++++++++++ apps/web/src/routes/kripke/lib/store.ts | 37 +++++++++++++ apps/web/src/routes/kripke/store.ts | 24 --------- 6 files changed, 108 insertions(+), 29 deletions(-) create mode 100644 apps/web/src/routes/kripke/lib/multiset.ts create mode 100644 apps/web/src/routes/kripke/lib/store.ts delete mode 100644 apps/web/src/routes/kripke/store.ts diff --git a/apps/web/src/lib/global.d.ts b/apps/web/src/lib/global.d.ts index a2ccae6..4a6eec7 100644 --- a/apps/web/src/lib/global.d.ts +++ b/apps/web/src/lib/global.d.ts @@ -40,10 +40,6 @@ interface ReadonlyArray { ): searchElement is T extends LiteralUnionLike ? T : never; } -interface Map { - has(key: Weaken): key is K; -} - declare module "*&enhanced" { import type { Picture } from "vite-imagetools"; diff --git a/apps/web/src/routes/kripke/+page.svelte b/apps/web/src/routes/kripke/+page.svelte index 6b98785..d34ef00 100644 --- a/apps/web/src/routes/kripke/+page.svelte +++ b/apps/web/src/routes/kripke/+page.svelte @@ -11,8 +11,8 @@ import Game, { type GameStatus } from "./components/game.svelte"; import Rules from "./components/rules.svelte"; import Share from "./components/share.svelte"; +import { daily } from "./lib/store"; import { getFrameBySeed, getTimeUntilNextGame } from "./lib/system"; -import { daily } from "./store"; let { data } = $props(); const seed = data.seed; diff --git a/apps/web/src/routes/kripke/components/formula-input.svelte b/apps/web/src/routes/kripke/components/formula-input.svelte index 3431dc9..a4bd056 100644 --- a/apps/web/src/routes/kripke/components/formula-input.svelte +++ b/apps/web/src/routes/kripke/components/formula-input.svelte @@ -1,5 +1,6 @@ +{#if history.length > 0} + + {#each history as fml} + + {/each} + +{/if} + extends Map { + constructor(iterable?: Iterable) { + super(); + if (iterable) { + for (const [item, count] of iterable) { + this.add(item, count); + } + } + } + + /** + * Adds the specified item to the multiset. + * If the item already exists, its count is incremented. + * + * @param item The element to add. + * @param count The number of times to add the element (default is 1). + * @returns The current instance for chaining. + */ + add(item: T, count = 1): this { + const currentCount = this.get(item) ?? 0; + this.set(item, currentCount + count); + return this; + } + + /** + * Removes one or more instances of the specified item. + * + * @param item The element to remove. + * @param count The number of times to remove the element (default is 1). + * @returns True if the element was present, false otherwise. + */ + remove(item: T, count = 1): boolean { + const currentCount = this.get(item); + if (currentCount === undefined) { + return false; + } + if (currentCount <= count) { + this.delete(item); + } else { + this.set(item, currentCount - count); + } + return true; + } + + /** + * Retrieves the count of the specified item. + * + * @param item The element whose count is to be retrieved. + * @returns The number of occurrences of the element. + */ + count(item: T): number { + return this.get(item) ?? 0; + } +} diff --git a/apps/web/src/routes/kripke/lib/store.ts b/apps/web/src/routes/kripke/lib/store.ts new file mode 100644 index 0000000..a6d72d5 --- /dev/null +++ b/apps/web/src/routes/kripke/lib/store.ts @@ -0,0 +1,37 @@ +import { persisted } from "svelte-persisted-store"; +import type { Move } from "../components/game.svelte"; +import { MultiSet } from "./multiset"; +import { date } from "./system"; + +export type Daily = { + date: string; + moves: Move[]; +}; + +export const daily = persisted( + "daily", + { + date: date(), + moves: [], + }, + { + syncTabs: true, + storage: "local", + beforeRead: (value) => { + if (value.date !== date()) return { date: date(), moves: [] }; + return value; + }, + }, +); + +export type FormulaHistory = MultiSet; + +export const formulaHistory = persisted< + FormulaHistory, + readonly [string, number][] +>("formula-history", new MultiSet(), { + syncTabs: true, + storage: "local", + beforeWrite: (val) => [...val], + beforeRead: (val) => new MultiSet(val), +}); diff --git a/apps/web/src/routes/kripke/store.ts b/apps/web/src/routes/kripke/store.ts deleted file mode 100644 index 8e96417..0000000 --- a/apps/web/src/routes/kripke/store.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { persisted } from "svelte-persisted-store"; -import type { Move } from "./components/game.svelte"; -import { date } from "./lib/system"; - -export type Daily = { - date: string; - moves: Move[]; -}; - -export const daily = persisted( - "daily", - { - date: date(), - moves: [], - }, - { - syncTabs: true, - storage: "local", - beforeRead: (value) => { - if (value.date !== date()) return { date: date(), moves: [] }; - return value; - }, - }, -);