spoint 0.1.668 → 0.1.670
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/BootFailureOverlay.js +49 -0
- package/client/app.js +1 -42
- package/package.json +1 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Boot-diagnostics helpers for app.js: shadow-cascade-count resolution (device-aware default the
|
|
2
|
+
// shadow pipeline registry itself has no knowledge of) and the single boot-failure overlay renderer,
|
|
3
|
+
// reused by every early-boot catch site (WebGL2-context-creation failure, window.onerror,
|
|
4
|
+
// unhandledrejection). Split out as the only two functions in app.js's top-level boot script with no
|
|
5
|
+
// interleaved side-effecting script logic immediately around them -- app.js itself is a flat top-to-
|
|
6
|
+
// bottom boot sequence, not a factory, so most of it cannot be safely cut without risking a module-eval
|
|
7
|
+
// ordering regression; these two are genuinely self-contained.
|
|
8
|
+
|
|
9
|
+
import { QualityPresets } from './core/QualityPresets.js'
|
|
10
|
+
|
|
11
|
+
function _shadowCascadeCountForBoot(deviceInfo) {
|
|
12
|
+
const explicit = typeof window !== 'undefined' ? window.__shadowCascades : undefined
|
|
13
|
+
if (Number.isFinite(explicit)) return Math.max(1, Math.min(3, Math.round(explicit)))
|
|
14
|
+
const presetName = QualityPresets.getPersisted() || QualityPresets.chooseInitialPreset(deviceInfo)
|
|
15
|
+
const byTier = { Low: 1, Medium: 1, High: 2, Ultra: 3 }
|
|
16
|
+
return byTier[presetName] || 1
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Single boot-failure overlay renderer, reused by both the WebGL2-specific catch below AND the
|
|
20
|
+
// generic window.onerror/unhandledrejection listeners -- one visual style for "the client failed
|
|
21
|
+
// to boot" regardless of WHERE in the boot sequence it failed, instead of a blank canvas / silently
|
|
22
|
+
// stuck loading screen. Idempotent (a data-flag guards double-render across multiple errors racing
|
|
23
|
+
// in, e.g. a synchronous throw immediately followed by a rejected promise from the same root cause).
|
|
24
|
+
let _bootFailureShown = false
|
|
25
|
+
function _showBootFailureOverlay(title, detail) {
|
|
26
|
+
if (_bootFailureShown) return
|
|
27
|
+
_bootFailureShown = true
|
|
28
|
+
try {
|
|
29
|
+
const o = document.createElement('div')
|
|
30
|
+
o.setAttribute('role', 'alert')
|
|
31
|
+
o.style.cssText = 'position:fixed;inset:0;z-index:99999;display:flex;align-items:center;justify-content:center;padding:24px;background:#0b0e14;color:#e6e6e6;font:16px/1.5 system-ui,sans-serif;text-align:center'
|
|
32
|
+
const titleEl = document.createElement('div')
|
|
33
|
+
titleEl.style.cssText = 'font-size:22px;font-weight:600;margin-bottom:12px'
|
|
34
|
+
titleEl.textContent = title
|
|
35
|
+
const detailEl = document.createElement('div')
|
|
36
|
+
detailEl.style.cssText = 'max-width:640px;white-space:pre-wrap;word-break:break-word;font:13px/1.5 ui-monospace,monospace;opacity:0.85;margin-top:8px;text-align:left'
|
|
37
|
+
detailEl.textContent = detail || ''
|
|
38
|
+
const wrap = document.createElement('div')
|
|
39
|
+
wrap.style.cssText = 'max-width:640px'
|
|
40
|
+
wrap.appendChild(titleEl)
|
|
41
|
+
wrap.appendChild(detailEl)
|
|
42
|
+
o.appendChild(wrap)
|
|
43
|
+
document.body.appendChild(o)
|
|
44
|
+
const ls = document.getElementById('loading-screen') || document.querySelector('.loading-screen')
|
|
45
|
+
if (ls) ls.style.display = 'none'
|
|
46
|
+
} catch (_) { /* overlay itself must never throw during an already-failing boot */ }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { _shadowCascadeCountForBoot, _showBootFailureOverlay }
|
package/client/app.js
CHANGED
|
@@ -62,6 +62,7 @@ import { getSharedStreamingScheduler } from './core/StreamingScheduler.js'
|
|
|
62
62
|
import { createPlacementScheduler } from './core/PlacementScheduler.js'
|
|
63
63
|
import { getSharedCacheRevalidationSweep } from './core/CacheRevalidationSweep.js'
|
|
64
64
|
import { QualityPresets, installQualityPresets } from './core/QualityPresets.js'
|
|
65
|
+
import { _shadowCascadeCountForBoot, _showBootFailureOverlay } from './BootFailureOverlay.js'
|
|
65
66
|
import { createSettingsMenu } from './hud/SettingsMenu.js'
|
|
66
67
|
import { createPauseMenu } from './hud/PauseMenu.js'
|
|
67
68
|
import { createEmoteWheel } from './hud/EmoteWheel.js'
|
|
@@ -118,48 +119,6 @@ if (typeof window !== 'undefined') window.__deviceInfo = _deviceInfoEarly
|
|
|
118
119
|
// Device-tier default for ShadowPipeline's cascade count (shadowCascades RenderControls knob, doc'd
|
|
119
120
|
// in RenderControls.js: Low/Medium=1, High=2, Ultra=3). RenderControls.get() itself only ever returns
|
|
120
121
|
// an explicit window.__shadowCascades override or the registry's static default (1) -- it has no
|
|
121
|
-
// device-awareness of its own -- so a real tier default has to be resolved here, once, the same way
|
|
122
|
-
// QualityPresets.autoApplyPersisted resolves a tier below (persisted user choice wins, else the same
|
|
123
|
-
// chooseInitialPreset heuristic), and passed into createShadowPipeline explicitly. window.__shadowCascades
|
|
124
|
-
// (if pre-set before this script runs, e.g. by a test harness) always wins over both.
|
|
125
|
-
function _shadowCascadeCountForBoot(deviceInfo) {
|
|
126
|
-
const explicit = typeof window !== 'undefined' ? window.__shadowCascades : undefined
|
|
127
|
-
if (Number.isFinite(explicit)) return Math.max(1, Math.min(3, Math.round(explicit)))
|
|
128
|
-
const presetName = QualityPresets.getPersisted() || QualityPresets.chooseInitialPreset(deviceInfo)
|
|
129
|
-
const byTier = { Low: 1, Medium: 1, High: 2, Ultra: 3 }
|
|
130
|
-
return byTier[presetName] || 1
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Single boot-failure overlay renderer, reused by both the WebGL2-specific catch below AND the
|
|
134
|
-
// generic window.onerror/unhandledrejection listeners -- one visual style for "the client failed
|
|
135
|
-
// to boot" regardless of WHERE in the boot sequence it failed, instead of a blank canvas / silently
|
|
136
|
-
// stuck loading screen. Idempotent (a data-flag guards double-render across multiple errors racing
|
|
137
|
-
// in, e.g. a synchronous throw immediately followed by a rejected promise from the same root cause).
|
|
138
|
-
let _bootFailureShown = false
|
|
139
|
-
function _showBootFailureOverlay(title, detail) {
|
|
140
|
-
if (_bootFailureShown) return
|
|
141
|
-
_bootFailureShown = true
|
|
142
|
-
try {
|
|
143
|
-
const o = document.createElement('div')
|
|
144
|
-
o.setAttribute('role', 'alert')
|
|
145
|
-
o.style.cssText = 'position:fixed;inset:0;z-index:99999;display:flex;align-items:center;justify-content:center;padding:24px;background:#0b0e14;color:#e6e6e6;font:16px/1.5 system-ui,sans-serif;text-align:center'
|
|
146
|
-
const titleEl = document.createElement('div')
|
|
147
|
-
titleEl.style.cssText = 'font-size:22px;font-weight:600;margin-bottom:12px'
|
|
148
|
-
titleEl.textContent = title
|
|
149
|
-
const detailEl = document.createElement('div')
|
|
150
|
-
detailEl.style.cssText = 'max-width:640px;white-space:pre-wrap;word-break:break-word;font:13px/1.5 ui-monospace,monospace;opacity:0.85;margin-top:8px;text-align:left'
|
|
151
|
-
detailEl.textContent = detail || ''
|
|
152
|
-
const wrap = document.createElement('div')
|
|
153
|
-
wrap.style.cssText = 'max-width:640px'
|
|
154
|
-
wrap.appendChild(titleEl)
|
|
155
|
-
wrap.appendChild(detailEl)
|
|
156
|
-
o.appendChild(wrap)
|
|
157
|
-
document.body.appendChild(o)
|
|
158
|
-
const ls = document.getElementById('loading-screen') || document.querySelector('.loading-screen')
|
|
159
|
-
if (ls) ls.style.display = 'none'
|
|
160
|
-
} catch (_) { /* overlay itself must never throw during an already-failing boot */ }
|
|
161
|
-
}
|
|
162
|
-
|
|
163
122
|
// Generic boot-failure safety net: ANY uncaught error or unhandled promise rejection during client
|
|
164
123
|
// boot (not just the WebGL2-context-creation case caught explicitly below) renders the same overlay
|
|
165
124
|
// style with the real error message/stack, instead of leaving the user staring at a stuck loading
|