diff --git a/.storybook/main.js b/.storybook/main.js index 144e24b..1a51bb1 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -27,6 +27,7 @@ module.exports = { $app: path.resolve("./fake/app"), "\\$lib": path.resolve(__dirname, "../src/lib/"), $lib: path.resolve(__dirname, "../src/lib/"), + "\\$app/env": path.resolve(__dirname, "../fake/app/env.js"), }, }, }; diff --git a/fake/app/env.js b/fake/app/env.js new file mode 100644 index 0000000..43dac6b --- /dev/null +++ b/fake/app/env.js @@ -0,0 +1 @@ +export const browser = true; diff --git a/package.json b/package.json index 2a98b5d..e40e34c 100644 --- a/package.json +++ b/package.json @@ -35,14 +35,13 @@ "@storybook/addon-svelte-csf": "^1.1.0", "@storybook/svelte": "^6.4.19", "@sveltejs/adapter-node": "^1.0.0-next.0", - "@yanick/updeep": "link:/home/yanick/work/javascript/updeep", "lodash": "^4.17.21", "redux": "^4.1.2", "reselect": "^4.1.5", "rollup-plugin-analyzer": "^4.0.0", "svelte-knobby": "^0.3.4", "ts-action": "^11.0.0", - "updux": "link:/home/yanick/work/javascript/updux/", + "updux": "link:/home/yanick/work/javascript/updux-js/", "webpack": "5" }, "prettier": { diff --git a/src/dux/index.js b/src/dux/index.js index 3565298..204169d 100644 --- a/src/dux/index.js +++ b/src/dux/index.js @@ -5,15 +5,15 @@ import { createSelector } from "reselect"; import ftl from "./ftl"; import engine, { calc_drive_reqs } from "./engine"; -import weaponry from './weaponry'; +import weaponry from "./weaponry"; import { calc_ftl_reqs } from "./ftl/rules"; import { calc_ship_req } from "./utils"; -import { candidate_ship_types } from './ship_types'; -import structure from './structure'; -import cargo from './cargo'; -import streamlining from './streamlining'; -import carrier from './carrier'; -import { ceil } from './utils'; +import { candidate_ship_types } from "./ship_types"; +import structure from "./structure"; +import cargo from "./cargo"; +import streamlining from "./streamlining"; +import carrier from "./carrier"; +import { ceil } from "./utils"; const set_ship_mass = action("set_ship_mass", payload()); const set_name = action("set_name", payload()); @@ -21,31 +21,29 @@ const set_name = action("set_name", payload()); const set_ship_reqs = action("set_ship_reqs", payload()); const set_hull = action("set_hull", payload()); -const set_ship_type = action('set_ship_type',payload()); +const set_ship_type = action("set_ship_type", payload()); -const reset = action('reset' ); +const reset = action("reset"); const initial = { - general: { - ship_class: "", - name: "", - ship_type: "", - mass: 10, - used_mass: 0, - cost: 10, - }, - }; - -console.log(Updux); + general: { + ship_class: "", + name: "", + ship_type: "", + mass: 10, + used_mass: 0, + cost: 10, + }, +}; const dux = new Updux({ subduxes: { ftl, engine, weaponry, structure, cargo, streamlining, carrier }, - initial + initial, }); -dux.addMutation( reset, () => () => initial ); +dux.addMutation(reset, () => () => initial); -dux.addMutation(set_hull, ({rating}) => (state) => { +dux.addMutation(set_hull, ({ rating }) => (state) => { return u.updateIn("structure.hull", { cost: 2 * rating, rating, @@ -55,8 +53,8 @@ dux.addMutation(set_hull, ({rating}) => (state) => { dux.addMutation(set_ship_mass, (mass) => u.updateIn("general", { mass })); dux.addMutation(set_name, (name) => u.updateIn("general", { name })); -dux.addMutation( action('set_ship_class',payload() ), - ship_class => u.updateIn('general',{ship_class}) +dux.addMutation(action("set_ship_class", payload()), (ship_class) => + u.updateIn("general", { ship_class }) ); dux.addMutation(set_ship_reqs, ({ cost, mass: used_mass }) => @@ -70,71 +68,73 @@ dux.addSubscription((store) => dux.addSubscription((store) => createSelector( - store => store.general.mass, - store => store.streamlining.type, - (ship_mass, streamlining ) => { - const mass = ceil( ship_mass * ( - streamlining === 'none' ? 0 - : streamlining === 'partial' ? 5 : 10 - ) / 100 ); - const cost = 2 * mass; + (store) => store.general.mass, + (store) => store.streamlining.type, + (ship_mass, streamlining) => { + const mass = ceil( + (ship_mass * + (streamlining === "none" ? 0 : streamlining === "partial" ? 5 : 10)) / + 100 + ); + const cost = 2 * mass; - store.dispatch( dux.actions.set_streamlining_cost_mass({cost,mass}) ); - } + store.dispatch(dux.actions.set_streamlining_cost_mass({ cost, mass })); + } ) ); dux.addSubscription((store) => - createSelector( - store => store.general.mass, - store => store.general.ship_type, - store => store.carrier.bays, - (mass,type,bays) => { - console.log({bays}); - const candidates = candidate_ship_types(mass,bays > 0); + createSelector( + (store) => store.general.mass, + (store) => store.general.ship_type, + (store) => store.carrier.bays, + (mass, type, bays) => { + console.log({ bays }); + const candidates = candidate_ship_types(mass, bays > 0); - console.log({candidates}); - if( candidates.length === 0 ) return; + console.log({ candidates }); + if (candidates.length === 0) return; - if( candidates.find( ({name}) => name === type ) ) return; + if (candidates.find(({ name }) => name === type)) return; - store.dispatch( - store.actions.set_ship_type( - candidates[0].name - ) - ) - - } - ) + store.dispatch(store.actions.set_ship_type(candidates[0].name)); + } + ) ); -dux.addMutation(set_ship_type, type => u.updateIn('general.ship_type',type) ); +dux.addMutation(set_ship_type, (type) => u.updateIn("general.ship_type", type)); dux.addSubscription((store) => createSelector( [(ship) => ship.general.mass, (ship) => ship.ftl.type], (ship_mass, type) => - store.dispatch(ftl.actions.set_ftl_reqs(calc_ftl_reqs(type,ship_mass))) + store.dispatch(ftl.actions.set_ftl_reqs(calc_ftl_reqs(type, ship_mass))) ) ); -dux.addSubscription( store => createSelector( - ship => ship.general.mass, - ship => ship.structure.screens.standard, - ship => ship.structure.screens.advanced, - (mass,standard,advanced) => { - console.log({ - mass, standard, advanced - }) - const standard_mass = standard * Math.max(3,ceil( 0.05 * mass )); - const advanced_mass = advanced * Math.max(4,ceil( 0.075 * mass )); +dux.addSubscription((store) => + createSelector( + (ship) => ship.general.mass, + (ship) => ship.structure.screens.standard, + (ship) => ship.structure.screens.advanced, + (mass, standard, advanced) => { + console.log({ + mass, + standard, + advanced, + }); + const standard_mass = standard * Math.max(3, ceil(0.05 * mass)); + const advanced_mass = advanced * Math.max(4, ceil(0.075 * mass)); - store.dispatch( dux.actions.set_screens_reqs({ - mass: standard_mass + advanced_mass, - cost: 3 * standard_mass + 4 * advanced_mass - })); + store.dispatch( + dux.actions.set_screens_reqs({ + mass: standard_mass + advanced_mass, + cost: 3 * standard_mass + 4 * advanced_mass, + }) + ); } -)); + ) +); dux.addSubscription((store) => createSelector( diff --git a/src/lib/components/Field/index.svelte b/src/lib/components/Field/index.svelte index 71657d3..764bd93 100644 --- a/src/lib/components/Field/index.svelte +++ b/src/lib/components/Field/index.svelte @@ -3,7 +3,7 @@ {/if} - + diff --git a/src/lib/components/ShipEdit/Identification/Identification.stories.svelte b/src/lib/components/ShipEdit/Identification/Identification.stories.svelte new file mode 100644 index 0000000..67ecb68 --- /dev/null +++ b/src/lib/components/ShipEdit/Identification/Identification.stories.svelte @@ -0,0 +1,22 @@ + + + + + + + diff --git a/src/lib/components/ShipEdit/Identification/index.svelte b/src/lib/components/ShipEdit/Identification/index.svelte new file mode 100644 index 0000000..6d79133 --- /dev/null +++ b/src/lib/components/ShipEdit/Identification/index.svelte @@ -0,0 +1,40 @@ +
+ + + + +
+ + + + diff --git a/src/dux/ship_types.js b/src/lib/components/ShipEdit/Identification/shipTypes.js similarity index 84% rename from src/dux/ship_types.js rename to src/lib/components/ShipEdit/Identification/shipTypes.js index f37b43b..be32552 100644 --- a/src/dux/ship_types.js +++ b/src/lib/components/ShipEdit/Identification/shipTypes.js @@ -20,7 +20,9 @@ const ship_types = [ { name: "Attack Carrier", mass: [150, 300], abbrev: "CVA", carrier: true }, ]; -export function candidate_ship_types(mass = 0, carrier = false) { - console.log({carrier}); - return ship_types.filter((c) => carrier == !!c.carrier).filter((c) => c.mass[0] <= mass).filter((c) => c.mass[1] >= mass); +export function candidateShipTypes(mass = 0, carrier = false) { + return ship_types + .filter((c) => carrier == !!c.carrier) + .filter((c) => c.mass[0] <= mass) + .filter((c) => c.mass[1] >= mass); } diff --git a/src/lib/components/ShipEdit/ShipEdit.stories.svelte b/src/lib/components/ShipEdit/ShipEdit.stories.svelte new file mode 100644 index 0000000..c1e743b --- /dev/null +++ b/src/lib/components/ShipEdit/ShipEdit.stories.svelte @@ -0,0 +1,21 @@ + + + + + + + diff --git a/src/lib/components/ShipEdit/index.svelte b/src/lib/components/ShipEdit/index.svelte new file mode 100644 index 0000000..841b7c7 --- /dev/null +++ b/src/lib/components/ShipEdit/index.svelte @@ -0,0 +1,12 @@ + + + + + diff --git a/src/lib/components/ShipSpecs/Identification.svelte b/src/lib/components/ShipSpecs/Identification.svelte deleted file mode 100644 index 7180a1e..0000000 --- a/src/lib/components/ShipSpecs/Identification.svelte +++ /dev/null @@ -1,49 +0,0 @@ -
- - - - - -
- - - - diff --git a/src/lib/components/ShipSpecs/index.svelte b/src/lib/components/ShipSpecs/index.svelte index a564076..af4d310 100644 --- a/src/lib/components/ShipSpecs/index.svelte +++ b/src/lib/components/ShipSpecs/index.svelte @@ -6,9 +6,3 @@ import Identification from "./Identification.svelte"; import ShipCost from "./ShipCost.svelte"; - - diff --git a/src/lib/shipDux/engine.js b/src/lib/shipDux/engine.js new file mode 100644 index 0000000..d0d4d70 --- /dev/null +++ b/src/lib/shipDux/engine.js @@ -0,0 +1,28 @@ +import { Updux } from "updux"; +import u from "updeep"; + +import reqs from "./reqs.js"; + +const dux = new Updux({ + subduxes: { reqs }, + initial: { + rating: 1, + advanced: false, + }, + actions: { + setEngine: null, + setEngineReqs: null, + }, +}); + +dux.setMutation("setEngine", (changes) => u(changes)); +dux.setMutation("setEngineReqs", (reqs) => u({ reqs })); + +export function calcDriveReqs(shipMass, rating, advanced = false) { + const mass = Math.ceil(rating * 0.05 * shipMass); + const cost = mass * (advanced ? 3 : 2); + + return { mass, cost }; +} + +export default dux; diff --git a/src/lib/shipDux/identification.js b/src/lib/shipDux/identification.js new file mode 100644 index 0000000..50abc17 --- /dev/null +++ b/src/lib/shipDux/identification.js @@ -0,0 +1,20 @@ +import { Updux } from "updux"; +import u from "updeep"; + +const dux = new Updux({ + actions: { + setShipType: null, + setShipClass: null, + }, + initial: { + shipType: "", + shipClass: "", + isCarrier: false, + mass: 10, + }, +}); + +dux.setMutation("setShipType", (shipType) => u({ shipType })); +dux.setMutation("setShipClass", (shipClass) => u({ shipClass })); + +export default dux; diff --git a/src/lib/shipDux/index.js b/src/lib/shipDux/index.js new file mode 100644 index 0000000..755e3e9 --- /dev/null +++ b/src/lib/shipDux/index.js @@ -0,0 +1,17 @@ +import { Updux } from "updux"; + +import engine from "./engine.js"; +import identification from "./identification.js"; +import reqs from "./reqs.js"; + +const dux = new Updux({ + subduxes: { + identification, + engine, + }, + initial: { + reqs: { cost: 0, mass: 10 }, + }, +}); + +export default dux; diff --git a/src/lib/shipDux/reqs.js b/src/lib/shipDux/reqs.js new file mode 100644 index 0000000..62ea2dd --- /dev/null +++ b/src/lib/shipDux/reqs.js @@ -0,0 +1,10 @@ +import { Updux } from "updux"; + +const dux = new Updux({ + initial: { + cost: 0, + mass: 0, + }, +}); + +export default dux; diff --git a/src/lib/store/ship.js b/src/lib/store/ship.js new file mode 100644 index 0000000..dcfbe80 --- /dev/null +++ b/src/lib/store/ship.js @@ -0,0 +1,32 @@ +import { browser } from "$app/env"; +import { readable, get } from "svelte/store"; +import { compose, applyMiddleware } from "redux"; + +import shipDux from "../shipDux/index.js"; + +let composeEnhancers = compose; + +if (browser) { + composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__; +} + +export default () => { + const duxStore = shipDux.createStore(undefined, (mw) => + composeEnhancers(applyMiddleware(mw)) + ); + + let previous; + const state = readable(duxStore.getState(), (set) => { + duxStore.subscribe(() => { + if (previous === duxStore.getState()) return; + previous = duxStore.getState(); + console.log("Setting!", previous); + set(previous); + }); + }); + + return { + dispatch: duxStore.dispatch, + state, + }; +};