Conversation
…tions post-boot. - Start with bundled - Next, load from disk - Finally, should query live (not done yet)
- Fixed error caused by fetchLatestSchema stub not including valid keys - Changed getMergedEcosystemPath to be more viable - Enabled updateLatestMergedEcosystemSchema call in GameSelectionScreen
- Also removed EcosystemSchema class as no longer needed - Replaced usages of EcosystemSchema getters with reactive equivalents.
| FsProvider.provide(() => NodeFsImplementation); | ||
| await updateEcosystemReactives(); | ||
| // @ts-ignore | ||
| FsProvider.provide(() => undefined); |
There was a problem hiding this comment.
This is really awkward but I presume it's necessary?
There was a problem hiding this comment.
Technically no, because we bind to the same provider later anyway, it's more just to keep a separation of concerns so that providers are all bound in the place you'd expect.
On the flip side, this (#2116) removes the need entirely and we can have all providers set before this is even ran.
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Introduces a new ecosystem schema loading pathway that can hydrate Vue-reactive schema state from either a bundled schema or a cached schema on disk, and updates schema consumers/tests to use the new reactive sources.
Changes:
- Added
EcosystemSchema.tsto load/validate bundled schema, read an on-disk cached schema, and populate reactive exports. - Refactored schema consumers (game list, install rules, modloader variants) to read from reactive schema refs instead of a static class.
- Added a Quasar boot step plus unit test updates/new tests to ensure the ecosystem reactives are initialized before use.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/r2mm/ecosystem/EcosystemSchema.ts |
New loader/validator + cache resolution that populates reactive ecosystem state |
src/model/schema/ThunderstoreSchema.ts |
Replaces static schema class with Vue ref exports for supported games and modloader packages |
src/r2mm/installing/profile_installers/ModLoaderVariantRecord.ts |
Reworks modloader exports to be derived from reactive schema state |
src/r2mm/installing/InstallationRules.ts |
Uses reactive supported games to build rules |
src/model/game/GameManager.ts |
Uses reactive game list source |
src/boot/ecosystem.ts |
Boot-time initialization/hydration of ecosystem reactives |
quasar.config.ts |
Registers new ecosystem boot file |
src/pages/GameSelectionScreen.vue |
Adjusts flow to return after proceed() and stubs schema update call |
test/vitest/tests/unit/EcosystemSchema/EcosystemSchema.spec.ts |
Adds coverage for cache fallback/version match and writing schema to disk |
Various test/vitest/... specs/utils |
Ensures ecosystem reactives are initialized for unit tests |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| FsProvider.provide(() => NodeFsImplementation); | ||
| await updateEcosystemReactives(); | ||
| // @ts-ignore | ||
| FsProvider.provide(() => undefined); |
| let content: VersionedThunderstoreEcosystem; | ||
| try { | ||
| content = await getLastSavedEcosystemSchema(); | ||
| } catch (e) { | ||
| const err = e as unknown as Error; | ||
| LoggerProvider.instance.Log( | ||
| LogSeverity.ERROR, | ||
| `Failed to load cached ecosystem schema, falling back to bundled schema\n${err.message}` | ||
| ); | ||
| return bundledSchema(); | ||
| } | ||
| if (!new VersionNumber(content.version).isEqualTo(ManagerInformation.VERSION)) { | ||
| return bundledSchema(); | ||
| } | ||
| return content; |
| async function getMergedEcosystemPath(): Promise<string> { | ||
| return path.join(PathResolver.ROOT, "latest-ecosystem-schema.json"); | ||
| } |
| async function loadBundledSchema(): Promise<ThunderstoreEcosystem> { | ||
| const ajv = new Ajv(); | ||
| addFormats(ajv); | ||
|
|
||
| const validate = ajv.compile(jsonSchema); | ||
| const isOk = validate(bundledEcosystem); |
| MODLOADER_PACKAGES = EcosystemModloaderPackages.value.map((x) => | ||
| new ModLoaderPackageMapping(x.packageId, x.rootFolder, x.loader) | ||
| ); | ||
| MOD_LOADER_VARIANTS = Object.fromEntries( | ||
| EcosystemSupportedGames.value | ||
| .map(([_, game]) => [ | ||
| game.internalFolderName, | ||
| OVERRIDES[game.internalFolderName] || MODLOADER_PACKAGES | ||
| ]) | ||
| ); |
Ecosystem Merge
Adds support for loading from bundled ecosystem-schema.json, as well as loading from a ecosystem-merge.json which can exist on disk
Process
TL;DR for reviews
!changes are just to reduce type errors in the files