@dcl-regenesislabs/bevy-explorer-web 0.1.0-30459451893.commit-81261ec → 0.1.0-30919084774.commit-e4fb497
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/assets/{Showcase-CaAXbFEg.js → Showcase-c98NYstO.js} +1 -1
- package/assets/{design-AkYQWR_q.js → design-H00ZXCGo.js} +1 -1
- package/assets/{index-1kXKOKzS.css → index-C0aNBww_.css} +1 -1
- package/assets/{index-B7P8SpTv.js → index-D1Ns6Ojf.js} +3 -3
- package/assets/{menus-BIKpIlPY.js → menus-FQ5bowl0.js} +1 -1
- package/assets/{vendor-BdSytRLl.css → vendor-1M5K-HyI.css} +1 -1
- package/assets/{vendor-IF3ckP4d.js → vendor-9zEBwSKp.js} +1 -1
- package/bridge-scene/static/BevyExplorerUI/about +1 -1
- package/bridge-scene/static/{bafkreicwcpndtmtjlha6jhggbeh3533l2odvlfhdv6pz4jkxk6r636f4ue → bafkreiarx6gwfip7unm5ejm6de66gt6hv2icjiefgojoxwi6gwfzacdwoa} +1 -1
- package/engine/boot.js +72 -4
- package/engine/pkg/webgpu_build_bg.wasm +0 -0
- package/index.html +17 -17
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
1
|
+
@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2)format("woff2-variations");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2)format("woff2-variations");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2)format("woff2-variations");unicode-range:U+1F??}@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/inter-greek-wght-normal-CkhJZR-_.woff2)format("woff2-variations");unicode-range:U+370-377,U+37A-37F,U+384-38A,U+38C,U+38E-3A1,U+3A3-3FF}@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2)format("woff2-variations");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2)format("woff2-variations");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/inter-latin-wght-normal-Dx4kXJAl.woff2)format("woff2-variations");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime-D9-fqq9M.js";import{M as t,N as n}from"./design-
|
|
1
|
+
import{t as e}from"./rolldown-runtime-D9-fqq9M.js";import{M as t,N as n}from"./design-H00ZXCGo.js";var r=e((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0<n;){var r=n-1>>>1,a=e[r];if(0<i(a,t))e[r]=t,e[n]=a,n=r;else break a}}function n(e){return e.length===0?null:e[0]}function r(e){if(e.length===0)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;a:for(var r=0,a=e.length,o=a>>>1;r<o;){var s=2*(r+1)-1,c=e[s],l=s+1,u=e[l];if(0>i(c,n))l<a&&0>i(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(l<a&&0>i(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,ee||(ee=!0,oe());else{var t=n(l);t!==null&&le(x,t.startTime-e)}}var ee=!1,te=-1,ne=5,re=-1;function ie(){return g?!0:!(e.unstable_now()-re<ne)}function ae(){if(g=!1,ee){var t=e.unstable_now();re=t;var i=!0;try{a:{m=!1,h&&(h=!1,v(te),te=-1),p=!0;var a=f;try{b:{for(b(t),d=n(c);d!==null&&!(d.expirationTime>t&&ie());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&le(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?oe():ee=!1}}}var oe;if(typeof y==`function`)oe=function(){y(ae)};else if(typeof MessageChannel<`u`){var se=new MessageChannel,ce=se.port2;se.port1.onmessage=ae,oe=function(){ce.postMessage(null)}}else oe=function(){_(ae,0)};function le(t,n){te=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125<e?console.error(`forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported`):ne=0<e?Math.floor(1e3/e):5},e.unstable_getCurrentPriorityLevel=function(){return f},e.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},e.unstable_requestPaint=function(){g=!0},e.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},e.unstable_scheduleCallback=function(r,i,a){var o=e.unstable_now();switch(typeof a==`object`&&a?(a=a.delay,a=typeof a==`number`&&0<a?o+a:o):a=o,r){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return s=a+s,r={id:u++,callback:i,priorityLevel:r,startTime:a,expirationTime:s,sortIndex:-1},a>o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(te),te=-1):h=!0,le(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,ee||(ee=!0,oe()))),r},e.unstable_shouldYield=ie,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),i=e(((e,t)=>{t.exports=r()})),a=e((e=>{var r=i(),a=n(),o=t();function s(e){var t=`https://react.dev/errors/`+e;if(1<arguments.length){t+=`?args[]=`+encodeURIComponent(arguments[1]);for(var n=2;n<arguments.length;n++)t+=`&args[]=`+encodeURIComponent(arguments[n])}return`Minified React error #`+e+`; visit `+t+` for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`}function c(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11)}function l(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do t=e,t.flags&4098&&(n=t.return),e=t.return;while(e)}return t.tag===3?n:null}function u(e){if(e.tag===13){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function d(e){if(e.tag===31){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function f(e){if(l(e)!==e)throw Error(s(188))}function p(e){var t=e.alternate;if(!t){if(t=l(e),t===null)throw Error(s(188));return t===e?e:null}for(var n=e,r=t;;){var i=n.return;if(i===null)break;var a=i.alternate;if(a===null){if(r=i.return,r!==null){n=r;continue}break}if(i.child===a.child){for(a=i.child;a;){if(a===n)return f(i),e;if(a===r)return f(i),t;a=a.sibling}throw Error(s(188))}if(n.return!==r.return)n=i,r=a;else{for(var o=!1,c=i.child;c;){if(c===n){o=!0,n=i,r=a;break}if(c===r){o=!0,r=i,n=a;break}c=c.sibling}if(!o){for(c=a.child;c;){if(c===n){o=!0,n=a,r=i;break}if(c===r){o=!0,r=a,n=i;break}c=c.sibling}if(!o)throw Error(s(189))}}if(n.alternate!==r)throw Error(s(190))}if(n.tag!==3)throw Error(s(188));return n.stateNode.current===n?e:t}function m(e){var t=e.tag;if(t===5||t===26||t===27||t===6)return e;for(e=e.child;e!==null;){if(t=m(e),t!==null)return t;e=e.sibling}return null}var h=Object.assign,g=Symbol.for(`react.element`),_=Symbol.for(`react.transitional.element`),v=Symbol.for(`react.portal`),y=Symbol.for(`react.fragment`),b=Symbol.for(`react.strict_mode`),x=Symbol.for(`react.profiler`),ee=Symbol.for(`react.consumer`),te=Symbol.for(`react.context`),ne=Symbol.for(`react.forward_ref`),re=Symbol.for(`react.suspense`),ie=Symbol.for(`react.suspense_list`),ae=Symbol.for(`react.memo`),oe=Symbol.for(`react.lazy`),se=Symbol.for(`react.activity`),ce=Symbol.for(`react.memo_cache_sentinel`),le=Symbol.iterator;function ue(e){return typeof e!=`object`||!e?null:(e=le&&e[le]||e[`@@iterator`],typeof e==`function`?e:null)}var de=Symbol.for(`react.client.reference`);function fe(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===de?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case y:return`Fragment`;case x:return`Profiler`;case b:return`StrictMode`;case re:return`Suspense`;case ie:return`SuspenseList`;case se:return`Activity`}if(typeof e==`object`)switch(e.$$typeof){case v:return`Portal`;case te:return e.displayName||`Context`;case ee:return(e._context.displayName||`Context`)+`.Consumer`;case ne:var t=e.render;return e=e.displayName,e||=(e=t.displayName||t.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case ae:return t=e.displayName||null,t===null?fe(e.type)||`Memo`:t;case oe:t=e._payload,e=e._init;try{return fe(e(t))}catch{}}return null}var pe=Array.isArray,S=a.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,C=o.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,me={pending:!1,data:null,method:null,action:null},he=[],ge=-1;function _e(e){return{current:e}}function w(e){0>ge||(e.current=he[ge],he[ge]=null,ge--)}function T(e,t){ge++,he[ge]=e.current,e.current=t}var ve=_e(null),ye=_e(null),be=_e(null),xe=_e(null);function Se(e,t){switch(T(be,t),T(ye,e),T(ve,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}w(ve),T(ve,e)}function Ce(){w(ve),w(ye),w(be)}function we(e){e.memoizedState!==null&&T(xe,e);var t=ve.current,n=Hd(t,e.type);t!==n&&(T(ye,e),T(ve,n))}function Te(e){ye.current===e&&(w(ve),w(ye)),xe.current===e&&(w(xe),Qf._currentValue=me)}var Ee,De;function Oe(e){if(Ee===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);Ee=t&&t[1]||``,De=-1<e.stack.indexOf(`
|
|
2
2
|
at`)?` (<anonymous>)`:-1<e.stack.indexOf(`@`)?`@unknown:0:0`:``}return`
|
|
3
3
|
`+Ee+e+De}var ke=!1;function Ae(e,t){if(!e||ke)return``;ke=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var r={DetermineComponentFrameRoot:function(){try{if(t){var n=function(){throw Error()};if(Object.defineProperty(n.prototype,"props",{set:function(){throw Error()}}),typeof Reflect==`object`&&Reflect.construct){try{Reflect.construct(n,[])}catch(e){var r=e}Reflect.construct(e,[],n)}else{try{n.call()}catch(e){r=e}e.call(n.prototype)}}else{try{throw Error()}catch(e){r=e}(n=e())&&typeof n.catch==`function`&&n.catch(function(){})}}catch(e){if(e&&r&&typeof e.stack==`string`)return[e.stack,r.stack]}return[null,null]}};r.DetermineComponentFrameRoot.displayName=`DetermineComponentFrameRoot`;var i=Object.getOwnPropertyDescriptor(r.DetermineComponentFrameRoot,`name`);i&&i.configurable&&Object.defineProperty(r.DetermineComponentFrameRoot,"name",{value:`DetermineComponentFrameRoot`});var a=r.DetermineComponentFrameRoot(),o=a[0],s=a[1];if(o&&s){var c=o.split(`
|
|
4
4
|
`),l=s.split(`
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"networkId": 0,
|
|
14
14
|
"globalScenesUrn": [],
|
|
15
15
|
"scenesUrn": [
|
|
16
|
-
"urn:decentraland:entity:
|
|
16
|
+
"urn:decentraland:entity:bafkreiarx6gwfip7unm5ejm6de66gt6hv2icjiefgojoxwi6gwfzacdwoa?=&baseUrl=https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/bridge-scene/static/"
|
|
17
17
|
],
|
|
18
18
|
"realmName": "BevyExplorerUI"
|
|
19
19
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"content":[{"file":"scene.json","hash":"bafkreidfb7vvixnyvoghjymlxn7dua6tl2rnscnhgj6yrk5cx3gr2dc3r4"},{"file":"main.crdt","hash":"bafkreihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku"},{"file":"images/icon-verified.png","hash":"bafkreiekho3ovv3r2wab75y2eanajcdcul3er4i73lk3gdl2ppher7nkxa"},{"file":"bin/index.js","hash":"bafybeiftxd6fnajhr5oajfmpjkbuofomyhgtjhyamm6nsy3vf4oany7yj4"}],"pointers":[],"timestamp":
|
|
1
|
+
{"content":[{"file":"scene.json","hash":"bafkreidfb7vvixnyvoghjymlxn7dua6tl2rnscnhgj6yrk5cx3gr2dc3r4"},{"file":"main.crdt","hash":"bafkreihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku"},{"file":"images/icon-verified.png","hash":"bafkreiekho3ovv3r2wab75y2eanajcdcul3er4i73lk3gdl2ppher7nkxa"},{"file":"bin/index.js","hash":"bafybeiftxd6fnajhr5oajfmpjkbuofomyhgtjhyamm6nsy3vf4oany7yj4"}],"pointers":[],"timestamp":1785856132054,"type":"scene","metadata":{"ecs7":true,"runtimeVersion":"7","display":{"title":"UI Scene","description":"UI Scene shows a functional UI for Bevy Explorer","navmapThumbnail":"scene-thumbnail.png","favicon":"favicon_asset"},"owner":"","contact":{"name":"SDK","email":""},"main":"bin/index.js","tags":[],"scene":{"parcels":["0,0"],"base":"0,0"},"spawnPoints":[],"featureToggles":{"voiceChat":"enabled","portableExperiences":"enabled"}},"version":"v3"}
|
package/engine/boot.js
CHANGED
|
@@ -47,6 +47,11 @@ publish()
|
|
|
47
47
|
// (window.__onEngineCrash) — React shows the error modal; there is no overlay here.
|
|
48
48
|
;(function () {
|
|
49
49
|
let shown = false
|
|
50
|
+
// Set when the crash came from the FLOOD detector: there the heartbeat never stopped, so
|
|
51
|
+
// "frames resumed" is not evidence of recovery — only a host dismiss (__rearmCrashWatchdog)
|
|
52
|
+
// clears this latch. Without it the stall watchdog's auto-rearm would clear `shown` ~4s in,
|
|
53
|
+
// the still-running flood would re-trip, and the crash cycle would repeat forever.
|
|
54
|
+
let floodLatched = false
|
|
50
55
|
let lastError = null
|
|
51
56
|
let lastBeat = 0
|
|
52
57
|
let beatsSeen = false
|
|
@@ -55,6 +60,26 @@ publish()
|
|
|
55
60
|
const HANG_TICKS = 8 // ~16s with no corroborating error
|
|
56
61
|
const ERROR_CONFIRM_TICKS = 2 // ~4s after a recorded error
|
|
57
62
|
|
|
63
|
+
// "Alive but rendering-dead" detector. The stall watchdog above only catches a FROZEN engine (the
|
|
64
|
+
// heartbeat stops). A render loop that keeps beating while every frame throws the SAME error — e.g. a
|
|
65
|
+
// wgpu pipeline/attachment mismatch that blanks the screen and spams the console — sails past it, so
|
|
66
|
+
// catch it by the flood: the same fatal-class engine error repeating FATAL_REPEATS times within
|
|
67
|
+
// FATAL_WINDOW_MS ⇒ runtime crash. Scene (UGC) console.error lives in the sandbox WORKER's own
|
|
68
|
+
// console and never reaches this main-thread patch, so this stream is engine-core only. Signatures are
|
|
69
|
+
// whitespace-normalized but otherwise EXACT (numbers/urls kept) so distinct errors — different assets,
|
|
70
|
+
// different coords — never pool into one false flood; only a truly identical per-frame error trips it.
|
|
71
|
+
const FATAL_REPEATS = 30
|
|
72
|
+
const FATAL_WINDOW_MS = 4000
|
|
73
|
+
// Only these engine messages can trip the flood. A healthy session floods the console with benign
|
|
74
|
+
// ERROR lines at exactly this rate — a 404 asset retried per frame by bevy_asset, comms "channel
|
|
75
|
+
// closed" during startup — so an allowlist, not a denylist, is what keeps the modal off a working
|
|
76
|
+
// world. `captured wgpu error` is src/lib.rs's on_uncaptured_error handler: the device-level GPU
|
|
77
|
+
// fault that blanks the screen while the render loop keeps beating.
|
|
78
|
+
const FATAL_SIGNALS = ['captured wgpu error']
|
|
79
|
+
// signature -> { count, since }. Per-signature counters (not a single last-seen key) so an identical
|
|
80
|
+
// per-frame error still floods even when the loop interleaves it with a second error each frame.
|
|
81
|
+
const floodCounts = new Map()
|
|
82
|
+
|
|
58
83
|
const nowMs = () => (window.performance?.now ? performance.now() : Date.now())
|
|
59
84
|
const errMessage = (err) => {
|
|
60
85
|
if (!err) return 'Unknown error'
|
|
@@ -62,9 +87,10 @@ publish()
|
|
|
62
87
|
return err.message || err.stack || String(err)
|
|
63
88
|
}
|
|
64
89
|
|
|
65
|
-
function crash(err, source) {
|
|
90
|
+
function crash(err, source, latch) {
|
|
66
91
|
if (shown) return
|
|
67
92
|
shown = true
|
|
93
|
+
if (latch) floodLatched = true
|
|
68
94
|
const msg = errMessage(err)
|
|
69
95
|
console.error('[crash watchdog]', source || 'error', err)
|
|
70
96
|
try {
|
|
@@ -75,11 +101,13 @@ publish()
|
|
|
75
101
|
// Re-arm from a clean slate (host dismissed the modal, or frames resumed).
|
|
76
102
|
function rearm() {
|
|
77
103
|
shown = false
|
|
104
|
+
floodLatched = false
|
|
78
105
|
lastError = null
|
|
79
106
|
lastBeat = nowMs()
|
|
80
107
|
missedTicks = 0
|
|
81
108
|
recoverTicks = 0
|
|
82
109
|
lastBeatCount = beatCount
|
|
110
|
+
floodCounts.clear()
|
|
83
111
|
window.__bevyPanic = undefined
|
|
84
112
|
}
|
|
85
113
|
window.__rearmCrashWatchdog = rearm
|
|
@@ -90,8 +118,31 @@ publish()
|
|
|
90
118
|
}
|
|
91
119
|
window.reportEngineError = recordError
|
|
92
120
|
|
|
93
|
-
//
|
|
94
|
-
|
|
121
|
+
// Collapse whitespace only (keep numbers/urls) so "the same error" groups but distinct ones don't.
|
|
122
|
+
const signature = (msg) => String(msg).replace(/\s+/g, ' ').trim().slice(0, 300)
|
|
123
|
+
|
|
124
|
+
// Flood detector (see FATAL_REPEATS above): an identical engine-core error repeating every frame is a
|
|
125
|
+
// running-but-dead loop the stall watchdog can't see. Latched via `shown`; rearm() clears the counters.
|
|
126
|
+
function considerFatalRepeat(msg) {
|
|
127
|
+
if (shown) return
|
|
128
|
+
if (!FATAL_SIGNALS.some((s) => msg.indexOf(s) !== -1)) return
|
|
129
|
+
const key = signature(msg)
|
|
130
|
+
const now = nowMs()
|
|
131
|
+
let e = floodCounts.get(key)
|
|
132
|
+
if (!e || now - e.since > FATAL_WINDOW_MS) {
|
|
133
|
+
e = { count: 0, since: now }
|
|
134
|
+
floodCounts.set(key, e)
|
|
135
|
+
}
|
|
136
|
+
if (++e.count >= FATAL_REPEATS) crash(msg, 'runtime', true)
|
|
137
|
+
// Bound memory: drop signatures whose window has lapsed once the map grows.
|
|
138
|
+
if (floodCounts.size > 64) {
|
|
139
|
+
for (const [k, v] of floodCounts) if (now - v.since > FATAL_WINDOW_MS) floodCounts.delete(k)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Capture Rust panic text: the wasm panic hook prints "panicked at …" via console.error (the only
|
|
144
|
+
// engine path that uses that channel — wasm-bindgen's __wbg_error), while the throw that surfaces
|
|
145
|
+
// is a generic trap — stash the readable message for the host.
|
|
95
146
|
const origConsoleError = console.error.bind(console)
|
|
96
147
|
console.error = function () {
|
|
97
148
|
try {
|
|
@@ -104,6 +155,20 @@ publish()
|
|
|
104
155
|
return origConsoleError.apply(console, arguments)
|
|
105
156
|
}
|
|
106
157
|
|
|
158
|
+
// Engine LOG lines — including every error!() — come through console.LOG, not console.error:
|
|
159
|
+
// bevy_log's wasm path (LogPlugin with no custom_layer) is tracing-wasm, whose only console
|
|
160
|
+
// binding is `log`. Each event is a 4-arg styled call whose first argument starts with the level
|
|
161
|
+
// ("%cERROR%c src/lib.rs:505 …"). So the flood detector has to listen here, or the wgpu storm this
|
|
162
|
+
// watchdog exists for never reaches it. FATAL_SIGNALS keeps the benign ERROR spam out.
|
|
163
|
+
const origConsoleLog = console.log.bind(console)
|
|
164
|
+
console.log = function () {
|
|
165
|
+
try {
|
|
166
|
+
const first = arguments[0]
|
|
167
|
+
if (typeof first === 'string') considerFatalRepeat(first)
|
|
168
|
+
} catch (_) {}
|
|
169
|
+
return origConsoleLog.apply(console, arguments)
|
|
170
|
+
}
|
|
171
|
+
|
|
107
172
|
window.__engineHeartbeat = () => {
|
|
108
173
|
lastBeat = nowMs()
|
|
109
174
|
beatsSeen = true
|
|
@@ -124,7 +189,10 @@ publish()
|
|
|
124
189
|
lastBeatCount = beatCount
|
|
125
190
|
|
|
126
191
|
if (shown) {
|
|
127
|
-
// Frames back for two consecutive ticks → transient stall, re-arm.
|
|
192
|
+
// Frames back for two consecutive ticks → transient stall, re-arm. Never for a flood crash:
|
|
193
|
+
// there the frames never stopped (that's the whole point), so this would clear the latch and
|
|
194
|
+
// let the ongoing flood re-trip every few seconds. Only a host dismiss re-arms that one.
|
|
195
|
+
if (floodLatched) return
|
|
128
196
|
recoverTicks = advanced ? recoverTicks + 1 : 0
|
|
129
197
|
if (recoverTicks >= 2) rearm()
|
|
130
198
|
return
|
|
Binary file
|
package/index.html
CHANGED
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
/>
|
|
11
11
|
<meta name="theme-color" content="#2c1442" />
|
|
12
12
|
<!-- Favicons (same art as the engine page's set). Vite rebases these for the CDN base. -->
|
|
13
|
-
<link rel="icon" type="image/png" href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
14
|
-
<link rel="icon" type="image/svg+xml" href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
15
|
-
<link rel="shortcut icon" href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
16
|
-
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
13
|
+
<link rel="icon" type="image/png" href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/favicon/favicon-96x96.png" sizes="96x96" />
|
|
14
|
+
<link rel="icon" type="image/svg+xml" href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/favicon/favicon.svg" />
|
|
15
|
+
<link rel="shortcut icon" href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/favicon/favicon.ico" />
|
|
16
|
+
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/favicon/apple-touch-icon.png" />
|
|
17
17
|
<meta name="apple-mobile-web-app-title" content="Decentraland Web" />
|
|
18
|
-
<link rel="manifest" href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
18
|
+
<link rel="manifest" href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/favicon/site.webmanifest" />
|
|
19
19
|
<!-- Social cards -->
|
|
20
20
|
<meta property="og:title" content="Decentraland" />
|
|
21
21
|
<meta property="og:description" content="Explore a social virtual world from your browser." />
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
<meta name="twitter:card" content="summary" />
|
|
24
24
|
<!-- The loading overlay's full-screen backdrop (1.7MB). Prefetch it during the login screen
|
|
25
25
|
(low priority, won't fight first paint) so it's cached before we enter and freeze. -->
|
|
26
|
-
<link rel="prefetch" as="image" href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
26
|
+
<link rel="prefetch" as="image" href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/login/gradient-background.webp" />
|
|
27
27
|
<style>
|
|
28
28
|
/* Instant branded first paint. The JS bundle + React mount take a moment (longer over a slow
|
|
29
29
|
tunnel/network) and #root is empty until then — without this the page flashes white. This
|
|
@@ -71,16 +71,16 @@
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
</style>
|
|
74
|
-
<script type="module" crossorigin src="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
75
|
-
<link rel="modulepreload" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
76
|
-
<link rel="modulepreload" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
77
|
-
<link rel="modulepreload" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
78
|
-
<link rel="modulepreload" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
79
|
-
<link rel="modulepreload" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
80
|
-
<link rel="stylesheet" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
81
|
-
<link rel="stylesheet" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
82
|
-
<link rel="stylesheet" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
83
|
-
<link rel="stylesheet" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
74
|
+
<script type="module" crossorigin src="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/index-D1Ns6Ojf.js"></script>
|
|
75
|
+
<link rel="modulepreload" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/rolldown-runtime-D9-fqq9M.js">
|
|
76
|
+
<link rel="modulepreload" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/design-H00ZXCGo.js">
|
|
77
|
+
<link rel="modulepreload" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/vendor-9zEBwSKp.js">
|
|
78
|
+
<link rel="modulepreload" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/menus-FQ5bowl0.js">
|
|
79
|
+
<link rel="modulepreload" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/emoji-DrfHOLaz.js">
|
|
80
|
+
<link rel="stylesheet" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/design-BdxsbUvY.css">
|
|
81
|
+
<link rel="stylesheet" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/vendor-1M5K-HyI.css">
|
|
82
|
+
<link rel="stylesheet" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/menus-BDWqQaLj.css">
|
|
83
|
+
<link rel="stylesheet" crossorigin href="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/index-C0aNBww_.css">
|
|
84
84
|
</head>
|
|
85
85
|
<body>
|
|
86
86
|
<!-- React HUD mounts here; the engine runs in a same-origin iframe rendered
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
pre-React branded splash; createRoot() clears it on mount. -->
|
|
89
89
|
<div id="root">
|
|
90
90
|
<div id="boot-splash">
|
|
91
|
-
<img src="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
91
|
+
<img src="https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497/assets/logo.png" alt="" />
|
|
92
92
|
<h1>Decentraland</h1>
|
|
93
93
|
</div>
|
|
94
94
|
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcl-regenesislabs/bevy-explorer-web",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-30919084774.commit-e4fb497",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"postinstall": "node ./scripts/prebuild.js"
|
|
6
6
|
},
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://github.com/decentraland/bevy-explorer.git"
|
|
10
10
|
},
|
|
11
|
-
"homepage": "https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-
|
|
12
|
-
"commit": "
|
|
11
|
+
"homepage": "https://cdn.decentraland.org/@dcl-regenesislabs/bevy-explorer-web/0.1.0-30919084774.commit-e4fb497",
|
|
12
|
+
"commit": "e4fb4974ff8b109caa8839f864228b2f89a89784"
|
|
13
13
|
}
|