Skip to content

Refactor: split the 1,462-line apidata.js and delete the two re-export shims #147

Description

@2ndtlmining

Summary

Split client/src/apidata.js (1,462 lines, 24 exported functions) into focused modules, and
delete the two re-export shims that make it look like there are three API layers when there is
one.

Correcting the premise

There is no duplicated API logic. client/src/home/apidata.js and
client/src/main/apidata.js are two-line shims:

// Shared API module — see client/src/apidata.js
export * from '../apidata';

They add an import path that hides where the code actually lives, and they make the tree look
like it holds three API modules. Worth deleting, but they are not the problem.

The real problem is that apidata.js is a 1,462-line grab bag. It currently owns the
global store shape, wallet lookup, node transformation, currency rates, parallel assets,
performance rankings, app specifications, geolocation, GPU pricing and DOS state.

Why it matters

This has already caused real bugs, twice, both found in the last week:

  1. Duplicated resource maths. fetch_global_app_specs() and AppsSection's specMap
    independently compute cpuPerInst / ramGBPerInst / ssdGBPerInst from the same specs.
    Both had the same bug — [].reduce((s, c) => s + c.cpu, 0) returns 0 for an encrypted
    enterprise compose, so "unknown" rendered as a confident 0.00. Fixing one left the other
    broken, and the second was only caught by someone looking at the UI.

  2. The same endpoint fetched twice. fetchTotalDeployedApps() and
    fetchWordpressInstancesCount() each pulled the same ~465 KB payload inside one
    Promise.all, because they were 60 lines apart in a file nobody reads end to end. See Other apps jump randomly #144.

The file is also effectively untestable as a unit. apidata.js imports utils.js, which does
import * as duration from 'dayjs/plugin/duration' — a namespace import of a CJS module that
webpack tolerates but Jest does not. Any test importing apidata.js dies before reaching the
code under test. That is why the #144 fix was extracted to client/src/fluxinfo.js: not for
tidiness, but because it was the only way to test it.

Current contents, by size

176  fetch_global_performance_rankings      64  fetch_country_node_counts
164  fetch_global_stats                     63  wallet_health_full
155  transformRawNode                       43  pa_summary_full
123  create_global_store                    39  fetch_total_donations
107  wallet_pas_summary                     32  fetch_gpu_prices
 95  fetch_global_app_specs                 26  getDemoWallet
 84  fetch_arcane_os_stats                  16  calc_mtn_window / fillPartialNode / getWalletNodes
 72  fetch_total_network_utils              15  isWalletDOSState
 67  lazy_load_currency_rate                13  getEnterpriseNodes
                                            10  validateAddress
                                             9  tier_global_projections
                                             4  normalize_raw_node_tier

Proposed split

client/src/api/ — one module per concern, each independently importable and testable:

Module Moves in ~lines
api/fluxinfo.js already extracted, move here 150
api/globalStats.js create_global_store, fetch_global_stats, fetch_total_network_utils, fetch_arcane_os_stats 440
api/nodes.js getWalletNodes, getEnterpriseNodes, transformRawNode, fillPartialNode, normalize_raw_node_tier, validateAddress, isWalletDOSState 220
api/appSpecs.js fetch_global_app_specs + a single shared spec-resource helper 120
api/rankings.js fetch_global_performance_rankings, fetch_country_node_counts 240
api/parallelAssets.js pa_summary_full, wallet_pas_summary 150
api/currency.js lazy_load_currency_rate 70
api/misc.js fetch_gpu_prices, fetch_total_donations, getDemoWallet 100
api/health.js wallet_health_full, fill_health, calc_mtn_window, tier_global_projections 100

Keep apidata.js as a re-export barrel so no call site changes in the first pass, then
migrate imports incrementally and drop it.

Do at the same time

  • Delete home/apidata.js and main/apidata.js, repointing their importers at the barrel.
    Currently main/AppsSection imports fetch_global_app_specs from main/apidata and
    home/Home.jsx imports the same function from a different path.
  • Extract one shared spec-resource helper (specResources(spec) returning
    {cpuPerInst, ramGBPerInst, ssdGBPerInst, repotag}, null for encrypted enterprise specs)
    and use it in both api/appSpecs.js and AppsSection. This is the root cause of bug (1)
    above and should not survive the refactor.
  • Fix the dayjs namespace imports in utils.js and apidata.js
    (import * as dayjs from 'dayjs'import dayjs from 'dayjs'). Correct ESM, works in both
    webpack and Jest, and unblocks unit tests for everything above.

Constraints

  • Behaviour-preserving. No displayed number may change. The existing figures are already
    pinned by client/src/fluxinfoResilience.test.js; extend that approach as modules are split.
  • Land in reviewable passes — one module per PR, barrel kept throughout — not one large commit.
  • create_global_store() defines the shape half the app reads. Move it first and leave it
    alone.

Acceptance criteria

  • No module over ~300 lines
  • home/apidata.js and main/apidata.js deleted
  • Spec-resource maths exists in exactly one place
  • import dayjs from 'dayjs'apidata importable from a Jest test without patching
  • Every displayed figure verified identical before/after
  • Production build clean, existing tests green

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions