Merge branch 'identification' into version-2
This commit is contained in:
commit
0a0b78336d
@ -27,6 +27,7 @@ module.exports = {
|
|||||||
$app: path.resolve("./fake/app"),
|
$app: path.resolve("./fake/app"),
|
||||||
"\\$lib": path.resolve(__dirname, "../src/lib/"),
|
"\\$lib": path.resolve(__dirname, "../src/lib/"),
|
||||||
$lib: path.resolve(__dirname, "../src/lib/"),
|
$lib: path.resolve(__dirname, "../src/lib/"),
|
||||||
|
"\\$app/env": path.resolve(__dirname, "../fake/app/env.js"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
1
fake/app/env.js
Normal file
1
fake/app/env.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const browser = true;
|
@ -35,14 +35,13 @@
|
|||||||
"@storybook/addon-svelte-csf": "^1.1.0",
|
"@storybook/addon-svelte-csf": "^1.1.0",
|
||||||
"@storybook/svelte": "^6.4.19",
|
"@storybook/svelte": "^6.4.19",
|
||||||
"@sveltejs/adapter-node": "^1.0.0-next.0",
|
"@sveltejs/adapter-node": "^1.0.0-next.0",
|
||||||
"@yanick/updeep": "link:/home/yanick/work/javascript/updeep",
|
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"redux": "^4.1.2",
|
"redux": "^4.1.2",
|
||||||
"reselect": "^4.1.5",
|
"reselect": "^4.1.5",
|
||||||
"rollup-plugin-analyzer": "^4.0.0",
|
"rollup-plugin-analyzer": "^4.0.0",
|
||||||
"svelte-knobby": "^0.3.4",
|
"svelte-knobby": "^0.3.4",
|
||||||
"ts-action": "^11.0.0",
|
"ts-action": "^11.0.0",
|
||||||
"updux": "link:/home/yanick/work/javascript/updux/",
|
"updux": "link:/home/yanick/work/javascript/updux-js/",
|
||||||
"webpack": "5"
|
"webpack": "5"
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
|
110
src/dux/index.js
110
src/dux/index.js
@ -5,15 +5,15 @@ import { createSelector } from "reselect";
|
|||||||
|
|
||||||
import ftl from "./ftl";
|
import ftl from "./ftl";
|
||||||
import engine, { calc_drive_reqs } from "./engine";
|
import engine, { calc_drive_reqs } from "./engine";
|
||||||
import weaponry from './weaponry';
|
import weaponry from "./weaponry";
|
||||||
import { calc_ftl_reqs } from "./ftl/rules";
|
import { calc_ftl_reqs } from "./ftl/rules";
|
||||||
import { calc_ship_req } from "./utils";
|
import { calc_ship_req } from "./utils";
|
||||||
import { candidate_ship_types } from './ship_types';
|
import { candidate_ship_types } from "./ship_types";
|
||||||
import structure from './structure';
|
import structure from "./structure";
|
||||||
import cargo from './cargo';
|
import cargo from "./cargo";
|
||||||
import streamlining from './streamlining';
|
import streamlining from "./streamlining";
|
||||||
import carrier from './carrier';
|
import carrier from "./carrier";
|
||||||
import { ceil } from './utils';
|
import { ceil } from "./utils";
|
||||||
|
|
||||||
const set_ship_mass = action("set_ship_mass", payload());
|
const set_ship_mass = action("set_ship_mass", payload());
|
||||||
const set_name = action("set_name", payload());
|
const set_name = action("set_name", payload());
|
||||||
@ -21,9 +21,9 @@ const set_name = action("set_name", payload());
|
|||||||
const set_ship_reqs = action("set_ship_reqs", payload());
|
const set_ship_reqs = action("set_ship_reqs", payload());
|
||||||
const set_hull = action("set_hull", 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 = {
|
const initial = {
|
||||||
general: {
|
general: {
|
||||||
@ -34,18 +34,16 @@ const initial = {
|
|||||||
used_mass: 0,
|
used_mass: 0,
|
||||||
cost: 10,
|
cost: 10,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(Updux);
|
|
||||||
|
|
||||||
const dux = new Updux({
|
const dux = new Updux({
|
||||||
subduxes: { ftl, engine, weaponry, structure, cargo, streamlining, carrier },
|
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", {
|
return u.updateIn("structure.hull", {
|
||||||
cost: 2 * rating,
|
cost: 2 * rating,
|
||||||
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_ship_mass, (mass) => u.updateIn("general", { mass }));
|
||||||
dux.addMutation(set_name, (name) => u.updateIn("general", { name }));
|
dux.addMutation(set_name, (name) => u.updateIn("general", { name }));
|
||||||
|
|
||||||
dux.addMutation( action('set_ship_class',payload() ),
|
dux.addMutation(action("set_ship_class", payload()), (ship_class) =>
|
||||||
ship_class => u.updateIn('general',{ship_class})
|
u.updateIn("general", { ship_class })
|
||||||
);
|
);
|
||||||
|
|
||||||
dux.addMutation(set_ship_reqs, ({ cost, mass: used_mass }) =>
|
dux.addMutation(set_ship_reqs, ({ cost, mass: used_mass }) =>
|
||||||
@ -70,71 +68,73 @@ dux.addSubscription((store) =>
|
|||||||
|
|
||||||
dux.addSubscription((store) =>
|
dux.addSubscription((store) =>
|
||||||
createSelector(
|
createSelector(
|
||||||
store => store.general.mass,
|
(store) => store.general.mass,
|
||||||
store => store.streamlining.type,
|
(store) => store.streamlining.type,
|
||||||
(ship_mass, streamlining ) => {
|
(ship_mass, streamlining) => {
|
||||||
const mass = ceil( ship_mass * (
|
const mass = ceil(
|
||||||
streamlining === 'none' ? 0
|
(ship_mass *
|
||||||
: streamlining === 'partial' ? 5 : 10
|
(streamlining === "none" ? 0 : streamlining === "partial" ? 5 : 10)) /
|
||||||
) / 100 );
|
100
|
||||||
|
);
|
||||||
const cost = 2 * mass;
|
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) =>
|
dux.addSubscription((store) =>
|
||||||
createSelector(
|
createSelector(
|
||||||
store => store.general.mass,
|
(store) => store.general.mass,
|
||||||
store => store.general.ship_type,
|
(store) => store.general.ship_type,
|
||||||
store => store.carrier.bays,
|
(store) => store.carrier.bays,
|
||||||
(mass,type,bays) => {
|
(mass, type, bays) => {
|
||||||
console.log({bays});
|
console.log({ bays });
|
||||||
const candidates = candidate_ship_types(mass,bays > 0);
|
const candidates = candidate_ship_types(mass, bays > 0);
|
||||||
|
|
||||||
console.log({candidates});
|
console.log({ candidates });
|
||||||
if( candidates.length === 0 ) return;
|
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) =>
|
dux.addSubscription((store) =>
|
||||||
createSelector(
|
createSelector(
|
||||||
[(ship) => ship.general.mass, (ship) => ship.ftl.type],
|
[(ship) => ship.general.mass, (ship) => ship.ftl.type],
|
||||||
(ship_mass, 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(
|
dux.addSubscription((store) =>
|
||||||
ship => ship.general.mass,
|
createSelector(
|
||||||
ship => ship.structure.screens.standard,
|
(ship) => ship.general.mass,
|
||||||
ship => ship.structure.screens.advanced,
|
(ship) => ship.structure.screens.standard,
|
||||||
(mass,standard,advanced) => {
|
(ship) => ship.structure.screens.advanced,
|
||||||
|
(mass, standard, advanced) => {
|
||||||
console.log({
|
console.log({
|
||||||
mass, standard, advanced
|
mass,
|
||||||
})
|
standard,
|
||||||
const standard_mass = standard * Math.max(3,ceil( 0.05 * mass ));
|
advanced,
|
||||||
const advanced_mass = advanced * Math.max(4,ceil( 0.075 * mass ));
|
});
|
||||||
|
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({
|
store.dispatch(
|
||||||
|
dux.actions.set_screens_reqs({
|
||||||
mass: standard_mass + advanced_mass,
|
mass: standard_mass + advanced_mass,
|
||||||
cost: 3 * standard_mass + 4 * advanced_mass
|
cost: 3 * standard_mass + 4 * advanced_mass,
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
));
|
)
|
||||||
|
);
|
||||||
|
|
||||||
dux.addSubscription((store) =>
|
dux.addSubscription((store) =>
|
||||||
createSelector(
|
createSelector(
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<label>{label}</label>
|
<label>{label}</label>
|
||||||
{/if}
|
{/if}
|
||||||
<slot>
|
<slot>
|
||||||
<input type="text" {placeholder} {value} on:change />
|
<input type="text" {placeholder} bind:value on:change />
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
<Meta title="Identification" component={Identification} argTypes={{}} />
|
||||||
|
|
||||||
|
<Story name="Primary" args={{}} />
|
||||||
|
|
||||||
|
<Template let:args>
|
||||||
|
<div style="width: 50em">
|
||||||
|
<Identification {...args} />
|
||||||
|
</div>
|
||||||
|
</Template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
|
||||||
|
import { action } from "@storybook/addon-actions";
|
||||||
|
|
||||||
|
import { setContext } from "svelte";
|
||||||
|
|
||||||
|
import Identification from "./index.svelte";
|
||||||
|
|
||||||
|
setContext("ship", {
|
||||||
|
dispatch: (type, detail) => action(type)(detail),
|
||||||
|
});
|
||||||
|
</script>
|
40
src/lib/components/ShipEdit/Identification/index.svelte
Normal file
40
src/lib/components/ShipEdit/Identification/index.svelte
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<div>
|
||||||
|
<Field label="ship class" bind:value={shipClass} />
|
||||||
|
<Field label="ship type">
|
||||||
|
<select bind:value={shipType}>
|
||||||
|
{#each shipTypes as name (name)}
|
||||||
|
<option>{name}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</Field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte";
|
||||||
|
|
||||||
|
import Field from "$lib/components/Field/index.svelte";
|
||||||
|
import { candidateShipTypes } from "./shipTypes.js";
|
||||||
|
|
||||||
|
export let shipClass = "";
|
||||||
|
export let shipType = "";
|
||||||
|
export let mass = 10;
|
||||||
|
export let isCarrier = false;
|
||||||
|
|
||||||
|
const ship = getContext("ship");
|
||||||
|
|
||||||
|
$: shipTypes = candidateShipTypes(mass, isCarrier).map(({ name }) => name);
|
||||||
|
|
||||||
|
$: if (shipTypes.length > 0 && !shipTypes.includes(shipType))
|
||||||
|
shipType = shipTypes[0];
|
||||||
|
|
||||||
|
$: ship.dispatch.setShipType(shipType);
|
||||||
|
$: ship.dispatch.setShipClass(shipClass);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
align-items: end;
|
||||||
|
gap: 2em;
|
||||||
|
}
|
||||||
|
</style>
|
@ -20,7 +20,9 @@ const ship_types = [
|
|||||||
{ name: "Attack Carrier", mass: [150, 300], abbrev: "CVA", carrier: true },
|
{ name: "Attack Carrier", mass: [150, 300], abbrev: "CVA", carrier: true },
|
||||||
];
|
];
|
||||||
|
|
||||||
export function candidate_ship_types(mass = 0, carrier = false) {
|
export function candidateShipTypes(mass = 0, carrier = false) {
|
||||||
console.log({carrier});
|
return ship_types
|
||||||
return ship_types.filter((c) => carrier == !!c.carrier).filter((c) => c.mass[0] <= mass).filter((c) => c.mass[1] >= mass);
|
.filter((c) => carrier == !!c.carrier)
|
||||||
|
.filter((c) => c.mass[0] <= mass)
|
||||||
|
.filter((c) => c.mass[1] >= mass);
|
||||||
}
|
}
|
21
src/lib/components/ShipEdit/ShipEdit.stories.svelte
Normal file
21
src/lib/components/ShipEdit/ShipEdit.stories.svelte
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<Meta title="ShipEdit" component={ShipEdit} argTypes={{}} />
|
||||||
|
|
||||||
|
<Story name="Primary" args={{}} />
|
||||||
|
|
||||||
|
<Template let:args>
|
||||||
|
<div style="width: 50em">
|
||||||
|
<ShipEdit />
|
||||||
|
</div>
|
||||||
|
</Template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
|
||||||
|
import { action } from "@storybook/addon-actions";
|
||||||
|
|
||||||
|
import { setContext } from "svelte";
|
||||||
|
|
||||||
|
import ShipEdit from "./index.svelte";
|
||||||
|
import shipStore from "$lib/store/ship.js";
|
||||||
|
|
||||||
|
setContext("ship", shipStore());
|
||||||
|
</script>
|
12
src/lib/components/ShipEdit/index.svelte
Normal file
12
src/lib/components/ShipEdit/index.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<Identification {...$shipState.identification} {...$shipState.reqs} />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte";
|
||||||
|
|
||||||
|
import Identification from "./Identification/index.svelte";
|
||||||
|
|
||||||
|
const { state: shipState } = getContext("ship");
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
@ -1,49 +0,0 @@
|
|||||||
<div>
|
|
||||||
<Field
|
|
||||||
label="ship class"
|
|
||||||
value={general.ship_class}
|
|
||||||
on:change={change_class}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Field label="ship type">
|
|
||||||
<select value={ship_type} on:change={change_ship_type}>
|
|
||||||
{#each ship_types as type (type)}
|
|
||||||
<option>{type}</option>
|
|
||||||
{/each}
|
|
||||||
</select>
|
|
||||||
</Field>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getContext } from "svelte";
|
|
||||||
|
|
||||||
import Field from "$lib/components/Field/index.svelte";
|
|
||||||
import { candidate_ship_types } from "../../dux/ship_types";
|
|
||||||
|
|
||||||
export let ship = getContext("ship");
|
|
||||||
let general;
|
|
||||||
$: general = $ship.general;
|
|
||||||
|
|
||||||
const change_class = (event) =>
|
|
||||||
ship.dispatch(ship.actions.set_ship_class(event.target.value));
|
|
||||||
|
|
||||||
let ship_type;
|
|
||||||
$: ship_type = $ship.general.ship_type;
|
|
||||||
|
|
||||||
const change_ship_type = ({ target: { value } }) =>
|
|
||||||
ship.dispatch.set_ship_type(value);
|
|
||||||
|
|
||||||
let ship_types;
|
|
||||||
$: ship_types = candidate_ship_types(
|
|
||||||
$ship.general.mass,
|
|
||||||
$ship.carrier.bays > 0
|
|
||||||
).map(({ name }) => name);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
div {
|
|
||||||
display: flex;
|
|
||||||
align-items: end;
|
|
||||||
gap: 2em;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -6,9 +6,3 @@
|
|||||||
import Identification from "./Identification.svelte";
|
import Identification from "./Identification.svelte";
|
||||||
import ShipCost from "./ShipCost.svelte";
|
import ShipCost from "./ShipCost.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
div {
|
|
||||||
background-color: red;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
28
src/lib/shipDux/engine.js
Normal file
28
src/lib/shipDux/engine.js
Normal file
@ -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;
|
20
src/lib/shipDux/identification.js
Normal file
20
src/lib/shipDux/identification.js
Normal file
@ -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;
|
17
src/lib/shipDux/index.js
Normal file
17
src/lib/shipDux/index.js
Normal file
@ -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;
|
10
src/lib/shipDux/reqs.js
Normal file
10
src/lib/shipDux/reqs.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { Updux } from "updux";
|
||||||
|
|
||||||
|
const dux = new Updux({
|
||||||
|
initial: {
|
||||||
|
cost: 0,
|
||||||
|
mass: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default dux;
|
32
src/lib/store/ship.js
Normal file
32
src/lib/store/ship.js
Normal file
@ -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,
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user