diff --git a/js/app.js b/js/app.js index 6374f47b..9636cfba 100644 --- a/js/app.js +++ b/js/app.js @@ -247,7 +247,16 @@ class Application { } constructor({ services = {}, ui = {}, helpers = {}, loadView: viewLoader } = {}) { - this.loadView = viewLoader || null; + this.loadView = typeof viewLoader === "function" ? viewLoader : null; + this._setupOptions = { services, ui, helpers }; + this._isSetup = false; + } + + setup() { + if (this._isSetup) return; + this._isSetup = true; + + const { services = {}, ui = {}, helpers = {} } = this._setupOptions || {}; const bootstrapServices = { ...services, @@ -509,6 +518,8 @@ class Application { }; onActiveSignerChanged(this.handleShareNostrSignerChange); this.updateShareNostrAuthState({ reason: "init" }); + + delete this._setupOptions; } /** diff --git a/js/bootstrap.js b/js/bootstrap.js index b8e82d8b..bcbfa1b3 100644 --- a/js/bootstrap.js +++ b/js/bootstrap.js @@ -30,10 +30,12 @@ function mergeServices(overrides = {}) { } export async function createApplication({ services, loadView: loadViewOverride } = {}) { - return new Application({ + const app = new Application({ services: mergeServices(services), loadView: typeof loadViewOverride === "function" ? loadViewOverride : loadView, }); + app.setup(); + return app; } export default createApplication; diff --git a/js/embed.js b/js/embed.js index a6f76577..fec5d152 100644 --- a/js/embed.js +++ b/js/embed.js @@ -102,6 +102,8 @@ app.showSuccess = (message) => { setStatus(message, "success"); }; +app.setup(); + const resolvePlaybackPreference = (value) => { if (typeof value !== "string") { return null; diff --git a/tests/video-modal-accessibility.test.mjs b/tests/video-modal-accessibility.test.mjs index ebfaebfd..7401f3cf 100644 --- a/tests/video-modal-accessibility.test.mjs +++ b/tests/video-modal-accessibility.test.mjs @@ -599,6 +599,7 @@ async function setupPlaybackHarness() { helpers, ui: { videoModal: () => modalStub }, }); + app.setup(); app.showError = () => {}; app.showSuccess = () => {}; diff --git a/tests/video-modal-zap.test.mjs b/tests/video-modal-zap.test.mjs index 0a1ae2bd..c529d0fd 100644 --- a/tests/video-modal-zap.test.mjs +++ b/tests/video-modal-zap.test.mjs @@ -143,7 +143,15 @@ if (typeof globalThis.WebSocket === "undefined") { } globalThis.document = documentStub; -globalThis.navigator = windowStub.navigator; +try { + Object.defineProperty(globalThis, "navigator", { + value: windowStub.navigator, + writable: true, + configurable: true, + }); +} catch (e) { + // Fallback for environments where navigator is read-only +} globalThis.location = windowStub.location; if (typeof globalThis.fetch === "undefined") { @@ -302,6 +310,7 @@ async function createApp({ splitAndZap }) { videoModal: () => modalStub, }, }); + app.setup(); app.boundVideoModalZapOpenHandler = (event = {}) => { const requiresLogin = Boolean(event?.detail?.requiresLogin);