@dcl-regenesislabs/bevy-explorer-web 0.1.0-18229784557.commit-ef374b9
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/asset_loader.js +31 -0
- package/assets/animations/Dance_Female.glb +0 -0
- package/assets/animations/Dance_Male.glb +0 -0
- package/assets/animations/F_FistPump.glb +0 -0
- package/assets/animations/F_RobotDance.glb +0 -0
- package/assets/animations/Hands_Air.glb +0 -0
- package/assets/animations/M_FistPump.glb +0 -0
- package/assets/animations/M_RobotDance.glb +0 -0
- package/assets/animations/Raise_Hand.glb +0 -0
- package/assets/animations/Throw Money-Emote.glb +0 -0
- package/assets/animations/Wave_Female.glb +0 -0
- package/assets/animations/Wave_Male.glb +0 -0
- package/assets/animations/clap.glb +0 -0
- package/assets/animations/disco_dance.glb +0 -0
- package/assets/animations/dont_wanna_see.glb +0 -0
- package/assets/animations/f_head_explode.glb +0 -0
- package/assets/animations/idle.glb +0 -0
- package/assets/animations/jump2.glb +0 -0
- package/assets/animations/kiss.glb +0 -0
- package/assets/animations/m_head_explode.glb +0 -0
- package/assets/animations/mchammer-dance.glb +0 -0
- package/assets/animations/run.glb +0 -0
- package/assets/animations/shrug.glb +0 -0
- package/assets/animations/tektonik-dance.glb +0 -0
- package/assets/animations/thumbnails/clap.png +0 -0
- package/assets/animations/thumbnails/dance.png +0 -0
- package/assets/animations/thumbnails/disco.png +0 -0
- package/assets/animations/thumbnails/dontsee.png +0 -0
- package/assets/animations/thumbnails/fistpump.png +0 -0
- package/assets/animations/thumbnails/hammer.png +0 -0
- package/assets/animations/thumbnails/handsair.png +0 -0
- package/assets/animations/thumbnails/headexplode.png +0 -0
- package/assets/animations/thumbnails/kiss.png +0 -0
- package/assets/animations/thumbnails/money.png +0 -0
- package/assets/animations/thumbnails/raisehand.png +0 -0
- package/assets/animations/thumbnails/robot.png +0 -0
- package/assets/animations/thumbnails/shrug.png +0 -0
- package/assets/animations/thumbnails/tektonik.png +0 -0
- package/assets/animations/thumbnails/tik.png +0 -0
- package/assets/animations/thumbnails/wave.png +0 -0
- package/assets/animations/tik-tok-dance.glb +0 -0
- package/assets/animations/walk.glb +0 -0
- package/assets/fonts/NotoSans-Bold.ttf +0 -0
- package/assets/fonts/NotoSans-BoldItalic.ttf +0 -0
- package/assets/fonts/NotoSans-Italic.ttf +0 -0
- package/assets/fonts/NotoSans-Regular.ttf +0 -0
- package/assets/fonts/NotoSansMono-Bold.ttf +0 -0
- package/assets/fonts/NotoSansMono-Regular.ttf +0 -0
- package/assets/fonts/NotoSerif-Bold.ttf +0 -0
- package/assets/fonts/NotoSerif-BoldItalic.ttf +0 -0
- package/assets/fonts/NotoSerif-Italic.ttf +0 -0
- package/assets/fonts/NotoSerif-Regular.ttf +0 -0
- package/assets/fonts/OFL.txt +93 -0
- package/assets/images/FriendsIcon.png +0 -0
- package/assets/images/ask.png +0 -0
- package/assets/images/backpack/Background.jpeg +0 -0
- package/assets/images/backpack/empty.png +0 -0
- package/assets/images/backpack/item_bg.png +0 -0
- package/assets/images/backpack/wearable_categories/body_shape.png +0 -0
- package/assets/images/backpack/wearable_categories/earring.png +0 -0
- package/assets/images/backpack/wearable_categories/eyebrows.png +0 -0
- package/assets/images/backpack/wearable_categories/eyes.png +0 -0
- package/assets/images/backpack/wearable_categories/eyewear.png +0 -0
- package/assets/images/backpack/wearable_categories/facial_hair.png +0 -0
- package/assets/images/backpack/wearable_categories/feet.png +0 -0
- package/assets/images/backpack/wearable_categories/hair.png +0 -0
- package/assets/images/backpack/wearable_categories/hands_wear.png +0 -0
- package/assets/images/backpack/wearable_categories/hat.png +0 -0
- package/assets/images/backpack/wearable_categories/helmet.png +0 -0
- package/assets/images/backpack/wearable_categories/lower_body.png +0 -0
- package/assets/images/backpack/wearable_categories/mask.png +0 -0
- package/assets/images/backpack/wearable_categories/mouth.png +0 -0
- package/assets/images/backpack/wearable_categories/skin.png +0 -0
- package/assets/images/backpack/wearable_categories/tiara.png +0 -0
- package/assets/images/backpack/wearable_categories/top_head.png +0 -0
- package/assets/images/backpack/wearable_categories/upper_body.png +0 -0
- package/assets/images/button copy.png +0 -0
- package/assets/images/button.png +0 -0
- package/assets/images/button_base.png +0 -0
- package/assets/images/chat_button.png +0 -0
- package/assets/images/copy.png +0 -0
- package/assets/images/crosshair.png +0 -0
- package/assets/images/cursor.png +0 -0
- package/assets/images/dao_small.png +0 -0
- package/assets/images/dcl-godot-bevy.png +0 -0
- package/assets/images/discover/art.png +0 -0
- package/assets/images/discover/business.png +0 -0
- package/assets/images/discover/casino.png +0 -0
- package/assets/images/discover/crypto.png +0 -0
- package/assets/images/discover/education.png +0 -0
- package/assets/images/discover/eye.png +0 -0
- package/assets/images/discover/fashion.png +0 -0
- package/assets/images/discover/featured.png +0 -0
- package/assets/images/discover/game.png +0 -0
- package/assets/images/discover/icons.png +0 -0
- package/assets/images/discover/music.png +0 -0
- package/assets/images/discover/point of interest.png +0 -0
- package/assets/images/discover/shop.png +0 -0
- package/assets/images/discover/social.png +0 -0
- package/assets/images/discover/sports.png +0 -0
- package/assets/images/discover/thumbsup.png +0 -0
- package/assets/images/emote-button-background.png +0 -0
- package/assets/images/emote_button.png +0 -0
- package/assets/images/genesis_tx.png +0 -0
- package/assets/images/grid.png +0 -0
- package/assets/images/grip.png +0 -0
- package/assets/images/left-arrow.png +0 -0
- package/assets/images/line.png +0 -0
- package/assets/images/mic_button_inactive.png +0 -0
- package/assets/images/mic_button_off.png +0 -0
- package/assets/images/mic_button_on.png +0 -0
- package/assets/images/next.png +0 -0
- package/assets/images/person.png +0 -0
- package/assets/images/person_button.png +0 -0
- package/assets/images/profile_button.png +0 -0
- package/assets/images/redx.png +0 -0
- package/assets/images/right-arrow.png +0 -0
- package/assets/images/screenshots/montage.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_avatar_attach_1.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_avatar_attach_2.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_avatar_attach_3.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_avatar_attach_4.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_gltfcontainer_avocado.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_gltfcontainer_hev.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_01.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_02.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_03.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_04.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_05.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_06.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_07.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_08.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_09.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_10.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_11.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_12.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_13.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_material_14.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_mesh_renderer_box.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_mesh_renderer_cylinder.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_mesh_renderer_plane.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_mesh_renderer_sphere.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_text_shape_1.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_text_shape_2.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_text_shape_3.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_text_shape_4.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_text_shape_5.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_text_shape_6.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_ui_background_all_screen_green.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_ui_background_all_screen_red.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_ui_background_all_screen_rocks.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_ui_text_1.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_ui_text_2.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_video_player_1.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_video_player_2.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_video_player_3.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_video_player_4.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_visibility_false.png.png +0 -0
- package/assets/images/screenshots/screenshot%2Fbevy_snapshot_visibility_true.png.png +0 -0
- package/assets/images/skybox/skybox_cubemap.png +0 -0
- package/assets/images/skybox/skybox_cubemap_original.png +0 -0
- package/assets/images/spinner.png +0 -0
- package/assets/images/spinner_atlas.png +0 -0
- package/assets/images/tick.png +0 -0
- package/assets/images/toggle-off.png +0 -0
- package/assets/images/toggle-on.png +0 -0
- package/assets/images/unknown_person.png +0 -0
- package/assets/images/you_are_here.png +0 -0
- package/assets/nft_shapes/Baroque_Ornament.glb +0 -0
- package/assets/nft_shapes/Blocky.glb +0 -0
- package/assets/nft_shapes/Canvas.glb +0 -0
- package/assets/nft_shapes/Classic.glb +0 -0
- package/assets/nft_shapes/Diamond_Ornament.glb +0 -0
- package/assets/nft_shapes/Floor_Wood01.png +0 -0
- package/assets/nft_shapes/Genesis_TX.png +0 -0
- package/assets/nft_shapes/Gold_Carved.glb +0 -0
- package/assets/nft_shapes/Gold_Edges.glb +0 -0
- package/assets/nft_shapes/Gold_Rounded.glb +0 -0
- package/assets/nft_shapes/Gold_Wide.glb +0 -0
- package/assets/nft_shapes/Metal_Medium.glb +0 -0
- package/assets/nft_shapes/Metal_Rounded.glb +0 -0
- package/assets/nft_shapes/Metal_Slim.glb +0 -0
- package/assets/nft_shapes/Metal_Wide.glb +0 -0
- package/assets/nft_shapes/Minimal_Black.glb +0 -0
- package/assets/nft_shapes/Minimal_Grey.glb +0 -0
- package/assets/nft_shapes/Minimal_White.glb +0 -0
- package/assets/nft_shapes/Minimal_Wide.glb +0 -0
- package/assets/nft_shapes/MulticolorDotsLoading.png +0 -0
- package/assets/nft_shapes/NFTIcon.png +0 -0
- package/assets/nft_shapes/NoneIcon.png +0 -0
- package/assets/nft_shapes/Pins.glb +0 -0
- package/assets/nft_shapes/Tape.glb +0 -0
- package/assets/nft_shapes/Wood_Slim.glb +0 -0
- package/assets/nft_shapes/Wood_Twigs.glb +0 -0
- package/assets/nft_shapes/Wood_Wide.glb +0 -0
- package/assets/shaders/bound_material.wgsl +183 -0
- package/assets/shaders/bound_material_baker.wgsl +145 -0
- package/assets/shaders/bound_node.wgsl +57 -0
- package/assets/shaders/bound_prepass.wgsl +160 -0
- package/assets/shaders/floor_bake.wgsl +30 -0
- package/assets/shaders/floor_fragment.wgsl +74 -0
- package/assets/shaders/floor_vertex.wgsl +47 -0
- package/assets/shaders/loading.wgsl +35 -0
- package/assets/shaders/mask_material.wgsl +117 -0
- package/assets/shaders/nineslice_material.wgsl +47 -0
- package/assets/shaders/nishita_cloud.wgsl +378 -0
- package/assets/shaders/outline.wgsl +69 -0
- package/assets/shaders/simplex.wgsl +77 -0
- package/assets/shaders/stretch_uv_material.wgsl +79 -0
- package/assets/shaders/text_quad_vertex.wgsl +78 -0
- package/assets/sounds/avatar/avatar_footstep_jump01.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_jump02.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_jump03.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_land01.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_land02.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_run01.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_run02.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_run03.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_run04.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_run05.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_run06.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_run07.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_run08.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_walk01.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_walk02.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_walk03.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_walk04.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_walk05.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_walk06.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_walk07.wav +0 -0
- package/assets/sounds/avatar/avatar_footstep_walk08.wav +0 -0
- package/assets/sounds/ui/generic_button_hover.wav +0 -0
- package/assets/sounds/ui/generic_button_press.wav +0 -0
- package/assets/sounds/ui/mainmenu_widget_open.wav +0 -0
- package/assets/sounds/ui/toggle_disable.wav +0 -0
- package/assets/sounds/ui/toggle_enable.wav +0 -0
- package/assets/sounds/ui/voice_chat_mic_off.wav +0 -0
- package/assets/sounds/ui/voice_chat_mic_on.wav +0 -0
- package/assets/sounds/ui/widget_chat_message_private_send.wav +0 -0
- package/assets/sounds/ui/widget_emotes_close.wav +0 -0
- package/assets/sounds/ui/widget_emotes_highlight.wav +0 -0
- package/assets/sounds/ui/widget_emotes_open.wav +0 -0
- package/assets/ui/app_settings.dui +91 -0
- package/assets/ui/avatar.dui +18 -0
- package/assets/ui/button.dui +78 -0
- package/assets/ui/change-realm.dui +46 -0
- package/assets/ui/chat.dui +182 -0
- package/assets/ui/combo.dui +23 -0
- package/assets/ui/dialog.dui +46 -0
- package/assets/ui/discover.dui +139 -0
- package/assets/ui/emote-select.dui +45 -0
- package/assets/ui/emote.dui +116 -0
- package/assets/ui/foreign-profile-dialog.dui +18 -0
- package/assets/ui/fullscreen-block.dui +12 -0
- package/assets/ui/login.dui +72 -0
- package/assets/ui/map.dui +8 -0
- package/assets/ui/minimap.dui +16 -0
- package/assets/ui/motd.dui +25 -0
- package/assets/ui/nft-dialog.dui +29 -0
- package/assets/ui/oow.dui +41 -0
- package/assets/ui/permissions-dialog.dui +39 -0
- package/assets/ui/permissions.dui +54 -0
- package/assets/ui/profile-detail.dui +24 -0
- package/assets/ui/profile.dui +29 -0
- package/assets/ui/spinner.dui +3 -0
- package/assets/ui/toast.dui +27 -0
- package/assets/ui/tracker.dui +21 -0
- package/assets/ui/update.dui +16 -0
- package/assets/ui/utils.dui +40 -0
- package/assets/ui/wearables.dui +134 -0
- package/gpu_cache.js +302 -0
- package/index.html +134 -0
- package/main.js +284 -0
- package/package.json +9 -0
- package/sandbox_worker.js +394 -0
- package/serve.json +21 -0
- package/service_worker.js +93 -0
package/main.js
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
// Import the wasm-bindgen generated JS glue code and Rust functions
|
|
2
|
+
import { initGpuCache } from "./gpu_cache.js";
|
|
3
|
+
import init, { engine_init, engine_run } from "./pkg/webgpu_build.js"; // Ensure this path is correct
|
|
4
|
+
|
|
5
|
+
const initialRealmInput = document.getElementById("initialRealm");
|
|
6
|
+
const locationInput = document.getElementById("location");
|
|
7
|
+
const systemSceneInput = document.getElementById("systemScene");
|
|
8
|
+
const initButton = document.getElementById("initButton");
|
|
9
|
+
const canvas = document.getElementById("canvas-parent");
|
|
10
|
+
const header = document.getElementById("header");
|
|
11
|
+
|
|
12
|
+
let initialRealmGroup = document.getElementById("initialRealm")?.parentElement;
|
|
13
|
+
let locationGroup = document.getElementById("location")?.parentElement;
|
|
14
|
+
let systemSceneGroup = document.getElementById("systemScene")?.parentElement;
|
|
15
|
+
|
|
16
|
+
var autoStart = true;
|
|
17
|
+
|
|
18
|
+
function populateInputsFromQueryParams() {
|
|
19
|
+
const queryParams = new URLSearchParams(window.location.search);
|
|
20
|
+
|
|
21
|
+
const manualParams = queryParams.get("manualParams");
|
|
22
|
+
if (manualParams) {
|
|
23
|
+
autoStart = false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const initialRealmParam = queryParams.get("initialRealm");
|
|
27
|
+
if (initialRealmInput && initialRealmParam) {
|
|
28
|
+
initialRealmInput.value = decodeURIComponent(initialRealmParam);
|
|
29
|
+
} else if (initialRealmInput) {
|
|
30
|
+
initialRealmInput.value = "https://realm-provider-ea.decentraland.org/main";
|
|
31
|
+
}
|
|
32
|
+
const locationParam = queryParams.get("location");
|
|
33
|
+
if (locationInput && locationParam) {
|
|
34
|
+
locationInput.value = decodeURIComponent(locationParam);
|
|
35
|
+
} else if (locationInput) {
|
|
36
|
+
locationInput.value = "";
|
|
37
|
+
}
|
|
38
|
+
const systemSceneParam = queryParams.get("systemScene");
|
|
39
|
+
if (systemSceneInput && systemSceneParam) {
|
|
40
|
+
systemSceneInput.value = decodeURIComponent(systemSceneParam);
|
|
41
|
+
} else if (systemSceneInput) {
|
|
42
|
+
systemSceneInput.value = "https://dclexplorer.github.io/bevy-ui-scene/BevyUiScene";
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
initialRealmInput.disabled = autoStart;
|
|
46
|
+
locationInput.disabled = autoStart;
|
|
47
|
+
systemSceneInput.disabled = autoStart;
|
|
48
|
+
}
|
|
49
|
+
function hideHeader() {
|
|
50
|
+
if (header) header.style.display = "none";
|
|
51
|
+
if (canvas) canvas.style.display = "block";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if ("serviceWorker" in navigator) {
|
|
55
|
+
window.addEventListener("load", () => {
|
|
56
|
+
navigator.serviceWorker
|
|
57
|
+
.register("service_worker.js")
|
|
58
|
+
.then((registration) => {
|
|
59
|
+
console.log(
|
|
60
|
+
"Page: Service Worker registered successfully with scope: ",
|
|
61
|
+
registration.scope
|
|
62
|
+
);
|
|
63
|
+
})
|
|
64
|
+
.catch((error) => {
|
|
65
|
+
console.log("Page: Service Worker registration failed: ", error);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// make sure the worker stays around after a hard reload
|
|
70
|
+
// 1. Check if a service worker is active and controlling the page.
|
|
71
|
+
if (navigator.serviceWorker && navigator.serviceWorker.controller) {
|
|
72
|
+
// SUCCESS CASE:
|
|
73
|
+
// If the recovery flag is present, it means we just successfully
|
|
74
|
+
// recovered from a hard reload. We can now remove the flag.
|
|
75
|
+
if (sessionStorage.getItem('sw_reloaded')) {
|
|
76
|
+
console.log('Service Worker recovery successful. Cleaning up flag.');
|
|
77
|
+
sessionStorage.removeItem('sw_reloaded');
|
|
78
|
+
}
|
|
79
|
+
// Everything is fine, let the app load.
|
|
80
|
+
} else {
|
|
81
|
+
// 2. RECOVERY CASE: No service worker is in control.
|
|
82
|
+
// This could be a first visit or a hard reload.
|
|
83
|
+
if (navigator.serviceWorker && navigator.serviceWorker.getRegistration) {
|
|
84
|
+
navigator.serviceWorker.getRegistration().then(registration => {
|
|
85
|
+
// We only try to recover if a service worker is already registered.
|
|
86
|
+
if (registration) {
|
|
87
|
+
// Prevent an infinite reload loop.
|
|
88
|
+
if (sessionStorage.getItem('sw_reloaded')) {
|
|
89
|
+
sessionStorage.removeItem('sw_reloaded');
|
|
90
|
+
console.error('Service Worker failed to take control after reload.');
|
|
91
|
+
} else {
|
|
92
|
+
// Set the flag and perform a standard reload.
|
|
93
|
+
console.log('Page is uncontrolled. Reloading to activate Service Worker...');
|
|
94
|
+
sessionStorage.setItem('sw_reloaded', 'true');
|
|
95
|
+
window.location.reload();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function initEngine() {
|
|
104
|
+
populateInputsFromQueryParams();
|
|
105
|
+
|
|
106
|
+
if (initButton) {
|
|
107
|
+
initButton.disabled = true;
|
|
108
|
+
if (autoStart) {
|
|
109
|
+
initButton.textContent = "Autostarting .."
|
|
110
|
+
} else {
|
|
111
|
+
initButton.textContent = "Loading ..."
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const wasmUrl = "./pkg/webgpu_build_bg.wasm";
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
const compiledModule = await WebAssembly.compileStreaming(fetch(wasmUrl));
|
|
119
|
+
|
|
120
|
+
const initialMemoryPages = 640; // setting initial memory high causes malloc failures
|
|
121
|
+
const maximumMemoryPages = 65536;
|
|
122
|
+
const sharedMemory = new WebAssembly.Memory({
|
|
123
|
+
initial: initialMemoryPages,
|
|
124
|
+
maximum: maximumMemoryPages,
|
|
125
|
+
shared: true,
|
|
126
|
+
});
|
|
127
|
+
window.wasm_memory = sharedMemory;
|
|
128
|
+
|
|
129
|
+
window.setVideoSource = (video, src) => {
|
|
130
|
+
async function isHlsStream(url) {
|
|
131
|
+
try {
|
|
132
|
+
const response = await fetch(url, {
|
|
133
|
+
method: "HEAD",
|
|
134
|
+
mode: "cors",
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
if (!response.ok) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const contentType = response.headers.get("Content-Type");
|
|
142
|
+
|
|
143
|
+
if (contentType) {
|
|
144
|
+
return (
|
|
145
|
+
contentType.includes("application/vnd.apple.mpegurl") ||
|
|
146
|
+
contentType.includes("application/x-mpegURL")
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return false;
|
|
151
|
+
} catch (error) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (video.canPlayType("application/vnd.apple.mpegurl")) {
|
|
157
|
+
video.src = src;
|
|
158
|
+
} else if (Hls.isSupported()) {
|
|
159
|
+
// check if we need hls
|
|
160
|
+
setTimeout(async () => {
|
|
161
|
+
if (await isHlsStream(src)) {
|
|
162
|
+
var hls = new Hls();
|
|
163
|
+
hls.loadSource(src);
|
|
164
|
+
hls.attachMedia(video);
|
|
165
|
+
} else {
|
|
166
|
+
video.src = src;
|
|
167
|
+
}
|
|
168
|
+
}, 0);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
window.spawn_and_init_sandbox = async () => {
|
|
173
|
+
var timeoutId;
|
|
174
|
+
return new Promise((resolve, _reject) => {
|
|
175
|
+
// var sandboxWorker = new Worker(sandboxJs, { type: "module" });
|
|
176
|
+
var sandboxWorker = new Worker("sandbox_worker.js", { type: "module" });
|
|
177
|
+
|
|
178
|
+
var timeoutCount = 0;
|
|
179
|
+
let logTimeout = () => {
|
|
180
|
+
console.log(
|
|
181
|
+
"[Main JS] Still waiting for worker to init",
|
|
182
|
+
timeoutCount
|
|
183
|
+
);
|
|
184
|
+
timeoutCount += 1;
|
|
185
|
+
timeoutId = setTimeout(logTimeout, 5000);
|
|
186
|
+
};
|
|
187
|
+
timeoutId = setTimeout(logTimeout, 5000);
|
|
188
|
+
|
|
189
|
+
sandboxWorker.onmessage = (workerEvent) => {
|
|
190
|
+
if (workerEvent.data.type === "READY") {
|
|
191
|
+
sandboxWorker.postMessage({
|
|
192
|
+
type: "INIT_WORKER",
|
|
193
|
+
payload: {
|
|
194
|
+
compiledModule,
|
|
195
|
+
sharedMemory,
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (workerEvent.data.type === "INIT_COMPLETE") {
|
|
200
|
+
resolve();
|
|
201
|
+
}
|
|
202
|
+
if (workerEvent.data.type === "INIT_FAILED") {
|
|
203
|
+
console.log("[Main JS] Sandbox init failed; retrying");
|
|
204
|
+
sandboxWorker = new Worker(sandboxJs, { type: "module" });
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}).finally(() => {
|
|
208
|
+
clearTimeout(timeoutId);
|
|
209
|
+
});
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
await init({ module_or_path: compiledModule, memory: sharedMemory });
|
|
213
|
+
console.log("[Main JS] Main application WebAssembly module initialized.");
|
|
214
|
+
|
|
215
|
+
let res = await engine_init();
|
|
216
|
+
console.log(
|
|
217
|
+
"[Main JS] Main application WebAssembly module custom initialized: ",
|
|
218
|
+
res
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
// start asset loader thread
|
|
222
|
+
await new Promise((resolve, _reject) => {
|
|
223
|
+
const assetLoader = new Worker("asset_loader.js", { type: "module" });
|
|
224
|
+
assetLoader.onmessage = (workerEvent) => {
|
|
225
|
+
if (workerEvent.data.type === "READY") {
|
|
226
|
+
assetLoader.postMessage({
|
|
227
|
+
type: "INIT_ASSET_LOADER",
|
|
228
|
+
payload: {
|
|
229
|
+
compiledModule,
|
|
230
|
+
sharedMemory,
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
if (workerEvent.data.type === "INITIALIZED") {
|
|
235
|
+
resolve();
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
});
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.error(
|
|
241
|
+
"[Main JS] Error during Wasm initialization or setup:",
|
|
242
|
+
error
|
|
243
|
+
);
|
|
244
|
+
if (initButton) {
|
|
245
|
+
initButton.textContent = "Load Failed";
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function start() {
|
|
251
|
+
const initialRealm = initialRealmInput.value;
|
|
252
|
+
const location = locationInput.value;
|
|
253
|
+
const systemScene = systemSceneInput.value;
|
|
254
|
+
console.log(
|
|
255
|
+
`[Main JS] "Go" button clicked. Initial Realm: "${initialRealm}", Location: "${location}", System Scene: "${systemScene}"`
|
|
256
|
+
);
|
|
257
|
+
hideHeader();
|
|
258
|
+
|
|
259
|
+
const platform = (() => {
|
|
260
|
+
if (navigator.userAgent.includes("Mac")) return "macos";
|
|
261
|
+
if (navigator.userAgent.includes("Win")) return "windows";
|
|
262
|
+
if (navigator.userAgent.includes("Linux")) return "linux";
|
|
263
|
+
return "unknown";
|
|
264
|
+
})();
|
|
265
|
+
|
|
266
|
+
engine_run(platform, initialRealm, location, systemScene, true, 1e6);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
initButton.onclick = start;
|
|
270
|
+
|
|
271
|
+
Promise.all([initEngine(), initGpuCache()])
|
|
272
|
+
.then(() => {
|
|
273
|
+
if (autoStart) {
|
|
274
|
+
start()
|
|
275
|
+
} else {
|
|
276
|
+
initButton.disabled = false;
|
|
277
|
+
initButton.textContent = "Go";
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
.catch((e) => {
|
|
281
|
+
console.log("error", e);
|
|
282
|
+
initButton.textContent = "Load Failed";
|
|
283
|
+
});
|
|
284
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dcl-regenesislabs/bevy-explorer-web",
|
|
3
|
+
"version": "0.1.0-18229784557.commit-ef374b9",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/decentraland/bevy-explorer.git"
|
|
7
|
+
},
|
|
8
|
+
"commit": "ef374b9d611f6fcc5cdad1664cdbcc92d9a8a4a9"
|
|
9
|
+
}
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
// sandbox_worker.js - Runs inside the final Web Worker, the most isolated environment.
|
|
2
|
+
|
|
3
|
+
// Import the wasm-bindgen generated JS glue code.
|
|
4
|
+
import init, * as wasm_bindgen_exports from "./pkg/webgpu_build.js";
|
|
5
|
+
|
|
6
|
+
// self.WebSocket = {}
|
|
7
|
+
|
|
8
|
+
console.log("[Scene Worker] Starting");
|
|
9
|
+
|
|
10
|
+
const allowListES2020 = [
|
|
11
|
+
"Array",
|
|
12
|
+
"ArrayBuffer",
|
|
13
|
+
"BigInt",
|
|
14
|
+
"BigInt64Array",
|
|
15
|
+
"BigUint64Array",
|
|
16
|
+
"Boolean",
|
|
17
|
+
"DataView",
|
|
18
|
+
"Date",
|
|
19
|
+
"decodeURI",
|
|
20
|
+
"decodeURIComponent",
|
|
21
|
+
"encodeURI",
|
|
22
|
+
"encodeURIComponent",
|
|
23
|
+
"Error",
|
|
24
|
+
"escape",
|
|
25
|
+
"eval",
|
|
26
|
+
"EvalError",
|
|
27
|
+
"fetch",
|
|
28
|
+
"Float32Array",
|
|
29
|
+
"Float64Array",
|
|
30
|
+
"Function",
|
|
31
|
+
"Infinity",
|
|
32
|
+
"Int16Array",
|
|
33
|
+
"Int32Array",
|
|
34
|
+
"Int8Array",
|
|
35
|
+
"isFinite",
|
|
36
|
+
"isNaN",
|
|
37
|
+
"JSON",
|
|
38
|
+
"Map",
|
|
39
|
+
"Math",
|
|
40
|
+
"NaN",
|
|
41
|
+
"Number",
|
|
42
|
+
"Object",
|
|
43
|
+
"parseFloat",
|
|
44
|
+
"parseInt",
|
|
45
|
+
"Promise",
|
|
46
|
+
"Proxy",
|
|
47
|
+
"RangeError",
|
|
48
|
+
"ReferenceError",
|
|
49
|
+
"Reflect",
|
|
50
|
+
"RegExp",
|
|
51
|
+
"Set",
|
|
52
|
+
"SharedArrayBuffer",
|
|
53
|
+
"String",
|
|
54
|
+
"Symbol",
|
|
55
|
+
"SyntaxError",
|
|
56
|
+
"TypeError",
|
|
57
|
+
"Uint16Array",
|
|
58
|
+
"Uint32Array",
|
|
59
|
+
"Uint8Array",
|
|
60
|
+
"Uint8ClampedArray",
|
|
61
|
+
"undefined",
|
|
62
|
+
"unescape",
|
|
63
|
+
"URIError",
|
|
64
|
+
"WeakMap",
|
|
65
|
+
"WebSocket",
|
|
66
|
+
"WeakSet",
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
const jsContext = Object.create(null);
|
|
70
|
+
var jsProxy = undefined;
|
|
71
|
+
var jsPreamble = undefined;
|
|
72
|
+
function createJsContext(wasmApi, context) {
|
|
73
|
+
const isSuper = wasmApi.is_super(context);
|
|
74
|
+
|
|
75
|
+
Object.defineProperty(jsContext, "console", {
|
|
76
|
+
value: {
|
|
77
|
+
log: console.log.bind(console),
|
|
78
|
+
info: console.info.bind(console),
|
|
79
|
+
debug: console.debug.bind(console),
|
|
80
|
+
trace: console.trace.bind(console),
|
|
81
|
+
warning: console.error.bind(console),
|
|
82
|
+
error: console.error.bind(console),
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const ops = Object.create(null);
|
|
87
|
+
for (const exportName in wasmApi) {
|
|
88
|
+
if (exportName.substring(0, 3) === "op_") {
|
|
89
|
+
Object.defineProperty(ops, exportName, {
|
|
90
|
+
configurable: false,
|
|
91
|
+
get() {
|
|
92
|
+
return (...args) => {
|
|
93
|
+
// wrap ops to inject context arg
|
|
94
|
+
return wasmApi[exportName](context, ...args);
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const core = Object.create(null);
|
|
101
|
+
Object.defineProperty(core, "ops", {
|
|
102
|
+
configurable: false,
|
|
103
|
+
value: ops,
|
|
104
|
+
});
|
|
105
|
+
const Deno = Object.create(null);
|
|
106
|
+
Object.defineProperty(Deno, "core", {
|
|
107
|
+
configurable: false,
|
|
108
|
+
value: core,
|
|
109
|
+
});
|
|
110
|
+
Object.defineProperty(jsContext, "Deno", {
|
|
111
|
+
configurable: false,
|
|
112
|
+
value: Deno,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
Object.defineProperty(jsContext, "require", {
|
|
116
|
+
configurable: false,
|
|
117
|
+
value: require,
|
|
118
|
+
});
|
|
119
|
+
Object.defineProperty(jsContext, "localStorage", {
|
|
120
|
+
configurable: false,
|
|
121
|
+
value: createWebStorageProxy(ops),
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// if (!isSuper) {
|
|
125
|
+
// Object.defineProperty(jsContext, "fetch", {
|
|
126
|
+
// configurable: false,
|
|
127
|
+
// get() {
|
|
128
|
+
// return (url, options) => {
|
|
129
|
+
// console.error('[Sandbox worker] Fetch request to', url, 'was intentionally blocked by the proxy.');
|
|
130
|
+
// return Promise.reject(new Error('This request has been intentionally failed by the proxy.'));
|
|
131
|
+
// };
|
|
132
|
+
// }
|
|
133
|
+
// })
|
|
134
|
+
// Object.defineProperty(jsContext, "WebSocket", {
|
|
135
|
+
// configurable: false,
|
|
136
|
+
// get() {
|
|
137
|
+
// console.log("get WebSocket!!!")
|
|
138
|
+
// return {}
|
|
139
|
+
// }
|
|
140
|
+
// })
|
|
141
|
+
// }
|
|
142
|
+
|
|
143
|
+
jsProxy = new Proxy(jsContext, {
|
|
144
|
+
has() {
|
|
145
|
+
return true;
|
|
146
|
+
},
|
|
147
|
+
get(_target, propKey, _receiver) {
|
|
148
|
+
if (propKey === "eval") return eval;
|
|
149
|
+
if (propKey === "globalThis") return jsProxy;
|
|
150
|
+
if (propKey === "global") return jsProxy;
|
|
151
|
+
if (propKey === "undefined") return undefined;
|
|
152
|
+
if (jsContext[propKey] !== undefined) return jsContext[propKey];
|
|
153
|
+
if (allowListES2020.includes(propKey)) {
|
|
154
|
+
return globalThis[propKey];
|
|
155
|
+
}
|
|
156
|
+
return undefined;
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const contextKeys = Object.getOwnPropertyNames(jsContext);
|
|
161
|
+
const allGlobals = [...new Set([...allowListES2020, ...contextKeys])];
|
|
162
|
+
jsPreamble = allGlobals
|
|
163
|
+
.map((key) => `const ${key} = globalThis.${key};`)
|
|
164
|
+
.join("\n");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const defer = Promise.resolve().then.bind(Promise.resolve());
|
|
168
|
+
|
|
169
|
+
async function runWithScope(code) {
|
|
170
|
+
const module = { exports: {} };
|
|
171
|
+
|
|
172
|
+
const func = new Function(
|
|
173
|
+
"globalThis",
|
|
174
|
+
"module",
|
|
175
|
+
"exports",
|
|
176
|
+
`${jsPreamble}\n\n${code}`
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
await defer(() => func.call(jsProxy, jsProxy, module, module.exports));
|
|
180
|
+
return module.exports;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// prefetch all the requireable scripts before we replace the fetch function
|
|
184
|
+
var allowedModules = undefined;
|
|
185
|
+
|
|
186
|
+
async function preloadModules(context, fetch_fn) {
|
|
187
|
+
const modules = [
|
|
188
|
+
"~system/BevyExplorerApi",
|
|
189
|
+
"~system/CommunicationsController",
|
|
190
|
+
"~system/CommsApi",
|
|
191
|
+
"~system/EngineApi",
|
|
192
|
+
"~system/EnvironmentApi",
|
|
193
|
+
"~system/EthereumController",
|
|
194
|
+
"~system/Players",
|
|
195
|
+
"~system/PortableExperiences",
|
|
196
|
+
"~system/RestrictedActions",
|
|
197
|
+
"~system/Runtime",
|
|
198
|
+
"~system/Scene",
|
|
199
|
+
"~system/SignedFetch",
|
|
200
|
+
"~system/Testing",
|
|
201
|
+
"~system/UserActionModule",
|
|
202
|
+
"~system/UserIdentity",
|
|
203
|
+
"~system/AdaptationLayerHelper",
|
|
204
|
+
];
|
|
205
|
+
|
|
206
|
+
const promises = modules.map(async (key) => {
|
|
207
|
+
try {
|
|
208
|
+
const code = fetch_fn(context, key);
|
|
209
|
+
const result = await runWithScope(code);
|
|
210
|
+
return [key, result];
|
|
211
|
+
} catch (e) {
|
|
212
|
+
return undefined
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
allowedModules = Object.fromEntries((await Promise.all(promises)).filter(e => e));
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function require(moduleName) {
|
|
220
|
+
let code = allowedModules[moduleName];
|
|
221
|
+
if (!code) {
|
|
222
|
+
throw "can't find module `" + moduleName + "`";
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return code;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
self.onmessage = async (event) => {
|
|
229
|
+
if (event.data && event.data.type === "INIT_WORKER") {
|
|
230
|
+
const { compiledModule, sharedMemory } = event.data.payload;
|
|
231
|
+
|
|
232
|
+
if (!compiledModule || !sharedMemory) {
|
|
233
|
+
console.error("[Sandbox Worker] Invalid payload received.");
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
var wasm_init;
|
|
238
|
+
try {
|
|
239
|
+
// init wasm
|
|
240
|
+
wasm_init = await init({
|
|
241
|
+
module_or_path: compiledModule,
|
|
242
|
+
memory: sharedMemory,
|
|
243
|
+
});
|
|
244
|
+
} catch (e) {
|
|
245
|
+
console.error(
|
|
246
|
+
"[Scene Worker] Error during Wasm instantiation or setup:",
|
|
247
|
+
e
|
|
248
|
+
);
|
|
249
|
+
postMessage({ type: `INIT_FAILED` });
|
|
250
|
+
self.close();
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
postMessage({ type: `INIT_COMPLETE` });
|
|
255
|
+
|
|
256
|
+
// add listener to clean up on unhandled rejections
|
|
257
|
+
self.addEventListener("unhandledrejection", (event) => {
|
|
258
|
+
// Prevent the default browser action (logging to console)
|
|
259
|
+
event.preventDefault();
|
|
260
|
+
|
|
261
|
+
console.error(
|
|
262
|
+
"[Sandbox worker] FATAL: Unhandled Promise Rejection in Worker:",
|
|
263
|
+
event.reason
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
try {
|
|
267
|
+
wasm_init.__wbindgen_thread_destroy();
|
|
268
|
+
} catch (cleanupError) {
|
|
269
|
+
console.error(
|
|
270
|
+
"[Sandbox worker] Error during WASM cleanup:",
|
|
271
|
+
cleanupError
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
self.close();
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
var wasmContext;
|
|
279
|
+
try {
|
|
280
|
+
wasmContext = await wasm_bindgen_exports.wasm_init_scene();
|
|
281
|
+
} catch (e) {
|
|
282
|
+
console.error("[Scene Worker] Error during scene construction:", e);
|
|
283
|
+
try {
|
|
284
|
+
wasm_init.drop_context(wasmContext);
|
|
285
|
+
} catch (e) {}
|
|
286
|
+
wasm_init.__wbindgen_thread_destroy();
|
|
287
|
+
self.close();
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
try {
|
|
292
|
+
createJsContext(wasm_bindgen_exports, wasmContext);
|
|
293
|
+
const ops = jsContext.Deno.core.ops;
|
|
294
|
+
|
|
295
|
+
// preload modules
|
|
296
|
+
await preloadModules(wasmContext, wasm_bindgen_exports.builtin_module);
|
|
297
|
+
|
|
298
|
+
const sceneCode = wasmContext.get_source();
|
|
299
|
+
let module = await runWithScope(sceneCode);
|
|
300
|
+
|
|
301
|
+
// send any initial rpc requests
|
|
302
|
+
ops.op_crdt_send_to_renderer([]);
|
|
303
|
+
|
|
304
|
+
await module.onStart();
|
|
305
|
+
|
|
306
|
+
var elapsed = 0;
|
|
307
|
+
const startTime = new Date();
|
|
308
|
+
var prevElapsed = 0;
|
|
309
|
+
var elapsed = 0;
|
|
310
|
+
var count = 0;
|
|
311
|
+
while (ops.op_continue_running()) {
|
|
312
|
+
const dt = (elapsed - prevElapsed) / 1000;
|
|
313
|
+
await module.onUpdate(dt);
|
|
314
|
+
prevElapsed = elapsed;
|
|
315
|
+
elapsed = new Date() - startTime;
|
|
316
|
+
count += 1;
|
|
317
|
+
}
|
|
318
|
+
console.log("[Scene Worker] exiting gracefully");
|
|
319
|
+
} catch (e) {
|
|
320
|
+
console.error("[Scene Worker] Error during scene execution:", e);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
try {
|
|
324
|
+
wasm_init.drop_context(wasmContext);
|
|
325
|
+
} catch (e) {}
|
|
326
|
+
wasm_init.__wbindgen_thread_destroy();
|
|
327
|
+
self.close();
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
function createWebStorageProxy(ops) {
|
|
332
|
+
return new Proxy(
|
|
333
|
+
{},
|
|
334
|
+
{
|
|
335
|
+
get(_target, prop, _receiver) {
|
|
336
|
+
if (prop === "length") {
|
|
337
|
+
return ops.op_webstorage_length();
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (prop === "getItem") {
|
|
341
|
+
return (key) => ops.op_webstorage_get(String(key));
|
|
342
|
+
}
|
|
343
|
+
if (prop === "setItem") {
|
|
344
|
+
return (key, value) =>
|
|
345
|
+
ops.op_webstorage_set(String(key), String(value));
|
|
346
|
+
}
|
|
347
|
+
if (prop === "key") {
|
|
348
|
+
return (index) => ops.op_webstorage_key(index);
|
|
349
|
+
}
|
|
350
|
+
if (prop === "removeItem") {
|
|
351
|
+
return (key) => ops.op_webstorage_remove(String(key));
|
|
352
|
+
}
|
|
353
|
+
if (prop === "clear") {
|
|
354
|
+
return () => ops.op_webstorage_clear();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Handle direct property access like `localStorage.myKey`
|
|
358
|
+
return ops.op_storage_get(String(prop));
|
|
359
|
+
},
|
|
360
|
+
|
|
361
|
+
set(_target, prop, value, _receiver) {
|
|
362
|
+
ops.op_storage_set(String(prop), String(value));
|
|
363
|
+
return true;
|
|
364
|
+
},
|
|
365
|
+
|
|
366
|
+
deleteProperty(_target, prop) {
|
|
367
|
+
ops.op_webstorage_remove(String(prop));
|
|
368
|
+
return true;
|
|
369
|
+
},
|
|
370
|
+
|
|
371
|
+
ownKeys(_target) {
|
|
372
|
+
return ops.op_webstorage_iterate_keys();
|
|
373
|
+
},
|
|
374
|
+
|
|
375
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
376
|
+
if (ops.op_webstorage_has(String(prop))) {
|
|
377
|
+
return {
|
|
378
|
+
value: ops.op_webstorage_get(String(prop)),
|
|
379
|
+
writable: true,
|
|
380
|
+
enumerable: true,
|
|
381
|
+
configurable: true,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
return undefined;
|
|
385
|
+
},
|
|
386
|
+
|
|
387
|
+
has(_target, prop) {
|
|
388
|
+
return ops.op_webstorage_has(String(prop));
|
|
389
|
+
},
|
|
390
|
+
}
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
postMessage({ type: `READY` });
|
package/serve.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"headers": [
|
|
3
|
+
{
|
|
4
|
+
"source": "**/*",
|
|
5
|
+
"headers": [
|
|
6
|
+
{
|
|
7
|
+
"key": "Cross-Origin-Opener-Policy",
|
|
8
|
+
"value": "same-origin"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"key": "Cross-Origin-Embedder-Policy",
|
|
12
|
+
"value": "require-corp"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"key": "Cross-Origin-Resource-Policy",
|
|
16
|
+
"value": "cross-origin"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|