/** * Loads the config manifest and every JSON file it references. * * data/manifest.json: { "files": ["game.json", "menu.json", "ship.json"] } * * Adding a config file = drop the .json in /data + one line in the manifest. * Each file becomes a section keyed by its file name (without .json), so * `ship.json` is available as `config.get('ship.thrust')`. */ export class ConfigLoader { static async load(manifestPath = 'data/manifest.json') { const manifest = await this.fetchJson(manifestPath); const files = Array.isArray(manifest?.files) ? manifest.files : []; // Resolve config files relative to the manifest's own location, // so this works with relative or absolute manifest paths. const base = manifestPath.replace(/[^/]*$/, ''); const data = {}; for (const file of files) { const name = file.split('/').pop().replace(/\.json$/i, ''); data[name] = await this.fetchJson(base + file); } return data; } static async fetchJson(path) { const res = await fetch(path); if (!res.ok) { throw new Error(`Could not load config "${path}" (${res.status} ${res.statusText})`); } return res.json(); } }