You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.jsexport*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:
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.
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.
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
Summary
Split
client/src/apidata.js(1,462 lines, 24 exported functions) into focused modules, anddelete 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.jsandclient/src/main/apidata.jsare two-line shims: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.jsis a 1,462-line grab bag. It currently owns theglobal 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:
Duplicated resource maths.
fetch_global_app_specs()andAppsSection'sspecMapindependently compute
cpuPerInst/ramGBPerInst/ssdGBPerInstfrom the same specs.Both had the same bug —
[].reduce((s, c) => s + c.cpu, 0)returns0for an encryptedenterprise compose, so "unknown" rendered as a confident
0.00. Fixing one left the otherbroken, and the second was only caught by someone looking at the UI.
The same endpoint fetched twice.
fetchTotalDeployedApps()andfetchWordpressInstancesCount()each pulled the same ~465 KB payload inside onePromise.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.jsimportsutils.js, which doesimport * as duration from 'dayjs/plugin/duration'— a namespace import of a CJS module thatwebpack tolerates but Jest does not. Any test importing
apidata.jsdies before reaching thecode under test. That is why the #144 fix was extracted to
client/src/fluxinfo.js: not fortidiness, but because it was the only way to test it.
Current contents, by size
Proposed split
client/src/api/— one module per concern, each independently importable and testable:api/fluxinfo.jsapi/globalStats.jscreate_global_store,fetch_global_stats,fetch_total_network_utils,fetch_arcane_os_statsapi/nodes.jsgetWalletNodes,getEnterpriseNodes,transformRawNode,fillPartialNode,normalize_raw_node_tier,validateAddress,isWalletDOSStateapi/appSpecs.jsfetch_global_app_specs+ a single shared spec-resource helperapi/rankings.jsfetch_global_performance_rankings,fetch_country_node_countsapi/parallelAssets.jspa_summary_full,wallet_pas_summaryapi/currency.jslazy_load_currency_rateapi/misc.jsfetch_gpu_prices,fetch_total_donations,getDemoWalletapi/health.jswallet_health_full,fill_health,calc_mtn_window,tier_global_projectionsKeep
apidata.jsas a re-export barrel so no call site changes in the first pass, thenmigrate imports incrementally and drop it.
Do at the same time
home/apidata.jsandmain/apidata.js, repointing their importers at the barrel.Currently
main/AppsSectionimportsfetch_global_app_specsfrommain/apidataandhome/Home.jsximports the same function from a different path.specResources(spec)returning{cpuPerInst, ramGBPerInst, ssdGBPerInst, repotag},nullfor encrypted enterprise specs)and use it in both
api/appSpecs.jsandAppsSection. This is the root cause of bug (1)above and should not survive the refactor.
utils.jsandapidata.js(
import * as dayjs from 'dayjs'→import dayjs from 'dayjs'). Correct ESM, works in bothwebpack and Jest, and unblocks unit tests for everything above.
Constraints
pinned by
client/src/fluxinfoResilience.test.js; extend that approach as modules are split.create_global_store()defines the shape half the app reads. Move it first and leave italone.
Acceptance criteria
home/apidata.jsandmain/apidata.jsdeletedimport dayjs from 'dayjs'—apidataimportable from a Jest test without patching