← back to gorewood__arcane-optimizer

Function bodies 443 total

All specs Real LLM only Function bodies
updateArchive function · typescript · L424-L437 (14 LOC)
src/search/genetic-core.ts
function updateArchive(state: LoopState, maxArchiveSize: number): void {
  for (const ind of state.population) {
    const key = getPieceKey(ind);
    const existing = state.archive.get(key);
    if (existing == null || ind.score > existing.score) {
      state.archive.set(key, ind);
    }
  }
  // Trim archive to max size (keep highest-scoring entries)
  if (state.archive.size > maxArchiveSize) {
    const sorted = [...state.archive.entries()].sort((a, b) => b[1].score - a[1].score);
    state.archive = new Map(sorted.slice(0, maxArchiveSize));
  }
}
GeneticSearch.search method · typescript · L486-L548 (63 LOC)
src/search/genetic-core.ts
  async search(
    gearPool: GearPool,
    constraints: HardConstraints,
    fitness: readonly SoftConstraint[],
    options: SearchOptions,
  ): Promise<readonly SearchResult[]> {
    this.token.cancelled = false;
    this.migrantQueue = [];
    const pool = buildIndexedPool(gearPool);
    const populationSize = options.populationSize ?? 200;
    const generations = options.generations ?? 500;
    const mutationRate = options.mutationRate ?? 0.15;
    const crossoverRate = options.crossoverRate ?? 0.8;

    this.totalGenerations = generations;

    const population = initPopulation(pool, constraints, fitness, populationSize);
    this.currentPopulation = population;
    const evolveParams: EvolveParams = {
      pool, constraints, fitness, populationSize, mutationRate, crossoverRate,
    };

    const state: LoopState = {
      population,
      archive: new Map(),
      bestScore: population[0]?.score ?? -Infinity,
      stagnation: 0,
      injections: 0,
      finalGeneration: 0,
getPieceForSlot function · typescript · L27-L35 (9 LOC)
src/search/genetic-repair.ts
export function getPieceForSlot(
  chromo: Chromosome,
  slotIdx: number,
  pool: IndexedPool,
): EquipmentPiece | undefined {
  if (slotIdx === 0) return pool.chestplates[chromo.chestIdx];
  if (slotIdx === 1) return pool.leggings[chromo.legsIdx];
  return pool.accessories[chromo.accIndices[slotIdx - 2] ?? 0];
}
repair function · typescript · L47-L61 (15 LOC)
src/search/genetic-repair.ts
export function repair(
  chromo: Chromosome,
  pool: IndexedPool,
  maxUnwardedInsanity?: number,
): void {
  chromo.chestIdx = clamp(chromo.chestIdx, 0, pool.chestplates.length - 1);
  chromo.legsIdx = clamp(chromo.legsIdx, 0, pool.leggings.length - 1);
  repairAccessories(chromo, pool);
  for (let i = 0; i < 5; i++) {
    repairSlotIndices(chromo, i, pool);
  }
  if (maxUnwardedInsanity != null) {
    repairInsanity(chromo, pool, maxUnwardedInsanity);
  }
}
repairAccessories function · typescript · L67-L78 (12 LOC)
src/search/genetic-repair.ts
function repairAccessories(chromo: Chromosome, pool: IndexedPool): void {
  for (let i = 0; i < 3; i++) {
    chromo.accIndices[i] = clamp(chromo.accIndices[i] ?? 0, 0, pool.accessories.length - 1);
  }
  const accSet = new Set<number>();
  for (let i = 0; i < 3; i++) {
    let idx = chromo.accIndices[i] ?? 0;
    while (accSet.has(idx)) { idx = (idx + 1) % pool.accessories.length; }
    chromo.accIndices[i] = idx;
    accSet.add(idx);
  }
}
repairSetModifier function · typescript · L84-L93 (10 LOC)
src/search/genetic-repair.ts
function repairSetModifier(chromo: Chromosome, i: number, pool: IndexedPool): void {
  const piece = getPieceForSlot(chromo, i, pool);
  if (piece?.atlanteanOnly === false) return;
  const modIdx = chromo.modIndices[i] ?? -1;
  if (modIdx < 0) return;
  const mod = pool.modifiers[modIdx];
  if (mod != null && mod.atlanteanBehavior == null) {
    chromo.modIndices[i] = pool.setModifierIndices[0] ?? -1;
  }
}
repairSlotIndices function · typescript · L103-L114 (12 LOC)
src/search/genetic-repair.ts
function repairSlotIndices(chromo: Chromosome, i: number, pool: IndexedPool): void {
  const enchPool = getEnchantPool(i, pool);
  chromo.enchantIndices[i] = clamp(chromo.enchantIndices[i] ?? -1, -1, enchPool.length - 1);
  chromo.modIndices[i] = clamp(chromo.modIndices[i] ?? -1, -1, pool.modifiers.length - 1);
  repairSetModifier(chromo, i, pool);
  const slotGems = chromo.gemIndices[i];
  if (slotGems != null) {
    for (let s = 0; s < slotGems.length; s++) {
      slotGems[s] = clamp(slotGems[s] ?? -1, -1, pool.gems.length - 1);
    }
  }
}
Repobility (the analyzer behind this table) · https://repobility.com
repairInsanity function · typescript · L129-L148 (20 LOC)
src/search/genetic-repair.ts
function repairInsanity(
  chromo: Chromosome,
  pool: IndexedPool,
  maxUnwarded: number,
): void {
  const atlanteanSlots = gatherAtlanteanSlots(chromo, pool);
  let totalInsanity = atlanteanSlots.reduce(
    (sum, s) => sum + s.insanity, 0,
  );

  if (totalInsanity <= maxUnwarded) return;

  shuffleInPlace(atlanteanSlots);

  for (const entry of atlanteanSlots) {
    if (totalInsanity <= maxUnwarded) break;
    chromo.modIndices[entry.slot] = -1;
    totalInsanity -= entry.insanity;
  }
}
gatherAtlanteanSlots function · typescript · L155-L169 (15 LOC)
src/search/genetic-repair.ts
function gatherAtlanteanSlots(
  chromo: Chromosome,
  pool: IndexedPool,
): AtlanteanSlotEntry[] {
  const entries: AtlanteanSlotEntry[] = [];
  for (let i = 0; i < 5; i++) {
    const modIdx = chromo.modIndices[i] ?? -1;
    if (modIdx < 0) continue;
    const mod = pool.modifiers[modIdx];
    if (mod?.atlanteanBehavior != null) {
      entries.push({ slot: i, insanity: mod.atlanteanBehavior.insanity });
    }
  }
  return entries;
}
shuffleInPlace function · typescript · L171-L181 (11 LOC)
src/search/genetic-repair.ts
function shuffleInPlace(arr: unknown[]): void {
  for (let i = arr.length - 1; i > 0; i--) {
    const j = randInt(i + 1);
    const tmp = arr[i];
    const swp = arr[j];
    if (tmp != null && swp != null) {
      arr[i] = swp;
      arr[j] = tmp;
    }
  }
}
IslandCore.start method · typescript · L67-L96 (30 LOC)
src/search/island-core.ts
  start(config: IslandGAConfig): void {
    this.search = new GeneticSearch();

    // Wire up callbacks
    this.search.onProgress = (checked, _total, bestScore, topResults) => {
      this.callbacks.onProgress(checked, bestScore, topResults);
    };

    this.search.onStagnating = () => {
      this.callbacks.onStagnating();
    };

    // Run the search
    const { gearPool, constraints, fitness, options } = config;
    this.search
      .search(gearPool, constraints, fitness, options)
      .then((results) => {
        this.callbacks.onComplete(
          results,
          this.search?.exitReason ?? "complete",
          this.search?.finalGeneration ?? 0,
        );
        this.search = null;
      })
      .catch((err: unknown) => {
        const message = err instanceof Error ? err.message : "Unknown island error";
        this.callbacks.onError(message);
        this.search = null;
      });
  }
IslandCore.stop method · typescript · L99-L104 (6 LOC)
src/search/island-core.ts
  stop(): void {
    if (this.search != null) {
      this.search.cancel();
      this.search = null;
    }
  }
secondaryStatMultiplier function · typescript · L55-L75 (21 LOC)
src/search/multiplier-scoring.ts
export function secondaryStatMultiplier(stat: number, isHaste = false): number {
  // Handle edge cases
  if (stat <= 0) return 1;

  const coef = isHaste ? 0.2 : 0.1;
  const linearCoef = isHaste ? 0.3 : 0.15;
  const denominator = 0.1 + 0.15 * Math.sqrt(175);

  const logArg = coef * stat + 4;
  // Guard against log of non-positive (shouldn't happen with stat > 0 and coef > 0)
  if (logArg <= 0) return 1;

  const logTerm = Math.pow(Math.log(logArg), 3) * 0.09 * 16;
  const linearTerm = linearCoef * stat;
  const numerator = logTerm + linearTerm;

  const result = 1 + (1.35 / 100) * (numerator / denominator - 0.79);

  // Ensure we don't return less than 1 due to floating point
  return Math.max(1, result);
}
computeMultiplierScore function · typescript · L105-L138 (34 LOC)
src/search/multiplier-scoring.ts
export function computeMultiplierScore(
  stats: Stats,
  weights: Readonly<Record<StatName, number>>,
): number {
  const defWeight = weights.defense / 100;
  const powWeight = weights.power / 100;

  // Base multiplier from power/defense
  const defenseBonus = (1 + stats.defense / BASE_HEALTH) * defWeight;
  const powerBonus = (stats.power / BASE_ATTACK) * powWeight;
  const baseMultiplier = (defenseBonus + 1) * (powerBonus + 1);

  // Secondary stats with diminishing returns
  let secondaryMult = 1;

  for (const statName of SECONDARY_STATS_WITH_WEIGHTS) {
    const formulaWeight = STAT_FORMULA_WEIGHTS[statName];
    if (formulaWeight == null) continue;

    const value = stats[statName];
    const userWeight = weights[statName] / 100;

    // Skip if user weight is 0
    if (userWeight === 0) continue;

    const isHaste = statName === "haste";
    const statMult = secondaryStatMultiplier(value, isHaste);

    // Apply formula weight and user weight via exponentiation
    secondary
isRelevantItem function · typescript · L55-L66 (12 LOC)
src/search/pool-filter.ts
function isRelevantItem(item: EquipmentPiece, targetStats: Set<StatName>): boolean {
  // Keep items with sockets (enhancements can contribute goal stats)
  if (item.socketCount > 0) return true;

  // Keep items that contribute any goal stat (positive or negative)
  const stats = getEffectiveStats(item);
  for (const stat of targetStats) {
    if ((stats[stat] ?? 0) !== 0) return true;
  }

  return false;
}
Repobility · MCP-ready · https://repobility.com
filterEquipment function · typescript · L71-L77 (7 LOC)
src/search/pool-filter.ts
function filterEquipment(
  items: readonly EquipmentPiece[],
  targetStats: Set<StatName>,
): readonly EquipmentPiece[] {
  if (targetStats.size === 0) return items; // No goals = keep all
  return items.filter((item) => isRelevantItem(item, targetStats));
}
formatFilterStats function · typescript · L129-L143 (15 LOC)
src/search/pool-filter.ts
export function formatFilterStats(stats: PoolFilterStats): string | null {
  const prunedChest = stats.original.chestplates - stats.filtered.chestplates;
  const prunedLegs = stats.original.leggings - stats.filtered.leggings;
  const prunedAcc = stats.original.accessories - stats.filtered.accessories;
  const totalPruned = prunedChest + prunedLegs + prunedAcc;

  if (totalPruned === 0) return null;

  const parts: string[] = [];
  if (prunedChest > 0) parts.push(`${String(prunedChest)} chest`);
  if (prunedLegs > 0) parts.push(`${String(prunedLegs)} legs`);
  if (prunedAcc > 0) parts.push(`${String(prunedAcc)} acc`);

  return `Pruned ${parts.join(", ")} (no goal stats)`;
}
checkBetween function · typescript · L38-L46 (9 LOC)
src/search/satisfaction.ts
function checkBetween(value: number, min: number, max: number): SatisfactionLevel {
  if (value >= min && value <= max) return "positive";
  const belowMin = min - value;
  const aboveMax = value - max;
  const margin = (max - min) * 0.1 || 1;
  if (belowMin > 0 && belowMin <= margin) return "warning";
  if (aboveMax > 0 && aboveMax <= margin) return "warning";
  return "negative";
}
getSatisfaction function · typescript · L66-L71 (6 LOC)
src/search/satisfaction.ts
export function getSatisfaction(
  value: number,
  constraint: SoftConstraint,
): SatisfactionLevel {
  return CHECKERS[constraint.type](value, constraint.value, constraint.hardCap);
}
emptyStats function · typescript · L59-L74 (16 LOC)
src/search/stats.ts
export function emptyStats(): Stats {
  return {
    power: 0,
    defense: 0,
    size: 0,
    dexterity: 0,
    range: 0,
    haste: 0,
    insanity: 0,
    warding: 0,
    drawback: 0,
    regeneration: 0,
    pierce: 0,
    resistance: 0,
  };
}
sumStats function · typescript · L77-L85 (9 LOC)
src/search/stats.ts
export function sumStats(...blocks: readonly Partial<Stats>[]): Stats {
  const result = emptyStats();
  for (const block of blocks) {
    for (const name of STAT_NAMES) {
      result[name] += block[name] ?? 0;
    }
  }
  return result;
}
getValidAtlanteanChoices function · typescript · L103-L115 (13 LOC)
src/search/stats.ts
export function getValidAtlanteanChoices(
  slot: EquippedSlot,
): readonly StatName[] {
  const config = slot.modifier?.atlanteanBehavior;
  if (config == null) return [];

  const pieceStats = getPieceStats(slot.piece);
  return config.possibleBonusStats.filter((stat) => {
    if (hasNonZeroStat(pieceStats, stat)) return false;
    if (slot.enchantment != null && hasNonZeroStat(slot.enchantment.stats, stat)) return false;
    return !slot.gems.some((gem) => hasNonZeroStat(gem.stats, stat));
  });
}
getAtlanteanBonusStat function · typescript · L124-L129 (6 LOC)
src/search/stats.ts
export function getAtlanteanBonusStat(
  slot: EquippedSlot,
): StatName | null {
  const choices = getValidAtlanteanChoices(slot);
  return choices[0] ?? null;
}
If a scraper extracted this row, it came from Repobility (https://repobility.com)
resolveAtlanteanBonus function · typescript · L137-L148 (12 LOC)
src/search/stats.ts
export function resolveAtlanteanBonus(
  slot: EquippedSlot,
  atlanteanChoice: StatName | null,
): Partial<Stats> {
  if (atlanteanChoice == null) return {};
  if (slot.modifier?.atlanteanBehavior == null) return {};

  const bonusValue = ATLANTEAN_BONUS_VALUES[atlanteanChoice];
  if (bonusValue === 0) return {};

  return { [atlanteanChoice]: bonusValue };
}
computeLoadoutStats function · typescript · L160-L179 (20 LOC)
src/search/stats.ts
export function computeLoadoutStats(
  loadout: Loadout,
  atlanteanChoices?: ReadonlyMap<number, StatName>,
): Stats {
  const slotBlocks: Partial<Stats>[] = [];

  for (let i = 0; i < loadout.slots.length; i++) {
    const slot = loadout.slots[i];
    if (slot == null) continue;

    slotBlocks.push(computeSlotStats(slot));

    if (slot.modifier?.atlanteanBehavior != null) {
      const choice = atlanteanChoices?.get(i) ?? null;
      slotBlocks.push(resolveAtlanteanBonus(slot, choice));
    }
  }

  return sumStats(...slotBlocks);
}
getNumericProperty function · typescript · L71-L77 (7 LOC)
src/stores/fitness-store-migrations.ts
function getNumericProperty(obj: object, key: string): number | undefined {
  if (Object.prototype.hasOwnProperty.call(obj, key)) {
    const val = Reflect.get(obj, key) as unknown;
    if (typeof val === "number") return val;
  }
  return undefined;
}
parseStatWeights function · typescript · L83-L98 (16 LOC)
src/stores/fitness-store-migrations.ts
function parseStatWeights(
  value: unknown,
  fallback: Readonly<Record<StatName, number>>,
): StatWeights {
  if (value == null || typeof value !== "object" || Array.isArray(value)) {
    return fallback;
  }
  const merged = { ...DEFAULT_STAT_WEIGHTS };
  for (const statKey of STAT_NAME_LIST) {
    const numVal = getNumericProperty(value, statKey);
    if (numVal !== undefined) {
      merged[statKey] = numVal;
    }
  }
  return merged;
}
parseStatLimits function · typescript · L100-L112 (13 LOC)
src/stores/fitness-store-migrations.ts
function parseStatLimits(value: unknown): StatLimits {
  if (value == null || typeof value !== "object" || Array.isArray(value)) {
    return DEFAULT_LIMITS;
  }
  const insanityVal = getNumericProperty(value, "insanity");
  const wardingVal = getNumericProperty(value, "warding");
  const drawbackVal = getNumericProperty(value, "drawback");
  return {
    insanity: insanityVal ?? DEFAULT_LIMITS.insanity,
    warding: wardingVal ?? DEFAULT_LIMITS.warding,
    drawback: drawbackVal ?? DEFAULT_LIMITS.drawback,
  };
}
parseStatMinimums function · typescript · L114-L126 (13 LOC)
src/stores/fitness-store-migrations.ts
function parseStatMinimums(value: unknown): StatMinimums {
  if (value == null || typeof value !== "object" || Array.isArray(value)) {
    return DEFAULT_MINIMUMS;
  }
  const result: Partial<Record<StatName, number>> = {};
  for (const statKey of STAT_NAME_LIST) {
    const numVal = getNumericProperty(value, statKey);
    if (numVal !== undefined) {
      result[statKey] = numVal;
    }
  }
  return result;
}
parseConstraintsModeConfig function · typescript · L128-L136 (9 LOC)
src/stores/fitness-store-migrations.ts
export function parseConstraintsModeConfig(value: unknown): ConstraintsModeConfig {
  if (value == null || typeof value !== "object" || Array.isArray(value)) {
    return DEFAULT_CONSTRAINTS_CONFIG;
  }
  const obj = value as { constraints?: unknown };
  return {
    constraints: Array.isArray(obj.constraints) ? obj.constraints : [],
  };
}
parseWeightsModeConfig function · typescript · L138-L148 (11 LOC)
src/stores/fitness-store-migrations.ts
export function parseWeightsModeConfig(value: unknown): WeightsModeConfig {
  if (value == null || typeof value !== "object" || Array.isArray(value)) {
    return DEFAULT_WEIGHTS_CONFIG;
  }
  const obj = value as { limits?: unknown; minimums?: unknown; weights?: unknown };
  return {
    limits: parseStatLimits(obj.limits),
    minimums: parseStatMinimums(obj.minimums),
    weights: parseStatWeights(obj.weights, DEFAULT_STAT_WEIGHTS),
  };
}
Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
migrateConstraints function · typescript · L154-L161 (8 LOC)
src/stores/fitness-store-migrations.ts
function migrateConstraints(raw: readonly SoftConstraint[]): readonly SoftConstraint[] {
  return raw.map((c) => {
    if (c.stat === "insanity" && c.type === "exactly") {
      return { ...c, type: "atMost" as const };
    }
    return c;
  });
}
migrateFromV4Plus function · typescript · L163-L175 (13 LOC)
src/stores/fitness-store-migrations.ts
function migrateFromV4Plus(raw: Partial<FitnessSerialized>): FitnessState {
  return {
    scoringMode: isValidScoringMode(raw.scoringMode) ? raw.scoringMode : "linear",
    enabledVariants: Array.isArray(raw.enabledVariants)
      ? new Set<string>(raw.enabledVariants)
      : new Set<string>(),
    constraintsConfig: parseConstraintsModeConfig(raw.constraintsConfig),
    efficiencyConfig: parseWeightsModeConfig(raw.efficiencyConfig),
    multiplierConfig: parseWeightsModeConfig(raw.multiplierConfig),
    activeProfileId: typeof raw.activeProfileId === "string" ? raw.activeProfileId : null,
    hasUnsavedChanges: typeof raw.hasUnsavedChanges === "boolean" ? raw.hasUnsavedChanges : false,
  };
}
migrateFromLegacy function · typescript · L177-L200 (24 LOC)
src/stores/fitness-store-migrations.ts
function migrateFromLegacy(legacy: LegacyFitnessSerialized): FitnessState {
  const constraints = Array.isArray(legacy.constraints)
    ? migrateConstraints(legacy.constraints)
    : [];
  const statWeights = parseStatWeights(legacy.statWeights, DEFAULT_STAT_WEIGHTS);
  const constraintsConfig: ConstraintsModeConfig = { constraints };
  const weightsConfig: WeightsModeConfig = {
    limits: DEFAULT_LIMITS,
    minimums: DEFAULT_MINIMUMS,
    weights: statWeights,
  };

  return {
    scoringMode: isValidScoringMode(legacy.scoringMode) ? legacy.scoringMode : "linear",
    enabledVariants: Array.isArray(legacy.enabledVariants)
      ? new Set<string>(legacy.enabledVariants)
      : new Set<string>(),
    constraintsConfig,
    efficiencyConfig: weightsConfig,
    multiplierConfig: weightsConfig,
    activeProfileId: typeof legacy.activeProfileId === "string" ? legacy.activeProfileId : null,
    hasUnsavedChanges: typeof legacy.hasUnsavedChanges === "boolean" ? legacy.hasUnsavedChanges : 
migrateFitnessState function · typescript · L202-L210 (9 LOC)
src/stores/fitness-store-migrations.ts
export function migrateFitnessState(
  persisted: unknown,
  version: number,
  initialState: FitnessState,
): FitnessState {
  if (persisted == null || typeof persisted !== "object") return initialState;
  if (version >= 4) return migrateFromV4Plus(persisted as Partial<FitnessSerialized>);
  return migrateFromLegacy(persisted as LegacyFitnessSerialized);
}
mergePersistedState function · typescript · L212-L233 (22 LOC)
src/stores/fitness-store-migrations.ts
export function mergePersistedState<T extends FitnessState>(
  persisted: unknown,
  current: T,
): T {
  if (persisted == null || typeof persisted !== "object") {
    return current;
  }
  const raw = persisted as Partial<FitnessSerialized>;

  return {
    ...current,
    scoringMode: isValidScoringMode(raw.scoringMode) ? raw.scoringMode : current.scoringMode,
    enabledVariants: Array.isArray(raw.enabledVariants)
      ? new Set<string>(raw.enabledVariants)
      : current.enabledVariants,
    constraintsConfig: raw.constraintsConfig ?? current.constraintsConfig,
    efficiencyConfig: raw.efficiencyConfig ?? current.efficiencyConfig,
    multiplierConfig: raw.multiplierConfig ?? current.multiplierConfig,
    activeProfileId: typeof raw.activeProfileId === "string" ? raw.activeProfileId : current.activeProfileId,
    hasUnsavedChanges: typeof raw.hasUnsavedChanges === "boolean" ? raw.hasUnsavedChanges : current.hasUnsavedChanges,
  };
}
buildInitialStateFromProfile function · typescript · L73-L83 (11 LOC)
src/stores/fitness-store.ts
function buildInitialStateFromProfile(profile: ProfileConfig & { id?: string }): FitnessState {
  return {
    scoringMode: profile.scoringMode,
    enabledVariants: new Set<string>(profile.enabledVariants),
    constraintsConfig: profile.constraintsConfig,
    efficiencyConfig: profile.efficiencyConfig,
    multiplierConfig: profile.multiplierConfig,
    activeProfileId: profile.id ?? null,
    hasUnsavedChanges: false,
  };
}
getDefaultFitnessState function · typescript · L85-L95 (11 LOC)
src/stores/fitness-store.ts
function getDefaultFitnessState(): FitnessState {
  return {
    scoringMode: "linear",
    enabledVariants: new Set<string>(),
    constraintsConfig: DEFAULT_CONSTRAINTS_CONFIG,
    efficiencyConfig: DEFAULT_WEIGHTS_CONFIG,
    multiplierConfig: DEFAULT_WEIGHTS_CONFIG,
    activeProfileId: null,
    hasUnsavedChanges: false,
  };
}
getInitialState function · typescript · L97-L102 (6 LOC)
src/stores/fitness-store.ts
function getInitialState(): FitnessState {
  const defaults = loadDefaultProfiles();
  const firstProfile = defaults[0];
  if (!firstProfile) return getDefaultFitnessState();
  return buildInitialStateFromProfile(firstProfile);
}
Repobility (the analyzer behind this table) · https://repobility.com
createSetStorage function · typescript · L110-L118 (9 LOC)
src/stores/fitness-store.ts
function createSetStorage(): ReturnType<typeof createJSONStorage<FitnessState>> {
  return createJSONStorage<FitnessState>(() => localStorage, {
    replacer: (_key: string, value: unknown): unknown => {
      if (value instanceof Set) return [...value];
      return value;
    },
    reviver: (_key: string, value: unknown): unknown => value,
  });
}
toggleSetItem function · typescript · L124-L129 (6 LOC)
src/stores/fitness-store.ts
function toggleSetItem(set: ReadonlySet<string>, item: string): ReadonlySet<string> {
  const next = new Set(set);
  if (next.has(item)) next.delete(item);
  else next.add(item);
  return next;
}
addVariantsOfType function · typescript · L131-L138 (8 LOC)
src/stores/fitness-store.ts
function addVariantsOfType(current: ReadonlySet<string>, typeId: string): ReadonlySet<string> {
  const variantTypes = loadVariantTypes();
  const typeEntry = variantTypes[typeId];
  if (!typeEntry) return current;
  const next = new Set(current);
  for (const v of typeEntry.variants) next.add(v);
  return next;
}
removeVariantsOfType function · typescript · L140-L147 (8 LOC)
src/stores/fitness-store.ts
function removeVariantsOfType(current: ReadonlySet<string>, typeId: string): ReadonlySet<string> {
  const variantTypes = loadVariantTypes();
  const typeEntry = variantTypes[typeId];
  if (!typeEntry) return current;
  const next = new Set(current);
  for (const v of typeEntry.variants) next.delete(v);
  return next;
}
createConstraintActions function · typescript · L156-L182 (27 LOC)
src/stores/fitness-store.ts
function createConstraintActions(set: SetFn): Pick<FitnessActions,
  "setConstraints" | "addConstraint" | "removeConstraint" | "updateConstraint"
> {
  return {
    setConstraints: (constraints) => {
      set({ constraintsConfig: { constraints }, hasUnsavedChanges: true });
    },
    addConstraint: (constraint) => {
      set((s) => ({
        constraintsConfig: { constraints: [...s.constraintsConfig.constraints, constraint] },
        hasUnsavedChanges: true,
      }));
    },
    removeConstraint: (index) => {
      set((s) => ({
        constraintsConfig: { constraints: s.constraintsConfig.constraints.filter((_, i) => i !== index) },
        hasUnsavedChanges: true,
      }));
    },
    updateConstraint: (index, constraint) => {
      set((s) => ({
        constraintsConfig: { constraints: s.constraintsConfig.constraints.map((c, i) => (i === index ? constraint : c)) },
        hasUnsavedChanges: true,
      }));
    },
  };
}
createVariantActions function · typescript · L184-L199 (16 LOC)
src/stores/fitness-store.ts
function createVariantActions(set: SetFn): Pick<FitnessActions,
  "toggleVariant" | "setEnabledVariants" | "enableAllVariantsOfType" | "disableAllVariantsOfType"
> {
  return {
    toggleVariant: (variant) => {
      set((s) => ({ enabledVariants: toggleSetItem(s.enabledVariants, variant), hasUnsavedChanges: true }));
    },
    setEnabledVariants: (variants) => { set({ enabledVariants: variants, hasUnsavedChanges: true }); },
    enableAllVariantsOfType: (typeId) => {
      set((s) => ({ enabledVariants: addVariantsOfType(s.enabledVariants, typeId), hasUnsavedChanges: true }));
    },
    disableAllVariantsOfType: (typeId) => {
      set((s) => ({ enabledVariants: removeVariantsOfType(s.enabledVariants, typeId), hasUnsavedChanges: true }));
    },
  };
}
createScoringActions function · typescript · L204-L244 (41 LOC)
src/stores/fitness-store.ts
function createScoringActions(set: SetFn, get: GetFn): Pick<FitnessActions,
  "setScoringMode" | "getCurrentModeConfig" | "setLimit" | "setMinimum" | "setWeight" | "resetWeights"
> {
  return {
    setScoringMode: (mode) => { set({ scoringMode: mode, hasUnsavedChanges: true }); },
    getCurrentModeConfig: () => {
      const s = get();
      return s.scoringMode === "linear" ? s.constraintsConfig : s[getConfigKey(s.scoringMode)];
    },
    setLimit: (stat, value) => {
      set((s) => {
        if (s.scoringMode === "linear") return s;
        const key = getConfigKey(s.scoringMode);
        return { [key]: { ...s[key], limits: { ...s[key].limits, [stat]: value } }, hasUnsavedChanges: true };
      });
    },
    setMinimum: (stat, value) => {
      set((s) => {
        if (s.scoringMode === "linear") return s;
        const key = getConfigKey(s.scoringMode);
        const { [stat]: _removed, ...rest } = s[key].minimums;
        const minimums = value === null ? rest : { ...s[key].mi
createProfileActions function · typescript · L246-L274 (29 LOC)
src/stores/fitness-store.ts
function createProfileActions(set: SetFn, get: GetFn): Pick<FitnessActions,
  "applyProfile" | "getCurrentConfig" | "markDirty" | "markClean"
> {
  return {
    applyProfile: (id, config) => {
      set({
        scoringMode: config.scoringMode,
        enabledVariants: new Set(config.enabledVariants),
        constraintsConfig: config.constraintsConfig,
        efficiencyConfig: config.efficiencyConfig,
        multiplierConfig: config.multiplierConfig,
        activeProfileId: id,
        hasUnsavedChanges: false,
      });
    },
    getCurrentConfig: () => {
      const s = get();
      return {
        scoringMode: s.scoringMode,
        enabledVariants: [...s.enabledVariants],
        constraintsConfig: s.constraintsConfig,
        efficiencyConfig: s.efficiencyConfig,
        multiplierConfig: s.multiplierConfig,
      };
    },
    markDirty: () => { set({ hasUnsavedChanges: true }); },
    markClean: () => { set({ hasUnsavedChanges: false }); },
  };
}
Repobility · MCP-ready · https://repobility.com
toggleSetItem function · typescript · L48-L56 (9 LOC)
src/stores/gear-pool-store.ts
function toggleSetItem(set: ReadonlySet<string>, id: string): ReadonlySet<string> {
  const next = new Set(set);
  if (next.has(id)) {
    next.delete(id);
  } else {
    next.add(id);
  }
  return next;
}
createSetStorage function · typescript · L73-L83 (11 LOC)
src/stores/gear-pool-store.ts
function createSetStorage(): ReturnType<typeof createJSONStorage<GearPoolState>> {
  return createJSONStorage<GearPoolState>(() => localStorage, {
    replacer: (_key: string, value: unknown): unknown => {
      if (value instanceof Set) {
        return [...value];
      }
      return value;
    },
    reviver: (_key: string, value: unknown): unknown => value,
  });
}
mergePersistedState function · typescript · L89-L127 (39 LOC)
src/stores/gear-pool-store.ts
function mergePersistedState(
  persisted: unknown,
  current: GearPoolState & GearPoolActions,
): GearPoolState & GearPoolActions {
  if (persisted == null || typeof persisted !== "object") {
    return current;
  }
  const raw = persisted as Partial<GearPoolSerialized>;
  const allEquipmentIds = new Set(loadEquipment().map((e) => e.id));
  const allEnchantmentIds = new Set(loadEnchantments().map((e) => e.id));
  const allModifierIds = new Set(loadModifiers().map((m) => m.id));
  const allGemIds = new Set(loadGems().map((g) => g.id));

  // Merge persisted IDs, adding any new items not in persisted set
  const mergeIds = (
    persistedIds: string[] | undefined,
    allIds: Set<string>,
  ): Set<string> => {
    if (!Array.isArray(persistedIds)) return allIds;
    const persisted = new Set<string>(persistedIds);
    // Add any new IDs that weren't in the persisted set
    for (const id of allIds) {
      if (!persisted.has(id)) persisted.add(id);
    }
    // Remove IDs that no longer
‹ prevpage 4 / 9next ›