fix: Object.values null safety + Docker dev build
Build and Publish Mana Loop Docker Image / build-and-publish (push) Has been cancelled
Build and Publish Mana Loop Docker Image / build-and-publish (push) Has been cancelled
- Change Dockerfile to use development build (better error messages)
- Add || {} fallbacks to all Object.values() calls accessing state
- Fixes "Cannot convert undefined or null to object" browser error during SSR/hydration
- Verified TypeScript compilation and Next.js build successful
Files modified:
- Dockerfile
- src/app/page.tsx
- src/components/game/tabs/StatsTab.tsx
- src/components/game/StatsTab/LoopStatsSection.tsx
- src/components/game/StatsTab/ElementStatsSection.tsx
- src/components/game/tabs/AttunementsTab.tsx
- src/components/game/tabs/GolemancyTab.tsx
- src/lib/game/effects.ts
- src/lib/game/utils/combat-utils.ts
- src/lib/game/crafting-loot.ts
- src/components/game/LootInventory/LootInventoryDisplay.tsx
- src/components/game/LootInventory/index.tsx
- src/components/game/crafting/EnchantmentDesigner/utils.ts
This commit is contained in:
@@ -7,7 +7,7 @@ export function getEquipmentSpells(get: () => GameState): string[] {
|
||||
const state = get();
|
||||
const spells: string[] = [];
|
||||
|
||||
for (const instanceId of Object.values(state.equippedInstances)) {
|
||||
for (const instanceId of Object.values(state.equippedInstances || {})) {
|
||||
if (!instanceId) continue;
|
||||
const instance = state.equipmentInstances[instanceId];
|
||||
if (!instance) continue;
|
||||
@@ -27,7 +27,7 @@ export function getEquipmentEffects(get: () => GameState): Record<string, number
|
||||
const state = get();
|
||||
const effects: Record<string, number> = {};
|
||||
|
||||
for (const instanceId of Object.values(state.equippedInstances)) {
|
||||
for (const instanceId of Object.values(state.equippedInstances || {})) {
|
||||
if (!instanceId) continue;
|
||||
const instance = state.equipmentInstances[instanceId];
|
||||
if (!instance) continue;
|
||||
|
||||
@@ -28,7 +28,7 @@ export function getUniqueMaterialCount(inventory: LootInventory): number {
|
||||
|
||||
// Get total material stacks (sum of all quantities)
|
||||
export function getTotalMaterialStacks(inventory: LootInventory): number {
|
||||
return Object.values(inventory.materials).reduce((sum, qty) => sum + qty, 0);
|
||||
return Object.values(inventory.materials || {}).reduce((sum, qty) => sum + qty, 0);
|
||||
}
|
||||
|
||||
// ─── Inventory Modifications ────────────────────────────────────────────────
|
||||
@@ -265,7 +265,7 @@ export interface InventoryStats {
|
||||
|
||||
export function getInventoryStats(inventory: LootInventory): InventoryStats {
|
||||
const totalUniqueMaterials = Object.keys(inventory.materials).length;
|
||||
const totalMaterialStacks = Object.values(inventory.materials).reduce((sum, qty) => sum + qty, 0);
|
||||
const totalMaterialStacks = Object.values(inventory.materials || {}).reduce((sum, qty) => sum + qty, 0);
|
||||
const totalBlueprints = inventory.blueprints.length;
|
||||
|
||||
return {
|
||||
|
||||
@@ -35,7 +35,7 @@ export function computeEquipmentEffects(
|
||||
const specials = new Set<string>();
|
||||
|
||||
// Iterate through all equipped items
|
||||
for (const instanceId of Object.values(equippedInstances)) {
|
||||
for (const instanceId of Object.values(equippedInstances || {})) {
|
||||
if (!instanceId) continue;
|
||||
const instance = equipmentInstances[instanceId];
|
||||
if (!instance) continue;
|
||||
@@ -172,8 +172,8 @@ export function getUnifiedEffects(state: Pick<GameState, 'skillUpgrades' | 'skil
|
||||
return computeAllEffects(
|
||||
state.skillUpgrades || {},
|
||||
state.skillTiers || {},
|
||||
state.equipmentInstances,
|
||||
state.equippedInstances
|
||||
state.equipmentInstances || {},
|
||||
state.equippedInstances || {}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
/**
|
||||
* Helper to get unified effects from game state
|
||||
*/
|
||||
export function getUnifiedEffects(state: Pick<GameState, 'skillUpgrades' | 'skillTiers' | 'equipmentInstances' | 'equippedInstances'>): UnifiedEffects {
|
||||
return computeAllEffects(
|
||||
state.skillUpgrades || {},
|
||||
state.skillTiers || {},
|
||||
state.equipmentInstances || {},
|
||||
state.equippedInstances || {}
|
||||
);
|
||||
}
|
||||
@@ -237,7 +237,7 @@ export function getActiveEquipmentSpells(
|
||||
equippedInstances: Record<string, string | null>,
|
||||
equipmentInstances: Record<string, EquipmentInstance>
|
||||
): ActiveEquipmentSpell[] {
|
||||
const equippedIds = Object.values(equippedInstances).filter((id): id is string => id !== null);
|
||||
const equippedIds = Object.values(equippedInstances || {}).filter((id): id is string => id !== null);
|
||||
const spells: ActiveEquipmentSpell[] = [];
|
||||
|
||||
for (const id of equippedIds) {
|
||||
|
||||
Reference in New Issue
Block a user