fix: guard against the script bootstrapping twice on a page#63
Merged
Conversation
When the userscript was injected more than once into the same page (re-injection
or a same-origin iframe), bootstrap ran twice and TheWestApi.register threw
"given parameter ('tw-calc') is already registered!" on the second run — the
visible symptom of everything initializing twice.
Extract the injection logic into src/inject.ts and skip bootstrapping when
window.TW_Calc is already set, making injection idempotent. Add tests for the
ready/already-injected guards.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Reported in production:
Initializer.registerApi | given parameter ('tw-calc') is already registered!The game's
TheWestApi.register('tw-calc', …)throws when that key is already registered. Since the key is a constant, the only way to hit it is the script bootstrapping twice in the same window:index.tsstarts asetIntervalthat bootstraps once the game is ready, with no guard against the bundle being injected more than once (re-injection or a same-origin iframe). The register collision is the visible symptom of everything initializing twice.What
src/inject.tsand skip bootstrapping whenwindow.TW_Calcis already set, making injection idempotent. This fixes the root cause (all double-init), not just the API-register symptom.src/index.tsdown to wiring + theinject(...)call.Tests
New
inject.spec.ts(5 tests, driven with jasmine's clock): the game-ready guard, bootstraps exactly once when ready, and does not bootstrap again when already injected. Full suite green (npm test→ 18/18);tscandeslintclean.🤖 Generated with Claude Code