Skip to content

perf: load the network from a single shared asset instead of inlining it in both builds - #18

Merged
mayurrawte merged 1 commit into
mainfrom
feat/issue-10-shared-network-asset
Jul 3, 2026
Merged

perf: load the network from a single shared asset instead of inlining it in both builds#18
mayurrawte merged 1 commit into
mainfrom
feat/issue-10-shared-network-asset

Conversation

@mayurrawte

@mayurrawte mayurrawte commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Summary

The Eurostat marnet was inlined as a ~1.1 MB JSON string in src/lib/marnet.ts and compiled into both the CJS and ESM builds, so the published tarball shipped the network twice (~2.2 MB of identical data). This was already flagged as a follow-up in CHANGELOG.md.

This PR extracts the network to a single shared asset that both builds load at runtime, rather than a source module compiled into each.

What changed

  • data/marnet.cjs — the network now lives in one committed CommonJS data module (module.exports = JSON.parse(...)), with a companion data/marnet.d.cts type declaration.
  • src/lib/marnet.ts — slimmed to import marnetData from '../../data/marnet.cjs' and re-export. The specifier resolves to a single dist/data/marnet.cjs at runtime from both dist/cjs/lib and dist/esm/lib (../../data/marnet.cjsdist/data/marnet.cjs in both).
  • scripts/build-marnet.cjs — updated to generate data/marnet.cjs instead of src/lib/marnet.ts.
  • scripts/copy-marnet.cjs (new) — copies the asset into dist/data (build) and build/data (tests).
  • package.jsonbuild and build:test copy the asset into place; files already ships dist.
  • Docs: CHANGELOG entry, README bundle-size FAQ, and the old follow-up note marked done.

Why a .cjs data module (not fs or JSON import)

  • A .cjs file is always CommonJS regardless of the surrounding package.json type, so CJS require and ESM import of it both resolve the single asset across Node 18/20/22 — no import.meta vs __dirname split, no version-fragile JSON import attributes (assert vs with), and no fs (so it stays bundler-friendly).

Impact

Validation

All steps CI runs, from a clean tree:

  • npm ci
  • npm run lint
  • npm run format:check
  • npm run build
  • npm test ✅ (45 tests; added DEFAULT_MARNET loads the shared network asset)

Additionally verified both published entrypoints load the single asset and route identically:

  • require('./dist/cjs/index.js') → 9847 features, Shanghai→Rotterdam 10666 nm
  • import('./dist/esm/index.js') → 9847 features, Shanghai→Rotterdam 10666 nm

Closes #10

… it in both builds

The Eurostat marnet was inlined as a ~1.1 MB JSON string in src/lib/marnet.ts
and compiled into both the CJS and ESM builds, so the published tarball
carried the network twice (~2.2 MB of identical data).

Extract the network to a single data/marnet.cjs module. Both builds import it
via '../../data/marnet.cjs', which resolves to one shared dist/data/marnet.cjs
at runtime (CJS require and ESM import of a .cjs both load it). The build and
test scripts copy the asset into dist/data and build/data respectively.

Roughly halves the published size (~329 KB -> ~184 KB packed, ~2.5 MB ->
~1.3 MB unpacked). No public API change.
@mayurrawte
mayurrawte force-pushed the feat/issue-10-shared-network-asset branch from a2937be to 53173ff Compare July 3, 2026 07:54
@mayurrawte
mayurrawte merged commit 2d59a1a into main Jul 3, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Halve package size: load the network from a single shared asset instead of inlining it in both builds

1 participant