spoint 0.1.683 → 0.1.685

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/app.js CHANGED
@@ -2204,7 +2204,7 @@ const settingsMenu = createSettingsMenu({ getCam: () => cam, getRenderer: () =>
2204
2204
  if (window.__app) window.__app.settingsMenu = settingsMenu
2205
2205
  let _hasEverLocked = false
2206
2206
  const pauseMenu = createPauseMenu({
2207
- requestPointerLock: () => renderer.domElement.requestPointerLock(),
2207
+ requestPointerLock: () => { try { renderer.domElement.requestPointerLock() } catch (e) { console.warn('[input] requestPointerLock failed:', e?.message || e) } },
2208
2208
  settingsMenu,
2209
2209
  getRoomInfo: () => _wwRoom ? { code: _wwRoom, joinLink: `${location.origin}${location.pathname}?wwjoin&room=${_wwRoom}` } : null,
2210
2210
  })
@@ -2424,12 +2424,17 @@ function startInputLoop() {
2424
2424
  }
2425
2425
  renderer.domElement.addEventListener('click', ()=>{
2426
2426
  if (!inputConfig.pointerLock || document.pointerLockElement) return
2427
- // requestPointerLock() can throw synchronously (not just reject) in some browser/automation
2428
- // contexts -- e.g. "The root document of this element is not valid for pointer lock" when the
2429
- // element's document isn't the active top-level document at click time. Left unguarded this was
2430
- // an uncaught exception that tripped the app's global error boundary, converting a benign
2431
- // lock-denial into a full page crash. The keydown fallback below still recovers gameplay either way.
2432
- try { renderer.domElement.requestPointerLock() } catch (e) { console.warn('[input] requestPointerLock failed:', e?.message || e) }
2427
+ // requestPointerLock() can both throw synchronously AND return a Promise that rejects
2428
+ // asynchronously (spec-dependent by browser/context) -- e.g. "The root document of this
2429
+ // element is not valid for pointer lock". A try/catch alone only catches the synchronous
2430
+ // case; the async rejection surfaces as an unhandledrejection that still trips the app's
2431
+ // global error boundary, converting a benign lock-denial into a full page crash (reproduced
2432
+ // live even after the sync try/catch was added). Guard both paths. The keydown fallback below
2433
+ // still recovers gameplay either way.
2434
+ try {
2435
+ const p = renderer.domElement.requestPointerLock()
2436
+ if (p && typeof p.catch === 'function') p.catch(e => console.warn('[input] requestPointerLock rejected:', e?.message || e))
2437
+ } catch (e) { console.warn('[input] requestPointerLock failed:', e?.message || e) }
2433
2438
  })
2434
2439
  // requestPointerLock() is a trusted-gesture-gated browser API that can silently reject (denied
2435
2440
  // engagement heuristic, automation-driven click, embedded/iframe context) with no visible error --
@@ -117,7 +117,12 @@ export function createPauseMenu({ requestPointerLock = null, settingsMenu = null
117
117
  }
118
118
  function resume() {
119
119
  overlay.classList.remove('open')
120
- if (requestPointerLock) { try { requestPointerLock() } catch (e) { console.warn('[pause-menu] requestPointerLock failed:', e?.message || e) } }
120
+ if (requestPointerLock) {
121
+ try {
122
+ const p = requestPointerLock()
123
+ if (p && typeof p.catch === 'function') p.catch(e => console.warn('[pause-menu] requestPointerLock rejected:', e?.message || e))
124
+ } catch (e) { console.warn('[pause-menu] requestPointerLock failed:', e?.message || e) }
125
+ }
121
126
  if (onResumeCb) onResumeCb()
122
127
  }
123
128
  function leaveMatch() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spoint",
3
- "version": "0.1.683",
3
+ "version": "0.1.685",
4
4
  "description": "Physics and netcode SDK for multiplayer game servers",
5
5
  "type": "module",
6
6
  "workspaces": [