My object is like:
const inventory = {
maxSlots: 24,
content: [
{id: "item_01", quantity: 5, slotId: 0},
{id: "item_02", quantity: 2, slotId: 2},
{id: "item_03", quantity: 1, slotId: 6},
]
};
I need custom methods like:
inventory.getRemainingSlots()
inventory.getFirstFreeSlotid()
inventory.addItem()
(this one depends on inventory.getFirstFreeSlotid()
)How should I make this object reactive?
get
, set
, update
and subscribe
methods?I've reached this point so far:
inventoryStore.js
function createStore() {
const { subscribe, set, update } = writable({
maxSlots: 8,
content: [
{ id: "item_01", quantity: 5, slotId: 0 },
{ id: "item_02", quantity: 2, slotId: 2 },
{ id: "item_03", quantity: 1, slotId: 6 },
],
});
return {
// Store methods
subscribe,
set,
update,
get: () => get({ subscribe }),
// Custom methods
getContent: () => {
// I can't use this in .svelte files
return inventoryStore.get().content;
},
getFirstFreeSlotId: () => {
const content = inventoryStore.get().content;
const maxSlots = inventoryStore.get().inventoryMaxSlots;
for (let _slotId = 0; _slotId < maxSlots; _slotId++) {
const foundItem = content.find(_x => _x.slotId === _slotId);
if (!foundItem?.id) {
return _slotId;
}
}
return -1;
}
};
}
export const inventoryStore = createStore();
I figured it out:
/stores/inventoryStore
import { derived, writable } from "svelte/store";
import { get } from "svelte/store";
const inventoryStore = writable({
toolbarMaxSlots: 8,
inventoryMaxSlots: 24,
/** @type {Array<{id: string, quantity: number, slotId: number}>} */
content: [
{id: "item_01", quantity: 5, slotId: 0},
{id: "item_02", quantity: 2, slotId: 2},
{id: "item_03", quantity: 1, slotId: 6},
],
});
export const inventory = {
_store: inventoryStore,
subscribe: inventoryStore.subscribe,
set: inventoryStore.set,
update: inventoryStore.update,
get,
addItem: function ({ id = "", quantity = 1 }) {
return this.update((_prev) => {
const newItem = {
id,
quantity,
slotId: 1, // todo: get first free slot
};
_prev.content = [..._prev.content, newItem];
return _prev;
});
},
// usable in js
getItems: function () {
return this.get(this._store).content;
},
// usable in svelte
getDerivedItems: function () {
return derived(this._store, ($store) => {
return $store.content
})
}
};
+page.svelte
<script>
import { inventory } from "./stores/inventoryStore";
const derivedItems = inventory.getDerivedItems();
</script>
<pre>
{JSON.stringify($derivedItems)}
</pre>