Skip to content

Latest commit

 

History

History
96 lines (73 loc) · 5.74 KB

File metadata and controls

96 lines (73 loc) · 5.74 KB
alwaysApply true

Dashboard alerts

  • When being asked to create a new alert make sure to scan the following files to get the context:
    • @IdleonToolbox/utility/migrations.js
    • @IdleonToolbox/pages/dashboard.jsx
    • @IdleonToolbox/components/dashboard/Account.jsx
    • @IdleonToolbox/components/dashboard/Characters.jsx
    • @IdleonToolbox/utility/dashboard/account.js
    • @IdleonToolbox/utility/dashboard/characters.js
  • If the "baseTrackers" object version in dashboard.jsx was already updated in the current changes, don't update it, if it didn't make sure to bump it one version and add the relevant migration.

New page

  • When being asked to create new page, make sure to add it to the correct folder path, when unsure, ask.
  • Update the relevant PAGES path at @IdleonToolbox/components/constants.jsx
  • In case tabs are being added to the page, make sure to update the tabs array as well.
  • Every new page should have an icon, if an icon is not being provided, you can use "/data/ClassIconsNA2.png" as a temporary file.

Obfuscated code

  • When being asked to reformat, validate or restructure an obuscated code, make sure to look at @IdleonToolbox/parsers for more context.
  • Always prefer using existing functions.
  • Always use readable and maintainable code.
  • For more context you can query the @IdleonToolbox/data/website-data.json file - which contains most of the data relevant to the project.
  • Few examples of obfuscated function vs existing one:
    • m._customBlock_Summoning("WinBonus", 27, 0) -> getWinnerBonus(account, '<x Amber Gain')
    • a.engine.getGameAttribute("OptionsListAccount")[478] -> account?.accountOptions?.[478]
    • m._customBlock_Summoning2("MeritocBonusz", 17, 0) -> getMeritocracyBonus(account, 17)
    • a.engine.getGameAttribute("DNSM").h.AlchBubbles.h.M11 -> getBubbleBonus(account, 'DEEP_DEPTH', false)

Testing

When testing add "http://localhost:3001?demo=true" to be able to access all pages without login in

TypeScript

This is a gradual TypeScript migration. The codebase is mixed JS/TS:

  • Parsers (parsers/) — TypeScript (.ts). All new parsers must be .ts.
  • Components (components/) — JavaScript (.jsx). Keep them .jsx unless explicitly asked to migrate.
  • Utilities/hooks/services — mostly .js, migrate to .ts only when requested.

Type definitions

  • Auto-generated — do not edit manually:
    • parsers/generated-types.ts — parsed Account and Character shapes (generated via Jest)
    • parsers/generated-firebase-types.ts — raw Firebase data types (IdleonData, ServerVars, etc.)
    • data/website-data.d.json.ts — types for website-data.json (generated by z-processing/typeGenerator.js)
  • Canonical imports: use import type { IdleonData, Account } from './types' (barrel file in parsers/types.ts)
  • Ambient globals: custom.ts declares Account, Character, IdleonData as global interfaces so .js/.jsx files can use them without imports. Prefer explicit imports in .ts files.

Conventions in .ts parser files

  • Export interfaces for return types (e.g., export interface Achievement { ... })
  • Use type imports: import type { IdleonData, Account } from './types'
  • Signature: export const getXxx = (idleonData: IdleonData, account: Account, ...): ReturnType => { ... }
  • Internal helper params can use any where full typing is impractical

Path aliases

Configured in both tsconfig.json and next.config.js:

  • @components/*components/*
  • @parsers/*parsers/*
  • @hooks/*hooks/*
  • @utility/*utility/*
  • @website-datadata/website-data.json

Date & Time Formatting

All user-facing dates and times must respect user preferences (DD/MM vs MM/DD, 24h vs 12h). Preferences are stored in localStorage (pref-dateFormat, pref-timeFormat) and exposed via PreferencesContext.

In React components, use one of these hooks — never hardcode format strings like 'dd/MM/yyyy HH:mm:ss':

  • useFormatDate (@hooks/useFormatDate) — returns formatDate(dateMs, options?). Use for direct date formatting.
    • Options: { showSeconds, shortYear, timeOnly } (all default false except showSeconds which defaults true)
    • Example: formatDate(timestamp), formatDate(date, { timeOnly: true }), formatDate(date, { shortYear: true, showSeconds: false })
  • useRealDate (@hooks/useRealDate) — returns (ms, shouldFormat?) => string. Drop-in replacement for getRealDateInMs. Handles the "X days" fallback for non-date values.
    • Example: const getRealDateInMs = useRealDate(); then use like before.

Outside React (parsers, utilities): getRealDateInMs in utility/helpers.js accepts an optional formatString parameter. No React components should import this directly — use the hooks instead.

Formats that are intentionally unambiguous (e.g., 'MMM do, yyyy' showing month names) do not need migration.

Data export formats (e.g., clipboard export, image footers in Breakdown.hook.js) may use the preference system too, so the exported data matches what the user sees on screen.

General

This project uses React Compiler (reactCompiler: true in next.config.js), so manual memoization with useMemo and useCallback is generally unnecessary. The compiler automatically optimizes component re-renders.

Multi-pass serialization rule

Some fields produced by serializeData depend on values that are computed during the same serialization step.

For this reason, serializeData is intentionally executed multiple times (currently 3 passes). Each pass may unlock additional derived values for the next one.

By the final pass, all cascading and inter-dependent calculations are considered stabilized, and code is allowed to rely on values that were produced in earlier passes.