diff --git a/Taskfile.yml b/Taskfile.yml index e8e2240..ab27475 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -3,7 +3,6 @@ version: "3" vars: - GREETING: Hello, World! PARENT_BRANCH: main tasks: @@ -14,6 +13,12 @@ tasks: cmds: - vitest src + test:update: + deps: + - histoire:build + cmds: + - vitest run -u src + check: deps: - histoire:build diff --git a/src/lib/components/ShipEdit.svelte b/src/lib/components/ShipEdit.svelte index ada6960..f221b9f 100644 --- a/src/lib/components/ShipEdit.svelte +++ b/src/lib/components/ShipEdit.svelte @@ -3,17 +3,23 @@ +{#if identification.isCarrier} + +{/if} + diff --git a/src/lib/components/ShipEdit/Identification.story.svelte b/src/lib/components/ShipEdit/Identification.story.svelte index d0bbadc..b9e441b 100644 --- a/src/lib/components/ShipEdit/Identification.story.svelte +++ b/src/lib/components/ShipEdit/Identification.story.svelte @@ -8,10 +8,18 @@ mass: 13, usedMass: 9, }} + {api} /> diff --git a/src/lib/components/ShipEdit/Identification.svelte b/src/lib/components/ShipEdit/Identification.svelte index 6381b18..5ca8fbf 100644 --- a/src/lib/components/ShipEdit/Identification.svelte +++ b/src/lib/components/ShipEdit/Identification.svelte @@ -10,6 +10,14 @@ arrow_drop_down + @@ -26,6 +34,8 @@ export let isCarrier = false; export let reqs = {}; + $: console.log("in the comp", isCarrier, shipClass); + export let api = getContext("api"); $: shipTypes = candidateShipTypes(reqs.mass, isCarrier).map( @@ -36,6 +46,8 @@ shipType = shipTypes[0]; $: api?.dispatch?.updateIdentification?.({ shipType, shipClass }); + + $: api?.dispatch.setCarrier?.(isCarrier); diff --git a/src/lib/components/ShipEdit/Identification.test.js b/src/lib/components/ShipEdit/Identification.test.js new file mode 100644 index 0000000..9b8963e --- /dev/null +++ b/src/lib/components/ShipEdit/Identification.test.js @@ -0,0 +1,10 @@ +import { render, fireEvent } from "@testing-library/svelte"; +import "@testing-library/jest-dom"; +import { tick } from "svelte"; + +import Identification from "./Identification.svelte"; + +test("carrier", () => { + const { getByText } = render(Identification); + expect(getByText("carrier")).toBeInTheDocument(); +}); diff --git a/src/lib/components/ShipEdit/Propulsion.story.svelte b/src/lib/components/ShipEdit/Propulsion.story.svelte index be414b8..a89dbde 100644 --- a/src/lib/components/ShipEdit/Propulsion.story.svelte +++ b/src/lib/components/ShipEdit/Propulsion.story.svelte @@ -1,8 +1,9 @@ - + diff --git a/src/lib/components/ShipEdit/index.svelte b/src/lib/components/ShipEdit/index.svelte index 366fb15..16b2f97 100644 --- a/src/lib/components/ShipEdit/index.svelte +++ b/src/lib/components/ShipEdit/index.svelte @@ -1,44 +1,46 @@
-
+
-
+
- + - + - + - -
+ {#if $shipState.identification.isCarrier} + + {/if} + diff --git a/src/lib/store/__snapshots__/ship.test.ts.snap b/src/lib/store/__snapshots__/ship.test.ts.snap index 6be9769..4f447f0 100644 --- a/src/lib/store/__snapshots__/ship.test.ts.snap +++ b/src/lib/store/__snapshots__/ship.test.ts.snap @@ -53,6 +53,14 @@ exports[`state has the expected shape 1`] = ` }, "space": 0, }, + "carrier": { + "nbrBays": 0, + "reqs": { + "cost": 0, + "mass": 0, + }, + "squadrons": [], + }, "hull": { "max": 0, "min": 0, diff --git a/src/lib/store/api.ts b/src/lib/store/api.ts index a90e647..ff43570 100644 --- a/src/lib/store/api.ts +++ b/src/lib/store/api.ts @@ -8,10 +8,15 @@ export const createApi = () => { ? JSON.parse(localStorage.getItem("ship") || "null") : undefined; - const api = ship.createStore(state || undefined); + const api = ship.createStore({ + preloadedState: state, + }); + + api.dispatch.restore(state); if (browser) { api.subscribe(() => { + console.log("saving...", api.getState()); localStorage.setItem("ship", JSON.stringify(api.getState())); }); } diff --git a/src/lib/store/ship.test.ts b/src/lib/store/ship.test.ts index 56a1724..6bd041f 100644 --- a/src/lib/store/ship.test.ts +++ b/src/lib/store/ship.test.ts @@ -17,11 +17,13 @@ test("kicking the tires", () => { store.dispatch.setNbrCarrierBays(2); expect(store.getState().carrier.nbrBays).toEqual(2); + expect(store.getState.isCarrier()).toBe(false); + + store.dispatch.setCarrier(true); store.dispatch.setSquadronType(2, "fast"); - expect(store.getState().carrier.squadrons[1]).toHaveProperty("type", "fast"); - expect(store.getState.isCarrier()).toBe(true); + expect(store.getState().carrier.squadrons[1]).toHaveProperty("type", "fast"); store.dispatch.setStreamlining("partial"); diff --git a/src/lib/store/ship.ts b/src/lib/store/ship.ts index b177bf8..969f5cb 100644 --- a/src/lib/store/ship.ts +++ b/src/lib/store/ship.ts @@ -1,5 +1,5 @@ import { createSelector } from "@reduxjs/toolkit"; -import Updux from "updux"; +import Updux, { createPayloadAction } from "updux"; import * as R from "remeda"; import memoize from "memoize-one"; @@ -30,6 +30,7 @@ const structure = new Updux({ hull: hullDux, screens: screensDux, armor: armorDux, + carrier: carrierDux, }, }); @@ -50,7 +51,12 @@ const weaponry = new Updux({ }, }); +const restore = createPayloadAction("restore"); + const shipDux = new Updux({ + actions: { + restore, + }, initialState: { schemaVersion: "1", }, @@ -63,6 +69,8 @@ const shipDux = new Updux({ }, }); +shipDux.addMutation(restore, (state) => () => state); + shipDux.addReaction((api) => { return createSelector( api.selectors.getFtlType, diff --git a/src/lib/store/ship/carrier.ts b/src/lib/store/ship/carrier.ts index 7426fd1..2a1cdf6 100644 --- a/src/lib/store/ship/carrier.ts +++ b/src/lib/store/ship/carrier.ts @@ -3,116 +3,89 @@ import u from "@yanick/updeep-remeda"; import { reqs, type Reqs } from "$lib/shipDux/reqs"; type Squadron = { - type: string; - reqs: Reqs; + type: string; + reqs: Reqs; }; const initialState = { - nbrBays: 0, - squadrons: [] as Squadron[], - reqs, + nbrBays: 0, + squadrons: [] as Squadron[], + reqs, }; export const squadronTypes = [ - { type: "standard", cost: 3 }, - { type: "fast", cost: 4 }, - { type: "heavy", cost: 5 }, - { type: "interceptor", cost: 3 }, - { type: "attack", cost: 4 }, - { type: "long range", cost: 4 }, - { type: "torpedo", cost: 6 }, + { type: "standard", cost: 3 }, + { type: "fast", cost: 4 }, + { type: "heavy", cost: 5 }, + { type: "interceptor", cost: 3 }, + { type: "attack", cost: 4 }, + { type: "long range", cost: 4 }, + { type: "torpedo", cost: 6 }, ]; const setNbrCarrierBays = createPayloadAction("setNbrCarrierBays"); const setSquadronType = createPayloadAction( - "setSquadronType", - (id: number, type: string) => ({ id, type }) + "setSquadronType", + (id: number, type: string) => ({ id, type }) ); export const carrierDux = new Updux({ - initialState, - actions: { setNbrCarrierBays, setSquadronType }, + initialState, + actions: { setNbrCarrierBays, setSquadronType }, }); function calcBaysReqs(bays) { - return { - mass: 9 * bays, - cost: 18 * bays, - }; + return { + mass: 9 * bays, + cost: 18 * bays, + }; } const adjustSquadrons = (bays: number) => (squadrons) => { - if (squadrons.length === bays) return squadrons; + if (squadrons.length === bays) return squadrons; - if (squadrons.length > bays) { - return squadrons.slice(0, bays); - } + if (squadrons.length > bays) { + return squadrons.slice(0, bays); + } - return [ - ...squadrons, - ...Array.from({ length: bays - squadrons.length }) - .fill({ - type: squadronTypes[0].type, - reqs: { - cost: 6 * squadronTypes[0].cost, - mass: 6, - }, - }) - .map((s, i) => ({ ...s, id: squadrons.length + i + 1 })), - ]; + return [ + ...squadrons, + ...Array.from({ length: bays - squadrons.length }) + .fill({ + type: squadronTypes[0].type, + reqs: { + cost: 6 * squadronTypes[0].cost, + mass: 6, + }, + }) + .map((s, i) => ({ ...s, id: squadrons.length + i + 1 })), + ]; }; carrierDux.addMutation(setNbrCarrierBays, (nbrBays) => - u({ - nbrBays, - reqs: calcBaysReqs(nbrBays), - squadrons: adjustSquadrons(nbrBays), - }) + u({ + nbrBays, + reqs: calcBaysReqs(nbrBays), + squadrons: adjustSquadrons(nbrBays), + }) ); carrierDux.addMutation(setSquadronType, ({ id, type }) => { - return u({ - squadrons: u.map( - u.if(u.matches({ id }), (state) => { - return u(state, { - type, - reqs: squadronReqs(type), - }); - }) - ), - }); + return u({ + squadrons: u.map( + u.if(u.matches({ id }), (state) => { + return u(state, { + type, + reqs: squadronReqs(type), + }); + }) + ), + }); }); function squadronReqs(type: string) { - return { - mass: 6, - cost: 6 * squadronTypes.find((s) => s.type === type)?.cost, - }; + return { + mass: 6, + cost: 6 * squadronTypes.find((s) => s.type === type)?.cost, + }; } - -/* -export const { actions, reducer } = createSlice({ - name: "carrier", - initialStateState, - reducers: { - setCarrierBays: (state, action: PayloadAction) => { - state.bays = action.payload; - state.reqs = calcBaysReqs(action.payload); - state.squadrons = adjustSquadrons(action.payload)(state.squadrons); - }, - setSquadronType: ( - state, - action: PayloadAction<{ type: string; id: number }> - ) => { - state.squadrons[action.payload.id - 1] = { - type: action.payload.type, - reqs: squadronReqs(action.payload.type), - }; - }, - }, -}); - - - - -*/ diff --git a/src/lib/store/ship/identification.ts b/src/lib/store/ship/identification.ts index 272dde7..bdb65f0 100644 --- a/src/lib/store/ship/identification.ts +++ b/src/lib/store/ship/identification.ts @@ -1,6 +1,5 @@ import Updux, { createAction, withPayload } from "updux"; import u from "@yanick/updeep-remeda"; -import * as R from "remeda"; import { carrierDux } from "./carrier"; const initialState = { @@ -17,6 +16,7 @@ const initialState = { const setShipClass = createAction("setShipClass", withPayload()); const updateIdentification = createAction("updateIdentification"); const setShipReqs = createAction("setShipReqs", withPayload()); +const setCarrier = createAction("setCarrier", withPayload()); export const identificationDux = new Updux({ initialState, @@ -24,6 +24,7 @@ export const identificationDux = new Updux({ setShipClass, updateIdentification, setShipReqs, + setCarrier, }, selectors: { getShipMass: (state) => state.reqs.mass, @@ -33,12 +34,15 @@ export const identificationDux = new Updux({ identificationDux.addMutation(setShipClass, (shipClass) => u({ shipClass })); identificationDux.addMutation(updateIdentification, (update) => u(update)); + +identificationDux.addMutation(setCarrier, (isCarrier) => u({ isCarrier })); +identificationDux.addEffect(setCarrier, (api) => (next) => (action) => { + next(action); + if (!action.payload) { + api.dispatch(carrierDux.actions.setNbrCarrierBays(0)); + } +}); + identificationDux.addMutation(setShipReqs, (reqs) => u({ reqs })); -identificationDux.addMutation(carrierDux.actions.setNbrCarrierBays, (nbrBays) => - u({ - isCarrier: nbrBays > 0, - }) -); - export default identificationDux; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 5e8a0f9..212dbf0 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,4 +1,6 @@ - +{#if ship} + +{/if}