@auraindustry/aurajs 0.0.7 → 0.1.1
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/README.md +98 -2
- package/benchmarks/perf-thresholds.json +54 -0
- package/package.json +4 -7
- package/src/asset-pack.mjs +8 -1
- package/src/authored-project.mjs +1449 -0
- package/src/authored-runtime.mjs +2016 -0
- package/src/authoring/avatar-animation-graph.mjs +648 -0
- package/src/bin-integrity.mjs +272 -0
- package/src/build-contract/assets.mjs +130 -0
- package/src/build-contract/capabilities.mjs +116 -0
- package/src/build-contract/constants.mjs +6 -0
- package/src/build-contract/helpers.mjs +44 -0
- package/src/build-contract/web-templates.mjs +5993 -0
- package/src/build-contract.mjs +27 -2910
- package/src/bundler.mjs +188 -55
- package/src/cli.mjs +4840 -1512
- package/src/commands/project-authoring.mjs +454 -0
- package/src/config.mjs +44 -0
- package/src/conformance/cases/app-and-ui-runtime-cases.mjs +3309 -0
- package/src/conformance/cases/core-runtime-cases.mjs +1431 -0
- package/src/conformance/cases/index.mjs +11 -0
- package/src/conformance/cases/scene3d-and-media-cases.mjs +2094 -0
- package/src/conformance/cases/systems-and-gameplay-cases.mjs +1776 -0
- package/src/conformance/shared.mjs +27 -0
- package/src/conformance-runner.mjs +25 -13
- package/src/conformance.mjs +619 -4020
- package/src/cutscene.mjs +362 -5
- package/src/dev-cli-action.mjs +249 -0
- package/src/dev-cli-inspect.mjs +92 -0
- package/src/dev-cli-state.mjs +80 -0
- package/src/external-asset-cache.mjs +587 -0
- package/src/external-asset-policy.mjs +217 -0
- package/src/external-package-surface.mjs +206 -0
- package/src/game-action-runtime.mjs +869 -0
- package/src/game-state-runtime.mjs +206 -6
- package/src/headless-action.mjs +186 -0
- package/src/headless-test/runtime-animation.mjs +1173 -0
- package/src/headless-test/runtime-coordinator.mjs +1514 -0
- package/src/headless-test/runtime-primitives.mjs +320 -0
- package/src/headless-test/runtime-world.mjs +2253 -0
- package/src/headless-test.mjs +392 -4298
- package/src/host-binary.mjs +342 -14
- package/src/icon-discovery.mjs +64 -0
- package/src/make-catalog.mjs +109 -0
- package/src/make.mjs +197 -0
- package/src/package-integrity.mjs +586 -0
- package/src/perf-benchmark.mjs +353 -0
- package/src/postinstall.mjs +5 -5
- package/src/prefabs/index.mjs +34 -0
- package/src/prefabs/scene-serialization.mjs +184 -0
- package/src/project-importer.mjs +620 -0
- package/src/project-registry.mjs +24 -0
- package/src/publish-command.mjs +195 -0
- package/src/publish-env-example.mjs +83 -0
- package/src/publish-validation.mjs +708 -0
- package/src/retro/assets/compile.mjs +232 -0
- package/src/retro/backend-gba/authoring.mjs +1029 -0
- package/src/retro/backend-gba/rom.mjs +363 -0
- package/src/retro/backend-gbc/rom.mjs +85 -0
- package/src/retro/build.mjs +278 -0
- package/src/retro/cli/commands.mjs +292 -0
- package/src/retro/cli/templates.mjs +84 -0
- package/src/retro/diagnostics/catalog.mjs +110 -0
- package/src/retro/diagnostics/emit.mjs +72 -0
- package/src/retro/emulator/case-overlay.mjs +64 -0
- package/src/retro/emulator/discovery.mjs +158 -0
- package/src/retro/emulator/macos-case-overlay.swift +220 -0
- package/src/retro/emulator/profiles.mjs +146 -0
- package/src/retro/emulator/runner.mjs +289 -0
- package/src/retro/frontend/load-project.mjs +98 -0
- package/src/retro/index.mjs +30 -0
- package/src/retro/ir/build-ir.mjs +108 -0
- package/src/retro/runtime-gba/contract.mjs +151 -0
- package/src/retro/runtime-gbc/contract.mjs +117 -0
- package/src/retro/shared/span.mjs +26 -0
- package/src/retro/shared/targets.mjs +64 -0
- package/src/retro/validator/check-project.mjs +114 -0
- package/src/runtime-hotspot-audit.mjs +707 -0
- package/src/scaffold/config.mjs +1000 -0
- package/src/scaffold/fs.mjs +56 -0
- package/src/scaffold/layout.mjs +318 -0
- package/src/scaffold/project-docs.mjs +439 -0
- package/src/scaffold.mjs +93 -596
- package/src/scene-composition/index.mjs +326 -0
- package/src/scene-composition/runtime.mjs +751 -0
- package/src/self-hosted-assets.mjs +604 -0
- package/src/session-client.mjs +750 -0
- package/src/session-native-launcher.mjs +74 -0
- package/src/session-protocol.mjs +75 -0
- package/src/session-runtime.mjs +321 -0
- package/src/session-server.mjs +360 -0
- package/src/shader-kits/index.mjs +773 -0
- package/src/starter-content-registry.mjs +292 -0
- package/src/state-artifacts.mjs +662 -24
- package/src/state-dev-reload.mjs +99 -2
- package/src/terminal-ui.mjs +245 -0
- package/src/web-conformance.mjs +219 -0
- package/templates/create/2d/config/gameplay/shooter.config.js +26 -0
- package/templates/create/2d/content/gameplay/waves.json +26 -0
- package/templates/create/2d/content/registries/.gitkeep +1 -0
- package/templates/create/2d/docs/design/.gitkeep +1 -0
- package/templates/create/2d/docs/design/loop.md +5 -0
- package/templates/create/2d/prefabs/enemies.prefab.js +90 -0
- package/templates/create/2d/prefabs/enemy-basic.prefab.js +18 -0
- package/templates/create/2d/prefabs/player.prefab.js +36 -0
- package/templates/create/2d/prefabs/projectiles.prefab.js +35 -0
- package/templates/create/2d/scenes/boot.scene.js +12 -0
- package/templates/create/2d/scenes/gameplay.scene.js +230 -0
- package/templates/create/2d/scenes/menu.scene.js +9 -0
- package/templates/create/2d/src/main.js +6 -185
- package/templates/create/2d/src/runtime/app.js +49 -0
- package/templates/create/2d/src/runtime/capabilities.js +35 -0
- package/templates/create/2d/ui/hud.screen.js +40 -0
- package/templates/create/2d/ui/pause.screen.js +149 -0
- package/templates/create/2d/ui/settings.screen.js +347 -0
- package/templates/create/2d/ui/title.screen.js +13 -0
- package/templates/create/2d-adventure/aura.config.json +28 -0
- package/templates/create/2d-adventure/config/gameplay/adventure.config.js +14 -0
- package/templates/create/2d-adventure/content/gameplay/world.js +46 -0
- package/templates/create/2d-adventure/content/registries/.gitkeep +1 -0
- package/templates/create/2d-adventure/docs/design/loop.md +5 -0
- package/templates/create/2d-adventure/prefabs/player.prefab.js +54 -0
- package/templates/create/2d-adventure/prefabs/relic.prefab.js +38 -0
- package/templates/create/2d-adventure/prefabs/world.prefab.js +125 -0
- package/templates/create/2d-adventure/scenes/gameplay.scene.js +256 -0
- package/templates/create/2d-adventure/src/runtime/capabilities.js +34 -0
- package/templates/create/2d-adventure/ui/hud.screen.js +60 -0
- package/templates/create/2d-survivor/config/gameplay/survivor.config.js +33 -0
- package/templates/create/2d-survivor/content/gameplay/spawn-zones.json +29 -0
- package/templates/create/2d-survivor/content/registries/.gitkeep +1 -0
- package/templates/create/2d-survivor/docs/design/.gitkeep +1 -0
- package/templates/create/2d-survivor/docs/design/loop.md +5 -0
- package/templates/create/2d-survivor/prefabs/enemies.prefab.js +178 -0
- package/templates/create/2d-survivor/prefabs/enemy-swarm.prefab.js +18 -0
- package/templates/create/2d-survivor/prefabs/player.prefab.js +42 -0
- package/templates/create/2d-survivor/prefabs/projectiles.prefab.js +56 -0
- package/templates/create/2d-survivor/scenes/boot.scene.js +12 -0
- package/templates/create/2d-survivor/scenes/gameplay.scene.js +314 -0
- package/templates/create/2d-survivor/scenes/menu.scene.js +9 -0
- package/templates/create/2d-survivor/src/main.js +5 -332
- package/templates/create/2d-survivor/src/runtime/app.js +49 -0
- package/templates/create/2d-survivor/src/runtime/capabilities.js +35 -0
- package/templates/create/2d-survivor/ui/hud.screen.js +45 -0
- package/templates/create/2d-survivor/ui/title.screen.js +13 -0
- package/templates/create/3d/assets/models/starter-avatar.gltf +184 -0
- package/templates/create/3d/config/gameplay/.gitkeep +1 -0
- package/templates/create/3d/content/gameplay/checkpoints.json +33 -0
- package/templates/create/3d/content/gameplay/course.js +40 -0
- package/templates/create/3d/content/registries/.gitkeep +1 -0
- package/templates/create/3d/docs/design/.gitkeep +1 -0
- package/templates/create/3d/docs/design/loop.md +5 -0
- package/templates/create/3d/prefabs/checkpoint.prefab.js +15 -0
- package/templates/create/3d/prefabs/player.prefab.js +204 -0
- package/templates/create/3d/prefabs/world.prefab.js +112 -0
- package/templates/create/3d/scenes/boot.scene.js +12 -0
- package/templates/create/3d/scenes/checkpoint.scene.js +9 -0
- package/templates/create/3d/scenes/gameplay.scene.js +292 -0
- package/templates/create/3d/src/main.js +6 -295
- package/templates/create/3d/src/runtime/app.js +49 -0
- package/templates/create/3d/src/runtime/capabilities.js +53 -0
- package/templates/create/3d/src/runtime/materials.js +34 -0
- package/templates/create/3d/src/runtime/state.js +39 -0
- package/templates/create/3d/ui/hud.screen.js +75 -0
- package/templates/create/3d/ui/pause.screen.js +166 -0
- package/templates/create/3d/ui/settings.screen.js +387 -0
- package/templates/create/3d-adventure/assets/models/starter-avatar.gltf +184 -0
- package/templates/create/3d-adventure/aura.config.json +28 -0
- package/templates/create/3d-adventure/config/gameplay/adventure.config.js +9 -0
- package/templates/create/3d-adventure/content/gameplay/course.js +62 -0
- package/templates/create/3d-adventure/content/registries/.gitkeep +1 -0
- package/templates/create/3d-adventure/docs/design/loop.md +5 -0
- package/templates/create/3d-adventure/prefabs/player.prefab.js +168 -0
- package/templates/create/3d-adventure/prefabs/relic.prefab.js +35 -0
- package/templates/create/3d-adventure/prefabs/world.prefab.js +119 -0
- package/templates/create/3d-adventure/scenes/gameplay.scene.js +358 -0
- package/templates/create/3d-adventure/src/runtime/capabilities.js +56 -0
- package/templates/create/3d-adventure/src/runtime/materials.js +39 -0
- package/templates/create/3d-adventure/src/runtime/state.js +31 -0
- package/templates/create/3d-adventure/ui/hud.screen.js +70 -0
- package/templates/create/3d-adventure/ui/pause.screen.js +437 -0
- package/templates/create/3d-collectathon/assets/models/starter-avatar.gltf +184 -0
- package/templates/create/3d-collectathon/config/gameplay/.gitkeep +1 -0
- package/templates/create/3d-collectathon/content/gameplay/collectibles.json +26 -0
- package/templates/create/3d-collectathon/content/gameplay/course.js +46 -0
- package/templates/create/3d-collectathon/content/registries/.gitkeep +1 -0
- package/templates/create/3d-collectathon/docs/design/.gitkeep +1 -0
- package/templates/create/3d-collectathon/docs/design/loop.md +5 -0
- package/templates/create/3d-collectathon/prefabs/collectible.prefab.js +15 -0
- package/templates/create/3d-collectathon/prefabs/player.prefab.js +207 -0
- package/templates/create/3d-collectathon/prefabs/world.prefab.js +112 -0
- package/templates/create/3d-collectathon/scenes/boot.scene.js +12 -0
- package/templates/create/3d-collectathon/scenes/checkpoint.scene.js +9 -0
- package/templates/create/3d-collectathon/scenes/gameplay.scene.js +200 -0
- package/templates/create/3d-collectathon/src/main.js +5 -355
- package/templates/create/3d-collectathon/src/runtime/app.js +49 -0
- package/templates/create/3d-collectathon/src/runtime/capabilities.js +53 -0
- package/templates/create/3d-collectathon/src/runtime/materials.js +34 -0
- package/templates/create/3d-collectathon/src/runtime/state.js +27 -0
- package/templates/create/3d-collectathon/ui/hud.screen.js +66 -0
- package/templates/create/3d-collectathon/ui/pause.screen.js +13 -0
- package/templates/create/blank/config/gameplay/.gitkeep +1 -0
- package/templates/create/blank/content/gameplay/.gitkeep +1 -0
- package/templates/create/blank/content/registries/.gitkeep +1 -0
- package/templates/create/blank/docs/design/.gitkeep +1 -0
- package/templates/create/blank/docs/design/loop.md +5 -0
- package/templates/create/blank/prefabs/.gitkeep +1 -0
- package/templates/create/blank/scenes/.gitkeep +1 -0
- package/templates/create/blank/src/runtime/.gitkeep +1 -0
- package/templates/create/blank/ui/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/assets/audio/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/assets/fonts/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/assets/sprites/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/assets/starter/README.md +11 -0
- package/templates/create/deckbuilder-2d/assets/ui/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/aura.config.json +28 -0
- package/templates/create/deckbuilder-2d/config/gameplay/deckbuilder.config.js +26 -0
- package/templates/create/deckbuilder-2d/content/cards/guard.card.js +19 -0
- package/templates/create/deckbuilder-2d/content/cards/spark.card.js +20 -0
- package/templates/create/deckbuilder-2d/content/cards/starter.deck.js +69 -0
- package/templates/create/deckbuilder-2d/content/cards/strike.card.js +19 -0
- package/templates/create/deckbuilder-2d/content/cards/survey.card.js +20 -0
- package/templates/create/deckbuilder-2d/content/encounters/training-battle.encounter.js +14 -0
- package/templates/create/deckbuilder-2d/content/encounters/training-battle.js +65 -0
- package/templates/create/deckbuilder-2d/content/enemies/training-automaton.enemy.js +48 -0
- package/templates/create/deckbuilder-2d/content/gameplay/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/content/registries/cards.registry.js +26 -0
- package/templates/create/deckbuilder-2d/content/registries/encounters.registry.js +20 -0
- package/templates/create/deckbuilder-2d/content/registries/enemies.registry.js +20 -0
- package/templates/create/deckbuilder-2d/content/registries/relics.registry.js +20 -0
- package/templates/create/deckbuilder-2d/content/relics/ember-charm.relic.js +18 -0
- package/templates/create/deckbuilder-2d/docs/design/loop.md +12 -0
- package/templates/create/deckbuilder-2d/prefabs/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/scenes/boot.scene.js +84 -0
- package/templates/create/deckbuilder-2d/scenes/gameplay.scene.js +641 -0
- package/templates/create/deckbuilder-2d/src/components/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/src/main.js +17 -0
- package/templates/create/deckbuilder-2d/src/runtime/capabilities.js +22 -0
- package/templates/create/deckbuilder-2d/src/shared/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/src/systems/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/tests/smoke/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/ui/hud.screen.js +80 -0
- package/templates/create/deckbuilder-2d/ui/pause.screen.js +146 -0
- package/templates/create/deckbuilder-2d/ui/settings.screen.js +342 -0
- package/templates/create/local-multiplayer/aura.config.json +41 -0
- package/templates/create/local-multiplayer/config/gameplay/local-multiplayer.config.js +26 -0
- package/templates/create/local-multiplayer/content/gameplay/room-layout.js +13 -0
- package/templates/create/local-multiplayer/content/registries/.gitkeep +1 -0
- package/templates/create/local-multiplayer/docs/design/loop.md +16 -0
- package/templates/create/local-multiplayer/prefabs/player.prefab.js +99 -0
- package/templates/create/local-multiplayer/scenes/boot.scene.js +12 -0
- package/templates/create/local-multiplayer/scenes/gameplay.scene.js +472 -0
- package/templates/create/local-multiplayer/src/main.js +17 -0
- package/templates/create/local-multiplayer/src/runtime/capabilities.js +28 -0
- package/templates/create/local-multiplayer/ui/hud.screen.js +65 -0
- package/templates/create/shared/src/runtime/project-inspector.js +105 -0
- package/templates/create/shared/src/runtime/scene-flow.js +290 -0
- package/templates/create/shared/src/runtime/screen-shell.js +222 -0
- package/templates/create/shared/src/runtime/ui-forms.js +209 -0
- package/templates/create/shared/src/runtime/ui-settings.js +237 -0
- package/templates/create/shared/src/runtime/ui-theme.js +352 -0
- package/templates/create/shared/src/starter-utils/adventure-objectives.js +102 -0
- package/templates/create/shared/src/starter-utils/animation-2d.js +337 -0
- package/templates/create/shared/src/starter-utils/avatar-3d.js +404 -0
- package/templates/create/shared/src/starter-utils/combat-feedback-2d.js +320 -0
- package/templates/create/shared/src/starter-utils/core.js +39 -3
- package/templates/create/shared/src/starter-utils/index.js +8 -2
- package/templates/create/shared/src/starter-utils/platformer-3d.js +34 -3
- package/templates/create/shared/src/starter-utils/triggers.js +662 -0
- package/templates/create/shared/src/starter-utils/tween-2d.js +615 -0
- package/templates/create/video-cutscene/assets/video/.gitkeep +0 -0
- package/templates/create/video-cutscene/aura.config.json +28 -0
- package/templates/create/video-cutscene/config/gameplay/.gitkeep +0 -0
- package/templates/create/video-cutscene/content/gameplay/.gitkeep +0 -0
- package/templates/create/video-cutscene/content/registries/.gitkeep +0 -0
- package/templates/create/video-cutscene/docs/design/loop.md +22 -0
- package/templates/create/video-cutscene/prefabs/.gitkeep +0 -0
- package/templates/create/video-cutscene/scenes/boot.scene.js +11 -0
- package/templates/create/video-cutscene/scenes/cutscene.scene.js +113 -0
- package/templates/create/video-cutscene/scenes/gameplay.scene.js +50 -0
- package/templates/create/video-cutscene/src/main.js +17 -0
- package/templates/create/video-cutscene/src/runtime/app.js +52 -0
- package/templates/create/video-cutscene/src/runtime/capabilities.js +35 -0
- package/templates/create/video-cutscene/src/runtime/state.js +13 -0
- package/templates/create/video-cutscene/ui/.gitkeep +0 -0
- package/templates/create-bin/play.js +1192 -0
- package/templates/make/README.md +46 -0
- package/templates/make/catalog.json +51 -0
- package/templates/make/component/files/{{MAKE_NAME}}.component.js +20 -0
- package/templates/make/component/manifest.json +9 -0
- package/templates/make/data/files/{{MAKE_NAME}}.json +14 -0
- package/templates/make/data/manifest.json +9 -0
- package/templates/make/material/files/{{MAKE_NAME}}.material.json +17 -0
- package/templates/make/material/manifest.json +9 -0
- package/templates/make/prefab/files/{{MAKE_NAME}}.prefab.js +20 -0
- package/templates/make/prefab/manifest.json +9 -0
- package/templates/make/scene/files/{{MAKE_NAME}}.scene.js +31 -0
- package/templates/make/scene/manifest.json +9 -0
- package/templates/make/shader/files/{{MAKE_NAME}}.shader.js +23 -0
- package/templates/make/shader/manifest.json +9 -0
- package/templates/make/system/files/{{MAKE_NAME}}.system.js +15 -0
- package/templates/make/system/manifest.json +9 -0
- package/templates/make/ui-screen/files/{{MAKE_NAME}}.screen.js +16 -0
- package/templates/make/ui-screen/files/{{MAKE_NAME}}.screen.json +23 -0
- package/templates/make/ui-screen/manifest.json +10 -0
- package/templates/make-starters/deckbuilder-2d/card/files/{{MAKE_NAME}}.card.js +22 -0
- package/templates/make-starters/deckbuilder-2d/card/manifest.json +9 -0
- package/templates/make-starters/deckbuilder-2d/catalog.json +34 -0
- package/templates/make-starters/deckbuilder-2d/encounter/files/{{MAKE_NAME}}.encounter.js +18 -0
- package/templates/make-starters/deckbuilder-2d/encounter/manifest.json +9 -0
- package/templates/make-starters/deckbuilder-2d/enemy/files/{{MAKE_NAME}}.enemy.js +28 -0
- package/templates/make-starters/deckbuilder-2d/enemy/manifest.json +9 -0
- package/templates/make-starters/deckbuilder-2d/relic/files/{{MAKE_NAME}}.relic.js +23 -0
- package/templates/make-starters/deckbuilder-2d/relic/manifest.json +9 -0
- package/templates/retro/platformer/README.md +10 -0
- package/templates/retro/platformer/assets/retro/assets.json +91 -0
- package/templates/retro/platformer/aura.config.json +7 -0
- package/templates/retro/platformer/package.json +5 -0
- package/templates/retro/platformer/src/main.js +40 -0
- package/templates/retro/puzzle-grid/README.md +10 -0
- package/templates/retro/puzzle-grid/assets/retro/assets.json +90 -0
- package/templates/retro/puzzle-grid/aura.config.json +7 -0
- package/templates/retro/puzzle-grid/package.json +5 -0
- package/templates/retro/puzzle-grid/src/main.js +29 -0
- package/templates/retro/tactics-grid/README.md +10 -0
- package/templates/retro/tactics-grid/assets/retro/assets.json +90 -0
- package/templates/retro/tactics-grid/aura.config.json +7 -0
- package/templates/retro/tactics-grid/package.json +5 -0
- package/templates/retro/tactics-grid/src/main.js +35 -0
- package/templates/retro/topdown-adventure/README.md +10 -0
- package/templates/retro/topdown-adventure/assets/retro/assets.json +95 -0
- package/templates/retro/topdown-adventure/aura.config.json +7 -0
- package/templates/retro/topdown-adventure/package.json +5 -0
- package/templates/retro/topdown-adventure/src/main.js +29 -0
- package/templates/skills/aurajs/SKILL.md +61 -5
package/src/build-contract.mjs
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
copyFileSync,
|
|
4
|
-
existsSync,
|
|
5
|
-
mkdirSync,
|
|
6
|
-
readdirSync,
|
|
7
|
-
readFileSync,
|
|
8
|
-
rmSync,
|
|
9
|
-
statSync,
|
|
10
|
-
writeFileSync,
|
|
11
|
-
} from 'node:fs';
|
|
12
|
-
import { extname, relative, resolve, sep } from 'node:path';
|
|
1
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { relative, resolve } from 'node:path';
|
|
13
3
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
4
|
+
import { emitWebAssets } from './build-contract/assets.mjs';
|
|
5
|
+
import { buildRuntimeConfig, readProjectCapabilityDeclaration } from './build-contract/capabilities.mjs';
|
|
6
|
+
import { BUILD_MANIFEST_SCHEMA, WEB_BUILD_MANIFEST_SCHEMA } from './build-contract/constants.mjs';
|
|
7
|
+
import {
|
|
8
|
+
normalizeAssetMode,
|
|
9
|
+
resolveOptionalRelative,
|
|
10
|
+
resolveRequiredPath,
|
|
11
|
+
sha256,
|
|
12
|
+
toPosix,
|
|
13
|
+
writeCanonicalJsonFile,
|
|
14
|
+
} from './build-contract/helpers.mjs';
|
|
15
|
+
import { WEB_INDEX_HTML, WEB_LOADER_SOURCE } from './build-contract/web-templates.mjs';
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
BUILD_MANIFEST_SCHEMA,
|
|
19
|
+
WEB_BUILD_MANIFEST_SCHEMA,
|
|
20
|
+
WEB_CAPABILITY_DECLARATION_SCHEMA,
|
|
21
|
+
WEB_RUNTIME_CONFIG_SCHEMA,
|
|
22
|
+
} from './build-contract/constants.mjs';
|
|
23
|
+
export { writeCanonicalJsonFile } from './build-contract/helpers.mjs';
|
|
19
24
|
|
|
20
25
|
export function writeBuildManifest(options = {}) {
|
|
21
26
|
const outRoot = resolve(options.outRoot || process.cwd());
|
|
@@ -47,6 +52,8 @@ export function writeBuildManifest(options = {}) {
|
|
|
47
52
|
},
|
|
48
53
|
icon: {
|
|
49
54
|
configuredPath: typeof icon?.configuredPath === 'string' ? icon.configuredPath : null,
|
|
55
|
+
discoveredPath: typeof icon?.discoveredPath === 'string' ? icon.discoveredPath : null,
|
|
56
|
+
resolvedPath: typeof icon?.resolvedPath === 'string' ? icon.resolvedPath : null,
|
|
50
57
|
sourcePath: resolveOptionalRelative(outRoot, icon?.sourcePath),
|
|
51
58
|
outputPath: resolveOptionalRelative(outRoot, icon?.outputPath),
|
|
52
59
|
status: iconStatus,
|
|
@@ -71,13 +78,7 @@ export function writeWebBuildArtifacts(options = {}) {
|
|
|
71
78
|
}
|
|
72
79
|
|
|
73
80
|
mkdirSync(resolve(outRoot, 'js'), { recursive: true });
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const assets = emitWebAssets({
|
|
77
|
-
projectRoot,
|
|
78
|
-
outRoot,
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
+
const assets = emitWebAssets({ projectRoot, outRoot });
|
|
81
82
|
const capabilityDeclaration = readProjectCapabilityDeclaration({
|
|
82
83
|
projectRoot,
|
|
83
84
|
modules: options.modules || {},
|
|
@@ -88,7 +89,7 @@ export function writeWebBuildArtifacts(options = {}) {
|
|
|
88
89
|
capabilityDeclaration,
|
|
89
90
|
});
|
|
90
91
|
const runtimeConfigPath = resolve(outRoot, 'runtime-config.json');
|
|
91
|
-
|
|
92
|
+
writeCanonicalJsonFile(runtimeConfigPath, runtimeConfig);
|
|
92
93
|
|
|
93
94
|
const loaderPath = resolve(outRoot, 'js', 'aura-web-loader.js');
|
|
94
95
|
writeFileSync(loaderPath, `${WEB_LOADER_SOURCE}\n`, 'utf8');
|
|
@@ -118,7 +119,7 @@ export function writeWebBuildArtifacts(options = {}) {
|
|
|
118
119
|
};
|
|
119
120
|
|
|
120
121
|
const manifestPath = resolve(outRoot, 'web-build-manifest.json');
|
|
121
|
-
|
|
122
|
+
writeCanonicalJsonFile(manifestPath, manifest);
|
|
122
123
|
|
|
123
124
|
return {
|
|
124
125
|
outRoot,
|
|
@@ -130,2887 +131,3 @@ export function writeWebBuildArtifacts(options = {}) {
|
|
|
130
131
|
assetsRoot: assets.assetsOutRoot,
|
|
131
132
|
};
|
|
132
133
|
}
|
|
133
|
-
|
|
134
|
-
function resolveRequiredPath(pathLike, fieldName) {
|
|
135
|
-
if (typeof pathLike !== 'string' || pathLike.length === 0) {
|
|
136
|
-
throw new Error(`build contract requires a non-empty "${fieldName}" path.`);
|
|
137
|
-
}
|
|
138
|
-
return resolve(pathLike);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function normalizeAssetMode(value) {
|
|
142
|
-
if (value !== 'embed' && value !== 'sibling') {
|
|
143
|
-
throw new Error(`unsupported asset mode "${value}" for build contract.`);
|
|
144
|
-
}
|
|
145
|
-
return value;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function toPosix(input) {
|
|
149
|
-
return input.split(sep).join('/');
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function resolveOptionalRelative(outRoot, pathLike) {
|
|
153
|
-
if (typeof pathLike !== 'string' || pathLike.length === 0) {
|
|
154
|
-
return null;
|
|
155
|
-
}
|
|
156
|
-
return toPosix(relative(outRoot, resolve(pathLike)));
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function buildRuntimeConfig(options = {}) {
|
|
160
|
-
const windowConfig = options.windowConfig && typeof options.windowConfig === 'object'
|
|
161
|
-
? options.windowConfig
|
|
162
|
-
: {};
|
|
163
|
-
const modules = options.modules && typeof options.modules === 'object'
|
|
164
|
-
? options.modules
|
|
165
|
-
: {};
|
|
166
|
-
const capabilityDeclaration = normalizeWebCapabilityDeclaration(
|
|
167
|
-
options.capabilityDeclaration,
|
|
168
|
-
normalizeOptionalModules(modules),
|
|
169
|
-
options.capabilityDeclaration && typeof options.capabilityDeclaration === 'object'
|
|
170
|
-
? options.capabilityDeclaration.source || null
|
|
171
|
-
: null,
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
return {
|
|
175
|
-
schema: WEB_RUNTIME_CONFIG_SCHEMA,
|
|
176
|
-
schemaVersion: '1.0.0',
|
|
177
|
-
canvas: {
|
|
178
|
-
id: 'aura-canvas',
|
|
179
|
-
resizeMode: 'fit-container',
|
|
180
|
-
width: normalizePositiveInt(windowConfig.width, 1280),
|
|
181
|
-
height: normalizePositiveInt(windowConfig.height, 720),
|
|
182
|
-
devicePixelRatioMode: 'clamped',
|
|
183
|
-
},
|
|
184
|
-
loop: {
|
|
185
|
-
tickMode: 'raf',
|
|
186
|
-
maxDeltaMs: 50,
|
|
187
|
-
},
|
|
188
|
-
modules: {
|
|
189
|
-
physics: modules.physics === true,
|
|
190
|
-
network: modules.network === true,
|
|
191
|
-
multiplayer: modules.multiplayer === true,
|
|
192
|
-
},
|
|
193
|
-
capabilities: capabilityDeclaration,
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function normalizeRequiredApis(entries) {
|
|
198
|
-
if (!Array.isArray(entries)) {
|
|
199
|
-
return [];
|
|
200
|
-
}
|
|
201
|
-
return [...new Set(entries
|
|
202
|
-
.filter((entry) => typeof entry === 'string')
|
|
203
|
-
.map((entry) => entry.trim())
|
|
204
|
-
.filter(Boolean))]
|
|
205
|
-
.sort((a, b) => a.localeCompare(b));
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
function normalizeOptionalModules(modules) {
|
|
209
|
-
const source = modules && typeof modules === 'object' ? modules : {};
|
|
210
|
-
return {
|
|
211
|
-
physics: source.physics === true,
|
|
212
|
-
network: source.network === true || source.net === true,
|
|
213
|
-
multiplayer: source.multiplayer === true,
|
|
214
|
-
steam: source.steam === true,
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function normalizeWebCapabilityDeclaration(value, baseModules = {}, source = null) {
|
|
219
|
-
const declaration = value && typeof value === 'object' && !Array.isArray(value)
|
|
220
|
-
? value
|
|
221
|
-
: {};
|
|
222
|
-
if (
|
|
223
|
-
declaration.schema != null
|
|
224
|
-
&& declaration.schema !== 'aurajs.create-capabilities.v1'
|
|
225
|
-
&& declaration.schema !== 'aurajs.capability-declaration.v1'
|
|
226
|
-
&& declaration.schema !== WEB_CAPABILITY_DECLARATION_SCHEMA
|
|
227
|
-
) {
|
|
228
|
-
throw new Error(
|
|
229
|
-
`${source || 'Capability declaration'} must use `
|
|
230
|
-
+ '`aurajs.create-capabilities.v1`, `aurajs.capability-declaration.v1`, '
|
|
231
|
-
+ `or \`${WEB_CAPABILITY_DECLARATION_SCHEMA}\`.`,
|
|
232
|
-
);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const declaredModules = normalizeOptionalModules(declaration.optionalModules);
|
|
236
|
-
return {
|
|
237
|
-
schema: WEB_CAPABILITY_DECLARATION_SCHEMA,
|
|
238
|
-
source,
|
|
239
|
-
requiredApis: normalizeRequiredApis(declaration.requiredApis),
|
|
240
|
-
optionalModules: {
|
|
241
|
-
physics: baseModules.physics || declaredModules.physics,
|
|
242
|
-
network: baseModules.network || declaredModules.network,
|
|
243
|
-
multiplayer: baseModules.multiplayer || declaredModules.multiplayer,
|
|
244
|
-
steam: baseModules.steam || declaredModules.steam,
|
|
245
|
-
},
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
function readProjectCapabilityDeclaration({ projectRoot, modules }) {
|
|
250
|
-
const declarationPath = resolve(projectRoot, PROJECT_CAPABILITY_DECLARATION_FILE);
|
|
251
|
-
const baseModules = normalizeOptionalModules(modules);
|
|
252
|
-
if (!existsSync(declarationPath)) {
|
|
253
|
-
return normalizeWebCapabilityDeclaration({}, baseModules, null);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
let parsed;
|
|
257
|
-
try {
|
|
258
|
-
parsed = JSON.parse(readFileSync(declarationPath, 'utf8'));
|
|
259
|
-
} catch (error) {
|
|
260
|
-
throw new Error(`Failed to parse ${PROJECT_CAPABILITY_DECLARATION_FILE}: ${error.message}`);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return normalizeWebCapabilityDeclaration(parsed, baseModules, PROJECT_CAPABILITY_DECLARATION_FILE);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
function emitWebAssets({ projectRoot, outRoot }) {
|
|
267
|
-
const sourceRoot = resolve(projectRoot, 'assets');
|
|
268
|
-
const assetsOutRoot = resolve(outRoot, 'assets');
|
|
269
|
-
rmSync(assetsOutRoot, { recursive: true, force: true });
|
|
270
|
-
mkdirSync(assetsOutRoot, { recursive: true });
|
|
271
|
-
|
|
272
|
-
const sourceFiles = collectFiles(sourceRoot);
|
|
273
|
-
const entries = [];
|
|
274
|
-
for (const sourcePath of sourceFiles) {
|
|
275
|
-
const sourceRelative = toPosix(relative(sourceRoot, sourcePath));
|
|
276
|
-
const sourceBytes = readFileSync(sourcePath);
|
|
277
|
-
const contentHash = sha256(sourceBytes);
|
|
278
|
-
const relativeHash = sha256(Buffer.from(sourceRelative, 'utf8')).slice(0, 8);
|
|
279
|
-
const extension = extname(sourceRelative).toLowerCase();
|
|
280
|
-
const stemSource = extension.length > 0
|
|
281
|
-
? sourceRelative.slice(0, sourceRelative.length - extension.length)
|
|
282
|
-
: sourceRelative;
|
|
283
|
-
const stem = sanitizeAssetStem(stemSource);
|
|
284
|
-
const outputName = `${stem}.${relativeHash}.${contentHash.slice(0, 12)}${extension}`;
|
|
285
|
-
const outputPath = resolve(assetsOutRoot, outputName);
|
|
286
|
-
|
|
287
|
-
copyFileSync(sourcePath, outputPath);
|
|
288
|
-
entries.push({
|
|
289
|
-
path: `assets/${outputName}`,
|
|
290
|
-
sourcePath: sourceRelative,
|
|
291
|
-
bytes: sourceBytes.length,
|
|
292
|
-
sha256: contentHash,
|
|
293
|
-
mediaType: mediaTypeForExtension(extension),
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
entries.sort((a, b) => a.path.localeCompare(b.path));
|
|
298
|
-
removeUnexpectedFiles(assetsOutRoot, new Set(entries.map((entry) => entry.path.slice('assets/'.length))));
|
|
299
|
-
return { entries, assetsOutRoot };
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
function collectFiles(rootPath) {
|
|
303
|
-
if (!existsSync(rootPath)) {
|
|
304
|
-
return [];
|
|
305
|
-
}
|
|
306
|
-
const output = [];
|
|
307
|
-
walkFiles(rootPath, output);
|
|
308
|
-
output.sort((a, b) => toPosix(a).localeCompare(toPosix(b)));
|
|
309
|
-
return output;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
function walkFiles(dirPath, output) {
|
|
313
|
-
const names = readdirSync(dirPath).sort((a, b) => a.localeCompare(b));
|
|
314
|
-
for (const name of names) {
|
|
315
|
-
const fullPath = resolve(dirPath, name);
|
|
316
|
-
const stat = statSync(fullPath);
|
|
317
|
-
if (stat.isDirectory()) {
|
|
318
|
-
walkFiles(fullPath, output);
|
|
319
|
-
continue;
|
|
320
|
-
}
|
|
321
|
-
output.push(fullPath);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
function sanitizeAssetStem(value) {
|
|
326
|
-
const normalized = String(value || '')
|
|
327
|
-
.replace(/[\\/]+/g, '-')
|
|
328
|
-
.replace(/[^A-Za-z0-9._-]+/g, '-')
|
|
329
|
-
.replace(/-+/g, '-')
|
|
330
|
-
.replace(/^[-._]+|[-._]+$/g, '');
|
|
331
|
-
return normalized.length > 0 ? normalized : 'asset';
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
function mediaTypeForExtension(extension) {
|
|
335
|
-
switch (extension) {
|
|
336
|
-
case '.png':
|
|
337
|
-
return 'image/png';
|
|
338
|
-
case '.jpg':
|
|
339
|
-
case '.jpeg':
|
|
340
|
-
return 'image/jpeg';
|
|
341
|
-
case '.gif':
|
|
342
|
-
return 'image/gif';
|
|
343
|
-
case '.webp':
|
|
344
|
-
return 'image/webp';
|
|
345
|
-
case '.wav':
|
|
346
|
-
return 'audio/wav';
|
|
347
|
-
case '.ogg':
|
|
348
|
-
return 'audio/ogg';
|
|
349
|
-
case '.mp3':
|
|
350
|
-
return 'audio/mpeg';
|
|
351
|
-
case '.json':
|
|
352
|
-
return 'application/json';
|
|
353
|
-
case '.txt':
|
|
354
|
-
case '.md':
|
|
355
|
-
case '.csv':
|
|
356
|
-
return 'text/plain; charset=utf-8';
|
|
357
|
-
default:
|
|
358
|
-
return 'application/octet-stream';
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
function normalizePositiveInt(value, fallback) {
|
|
363
|
-
if (!Number.isFinite(value)) {
|
|
364
|
-
return fallback;
|
|
365
|
-
}
|
|
366
|
-
const normalized = Math.floor(value);
|
|
367
|
-
return normalized > 0 ? normalized : fallback;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
function writeCanonicalJson(path, value) {
|
|
371
|
-
writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
function removeUnexpectedFiles(rootPath, allowedNames) {
|
|
375
|
-
if (!existsSync(rootPath)) {
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
for (const name of readdirSync(rootPath)) {
|
|
379
|
-
if (allowedNames.has(name)) {
|
|
380
|
-
continue;
|
|
381
|
-
}
|
|
382
|
-
rmSync(resolve(rootPath, name), { recursive: true, force: true });
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
function sha256(value) {
|
|
387
|
-
return createHash('sha256').update(value).digest('hex');
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
const WEB_INDEX_HTML = [
|
|
391
|
-
'<!doctype html>',
|
|
392
|
-
'<html lang="en">',
|
|
393
|
-
'<head>',
|
|
394
|
-
' <meta charset="utf-8" />',
|
|
395
|
-
' <meta name="viewport" content="width=device-width, initial-scale=1" />',
|
|
396
|
-
' <title>AuraJS Web Build</title>',
|
|
397
|
-
' <style>',
|
|
398
|
-
' html, body { margin: 0; width: 100%; height: 100%; overflow: hidden; background: #060912; }',
|
|
399
|
-
' #aura-root { width: 100vw; height: 100vh; display: grid; place-items: center; }',
|
|
400
|
-
' #aura-canvas { display: block; max-width: 100%; max-height: 100%; }',
|
|
401
|
-
' </style>',
|
|
402
|
-
'</head>',
|
|
403
|
-
'<body>',
|
|
404
|
-
' <div id="aura-root">',
|
|
405
|
-
' <canvas id="aura-canvas"></canvas>',
|
|
406
|
-
' </div>',
|
|
407
|
-
' <script src="./js/aura-web-loader.js"></script>',
|
|
408
|
-
' <script>',
|
|
409
|
-
' window.addEventListener("load", function () {',
|
|
410
|
-
' if (!window.AuraWebLoader || typeof window.AuraWebLoader.mount !== "function") return;',
|
|
411
|
-
' window.AuraWebLoader.mount("#aura-root", { rootUrl: ".", mount: "#aura-root" }).catch(function (error) {',
|
|
412
|
-
' console.error(error);',
|
|
413
|
-
' });',
|
|
414
|
-
' });',
|
|
415
|
-
' </script>',
|
|
416
|
-
'</body>',
|
|
417
|
-
'</html>',
|
|
418
|
-
].join('\n');
|
|
419
|
-
|
|
420
|
-
const WEB_LOADER_SOURCE = `
|
|
421
|
-
(function (globalRef) {
|
|
422
|
-
const state = {
|
|
423
|
-
phase: 'idle',
|
|
424
|
-
reasonCode: null,
|
|
425
|
-
lastError: null,
|
|
426
|
-
lifecycle: {
|
|
427
|
-
running: false,
|
|
428
|
-
setupCalls: 0,
|
|
429
|
-
updateCalls: 0,
|
|
430
|
-
drawCalls: 0,
|
|
431
|
-
frameCount: 0,
|
|
432
|
-
lastDeltaSeconds: 0
|
|
433
|
-
}
|
|
434
|
-
};
|
|
435
|
-
let cachedManifest = null;
|
|
436
|
-
let cachedRuntimeConfig = null;
|
|
437
|
-
let cachedRootUrl = '.';
|
|
438
|
-
let mountedRuntime = null;
|
|
439
|
-
let auraRuntime = null;
|
|
440
|
-
|
|
441
|
-
function normalizeCount(value) {
|
|
442
|
-
const numeric = Number(value);
|
|
443
|
-
if (!Number.isFinite(numeric) || numeric < 0) return 0;
|
|
444
|
-
return Math.floor(numeric);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
function normalizeDeltaSeconds(value) {
|
|
448
|
-
const numeric = Number(value);
|
|
449
|
-
if (!Number.isFinite(numeric) || numeric < 0) return 0;
|
|
450
|
-
return Number(numeric.toFixed(6));
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
function cloneLifecycle(lifecycle) {
|
|
454
|
-
const source = lifecycle && typeof lifecycle === 'object' ? lifecycle : {};
|
|
455
|
-
return {
|
|
456
|
-
running: source.running === true,
|
|
457
|
-
setupCalls: normalizeCount(source.setupCalls),
|
|
458
|
-
updateCalls: normalizeCount(source.updateCalls),
|
|
459
|
-
drawCalls: normalizeCount(source.drawCalls),
|
|
460
|
-
frameCount: normalizeCount(source.frameCount),
|
|
461
|
-
lastDeltaSeconds: normalizeDeltaSeconds(source.lastDeltaSeconds)
|
|
462
|
-
};
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
function setState(phase, reasonCode, error) {
|
|
466
|
-
state.phase = phase;
|
|
467
|
-
state.reasonCode = reasonCode || null;
|
|
468
|
-
state.lastError = error || null;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
function createError(reasonCode, message, layer, retryable, details) {
|
|
472
|
-
const error = new Error(message);
|
|
473
|
-
error.ok = false;
|
|
474
|
-
error.reasonCode = reasonCode;
|
|
475
|
-
error.layer = layer;
|
|
476
|
-
error.retryable = Boolean(retryable);
|
|
477
|
-
error.details = details || {};
|
|
478
|
-
return error;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
function createUnsupportedRuntimeError(namespaceName, methodName, reasonCode, details) {
|
|
482
|
-
const normalizedDetails = details && typeof details === 'object' ? details : {};
|
|
483
|
-
return createError(
|
|
484
|
-
reasonCode,
|
|
485
|
-
'aura.' + namespaceName + '.' + methodName + '() is not supported in browser runtime. [reason:' + reasonCode + ']',
|
|
486
|
-
'runtime',
|
|
487
|
-
false,
|
|
488
|
-
Object.assign(
|
|
489
|
-
{
|
|
490
|
-
runtime: 'web',
|
|
491
|
-
namespace: namespaceName,
|
|
492
|
-
method: methodName
|
|
493
|
-
},
|
|
494
|
-
normalizedDetails
|
|
495
|
-
)
|
|
496
|
-
);
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
function createUnsupportedStateResult(methodName, reasonCode) {
|
|
500
|
-
return {
|
|
501
|
-
ok: false,
|
|
502
|
-
reasonCode: reasonCode,
|
|
503
|
-
detail: 'aura.state.' + methodName + '() is not supported in browser runtime. [reason:' + reasonCode + ']',
|
|
504
|
-
runtime: 'web'
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
function normalizeError(error, fallbackReasonCode, fallbackMessage, fallbackLayer, fallbackRetryable) {
|
|
509
|
-
if (error && typeof error === 'object' && typeof error.reasonCode === 'string') {
|
|
510
|
-
return error;
|
|
511
|
-
}
|
|
512
|
-
return createError(
|
|
513
|
-
fallbackReasonCode,
|
|
514
|
-
fallbackMessage,
|
|
515
|
-
fallbackLayer,
|
|
516
|
-
fallbackRetryable,
|
|
517
|
-
{ cause: String(error && error.message ? error.message : error) }
|
|
518
|
-
);
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
async function captureFailure(fallback, operation) {
|
|
522
|
-
try {
|
|
523
|
-
return await operation();
|
|
524
|
-
} catch (error) {
|
|
525
|
-
const normalized = normalizeError(
|
|
526
|
-
error,
|
|
527
|
-
fallback.reasonCode,
|
|
528
|
-
fallback.message,
|
|
529
|
-
fallback.layer,
|
|
530
|
-
fallback.retryable
|
|
531
|
-
);
|
|
532
|
-
setState('error', normalized.reasonCode, {
|
|
533
|
-
reasonCode: normalized.reasonCode,
|
|
534
|
-
layer: normalized.layer || fallback.layer,
|
|
535
|
-
retryable: normalized.retryable === true,
|
|
536
|
-
details: normalized.details || {}
|
|
537
|
-
});
|
|
538
|
-
throw normalized;
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
async function readJson(path, missingCode, parseCode) {
|
|
543
|
-
let response;
|
|
544
|
-
try {
|
|
545
|
-
response = await fetch(path, { cache: 'no-store' });
|
|
546
|
-
} catch (error) {
|
|
547
|
-
throw createError(missingCode, 'Failed to fetch ' + path + '.', 'loader', false, { cause: String(error) });
|
|
548
|
-
}
|
|
549
|
-
if (!response || response.ok !== true) {
|
|
550
|
-
throw createError(missingCode, path + ' not found.', 'loader', false, { status: response ? response.status : null });
|
|
551
|
-
}
|
|
552
|
-
try {
|
|
553
|
-
return await response.json();
|
|
554
|
-
} catch (error) {
|
|
555
|
-
throw createError(parseCode, path + ' is not valid JSON.', 'loader', false, { cause: String(error) });
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
function normalizePath(path) {
|
|
560
|
-
if (typeof path !== 'string') return '';
|
|
561
|
-
return path.replace(/\\\\/g, '/').replace(/^\\.\\//, '');
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
function clampUnit(value, fallback) {
|
|
565
|
-
const numeric = Number(value);
|
|
566
|
-
if (!Number.isFinite(numeric)) return fallback;
|
|
567
|
-
if (numeric <= 0) return 0;
|
|
568
|
-
if (numeric >= 1) return 1;
|
|
569
|
-
return numeric;
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
function createUnitColor(r, g, b, a) {
|
|
573
|
-
return {
|
|
574
|
-
r: clampUnit(r, 0),
|
|
575
|
-
g: clampUnit(g, 0),
|
|
576
|
-
b: clampUnit(b, 0),
|
|
577
|
-
a: clampUnit(a == null ? 1 : a, 1)
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
function createByteColor(r, g, b, a) {
|
|
582
|
-
return {
|
|
583
|
-
r: Math.max(0, Math.min(255, Math.round(Number(r) || 0))),
|
|
584
|
-
g: Math.max(0, Math.min(255, Math.round(Number(g) || 0))),
|
|
585
|
-
b: Math.max(0, Math.min(255, Math.round(Number(b) || 0))),
|
|
586
|
-
a: Math.max(0, Math.min(255, Math.round(Number.isFinite(Number(a)) ? Number(a) : 255)))
|
|
587
|
-
};
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
function normalizeColor(value, fallback) {
|
|
591
|
-
const source = value && typeof value === 'object' ? value : null;
|
|
592
|
-
const base = fallback && typeof fallback === 'object' ? fallback : createUnitColor(1, 1, 1, 1);
|
|
593
|
-
if (!source) {
|
|
594
|
-
return createUnitColor(base.r, base.g, base.b, base.a);
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
const rawR = Number(source.r);
|
|
598
|
-
const rawG = Number(source.g);
|
|
599
|
-
const rawB = Number(source.b);
|
|
600
|
-
const rawA = source.a == null ? base.a : Number(source.a);
|
|
601
|
-
const treatAsByteRange = [rawR, rawG, rawB, rawA].some((component) => Number.isFinite(component) && component > 1);
|
|
602
|
-
|
|
603
|
-
if (treatAsByteRange) {
|
|
604
|
-
return createUnitColor(
|
|
605
|
-
Number.isFinite(rawR) ? rawR / 255 : base.r,
|
|
606
|
-
Number.isFinite(rawG) ? rawG / 255 : base.g,
|
|
607
|
-
Number.isFinite(rawB) ? rawB / 255 : base.b,
|
|
608
|
-
Number.isFinite(rawA) ? rawA / 255 : base.a
|
|
609
|
-
);
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
return createUnitColor(
|
|
613
|
-
Number.isFinite(rawR) ? rawR : base.r,
|
|
614
|
-
Number.isFinite(rawG) ? rawG : base.g,
|
|
615
|
-
Number.isFinite(rawB) ? rawB : base.b,
|
|
616
|
-
Number.isFinite(rawA) ? rawA : base.a
|
|
617
|
-
);
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
function colorToCss(value, fallback) {
|
|
621
|
-
const normalized = normalizeColor(value, fallback);
|
|
622
|
-
return 'rgba('
|
|
623
|
-
+ Math.round(normalized.r * 255) + ', '
|
|
624
|
-
+ Math.round(normalized.g * 255) + ', '
|
|
625
|
-
+ Math.round(normalized.b * 255) + ', '
|
|
626
|
-
+ normalized.a + ')';
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
function normalizeCanvasSize(value, fallback) {
|
|
630
|
-
const numeric = Number(value);
|
|
631
|
-
if (!Number.isFinite(numeric) || numeric <= 0) return fallback;
|
|
632
|
-
return Math.max(1, Math.floor(numeric));
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
function normalizePositiveNumber(value, fallback) {
|
|
636
|
-
const numeric = Number(value);
|
|
637
|
-
if (!Number.isFinite(numeric) || numeric <= 0) return fallback;
|
|
638
|
-
return numeric;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
function toFinite(value, fallback) {
|
|
642
|
-
const numeric = Number(value);
|
|
643
|
-
return Number.isFinite(numeric) ? numeric : fallback;
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
function toPositive(value, fallback) {
|
|
647
|
-
const numeric = Number(value);
|
|
648
|
-
return Number.isFinite(numeric) && numeric > 0 ? numeric : fallback;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
function clamp01(value) {
|
|
652
|
-
const numeric = Number(value);
|
|
653
|
-
if (!Number.isFinite(numeric)) return 1;
|
|
654
|
-
if (numeric <= 0) return 0;
|
|
655
|
-
if (numeric >= 1) return 1;
|
|
656
|
-
return numeric;
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
function isObject(value) {
|
|
660
|
-
return value != null && typeof value === 'object';
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
function normalizeMouseButton(value) {
|
|
664
|
-
const numeric = Number(value);
|
|
665
|
-
if (!Number.isFinite(numeric) || numeric < 0) return 0;
|
|
666
|
-
return Math.floor(numeric);
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
function sanitizeAssetSourcePath(value) {
|
|
670
|
-
return String(value || '')
|
|
671
|
-
.replace(/\\\\/g, '/')
|
|
672
|
-
.replace(/^\\.\\//, '')
|
|
673
|
-
.replace(/^\\/+/, '');
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
function isImageMediaType(value) {
|
|
677
|
-
return typeof value === 'string' && value.startsWith('image/');
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
function normalizeTextAlign(value) {
|
|
681
|
-
if (value === 'center' || value === 'right' || value === 'left') {
|
|
682
|
-
return value;
|
|
683
|
-
}
|
|
684
|
-
return 'left';
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
function normalizeKeyName(value) {
|
|
688
|
-
if (typeof value !== 'string' || value.length === 0) {
|
|
689
|
-
return null;
|
|
690
|
-
}
|
|
691
|
-
const key = value.toLowerCase();
|
|
692
|
-
switch (key) {
|
|
693
|
-
case ' ':
|
|
694
|
-
case 'spacebar':
|
|
695
|
-
return 'space';
|
|
696
|
-
case 'left':
|
|
697
|
-
case 'arrowleft':
|
|
698
|
-
return 'arrowleft';
|
|
699
|
-
case 'right':
|
|
700
|
-
case 'arrowright':
|
|
701
|
-
return 'arrowright';
|
|
702
|
-
case 'up':
|
|
703
|
-
case 'arrowup':
|
|
704
|
-
return 'arrowup';
|
|
705
|
-
case 'down':
|
|
706
|
-
case 'arrowdown':
|
|
707
|
-
return 'arrowdown';
|
|
708
|
-
case 'return':
|
|
709
|
-
return 'enter';
|
|
710
|
-
default:
|
|
711
|
-
return key;
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
function rectIntersects(a, b) {
|
|
716
|
-
const ax = Number(a && a.x);
|
|
717
|
-
const ay = Number(a && a.y);
|
|
718
|
-
const aw = Number(a && a.w);
|
|
719
|
-
const ah = Number(a && a.h);
|
|
720
|
-
const bx = Number(b && b.x);
|
|
721
|
-
const by = Number(b && b.y);
|
|
722
|
-
const bw = Number(b && b.w);
|
|
723
|
-
const bh = Number(b && b.h);
|
|
724
|
-
|
|
725
|
-
if (![ax, ay, aw, ah, bx, by, bw, bh].every((value) => Number.isFinite(value))) {
|
|
726
|
-
return false;
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
return ax < bx + bw && ax + aw > bx && ay < by + bh && ay + ah > by;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
function resolveTarget(target) {
|
|
733
|
-
if (typeof target === 'string') {
|
|
734
|
-
return document.querySelector(target);
|
|
735
|
-
}
|
|
736
|
-
if (target && typeof target.appendChild === 'function') {
|
|
737
|
-
return target;
|
|
738
|
-
}
|
|
739
|
-
return document.getElementById('aura-root') || document.body;
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
function ensureManifestValid(manifest) {
|
|
743
|
-
if (!manifest || manifest.schema !== 'aurajs.web-build-manifest.v1') {
|
|
744
|
-
throw createError(
|
|
745
|
-
'web_manifest_schema_unsupported',
|
|
746
|
-
'Manifest schema major version is unsupported.',
|
|
747
|
-
'loader',
|
|
748
|
-
false,
|
|
749
|
-
{ schema: manifest && manifest.schema }
|
|
750
|
-
);
|
|
751
|
-
}
|
|
752
|
-
if (!manifest.entrypoints || typeof manifest.entrypoints.bundle !== 'string' || manifest.entrypoints.bundle.length === 0) {
|
|
753
|
-
throw createError('web_manifest_validation_failed', 'Manifest bundle entrypoint is missing.', 'loader', false, {});
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
function ensureRuntimeConfigValid(runtimeConfig) {
|
|
758
|
-
if (!runtimeConfig || runtimeConfig.schema !== 'aurajs.web-runtime-config.v1') {
|
|
759
|
-
throw createError(
|
|
760
|
-
'web_runtime_config_validation_failed',
|
|
761
|
-
'Runtime config schema major version is unsupported.',
|
|
762
|
-
'loader',
|
|
763
|
-
false,
|
|
764
|
-
{ schema: runtimeConfig && runtimeConfig.schema }
|
|
765
|
-
);
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
function normalizeCapabilityDeclaration(value) {
|
|
770
|
-
const declaration = value && typeof value === 'object' ? value : {};
|
|
771
|
-
const requiredApis = Array.isArray(declaration.requiredApis)
|
|
772
|
-
? Array.from(new Set(declaration.requiredApis
|
|
773
|
-
.filter(function (entry) { return typeof entry === 'string'; })
|
|
774
|
-
.map(function (entry) { return entry.trim(); })
|
|
775
|
-
.filter(Boolean)))
|
|
776
|
-
.sort(function (a, b) { return a.localeCompare(b); })
|
|
777
|
-
: [];
|
|
778
|
-
const declaredModules = declaration.optionalModules && typeof declaration.optionalModules === 'object'
|
|
779
|
-
? declaration.optionalModules
|
|
780
|
-
: {};
|
|
781
|
-
return {
|
|
782
|
-
schema: typeof declaration.schema === 'string'
|
|
783
|
-
? declaration.schema
|
|
784
|
-
: 'aurajs.web-capability-declaration.v1',
|
|
785
|
-
source: typeof declaration.source === 'string' ? declaration.source : null,
|
|
786
|
-
requiredApis: requiredApis,
|
|
787
|
-
optionalModules: {
|
|
788
|
-
physics: declaredModules.physics === true,
|
|
789
|
-
network: declaredModules.network === true,
|
|
790
|
-
multiplayer: declaredModules.multiplayer === true,
|
|
791
|
-
steam: declaredModules.steam === true
|
|
792
|
-
}
|
|
793
|
-
};
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
function resolveDeclaredApi(root, apiPath) {
|
|
797
|
-
if (typeof apiPath !== 'string' || apiPath.length === 0) {
|
|
798
|
-
return { found: false, value: undefined };
|
|
799
|
-
}
|
|
800
|
-
const segments = apiPath.split('.').filter(Boolean);
|
|
801
|
-
let current = root;
|
|
802
|
-
for (const segment of segments) {
|
|
803
|
-
if (
|
|
804
|
-
current == null
|
|
805
|
-
|| (typeof current !== 'object' && typeof current !== 'function')
|
|
806
|
-
|| !(segment in current)
|
|
807
|
-
) {
|
|
808
|
-
return { found: false, value: undefined };
|
|
809
|
-
}
|
|
810
|
-
current = current[segment];
|
|
811
|
-
}
|
|
812
|
-
return { found: current != null, value: current };
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
function collectCapabilityFailures(runtimeConfig, auraRef) {
|
|
816
|
-
const declaration = normalizeCapabilityDeclaration(runtimeConfig && runtimeConfig.capabilities);
|
|
817
|
-
const failures = [];
|
|
818
|
-
const root = { aura: auraRef && typeof auraRef === 'object' ? auraRef : {} };
|
|
819
|
-
|
|
820
|
-
for (const moduleName of ['physics', 'network', 'multiplayer', 'steam']) {
|
|
821
|
-
if (declaration.optionalModules[moduleName] === true) {
|
|
822
|
-
failures.push({
|
|
823
|
-
kind: 'optionalModule',
|
|
824
|
-
module: moduleName,
|
|
825
|
-
reasonCode: 'web_optional_module_unsupported'
|
|
826
|
-
});
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
for (const apiPath of declaration.requiredApis) {
|
|
831
|
-
const resolved = resolveDeclaredApi(root, apiPath);
|
|
832
|
-
if (!resolved.found) {
|
|
833
|
-
failures.push({
|
|
834
|
-
kind: 'requiredApi',
|
|
835
|
-
apiPath: apiPath,
|
|
836
|
-
reasonCode: 'web_required_api_missing'
|
|
837
|
-
});
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
return {
|
|
842
|
-
declaration: declaration,
|
|
843
|
-
failures: failures
|
|
844
|
-
};
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
function ensureCapabilityDeclarationSatisfied(runtimeConfig, auraRef) {
|
|
848
|
-
const report = collectCapabilityFailures(runtimeConfig, auraRef);
|
|
849
|
-
if (report.failures.length === 0) {
|
|
850
|
-
return;
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
const missingRequiredApis = [];
|
|
854
|
-
const unsupportedOptionalModules = [];
|
|
855
|
-
for (const failure of report.failures) {
|
|
856
|
-
if (failure.kind === 'requiredApi') {
|
|
857
|
-
missingRequiredApis.push(failure.apiPath);
|
|
858
|
-
} else if (failure.kind === 'optionalModule') {
|
|
859
|
-
unsupportedOptionalModules.push(failure.module);
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
let reasonCode = 'web_capability_gate_failed';
|
|
864
|
-
if (missingRequiredApis.length > 0 && unsupportedOptionalModules.length === 0) {
|
|
865
|
-
reasonCode = 'web_required_api_missing';
|
|
866
|
-
} else if (unsupportedOptionalModules.length > 0 && missingRequiredApis.length === 0) {
|
|
867
|
-
reasonCode = 'web_optional_module_unsupported';
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
throw createError(
|
|
871
|
-
reasonCode,
|
|
872
|
-
'Browser runtime does not satisfy the declared capability contract.',
|
|
873
|
-
'loader',
|
|
874
|
-
false,
|
|
875
|
-
{
|
|
876
|
-
schema: report.declaration.schema,
|
|
877
|
-
source: report.declaration.source,
|
|
878
|
-
missingRequiredApis: missingRequiredApis,
|
|
879
|
-
unsupportedOptionalModules: unsupportedOptionalModules,
|
|
880
|
-
failures: report.failures
|
|
881
|
-
}
|
|
882
|
-
);
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
function loadScript(path) {
|
|
886
|
-
return new Promise((resolvePromise, rejectPromise) => {
|
|
887
|
-
const script = document.createElement('script');
|
|
888
|
-
script.src = path;
|
|
889
|
-
script.async = false;
|
|
890
|
-
script.onload = function () { resolvePromise(); };
|
|
891
|
-
script.onerror = function () {
|
|
892
|
-
rejectPromise(createError('web_bundle_load_failed', 'Failed to load ' + path + '.', 'loader', true, { path }));
|
|
893
|
-
};
|
|
894
|
-
document.head.appendChild(script);
|
|
895
|
-
});
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
function createBrowserAuraSurface(runtimeConfig) {
|
|
899
|
-
const defaultColor = createUnitColor(1, 1, 1, 1);
|
|
900
|
-
let currentRuntimeConfig = runtimeConfig && typeof runtimeConfig === 'object' ? runtimeConfig : {};
|
|
901
|
-
let currentCanvasConfig = currentRuntimeConfig.canvas && typeof currentRuntimeConfig.canvas === 'object'
|
|
902
|
-
? currentRuntimeConfig.canvas
|
|
903
|
-
: {};
|
|
904
|
-
let currentManifest = { assets: [] };
|
|
905
|
-
let currentRootUrl = '.';
|
|
906
|
-
|
|
907
|
-
const auraRef = globalRef.aura && typeof globalRef.aura === 'object'
|
|
908
|
-
? globalRef.aura
|
|
909
|
-
: {};
|
|
910
|
-
globalRef.aura = auraRef;
|
|
911
|
-
|
|
912
|
-
const inputState = {
|
|
913
|
-
down: new Set(),
|
|
914
|
-
pendingPressed: new Set(),
|
|
915
|
-
pendingReleased: new Set(),
|
|
916
|
-
framePressed: new Set(),
|
|
917
|
-
frameReleased: new Set(),
|
|
918
|
-
mouseDown: new Set(),
|
|
919
|
-
pendingMousePressed: new Set(),
|
|
920
|
-
pendingMouseReleased: new Set(),
|
|
921
|
-
frameMousePressed: new Set(),
|
|
922
|
-
frameMouseReleased: new Set(),
|
|
923
|
-
pendingMouseDeltaX: 0,
|
|
924
|
-
pendingMouseDeltaY: 0,
|
|
925
|
-
frameMouseDeltaX: 0,
|
|
926
|
-
frameMouseDeltaY: 0
|
|
927
|
-
};
|
|
928
|
-
|
|
929
|
-
const assetState = {
|
|
930
|
-
bySourcePath: new Map(),
|
|
931
|
-
byOutputPath: new Map(),
|
|
932
|
-
loaded: new Map(),
|
|
933
|
-
storageFallback: new Map()
|
|
934
|
-
};
|
|
935
|
-
|
|
936
|
-
const runtime = {
|
|
937
|
-
canvas: null,
|
|
938
|
-
mountTarget: null,
|
|
939
|
-
context2d: null,
|
|
940
|
-
configuredWidth: normalizeCanvasSize(currentCanvasConfig.width, 1280),
|
|
941
|
-
configuredHeight: normalizeCanvasSize(currentCanvasConfig.height, 720),
|
|
942
|
-
resizeMode: currentCanvasConfig.resizeMode === 'fixed' ? 'fixed' : 'fit-container',
|
|
943
|
-
pixelRatio: 1,
|
|
944
|
-
width: normalizeCanvasSize(currentCanvasConfig.width, 1280),
|
|
945
|
-
height: normalizeCanvasSize(currentCanvasConfig.height, 720),
|
|
946
|
-
transformDepth: 0,
|
|
947
|
-
worldTransformActive: false,
|
|
948
|
-
cursorVisible: true,
|
|
949
|
-
cursorLocked: false,
|
|
950
|
-
listenersAttached: false,
|
|
951
|
-
keydownListener: null,
|
|
952
|
-
keyupListener: null,
|
|
953
|
-
focusListener: null,
|
|
954
|
-
blurListener: null,
|
|
955
|
-
resizeListener: null,
|
|
956
|
-
mousemoveListener: null,
|
|
957
|
-
mousedownListener: null,
|
|
958
|
-
mouseupListener: null,
|
|
959
|
-
wheelListener: null
|
|
960
|
-
};
|
|
961
|
-
|
|
962
|
-
function ensureStyleObject(node) {
|
|
963
|
-
if (!node || typeof node !== 'object') return null;
|
|
964
|
-
if (!node.style || typeof node.style !== 'object') {
|
|
965
|
-
node.style = {};
|
|
966
|
-
}
|
|
967
|
-
return node.style;
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
function ensureCanvasContext() {
|
|
971
|
-
if (!runtime.canvas) return null;
|
|
972
|
-
if (!runtime.context2d && typeof runtime.canvas.getContext === 'function') {
|
|
973
|
-
runtime.context2d = runtime.canvas.getContext('2d');
|
|
974
|
-
}
|
|
975
|
-
return runtime.context2d;
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
function normalizeAssetKey(value) {
|
|
979
|
-
return sanitizeAssetSourcePath(value);
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
function indexManifestAssets(manifest, rootUrl) {
|
|
983
|
-
currentManifest = manifest && typeof manifest === 'object' ? manifest : { assets: [] };
|
|
984
|
-
currentRootUrl = typeof rootUrl === 'string' && rootUrl.length > 0
|
|
985
|
-
? rootUrl.replace(/\\/$/, '')
|
|
986
|
-
: '.';
|
|
987
|
-
assetState.bySourcePath.clear();
|
|
988
|
-
assetState.byOutputPath.clear();
|
|
989
|
-
const entries = Array.isArray(currentManifest.assets) ? currentManifest.assets : [];
|
|
990
|
-
for (const entry of entries) {
|
|
991
|
-
if (!entry || typeof entry !== 'object') continue;
|
|
992
|
-
const outputPath = normalizePath(entry.path);
|
|
993
|
-
if (outputPath.length > 0) {
|
|
994
|
-
assetState.byOutputPath.set(outputPath, entry);
|
|
995
|
-
}
|
|
996
|
-
const sourcePath = normalizeAssetKey(entry.sourcePath || outputPath);
|
|
997
|
-
if (sourcePath.length > 0) {
|
|
998
|
-
assetState.bySourcePath.set(sourcePath, entry);
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
function buildAssetUrl(entryPath) {
|
|
1004
|
-
const normalized = normalizePath(entryPath);
|
|
1005
|
-
const root = currentRootUrl && currentRootUrl.length > 0 ? currentRootUrl : '.';
|
|
1006
|
-
return root + '/' + normalized;
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
function resolveAssetEntry(source) {
|
|
1010
|
-
const normalizedSource = normalizeAssetKey(source);
|
|
1011
|
-
if (normalizedSource.length === 0) return null;
|
|
1012
|
-
if (assetState.bySourcePath.has(normalizedSource)) {
|
|
1013
|
-
return assetState.bySourcePath.get(normalizedSource);
|
|
1014
|
-
}
|
|
1015
|
-
const outputPath = normalizePath(normalizedSource);
|
|
1016
|
-
if (assetState.byOutputPath.has(outputPath)) {
|
|
1017
|
-
return assetState.byOutputPath.get(outputPath);
|
|
1018
|
-
}
|
|
1019
|
-
return null;
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
|
-
function resolveAssetSourcePath(source) {
|
|
1023
|
-
if (typeof source === 'string') {
|
|
1024
|
-
return normalizeAssetKey(source);
|
|
1025
|
-
}
|
|
1026
|
-
if (source && typeof source === 'object') {
|
|
1027
|
-
if (typeof source.sourcePath === 'string') return normalizeAssetKey(source.sourcePath);
|
|
1028
|
-
if (typeof source.path === 'string') return normalizeAssetKey(source.path);
|
|
1029
|
-
if (typeof source.name === 'string') return normalizeAssetKey(source.name);
|
|
1030
|
-
}
|
|
1031
|
-
return '';
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
function resolveLoadedAsset(source) {
|
|
1035
|
-
const key = resolveAssetSourcePath(source);
|
|
1036
|
-
if (key.length === 0) return null;
|
|
1037
|
-
return assetState.loaded.get(key) || null;
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
function rememberLoadedAsset(sourcePath, handle) {
|
|
1041
|
-
const key = normalizeAssetKey(sourcePath);
|
|
1042
|
-
if (key.length === 0 || !handle || typeof handle !== 'object') return handle;
|
|
1043
|
-
handle.sourcePath = key;
|
|
1044
|
-
if (typeof handle.path !== 'string' || handle.path.length === 0) {
|
|
1045
|
-
handle.path = key;
|
|
1046
|
-
}
|
|
1047
|
-
assetState.loaded.set(key, handle);
|
|
1048
|
-
return handle;
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
async function fetchAssetResponse(entry) {
|
|
1052
|
-
if (!entry || typeof entry !== 'object') return null;
|
|
1053
|
-
const assetUrl = buildAssetUrl(entry.path);
|
|
1054
|
-
let response;
|
|
1055
|
-
try {
|
|
1056
|
-
response = await fetch(assetUrl, { cache: 'force-cache' });
|
|
1057
|
-
} catch (_) {
|
|
1058
|
-
return null;
|
|
1059
|
-
}
|
|
1060
|
-
if (!response || response.ok !== true) {
|
|
1061
|
-
return null;
|
|
1062
|
-
}
|
|
1063
|
-
return response;
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
async function readAssetBytes(entry) {
|
|
1067
|
-
const response = await fetchAssetResponse(entry);
|
|
1068
|
-
if (!response || typeof response.arrayBuffer !== 'function') {
|
|
1069
|
-
return null;
|
|
1070
|
-
}
|
|
1071
|
-
try {
|
|
1072
|
-
return new Uint8Array(await response.arrayBuffer());
|
|
1073
|
-
} catch (_) {
|
|
1074
|
-
return null;
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
async function readAssetText(entry) {
|
|
1079
|
-
const response = await fetchAssetResponse(entry);
|
|
1080
|
-
if (!response || typeof response.text !== 'function') {
|
|
1081
|
-
return null;
|
|
1082
|
-
}
|
|
1083
|
-
try {
|
|
1084
|
-
return await response.text();
|
|
1085
|
-
} catch (_) {
|
|
1086
|
-
return null;
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
async function loadImageHandle(sourcePath, entry) {
|
|
1091
|
-
const existing = resolveLoadedAsset(sourcePath);
|
|
1092
|
-
if (existing && existing.image) {
|
|
1093
|
-
return existing;
|
|
1094
|
-
}
|
|
1095
|
-
const ImageCtor = typeof globalRef.Image === 'function' ? globalRef.Image : null;
|
|
1096
|
-
const handle = existing || {
|
|
1097
|
-
kind: 'image',
|
|
1098
|
-
path: sourcePath,
|
|
1099
|
-
sourcePath: sourcePath,
|
|
1100
|
-
resolvedPath: entry && typeof entry.path === 'string' ? normalizePath(entry.path) : sourcePath,
|
|
1101
|
-
mediaType: entry && typeof entry.mediaType === 'string' ? entry.mediaType : 'image/png',
|
|
1102
|
-
image: null,
|
|
1103
|
-
width: 0,
|
|
1104
|
-
height: 0
|
|
1105
|
-
};
|
|
1106
|
-
if (!ImageCtor || !entry) {
|
|
1107
|
-
return rememberLoadedAsset(sourcePath, handle);
|
|
1108
|
-
}
|
|
1109
|
-
try {
|
|
1110
|
-
const image = await new Promise(function (resolvePromise, rejectPromise) {
|
|
1111
|
-
const node = new ImageCtor();
|
|
1112
|
-
node.onload = function () { resolvePromise(node); };
|
|
1113
|
-
node.onerror = function () { rejectPromise(new Error('image_load_failed')); };
|
|
1114
|
-
node.src = buildAssetUrl(entry.path);
|
|
1115
|
-
});
|
|
1116
|
-
handle.image = image;
|
|
1117
|
-
handle.width = normalizeCanvasSize(image.naturalWidth || image.width, 1);
|
|
1118
|
-
handle.height = normalizeCanvasSize(image.naturalHeight || image.height, 1);
|
|
1119
|
-
} catch (_) {}
|
|
1120
|
-
return rememberLoadedAsset(sourcePath, handle);
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
function createBrowserSoundHandle(sourcePath, entry, bytes) {
|
|
1124
|
-
return rememberLoadedAsset(sourcePath, {
|
|
1125
|
-
kind: 'sound',
|
|
1126
|
-
path: sourcePath,
|
|
1127
|
-
sourcePath: sourcePath,
|
|
1128
|
-
resolvedPath: entry && typeof entry.path === 'string' ? normalizePath(entry.path) : sourcePath,
|
|
1129
|
-
mediaType: entry && typeof entry.mediaType === 'string' ? entry.mediaType : 'audio/ogg',
|
|
1130
|
-
bytes: bytes instanceof Uint8Array ? bytes : new Uint8Array(),
|
|
1131
|
-
playbackSupported: false,
|
|
1132
|
-
reasonCode: 'web_audio_playback_unsupported',
|
|
1133
|
-
detail: 'Browser runtime resolves sound assets but does not support aura.audio playback. [reason:web_audio_playback_unsupported]'
|
|
1134
|
-
});
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
async function loadAssetRecord(source) {
|
|
1138
|
-
if (Array.isArray(source)) {
|
|
1139
|
-
const loaded = [];
|
|
1140
|
-
for (const entry of source) {
|
|
1141
|
-
const next = await loadAssetRecord(entry);
|
|
1142
|
-
if (next) loaded.push(next);
|
|
1143
|
-
}
|
|
1144
|
-
return loaded;
|
|
1145
|
-
}
|
|
1146
|
-
const sourcePath = resolveAssetSourcePath(source);
|
|
1147
|
-
if (sourcePath.length === 0) return null;
|
|
1148
|
-
const existing = resolveLoadedAsset(sourcePath);
|
|
1149
|
-
if (existing) return existing;
|
|
1150
|
-
const entry = resolveAssetEntry(sourcePath);
|
|
1151
|
-
if (!entry) return null;
|
|
1152
|
-
if (isImageMediaType(entry.mediaType)) {
|
|
1153
|
-
return await loadImageHandle(sourcePath, entry);
|
|
1154
|
-
}
|
|
1155
|
-
const bytes = await readAssetBytes(entry);
|
|
1156
|
-
if (entry.mediaType && entry.mediaType.startsWith('audio/')) {
|
|
1157
|
-
return createBrowserSoundHandle(sourcePath, entry, bytes);
|
|
1158
|
-
}
|
|
1159
|
-
if (!bytes) {
|
|
1160
|
-
return rememberLoadedAsset(sourcePath, {
|
|
1161
|
-
kind: 'asset',
|
|
1162
|
-
path: sourcePath,
|
|
1163
|
-
sourcePath: sourcePath,
|
|
1164
|
-
resolvedPath: normalizePath(entry.path),
|
|
1165
|
-
mediaType: entry.mediaType,
|
|
1166
|
-
bytes: new Uint8Array()
|
|
1167
|
-
});
|
|
1168
|
-
}
|
|
1169
|
-
const handle = {
|
|
1170
|
-
kind: 'asset',
|
|
1171
|
-
path: sourcePath,
|
|
1172
|
-
sourcePath: sourcePath,
|
|
1173
|
-
resolvedPath: normalizePath(entry.path),
|
|
1174
|
-
mediaType: entry.mediaType,
|
|
1175
|
-
bytes: bytes
|
|
1176
|
-
};
|
|
1177
|
-
if (entry.mediaType === 'application/json') {
|
|
1178
|
-
const text = typeof TextDecoder === 'function'
|
|
1179
|
-
? new TextDecoder('utf-8').decode(bytes)
|
|
1180
|
-
: String.fromCharCode.apply(null, Array.from(bytes));
|
|
1181
|
-
handle.text = text;
|
|
1182
|
-
try {
|
|
1183
|
-
handle.json = JSON.parse(text);
|
|
1184
|
-
} catch (_) {
|
|
1185
|
-
handle.json = null;
|
|
1186
|
-
}
|
|
1187
|
-
} else if (typeof entry.mediaType === 'string' && entry.mediaType.startsWith('text/')) {
|
|
1188
|
-
handle.text = typeof TextDecoder === 'function'
|
|
1189
|
-
? new TextDecoder('utf-8').decode(bytes)
|
|
1190
|
-
: String.fromCharCode.apply(null, Array.from(bytes));
|
|
1191
|
-
}
|
|
1192
|
-
return rememberLoadedAsset(sourcePath, handle);
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
function normalizeMousePosition(event) {
|
|
1196
|
-
const source = event && typeof event === 'object' ? event : {};
|
|
1197
|
-
if (Number.isFinite(Number(source.offsetX)) && Number.isFinite(Number(source.offsetY))) {
|
|
1198
|
-
return {
|
|
1199
|
-
x: Number(source.offsetX),
|
|
1200
|
-
y: Number(source.offsetY)
|
|
1201
|
-
};
|
|
1202
|
-
}
|
|
1203
|
-
const canvas = runtime.canvas;
|
|
1204
|
-
const rect = canvas && typeof canvas.getBoundingClientRect === 'function'
|
|
1205
|
-
? canvas.getBoundingClientRect()
|
|
1206
|
-
: null;
|
|
1207
|
-
const clientX = toFinite(source.clientX, auraRef.input.mouse.x);
|
|
1208
|
-
const clientY = toFinite(source.clientY, auraRef.input.mouse.y);
|
|
1209
|
-
if (rect) {
|
|
1210
|
-
return {
|
|
1211
|
-
x: clientX - toFinite(rect.left, 0),
|
|
1212
|
-
y: clientY - toFinite(rect.top, 0)
|
|
1213
|
-
};
|
|
1214
|
-
}
|
|
1215
|
-
return {
|
|
1216
|
-
x: clientX,
|
|
1217
|
-
y: clientY
|
|
1218
|
-
};
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1221
|
-
function syncMousePosition(event) {
|
|
1222
|
-
const point = normalizeMousePosition(event);
|
|
1223
|
-
const movementX = Number(event && event.movementX);
|
|
1224
|
-
const movementY = Number(event && event.movementY);
|
|
1225
|
-
const deltaX = Number.isFinite(movementX) ? movementX : point.x - auraRef.input.mouse.x;
|
|
1226
|
-
const deltaY = Number.isFinite(movementY) ? movementY : point.y - auraRef.input.mouse.y;
|
|
1227
|
-
inputState.pendingMouseDeltaX += deltaX;
|
|
1228
|
-
inputState.pendingMouseDeltaY += deltaY;
|
|
1229
|
-
auraRef.input.mouse.x = point.x;
|
|
1230
|
-
auraRef.input.mouse.y = point.y;
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
function clearMouseDeltaState() {
|
|
1234
|
-
inputState.pendingMouseDeltaX = 0;
|
|
1235
|
-
inputState.pendingMouseDeltaY = 0;
|
|
1236
|
-
inputState.frameMouseDeltaX = 0;
|
|
1237
|
-
inputState.frameMouseDeltaY = 0;
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
|
-
function clearTransientInputState() {
|
|
1241
|
-
inputState.pendingPressed.clear();
|
|
1242
|
-
inputState.pendingReleased.clear();
|
|
1243
|
-
inputState.framePressed.clear();
|
|
1244
|
-
inputState.frameReleased.clear();
|
|
1245
|
-
inputState.pendingMousePressed.clear();
|
|
1246
|
-
inputState.pendingMouseReleased.clear();
|
|
1247
|
-
inputState.frameMousePressed.clear();
|
|
1248
|
-
inputState.frameMouseReleased.clear();
|
|
1249
|
-
clearMouseDeltaState();
|
|
1250
|
-
}
|
|
1251
|
-
|
|
1252
|
-
function clearHeldInputState() {
|
|
1253
|
-
inputState.down.clear();
|
|
1254
|
-
inputState.mouseDown.clear();
|
|
1255
|
-
clearTransientInputState();
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1258
|
-
function applyCursorAppearance() {
|
|
1259
|
-
const style = ensureStyleObject(runtime.canvas);
|
|
1260
|
-
if (!style) return;
|
|
1261
|
-
style.cursor = (!runtime.cursorVisible || runtime.cursorLocked) ? 'none' : 'default';
|
|
1262
|
-
}
|
|
1263
|
-
|
|
1264
|
-
function syncCanvasSize(notifyResize) {
|
|
1265
|
-
let width = runtime.configuredWidth;
|
|
1266
|
-
let height = runtime.configuredHeight;
|
|
1267
|
-
if (runtime.resizeMode === 'fit-container') {
|
|
1268
|
-
const containerWidth = runtime.mountTarget
|
|
1269
|
-
? normalizeCanvasSize(runtime.mountTarget.clientWidth, 0)
|
|
1270
|
-
: 0;
|
|
1271
|
-
const containerHeight = runtime.mountTarget
|
|
1272
|
-
? normalizeCanvasSize(runtime.mountTarget.clientHeight, 0)
|
|
1273
|
-
: 0;
|
|
1274
|
-
if (containerWidth > 0 && containerHeight > 0) {
|
|
1275
|
-
width = containerWidth;
|
|
1276
|
-
height = containerHeight;
|
|
1277
|
-
}
|
|
1278
|
-
}
|
|
1279
|
-
|
|
1280
|
-
runtime.width = normalizeCanvasSize(width, runtime.configuredWidth);
|
|
1281
|
-
runtime.height = normalizeCanvasSize(height, runtime.configuredHeight);
|
|
1282
|
-
runtime.pixelRatio = Math.min(Math.max(normalizePositiveNumber(globalRef.devicePixelRatio, 1), 1), 2);
|
|
1283
|
-
|
|
1284
|
-
auraRef.window.width = runtime.width;
|
|
1285
|
-
auraRef.window.height = runtime.height;
|
|
1286
|
-
auraRef.window.pixelRatio = runtime.pixelRatio;
|
|
1287
|
-
|
|
1288
|
-
if (runtime.canvas) {
|
|
1289
|
-
runtime.canvas.width = Math.max(1, Math.round(runtime.width * runtime.pixelRatio));
|
|
1290
|
-
runtime.canvas.height = Math.max(1, Math.round(runtime.height * runtime.pixelRatio));
|
|
1291
|
-
runtime.canvas.tabIndex = 0;
|
|
1292
|
-
const style = ensureStyleObject(runtime.canvas);
|
|
1293
|
-
if (style) {
|
|
1294
|
-
style.width = runtime.width + 'px';
|
|
1295
|
-
style.height = runtime.height + 'px';
|
|
1296
|
-
style.display = 'block';
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
|
-
if (notifyResize && typeof auraRef.onResize === 'function') {
|
|
1301
|
-
auraRef.onResize(runtime.width, runtime.height);
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1304
|
-
|
|
1305
|
-
function resetDrawState() {
|
|
1306
|
-
const ctx = ensureCanvasContext();
|
|
1307
|
-
if (!ctx) return;
|
|
1308
|
-
if (typeof ctx.setTransform === 'function') {
|
|
1309
|
-
ctx.setTransform(runtime.pixelRatio, 0, 0, runtime.pixelRatio, 0, 0);
|
|
1310
|
-
} else {
|
|
1311
|
-
if (typeof ctx.resetTransform === 'function') {
|
|
1312
|
-
ctx.resetTransform();
|
|
1313
|
-
}
|
|
1314
|
-
if (typeof ctx.scale === 'function') {
|
|
1315
|
-
ctx.scale(runtime.pixelRatio, runtime.pixelRatio);
|
|
1316
|
-
}
|
|
1317
|
-
}
|
|
1318
|
-
runtime.transformDepth = 0;
|
|
1319
|
-
runtime.worldTransformActive = false;
|
|
1320
|
-
ctx.globalAlpha = 1;
|
|
1321
|
-
ctx.textAlign = 'left';
|
|
1322
|
-
ctx.textBaseline = 'top';
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
|
-
function applyWorldTransform() {
|
|
1326
|
-
const ctx = ensureCanvasContext();
|
|
1327
|
-
if (!ctx || runtime.worldTransformActive) return ctx;
|
|
1328
|
-
const camera = auraRef.camera && typeof auraRef.camera === 'object' ? auraRef.camera : null;
|
|
1329
|
-
if (camera) {
|
|
1330
|
-
const zoom = normalizePositiveNumber(camera.zoom, 1);
|
|
1331
|
-
const rotation = Number(camera.rotation) || 0;
|
|
1332
|
-
const x = Number(camera.x) || 0;
|
|
1333
|
-
const y = Number(camera.y) || 0;
|
|
1334
|
-
if (typeof ctx.scale === 'function' && zoom !== 1) {
|
|
1335
|
-
ctx.scale(zoom, zoom);
|
|
1336
|
-
}
|
|
1337
|
-
if (typeof ctx.rotate === 'function' && rotation !== 0) {
|
|
1338
|
-
ctx.rotate(rotation);
|
|
1339
|
-
}
|
|
1340
|
-
if (typeof ctx.translate === 'function' && (x !== 0 || y !== 0)) {
|
|
1341
|
-
ctx.translate(-x, -y);
|
|
1342
|
-
}
|
|
1343
|
-
}
|
|
1344
|
-
runtime.worldTransformActive = true;
|
|
1345
|
-
return ctx;
|
|
1346
|
-
}
|
|
1347
|
-
|
|
1348
|
-
function ensureWorldTransform() {
|
|
1349
|
-
const ctx = ensureCanvasContext();
|
|
1350
|
-
if (!ctx) return null;
|
|
1351
|
-
return runtime.worldTransformActive ? ctx : applyWorldTransform();
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
function normalizeTextOptions(sizeOrOptions, colorMaybe) {
|
|
1355
|
-
if (sizeOrOptions && typeof sizeOrOptions === 'object' && !Array.isArray(sizeOrOptions)) {
|
|
1356
|
-
return sizeOrOptions;
|
|
1357
|
-
}
|
|
1358
|
-
if (Number.isFinite(Number(sizeOrOptions))) {
|
|
1359
|
-
return {
|
|
1360
|
-
size: Number(sizeOrOptions),
|
|
1361
|
-
color: colorMaybe
|
|
1362
|
-
};
|
|
1363
|
-
}
|
|
1364
|
-
return {};
|
|
1365
|
-
}
|
|
1366
|
-
|
|
1367
|
-
function applyFont(options) {
|
|
1368
|
-
const ctx = ensureCanvasContext();
|
|
1369
|
-
const source = options && typeof options === 'object' ? options : {};
|
|
1370
|
-
const size = normalizePositiveNumber(source.size, 16);
|
|
1371
|
-
const family = typeof source.font === 'string' && source.font.trim().length > 0
|
|
1372
|
-
? source.font.trim()
|
|
1373
|
-
: 'sans-serif';
|
|
1374
|
-
if (ctx) {
|
|
1375
|
-
ctx.font = size + 'px ' + family;
|
|
1376
|
-
ctx.textAlign = normalizeTextAlign(source.align);
|
|
1377
|
-
ctx.textBaseline = 'top';
|
|
1378
|
-
}
|
|
1379
|
-
return { size, align: normalizeTextAlign(source.align) };
|
|
1380
|
-
}
|
|
1381
|
-
|
|
1382
|
-
function withScreenSpace(callback) {
|
|
1383
|
-
const ctx = ensureCanvasContext();
|
|
1384
|
-
if (!ctx || typeof callback !== 'function') return null;
|
|
1385
|
-
if (typeof ctx.save === 'function') {
|
|
1386
|
-
ctx.save();
|
|
1387
|
-
}
|
|
1388
|
-
if (typeof ctx.setTransform === 'function') {
|
|
1389
|
-
ctx.setTransform(runtime.pixelRatio, 0, 0, runtime.pixelRatio, 0, 0);
|
|
1390
|
-
} else {
|
|
1391
|
-
if (typeof ctx.resetTransform === 'function') {
|
|
1392
|
-
ctx.resetTransform();
|
|
1393
|
-
}
|
|
1394
|
-
if (typeof ctx.scale === 'function') {
|
|
1395
|
-
ctx.scale(runtime.pixelRatio, runtime.pixelRatio);
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
try {
|
|
1399
|
-
return callback(ctx);
|
|
1400
|
-
} finally {
|
|
1401
|
-
if (typeof ctx.restore === 'function') {
|
|
1402
|
-
ctx.restore();
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
|
|
1407
|
-
function resolveStorageBackend() {
|
|
1408
|
-
return globalRef.localStorage && typeof globalRef.localStorage.getItem === 'function'
|
|
1409
|
-
? globalRef.localStorage
|
|
1410
|
-
: null;
|
|
1411
|
-
}
|
|
1412
|
-
|
|
1413
|
-
function storageKey(key) {
|
|
1414
|
-
return 'aurajs:' + String(key || '');
|
|
1415
|
-
}
|
|
1416
|
-
|
|
1417
|
-
function readStorage(key) {
|
|
1418
|
-
const normalizedKey = String(key || '');
|
|
1419
|
-
if (normalizedKey.length === 0) return null;
|
|
1420
|
-
const backend = resolveStorageBackend();
|
|
1421
|
-
const namespaced = storageKey(normalizedKey);
|
|
1422
|
-
let raw = null;
|
|
1423
|
-
if (backend) {
|
|
1424
|
-
try {
|
|
1425
|
-
raw = backend.getItem(namespaced);
|
|
1426
|
-
} catch (_) {
|
|
1427
|
-
raw = null;
|
|
1428
|
-
}
|
|
1429
|
-
} else if (assetState.storageFallback.has(namespaced)) {
|
|
1430
|
-
raw = assetState.storageFallback.get(namespaced);
|
|
1431
|
-
}
|
|
1432
|
-
if (raw == null) return null;
|
|
1433
|
-
try {
|
|
1434
|
-
return JSON.parse(raw);
|
|
1435
|
-
} catch (_) {
|
|
1436
|
-
return raw;
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
function writeStorage(key, value) {
|
|
1441
|
-
const normalizedKey = String(key || '');
|
|
1442
|
-
if (normalizedKey.length === 0) return false;
|
|
1443
|
-
const payload = JSON.stringify(value);
|
|
1444
|
-
const backend = resolveStorageBackend();
|
|
1445
|
-
const namespaced = storageKey(normalizedKey);
|
|
1446
|
-
if (backend) {
|
|
1447
|
-
try {
|
|
1448
|
-
backend.setItem(namespaced, payload);
|
|
1449
|
-
return true;
|
|
1450
|
-
} catch (_) {
|
|
1451
|
-
return false;
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1454
|
-
assetState.storageFallback.set(namespaced, payload);
|
|
1455
|
-
return true;
|
|
1456
|
-
}
|
|
1457
|
-
|
|
1458
|
-
function deleteStorage(key) {
|
|
1459
|
-
const normalizedKey = String(key || '');
|
|
1460
|
-
if (normalizedKey.length === 0) return false;
|
|
1461
|
-
const namespaced = storageKey(normalizedKey);
|
|
1462
|
-
const backend = resolveStorageBackend();
|
|
1463
|
-
if (backend) {
|
|
1464
|
-
try {
|
|
1465
|
-
backend.removeItem(namespaced);
|
|
1466
|
-
return true;
|
|
1467
|
-
} catch (_) {
|
|
1468
|
-
return false;
|
|
1469
|
-
}
|
|
1470
|
-
}
|
|
1471
|
-
return assetState.storageFallback.delete(namespaced);
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
const camera = auraRef.camera && typeof auraRef.camera === 'object' ? auraRef.camera : {};
|
|
1475
|
-
let cameraBaseX = Number(camera.x) || 0;
|
|
1476
|
-
let cameraBaseY = Number(camera.y) || 0;
|
|
1477
|
-
let cameraBaseZoom = normalizePositiveNumber(camera.zoom, 1);
|
|
1478
|
-
let cameraBaseRotation = Number(camera.rotation) || 0;
|
|
1479
|
-
let cameraShakeX = 0;
|
|
1480
|
-
let cameraShakeY = 0;
|
|
1481
|
-
let cameraFollowState = null;
|
|
1482
|
-
let cameraDeadzone = null;
|
|
1483
|
-
let cameraBounds = null;
|
|
1484
|
-
let nextCameraEffectId = 1;
|
|
1485
|
-
let nextCameraListenerId = 1;
|
|
1486
|
-
const cameraEffects = [];
|
|
1487
|
-
const cameraEffectListeners = [];
|
|
1488
|
-
|
|
1489
|
-
function applyCameraBounds() {
|
|
1490
|
-
if (!cameraBounds) return;
|
|
1491
|
-
const maxX = cameraBounds.x + cameraBounds.width;
|
|
1492
|
-
const maxY = cameraBounds.y + cameraBounds.height;
|
|
1493
|
-
cameraBaseX = Math.max(cameraBounds.x, Math.min(cameraBaseX, maxX));
|
|
1494
|
-
cameraBaseY = Math.max(cameraBounds.y, Math.min(cameraBaseY, maxY));
|
|
1495
|
-
}
|
|
1496
|
-
|
|
1497
|
-
function normalizeFollowOptions(options) {
|
|
1498
|
-
if (options == null) {
|
|
1499
|
-
return {
|
|
1500
|
-
lerpX: 1,
|
|
1501
|
-
lerpY: 1,
|
|
1502
|
-
offsetX: 0,
|
|
1503
|
-
offsetY: 0
|
|
1504
|
-
};
|
|
1505
|
-
}
|
|
1506
|
-
if (!isObject(options)) return null;
|
|
1507
|
-
return {
|
|
1508
|
-
lerpX: clamp01(options.lerpX),
|
|
1509
|
-
lerpY: clamp01(options.lerpY),
|
|
1510
|
-
offsetX: toFinite(options.offsetX, 0),
|
|
1511
|
-
offsetY: toFinite(options.offsetY, 0)
|
|
1512
|
-
};
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
|
-
function normalizeDeadzone(value) {
|
|
1516
|
-
const input = isObject(value) ? value : null;
|
|
1517
|
-
const zoneWidth = toFinite(input && input.width, Number.NaN);
|
|
1518
|
-
const zoneHeight = toFinite(input && input.height, Number.NaN);
|
|
1519
|
-
if (!(zoneWidth > 0) || !(zoneHeight > 0)) return null;
|
|
1520
|
-
return {
|
|
1521
|
-
x: toFinite(input && input.x, 0),
|
|
1522
|
-
y: toFinite(input && input.y, 0),
|
|
1523
|
-
width: zoneWidth,
|
|
1524
|
-
height: zoneHeight
|
|
1525
|
-
};
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
function normalizeBounds(value) {
|
|
1529
|
-
const input = isObject(value) ? value : null;
|
|
1530
|
-
const zoneWidth = toFinite(input && input.width, Number.NaN);
|
|
1531
|
-
const zoneHeight = toFinite(input && input.height, Number.NaN);
|
|
1532
|
-
if (!(zoneWidth >= 0) || !(zoneHeight >= 0)) return null;
|
|
1533
|
-
return {
|
|
1534
|
-
x: toFinite(input && input.x, 0),
|
|
1535
|
-
y: toFinite(input && input.y, 0),
|
|
1536
|
-
width: zoneWidth,
|
|
1537
|
-
height: zoneHeight
|
|
1538
|
-
};
|
|
1539
|
-
}
|
|
1540
|
-
|
|
1541
|
-
function resolveFollowTarget(target) {
|
|
1542
|
-
let source = target;
|
|
1543
|
-
if (typeof source === 'function') {
|
|
1544
|
-
try {
|
|
1545
|
-
source = source();
|
|
1546
|
-
} catch (_) {
|
|
1547
|
-
return null;
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1550
|
-
if (!isObject(source)) return null;
|
|
1551
|
-
const x = toFinite(source.x, Number.NaN);
|
|
1552
|
-
const y = toFinite(source.y, Number.NaN);
|
|
1553
|
-
if (!Number.isFinite(x) || !Number.isFinite(y)) return null;
|
|
1554
|
-
return { x: x, y: y };
|
|
1555
|
-
}
|
|
1556
|
-
|
|
1557
|
-
function emitCameraEffectEvent(event) {
|
|
1558
|
-
if (cameraEffectListeners.length === 0) return;
|
|
1559
|
-
const ordered = cameraEffectListeners.slice().sort(function (a, b) {
|
|
1560
|
-
return (a.order - b.order) || (a.id - b.id);
|
|
1561
|
-
});
|
|
1562
|
-
for (const listener of ordered) {
|
|
1563
|
-
try {
|
|
1564
|
-
listener.callback(event);
|
|
1565
|
-
} catch (_) {}
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
1568
|
-
|
|
1569
|
-
Object.defineProperties(camera, {
|
|
1570
|
-
x: {
|
|
1571
|
-
enumerable: true,
|
|
1572
|
-
configurable: false,
|
|
1573
|
-
get: function () { return cameraBaseX + cameraShakeX; },
|
|
1574
|
-
set: function (value) {
|
|
1575
|
-
const numeric = Number(value);
|
|
1576
|
-
if (Number.isFinite(numeric)) cameraBaseX = numeric;
|
|
1577
|
-
}
|
|
1578
|
-
},
|
|
1579
|
-
y: {
|
|
1580
|
-
enumerable: true,
|
|
1581
|
-
configurable: false,
|
|
1582
|
-
get: function () { return cameraBaseY + cameraShakeY; },
|
|
1583
|
-
set: function (value) {
|
|
1584
|
-
const numeric = Number(value);
|
|
1585
|
-
if (Number.isFinite(numeric)) cameraBaseY = numeric;
|
|
1586
|
-
}
|
|
1587
|
-
},
|
|
1588
|
-
zoom: {
|
|
1589
|
-
enumerable: true,
|
|
1590
|
-
configurable: false,
|
|
1591
|
-
get: function () { return cameraBaseZoom; },
|
|
1592
|
-
set: function (value) {
|
|
1593
|
-
const numeric = Number(value);
|
|
1594
|
-
if (Number.isFinite(numeric) && numeric > 0) cameraBaseZoom = numeric;
|
|
1595
|
-
}
|
|
1596
|
-
},
|
|
1597
|
-
rotation: {
|
|
1598
|
-
enumerable: true,
|
|
1599
|
-
configurable: false,
|
|
1600
|
-
get: function () { return cameraBaseRotation; },
|
|
1601
|
-
set: function (value) {
|
|
1602
|
-
const numeric = Number(value);
|
|
1603
|
-
if (Number.isFinite(numeric)) cameraBaseRotation = numeric;
|
|
1604
|
-
}
|
|
1605
|
-
}
|
|
1606
|
-
});
|
|
1607
|
-
|
|
1608
|
-
camera.getState = function () {
|
|
1609
|
-
return {
|
|
1610
|
-
x: cameraBaseX + cameraShakeX,
|
|
1611
|
-
y: cameraBaseY + cameraShakeY,
|
|
1612
|
-
zoom: cameraBaseZoom,
|
|
1613
|
-
rotation: cameraBaseRotation,
|
|
1614
|
-
following: !!cameraFollowState,
|
|
1615
|
-
activeEffects: cameraEffects.length,
|
|
1616
|
-
deadzone: cameraDeadzone ? { x: cameraDeadzone.x, y: cameraDeadzone.y, width: cameraDeadzone.width, height: cameraDeadzone.height } : null,
|
|
1617
|
-
bounds: cameraBounds ? { x: cameraBounds.x, y: cameraBounds.y, width: cameraBounds.width, height: cameraBounds.height } : null
|
|
1618
|
-
};
|
|
1619
|
-
};
|
|
1620
|
-
|
|
1621
|
-
camera.follow = function (target, options) {
|
|
1622
|
-
if (!(typeof target === 'function' || isObject(target))) {
|
|
1623
|
-
return { ok: false, reasonCode: 'invalid_follow_target' };
|
|
1624
|
-
}
|
|
1625
|
-
const normalized = normalizeFollowOptions(options);
|
|
1626
|
-
if (!normalized) return { ok: false, reasonCode: 'invalid_follow_options' };
|
|
1627
|
-
cameraFollowState = {
|
|
1628
|
-
target: target,
|
|
1629
|
-
lerpX: normalized.lerpX,
|
|
1630
|
-
lerpY: normalized.lerpY,
|
|
1631
|
-
offsetX: normalized.offsetX,
|
|
1632
|
-
offsetY: normalized.offsetY
|
|
1633
|
-
};
|
|
1634
|
-
return { ok: true, reasonCode: 'camera_follow_started' };
|
|
1635
|
-
};
|
|
1636
|
-
|
|
1637
|
-
camera.stopFollow = function () {
|
|
1638
|
-
const stopped = !!cameraFollowState;
|
|
1639
|
-
cameraFollowState = null;
|
|
1640
|
-
return { ok: true, stopped: stopped, reasonCode: 'camera_follow_stopped' };
|
|
1641
|
-
};
|
|
1642
|
-
|
|
1643
|
-
camera.setDeadzone = function (value, maybeHeight) {
|
|
1644
|
-
const normalized = isObject(value)
|
|
1645
|
-
? normalizeDeadzone(value)
|
|
1646
|
-
: normalizeDeadzone({ width: value, height: maybeHeight });
|
|
1647
|
-
if (!normalized) return { ok: false, reasonCode: 'invalid_deadzone' };
|
|
1648
|
-
cameraDeadzone = normalized;
|
|
1649
|
-
return { ok: true, reasonCode: 'camera_deadzone_set' };
|
|
1650
|
-
};
|
|
1651
|
-
|
|
1652
|
-
camera.clearDeadzone = function () {
|
|
1653
|
-
cameraDeadzone = null;
|
|
1654
|
-
return { ok: true, reasonCode: 'camera_deadzone_cleared' };
|
|
1655
|
-
};
|
|
1656
|
-
|
|
1657
|
-
camera.setBounds = function (xOrBounds, y, boundsWidth, boundsHeight) {
|
|
1658
|
-
const normalized = isObject(xOrBounds)
|
|
1659
|
-
? normalizeBounds(xOrBounds)
|
|
1660
|
-
: normalizeBounds({ x: xOrBounds, y: y, width: boundsWidth, height: boundsHeight });
|
|
1661
|
-
if (!normalized) return { ok: false, reasonCode: 'invalid_bounds' };
|
|
1662
|
-
cameraBounds = normalized;
|
|
1663
|
-
applyCameraBounds();
|
|
1664
|
-
return { ok: true, reasonCode: 'camera_bounds_set' };
|
|
1665
|
-
};
|
|
1666
|
-
|
|
1667
|
-
camera.clearBounds = function () {
|
|
1668
|
-
cameraBounds = null;
|
|
1669
|
-
return { ok: true, reasonCode: 'camera_bounds_cleared' };
|
|
1670
|
-
};
|
|
1671
|
-
|
|
1672
|
-
camera.pan = function (x, y, options) {
|
|
1673
|
-
const targetX = Number(x);
|
|
1674
|
-
const targetY = Number(y);
|
|
1675
|
-
if (!Number.isFinite(targetX) || !Number.isFinite(targetY)) {
|
|
1676
|
-
return { ok: false, reasonCode: 'invalid_pan_target' };
|
|
1677
|
-
}
|
|
1678
|
-
if (options != null && !isObject(options)) return { ok: false, reasonCode: 'invalid_pan_options' };
|
|
1679
|
-
const duration = toPositive(options && options.duration, 0.25);
|
|
1680
|
-
if (!(duration > 0)) return { ok: false, reasonCode: 'invalid_pan_duration' };
|
|
1681
|
-
const effectId = nextCameraEffectId++;
|
|
1682
|
-
cameraEffects.push({
|
|
1683
|
-
id: effectId,
|
|
1684
|
-
type: 'pan',
|
|
1685
|
-
duration: duration,
|
|
1686
|
-
elapsed: 0,
|
|
1687
|
-
startX: cameraBaseX,
|
|
1688
|
-
startY: cameraBaseY,
|
|
1689
|
-
targetX: targetX,
|
|
1690
|
-
targetY: targetY
|
|
1691
|
-
});
|
|
1692
|
-
return { ok: true, effectId: effectId, reasonCode: 'camera_pan_started' };
|
|
1693
|
-
};
|
|
1694
|
-
camera.panTo = camera.pan;
|
|
1695
|
-
|
|
1696
|
-
camera.zoomTo = function (value, options) {
|
|
1697
|
-
const targetZoom = Number(value);
|
|
1698
|
-
if (!Number.isFinite(targetZoom) || !(targetZoom > 0)) {
|
|
1699
|
-
return { ok: false, reasonCode: 'invalid_zoom_target' };
|
|
1700
|
-
}
|
|
1701
|
-
if (options != null && !isObject(options)) return { ok: false, reasonCode: 'invalid_zoom_options' };
|
|
1702
|
-
const duration = toPositive(options && options.duration, 0.25);
|
|
1703
|
-
if (!(duration > 0)) return { ok: false, reasonCode: 'invalid_zoom_duration' };
|
|
1704
|
-
const effectId = nextCameraEffectId++;
|
|
1705
|
-
cameraEffects.push({
|
|
1706
|
-
id: effectId,
|
|
1707
|
-
type: 'zoom',
|
|
1708
|
-
duration: duration,
|
|
1709
|
-
elapsed: 0,
|
|
1710
|
-
startZoom: cameraBaseZoom,
|
|
1711
|
-
targetZoom: targetZoom
|
|
1712
|
-
});
|
|
1713
|
-
return { ok: true, effectId: effectId, reasonCode: 'camera_zoom_started' };
|
|
1714
|
-
};
|
|
1715
|
-
|
|
1716
|
-
camera.rotateTo = function (value, options) {
|
|
1717
|
-
const targetRotation = Number(value);
|
|
1718
|
-
if (!Number.isFinite(targetRotation)) {
|
|
1719
|
-
return { ok: false, reasonCode: 'invalid_rotation_target' };
|
|
1720
|
-
}
|
|
1721
|
-
if (options != null && !isObject(options)) return { ok: false, reasonCode: 'invalid_rotation_options' };
|
|
1722
|
-
const duration = toPositive(options && options.duration, 0.25);
|
|
1723
|
-
if (!(duration > 0)) return { ok: false, reasonCode: 'invalid_rotation_duration' };
|
|
1724
|
-
const effectId = nextCameraEffectId++;
|
|
1725
|
-
cameraEffects.push({
|
|
1726
|
-
id: effectId,
|
|
1727
|
-
type: 'rotate',
|
|
1728
|
-
duration: duration,
|
|
1729
|
-
elapsed: 0,
|
|
1730
|
-
startRotation: cameraBaseRotation,
|
|
1731
|
-
targetRotation: targetRotation
|
|
1732
|
-
});
|
|
1733
|
-
return { ok: true, effectId: effectId, reasonCode: 'camera_rotation_started' };
|
|
1734
|
-
};
|
|
1735
|
-
|
|
1736
|
-
camera.shake = function (options) {
|
|
1737
|
-
const source = options == null ? {} : options;
|
|
1738
|
-
if (!isObject(source)) return { ok: false, reasonCode: 'invalid_shake_options' };
|
|
1739
|
-
const sharedIntensity = Number.isFinite(Number(source.intensity))
|
|
1740
|
-
? Number(source.intensity)
|
|
1741
|
-
: null;
|
|
1742
|
-
const intensityX = toFinite(source.intensityX, sharedIntensity != null ? sharedIntensity : 6);
|
|
1743
|
-
const intensityY = toFinite(source.intensityY, sharedIntensity != null ? sharedIntensity : 6);
|
|
1744
|
-
if (!(intensityX >= 0) || !(intensityY >= 0)) {
|
|
1745
|
-
return { ok: false, reasonCode: 'invalid_shake_intensity' };
|
|
1746
|
-
}
|
|
1747
|
-
const duration = toPositive(source.duration, 0.3);
|
|
1748
|
-
if (!(duration > 0)) return { ok: false, reasonCode: 'invalid_shake_duration' };
|
|
1749
|
-
const frequency = toPositive(source.frequency, 30);
|
|
1750
|
-
if (!(frequency > 0)) return { ok: false, reasonCode: 'invalid_shake_frequency' };
|
|
1751
|
-
const effectId = nextCameraEffectId++;
|
|
1752
|
-
cameraEffects.push({
|
|
1753
|
-
id: effectId,
|
|
1754
|
-
type: 'shake',
|
|
1755
|
-
duration: duration,
|
|
1756
|
-
elapsed: 0,
|
|
1757
|
-
intensityX: intensityX,
|
|
1758
|
-
intensityY: intensityY,
|
|
1759
|
-
frequency: frequency,
|
|
1760
|
-
seed: effectId * 0.61803398875
|
|
1761
|
-
});
|
|
1762
|
-
return { ok: true, effectId: effectId, reasonCode: 'camera_shake_started' };
|
|
1763
|
-
};
|
|
1764
|
-
|
|
1765
|
-
camera.clearEffects = function () {
|
|
1766
|
-
const cleared = cameraEffects.length;
|
|
1767
|
-
cameraEffects.length = 0;
|
|
1768
|
-
cameraShakeX = 0;
|
|
1769
|
-
cameraShakeY = 0;
|
|
1770
|
-
return { ok: true, cleared: cleared, reasonCode: 'camera_effects_cleared' };
|
|
1771
|
-
};
|
|
1772
|
-
|
|
1773
|
-
camera.onEffectComplete = function (callback, order) {
|
|
1774
|
-
if (typeof callback !== 'function') {
|
|
1775
|
-
return { ok: false, reasonCode: 'invalid_effect_callback' };
|
|
1776
|
-
}
|
|
1777
|
-
const listener = {
|
|
1778
|
-
id: nextCameraListenerId++,
|
|
1779
|
-
callback: callback,
|
|
1780
|
-
order: Number.isFinite(Number(order)) ? Number(order) : 0
|
|
1781
|
-
};
|
|
1782
|
-
cameraEffectListeners.push(listener);
|
|
1783
|
-
return { ok: true, listenerId: listener.id, reasonCode: 'camera_effect_listener_registered' };
|
|
1784
|
-
};
|
|
1785
|
-
|
|
1786
|
-
camera.offEffectComplete = function (listenerId) {
|
|
1787
|
-
if (!Number.isInteger(listenerId) || listenerId <= 0) return false;
|
|
1788
|
-
const index = cameraEffectListeners.findIndex(function (entry) {
|
|
1789
|
-
return entry.id === listenerId;
|
|
1790
|
-
});
|
|
1791
|
-
if (index < 0) return false;
|
|
1792
|
-
cameraEffectListeners.splice(index, 1);
|
|
1793
|
-
return true;
|
|
1794
|
-
};
|
|
1795
|
-
|
|
1796
|
-
camera.update = function (dt) {
|
|
1797
|
-
const delta = Number(dt);
|
|
1798
|
-
if (!Number.isFinite(delta) || !(delta > 0)) {
|
|
1799
|
-
return { ok: false, reasonCode: 'invalid_dt' };
|
|
1800
|
-
}
|
|
1801
|
-
|
|
1802
|
-
cameraShakeX = 0;
|
|
1803
|
-
cameraShakeY = 0;
|
|
1804
|
-
|
|
1805
|
-
if (cameraFollowState) {
|
|
1806
|
-
const targetPoint = resolveFollowTarget(cameraFollowState.target);
|
|
1807
|
-
if (targetPoint) {
|
|
1808
|
-
let targetX = targetPoint.x + cameraFollowState.offsetX;
|
|
1809
|
-
let targetY = targetPoint.y + cameraFollowState.offsetY;
|
|
1810
|
-
|
|
1811
|
-
if (cameraDeadzone) {
|
|
1812
|
-
const left = cameraBaseX + cameraDeadzone.x;
|
|
1813
|
-
const right = left + cameraDeadzone.width;
|
|
1814
|
-
const top = cameraBaseY + cameraDeadzone.y;
|
|
1815
|
-
const bottom = top + cameraDeadzone.height;
|
|
1816
|
-
|
|
1817
|
-
if (targetX < left) targetX = targetX - cameraDeadzone.x;
|
|
1818
|
-
else if (targetX > right) targetX = targetX - cameraDeadzone.x - cameraDeadzone.width;
|
|
1819
|
-
else targetX = cameraBaseX;
|
|
1820
|
-
|
|
1821
|
-
if (targetY < top) targetY = targetY - cameraDeadzone.y;
|
|
1822
|
-
else if (targetY > bottom) targetY = targetY - cameraDeadzone.y - cameraDeadzone.height;
|
|
1823
|
-
else targetY = cameraBaseY;
|
|
1824
|
-
}
|
|
1825
|
-
|
|
1826
|
-
cameraBaseX += (targetX - cameraBaseX) * cameraFollowState.lerpX;
|
|
1827
|
-
cameraBaseY += (targetY - cameraBaseY) * cameraFollowState.lerpY;
|
|
1828
|
-
}
|
|
1829
|
-
}
|
|
1830
|
-
|
|
1831
|
-
const completedEffects = [];
|
|
1832
|
-
for (const effect of cameraEffects) {
|
|
1833
|
-
effect.elapsed += delta;
|
|
1834
|
-
const progress = effect.duration <= 0 ? 1 : Math.min(effect.elapsed / effect.duration, 1);
|
|
1835
|
-
if (effect.type === 'pan') {
|
|
1836
|
-
cameraBaseX = effect.startX + ((effect.targetX - effect.startX) * progress);
|
|
1837
|
-
cameraBaseY = effect.startY + ((effect.targetY - effect.startY) * progress);
|
|
1838
|
-
} else if (effect.type === 'zoom') {
|
|
1839
|
-
cameraBaseZoom = effect.startZoom + ((effect.targetZoom - effect.startZoom) * progress);
|
|
1840
|
-
} else if (effect.type === 'rotate') {
|
|
1841
|
-
cameraBaseRotation = effect.startRotation + ((effect.targetRotation - effect.startRotation) * progress);
|
|
1842
|
-
} else if (effect.type === 'shake') {
|
|
1843
|
-
const amplitude = 1 - progress;
|
|
1844
|
-
const angle = (effect.seed + (effect.elapsed * effect.frequency)) * 6.283185307179586;
|
|
1845
|
-
cameraShakeX += Math.sin(angle) * effect.intensityX * amplitude;
|
|
1846
|
-
cameraShakeY += Math.cos(angle * 1.17) * effect.intensityY * amplitude;
|
|
1847
|
-
}
|
|
1848
|
-
if (progress >= 1) completedEffects.push(effect);
|
|
1849
|
-
}
|
|
1850
|
-
|
|
1851
|
-
if (completedEffects.length > 0) {
|
|
1852
|
-
for (const completed of completedEffects) {
|
|
1853
|
-
const index = cameraEffects.indexOf(completed);
|
|
1854
|
-
if (index >= 0) cameraEffects.splice(index, 1);
|
|
1855
|
-
}
|
|
1856
|
-
completedEffects.sort(function (a, b) { return a.id - b.id; });
|
|
1857
|
-
for (const completed of completedEffects) {
|
|
1858
|
-
emitCameraEffectEvent({
|
|
1859
|
-
type: 'effect_complete',
|
|
1860
|
-
effectType: completed.type,
|
|
1861
|
-
effectId: completed.id,
|
|
1862
|
-
reasonCode: 'camera_effect_complete'
|
|
1863
|
-
});
|
|
1864
|
-
}
|
|
1865
|
-
}
|
|
1866
|
-
|
|
1867
|
-
applyCameraBounds();
|
|
1868
|
-
|
|
1869
|
-
return {
|
|
1870
|
-
ok: true,
|
|
1871
|
-
reasonCode: 'camera_updated',
|
|
1872
|
-
x: cameraBaseX + cameraShakeX,
|
|
1873
|
-
y: cameraBaseY + cameraShakeY,
|
|
1874
|
-
zoom: cameraBaseZoom,
|
|
1875
|
-
rotation: cameraBaseRotation,
|
|
1876
|
-
following: !!cameraFollowState,
|
|
1877
|
-
activeEffects: cameraEffects.length
|
|
1878
|
-
};
|
|
1879
|
-
};
|
|
1880
|
-
|
|
1881
|
-
function attachListeners() {
|
|
1882
|
-
if (runtime.listenersAttached) return;
|
|
1883
|
-
runtime.listenersAttached = true;
|
|
1884
|
-
|
|
1885
|
-
runtime.keydownListener = function (event) {
|
|
1886
|
-
const key = normalizeKeyName(event && (event.key || event.code));
|
|
1887
|
-
if (!key) return;
|
|
1888
|
-
if (!inputState.down.has(key)) {
|
|
1889
|
-
inputState.pendingPressed.add(key);
|
|
1890
|
-
}
|
|
1891
|
-
inputState.down.add(key);
|
|
1892
|
-
if (event && typeof event.preventDefault === 'function' && (key === 'space' || key.startsWith('arrow'))) {
|
|
1893
|
-
event.preventDefault();
|
|
1894
|
-
}
|
|
1895
|
-
};
|
|
1896
|
-
|
|
1897
|
-
runtime.keyupListener = function (event) {
|
|
1898
|
-
const key = normalizeKeyName(event && (event.key || event.code));
|
|
1899
|
-
if (!key) return;
|
|
1900
|
-
inputState.down.delete(key);
|
|
1901
|
-
inputState.pendingReleased.add(key);
|
|
1902
|
-
if (event && typeof event.preventDefault === 'function' && (key === 'space' || key.startsWith('arrow'))) {
|
|
1903
|
-
event.preventDefault();
|
|
1904
|
-
}
|
|
1905
|
-
};
|
|
1906
|
-
|
|
1907
|
-
runtime.mousemoveListener = function (event) {
|
|
1908
|
-
syncMousePosition(event);
|
|
1909
|
-
};
|
|
1910
|
-
|
|
1911
|
-
runtime.mousedownListener = function (event) {
|
|
1912
|
-
syncMousePosition(event);
|
|
1913
|
-
const button = normalizeMouseButton(event && event.button);
|
|
1914
|
-
if (!inputState.mouseDown.has(button)) {
|
|
1915
|
-
inputState.pendingMousePressed.add(button);
|
|
1916
|
-
}
|
|
1917
|
-
inputState.mouseDown.add(button);
|
|
1918
|
-
};
|
|
1919
|
-
|
|
1920
|
-
runtime.mouseupListener = function (event) {
|
|
1921
|
-
syncMousePosition(event);
|
|
1922
|
-
const button = normalizeMouseButton(event && event.button);
|
|
1923
|
-
inputState.mouseDown.delete(button);
|
|
1924
|
-
inputState.pendingMouseReleased.add(button);
|
|
1925
|
-
};
|
|
1926
|
-
|
|
1927
|
-
runtime.wheelListener = function (event) {
|
|
1928
|
-
if (event && Number.isFinite(Number(event.deltaY))) {
|
|
1929
|
-
auraRef.input.mouse.scroll += Number(event.deltaY);
|
|
1930
|
-
}
|
|
1931
|
-
};
|
|
1932
|
-
|
|
1933
|
-
runtime.focusListener = function () {
|
|
1934
|
-
clearMouseDeltaState();
|
|
1935
|
-
if (typeof auraRef.onFocus === 'function') {
|
|
1936
|
-
auraRef.onFocus();
|
|
1937
|
-
}
|
|
1938
|
-
};
|
|
1939
|
-
|
|
1940
|
-
runtime.blurListener = function () {
|
|
1941
|
-
clearHeldInputState();
|
|
1942
|
-
if (typeof auraRef.onBlur === 'function') {
|
|
1943
|
-
auraRef.onBlur();
|
|
1944
|
-
}
|
|
1945
|
-
};
|
|
1946
|
-
|
|
1947
|
-
runtime.resizeListener = function () {
|
|
1948
|
-
syncCanvasSize(true);
|
|
1949
|
-
};
|
|
1950
|
-
|
|
1951
|
-
if (typeof globalRef.addEventListener === 'function') {
|
|
1952
|
-
globalRef.addEventListener('keydown', runtime.keydownListener);
|
|
1953
|
-
globalRef.addEventListener('keyup', runtime.keyupListener);
|
|
1954
|
-
globalRef.addEventListener('focus', runtime.focusListener);
|
|
1955
|
-
globalRef.addEventListener('mousemove', runtime.mousemoveListener);
|
|
1956
|
-
globalRef.addEventListener('mousedown', runtime.mousedownListener);
|
|
1957
|
-
globalRef.addEventListener('mouseup', runtime.mouseupListener);
|
|
1958
|
-
globalRef.addEventListener('wheel', runtime.wheelListener);
|
|
1959
|
-
globalRef.addEventListener('blur', runtime.blurListener);
|
|
1960
|
-
globalRef.addEventListener('resize', runtime.resizeListener);
|
|
1961
|
-
}
|
|
1962
|
-
}
|
|
1963
|
-
|
|
1964
|
-
function detachListeners() {
|
|
1965
|
-
if (!runtime.listenersAttached) return;
|
|
1966
|
-
runtime.listenersAttached = false;
|
|
1967
|
-
if (typeof globalRef.removeEventListener === 'function') {
|
|
1968
|
-
globalRef.removeEventListener('keydown', runtime.keydownListener);
|
|
1969
|
-
globalRef.removeEventListener('keyup', runtime.keyupListener);
|
|
1970
|
-
globalRef.removeEventListener('focus', runtime.focusListener);
|
|
1971
|
-
globalRef.removeEventListener('mousemove', runtime.mousemoveListener);
|
|
1972
|
-
globalRef.removeEventListener('mousedown', runtime.mousedownListener);
|
|
1973
|
-
globalRef.removeEventListener('mouseup', runtime.mouseupListener);
|
|
1974
|
-
globalRef.removeEventListener('wheel', runtime.wheelListener);
|
|
1975
|
-
globalRef.removeEventListener('blur', runtime.blurListener);
|
|
1976
|
-
globalRef.removeEventListener('resize', runtime.resizeListener);
|
|
1977
|
-
}
|
|
1978
|
-
}
|
|
1979
|
-
|
|
1980
|
-
auraRef.setup = typeof auraRef.setup === 'function' ? auraRef.setup : null;
|
|
1981
|
-
auraRef.update = typeof auraRef.update === 'function' ? auraRef.update : null;
|
|
1982
|
-
auraRef.draw = typeof auraRef.draw === 'function' ? auraRef.draw : null;
|
|
1983
|
-
auraRef.onResize = typeof auraRef.onResize === 'function' ? auraRef.onResize : null;
|
|
1984
|
-
auraRef.onFocus = typeof auraRef.onFocus === 'function' ? auraRef.onFocus : null;
|
|
1985
|
-
auraRef.onBlur = typeof auraRef.onBlur === 'function' ? auraRef.onBlur : null;
|
|
1986
|
-
auraRef.onQuit = typeof auraRef.onQuit === 'function' ? auraRef.onQuit : null;
|
|
1987
|
-
|
|
1988
|
-
auraRef.rgba = function (r, g, b, a) {
|
|
1989
|
-
return createUnitColor(r, g, b, a == null ? 1 : a);
|
|
1990
|
-
};
|
|
1991
|
-
auraRef.rgb = function (r, g, b) {
|
|
1992
|
-
return createUnitColor(r, g, b, 1);
|
|
1993
|
-
};
|
|
1994
|
-
auraRef.color = auraRef.rgba;
|
|
1995
|
-
auraRef.Color = auraRef.Color && typeof auraRef.Color === 'object'
|
|
1996
|
-
? auraRef.Color
|
|
1997
|
-
: {
|
|
1998
|
-
WHITE: createUnitColor(1, 1, 1, 1),
|
|
1999
|
-
BLACK: createUnitColor(0, 0, 0, 1),
|
|
2000
|
-
RED: createUnitColor(1, 0, 0, 1),
|
|
2001
|
-
YELLOW: createUnitColor(1, 1, 0, 1),
|
|
2002
|
-
TRANSPARENT: createUnitColor(0, 0, 0, 0)
|
|
2003
|
-
};
|
|
2004
|
-
auraRef.colors = auraRef.colors && typeof auraRef.colors === 'object'
|
|
2005
|
-
? auraRef.colors
|
|
2006
|
-
: {
|
|
2007
|
-
white: createByteColor(255, 255, 255, 255),
|
|
2008
|
-
black: createByteColor(0, 0, 0, 255),
|
|
2009
|
-
red: createByteColor(255, 0, 0, 255),
|
|
2010
|
-
yellow: createByteColor(255, 255, 0, 255),
|
|
2011
|
-
transparent: createByteColor(0, 0, 0, 0)
|
|
2012
|
-
};
|
|
2013
|
-
|
|
2014
|
-
auraRef.math = auraRef.math && typeof auraRef.math === 'object' ? auraRef.math : {};
|
|
2015
|
-
auraRef.math.clamp = typeof auraRef.math.clamp === 'function'
|
|
2016
|
-
? auraRef.math.clamp
|
|
2017
|
-
: function (value, min, max) {
|
|
2018
|
-
const numeric = Number(value);
|
|
2019
|
-
const minValue = Number(min);
|
|
2020
|
-
const maxValue = Number(max);
|
|
2021
|
-
if (!Number.isFinite(numeric) || !Number.isFinite(minValue) || !Number.isFinite(maxValue)) {
|
|
2022
|
-
return Number.isFinite(numeric) ? numeric : 0;
|
|
2023
|
-
}
|
|
2024
|
-
return Math.min(maxValue, Math.max(minValue, numeric));
|
|
2025
|
-
};
|
|
2026
|
-
|
|
2027
|
-
auraRef.window = auraRef.window && typeof auraRef.window === 'object' ? auraRef.window : {};
|
|
2028
|
-
auraRef.window.width = runtime.width;
|
|
2029
|
-
auraRef.window.height = runtime.height;
|
|
2030
|
-
auraRef.window.pixelRatio = runtime.pixelRatio;
|
|
2031
|
-
auraRef.window.fps = 60;
|
|
2032
|
-
auraRef.window.setTitle = function (title) {
|
|
2033
|
-
if (typeof title === 'string') {
|
|
2034
|
-
document.title = title;
|
|
2035
|
-
}
|
|
2036
|
-
};
|
|
2037
|
-
auraRef.window.setSize = function (width, height) {
|
|
2038
|
-
runtime.configuredWidth = normalizeCanvasSize(width, runtime.configuredWidth);
|
|
2039
|
-
runtime.configuredHeight = normalizeCanvasSize(height, runtime.configuredHeight);
|
|
2040
|
-
syncCanvasSize(true);
|
|
2041
|
-
resetDrawState();
|
|
2042
|
-
return true;
|
|
2043
|
-
};
|
|
2044
|
-
auraRef.window.setFullscreen = function () {
|
|
2045
|
-
return false;
|
|
2046
|
-
};
|
|
2047
|
-
auraRef.window.setCursorVisible = function (visible) {
|
|
2048
|
-
runtime.cursorVisible = !!visible;
|
|
2049
|
-
applyCursorAppearance();
|
|
2050
|
-
return true;
|
|
2051
|
-
};
|
|
2052
|
-
auraRef.window.setCursorLocked = function (locked) {
|
|
2053
|
-
runtime.cursorLocked = !!locked;
|
|
2054
|
-
clearMouseDeltaState();
|
|
2055
|
-
applyCursorAppearance();
|
|
2056
|
-
if (runtime.canvas && typeof runtime.canvas.requestPointerLock === 'function' && runtime.cursorLocked) {
|
|
2057
|
-
runtime.canvas.requestPointerLock();
|
|
2058
|
-
} else if (
|
|
2059
|
-
!runtime.cursorLocked &&
|
|
2060
|
-
globalRef.document &&
|
|
2061
|
-
typeof globalRef.document.exitPointerLock === 'function'
|
|
2062
|
-
) {
|
|
2063
|
-
globalRef.document.exitPointerLock();
|
|
2064
|
-
}
|
|
2065
|
-
return true;
|
|
2066
|
-
};
|
|
2067
|
-
auraRef.window.getSize = function () {
|
|
2068
|
-
return { width: runtime.width, height: runtime.height };
|
|
2069
|
-
};
|
|
2070
|
-
auraRef.window.getPixelRatio = function () {
|
|
2071
|
-
return runtime.pixelRatio;
|
|
2072
|
-
};
|
|
2073
|
-
auraRef.window.getFPS = function () {
|
|
2074
|
-
return auraRef.window.fps;
|
|
2075
|
-
};
|
|
2076
|
-
auraRef.window.close = function () {
|
|
2077
|
-
return true;
|
|
2078
|
-
};
|
|
2079
|
-
|
|
2080
|
-
auraRef.collision = auraRef.collision && typeof auraRef.collision === 'object' ? auraRef.collision : {};
|
|
2081
|
-
auraRef.collision.rectRect = function (a, b) {
|
|
2082
|
-
return rectIntersects(a, b);
|
|
2083
|
-
};
|
|
2084
|
-
auraRef.collide = auraRef.collide && typeof auraRef.collide === 'object' ? auraRef.collide : auraRef.collision;
|
|
2085
|
-
auraRef.collide.rectRect = auraRef.collision.rectRect;
|
|
2086
|
-
|
|
2087
|
-
auraRef.camera = camera;
|
|
2088
|
-
|
|
2089
|
-
auraRef.input = auraRef.input && typeof auraRef.input === 'object' ? auraRef.input : {};
|
|
2090
|
-
auraRef.input.isDown = function (name) {
|
|
2091
|
-
const key = normalizeKeyName(name);
|
|
2092
|
-
return key ? inputState.down.has(key) : false;
|
|
2093
|
-
};
|
|
2094
|
-
auraRef.input.isPressed = function (name) {
|
|
2095
|
-
const key = normalizeKeyName(name);
|
|
2096
|
-
return key ? inputState.framePressed.has(key) : false;
|
|
2097
|
-
};
|
|
2098
|
-
auraRef.input.isReleased = function (name) {
|
|
2099
|
-
const key = normalizeKeyName(name);
|
|
2100
|
-
return key ? inputState.frameReleased.has(key) : false;
|
|
2101
|
-
};
|
|
2102
|
-
auraRef.input.isKeyDown = function (name) {
|
|
2103
|
-
return auraRef.input.isDown(name);
|
|
2104
|
-
};
|
|
2105
|
-
auraRef.input.isKeyPressed = function (name) {
|
|
2106
|
-
return auraRef.input.isPressed(name);
|
|
2107
|
-
};
|
|
2108
|
-
auraRef.input.isKeyReleased = function (name) {
|
|
2109
|
-
return auraRef.input.isReleased(name);
|
|
2110
|
-
};
|
|
2111
|
-
auraRef.input.isGamepadConnected = typeof auraRef.input.isGamepadConnected === 'function'
|
|
2112
|
-
? auraRef.input.isGamepadConnected
|
|
2113
|
-
: function () { return false; };
|
|
2114
|
-
auraRef.input.mouse = auraRef.input.mouse && typeof auraRef.input.mouse === 'object' ? auraRef.input.mouse : {};
|
|
2115
|
-
auraRef.input.mouse.x = Number(auraRef.input.mouse.x) || 0;
|
|
2116
|
-
auraRef.input.mouse.y = Number(auraRef.input.mouse.y) || 0;
|
|
2117
|
-
auraRef.input.mouse.scroll = Number(auraRef.input.mouse.scroll) || 0;
|
|
2118
|
-
auraRef.input.mouse.isDown = function (button) {
|
|
2119
|
-
return inputState.mouseDown.has(normalizeMouseButton(button));
|
|
2120
|
-
};
|
|
2121
|
-
auraRef.input.mouse.isPressed = function (button) {
|
|
2122
|
-
return inputState.frameMousePressed.has(normalizeMouseButton(button));
|
|
2123
|
-
};
|
|
2124
|
-
auraRef.input.mouse.isReleased = function (button) {
|
|
2125
|
-
return inputState.frameMouseReleased.has(normalizeMouseButton(button));
|
|
2126
|
-
};
|
|
2127
|
-
auraRef.input.isMouseDown = function (button) {
|
|
2128
|
-
return auraRef.input.mouse.isDown(button);
|
|
2129
|
-
};
|
|
2130
|
-
auraRef.input.isMousePressed = function (button) {
|
|
2131
|
-
return auraRef.input.mouse.isPressed(button);
|
|
2132
|
-
};
|
|
2133
|
-
auraRef.input.isMouseReleased = function (button) {
|
|
2134
|
-
return auraRef.input.mouse.isReleased(button);
|
|
2135
|
-
};
|
|
2136
|
-
auraRef.input.getMousePosition = function () {
|
|
2137
|
-
return { x: auraRef.input.mouse.x, y: auraRef.input.mouse.y };
|
|
2138
|
-
};
|
|
2139
|
-
auraRef.input.getMouseDelta = function () {
|
|
2140
|
-
return { x: inputState.frameMouseDeltaX, y: inputState.frameMouseDeltaY };
|
|
2141
|
-
};
|
|
2142
|
-
|
|
2143
|
-
auraRef.state = auraRef.state && typeof auraRef.state === 'object' ? auraRef.state : {};
|
|
2144
|
-
auraRef.state.export = typeof auraRef.state.export === 'function'
|
|
2145
|
-
? auraRef.state.export
|
|
2146
|
-
: function () {
|
|
2147
|
-
return createUnsupportedStateResult('export', 'web_state_export_unsupported');
|
|
2148
|
-
};
|
|
2149
|
-
auraRef.state.apply = typeof auraRef.state.apply === 'function'
|
|
2150
|
-
? auraRef.state.apply
|
|
2151
|
-
: function () {
|
|
2152
|
-
return createUnsupportedStateResult('apply', 'web_state_apply_unsupported');
|
|
2153
|
-
};
|
|
2154
|
-
auraRef.state.diff = typeof auraRef.state.diff === 'function'
|
|
2155
|
-
? auraRef.state.diff
|
|
2156
|
-
: function () {
|
|
2157
|
-
return createUnsupportedStateResult('diff', 'web_state_diff_unsupported');
|
|
2158
|
-
};
|
|
2159
|
-
auraRef.state.patch = typeof auraRef.state.patch === 'function'
|
|
2160
|
-
? auraRef.state.patch
|
|
2161
|
-
: function () {
|
|
2162
|
-
return createUnsupportedStateResult('patch', 'web_state_patch_unsupported');
|
|
2163
|
-
};
|
|
2164
|
-
auraRef.state.exportState = typeof auraRef.state.exportState === 'function'
|
|
2165
|
-
? auraRef.state.exportState
|
|
2166
|
-
: function (options) {
|
|
2167
|
-
return auraRef.state.export(options);
|
|
2168
|
-
};
|
|
2169
|
-
auraRef.state.applyState = typeof auraRef.state.applyState === 'function'
|
|
2170
|
-
? auraRef.state.applyState
|
|
2171
|
-
: function (payload, options) {
|
|
2172
|
-
return auraRef.state.apply(payload, options);
|
|
2173
|
-
};
|
|
2174
|
-
auraRef.state.diffState = typeof auraRef.state.diffState === 'function'
|
|
2175
|
-
? auraRef.state.diffState
|
|
2176
|
-
: function (beforePayload, afterPayload) {
|
|
2177
|
-
return auraRef.state.diff(beforePayload, afterPayload);
|
|
2178
|
-
};
|
|
2179
|
-
auraRef.state.patchState = typeof auraRef.state.patchState === 'function'
|
|
2180
|
-
? auraRef.state.patchState
|
|
2181
|
-
: function (payload, patchPayload, options) {
|
|
2182
|
-
return auraRef.state.patch(payload, patchPayload, options);
|
|
2183
|
-
};
|
|
2184
|
-
|
|
2185
|
-
auraRef.net = auraRef.net && typeof auraRef.net === 'object' ? auraRef.net : {};
|
|
2186
|
-
auraRef.net.connect = typeof auraRef.net.connect === 'function'
|
|
2187
|
-
? auraRef.net.connect
|
|
2188
|
-
: function () {
|
|
2189
|
-
throw createUnsupportedRuntimeError('net', 'connect', 'web_net_connect_unsupported');
|
|
2190
|
-
};
|
|
2191
|
-
auraRef.net.websocket = typeof auraRef.net.websocket === 'function'
|
|
2192
|
-
? auraRef.net.websocket
|
|
2193
|
-
: function () {
|
|
2194
|
-
throw createUnsupportedRuntimeError('net', 'websocket', 'web_net_websocket_unsupported');
|
|
2195
|
-
};
|
|
2196
|
-
auraRef.net.fetch = typeof auraRef.net.fetch === 'function'
|
|
2197
|
-
? auraRef.net.fetch
|
|
2198
|
-
: function () {
|
|
2199
|
-
throw createUnsupportedRuntimeError('net', 'fetch', 'web_net_fetch_unsupported');
|
|
2200
|
-
};
|
|
2201
|
-
auraRef.net.get = typeof auraRef.net.get === 'function'
|
|
2202
|
-
? auraRef.net.get
|
|
2203
|
-
: function () {
|
|
2204
|
-
throw createUnsupportedRuntimeError('net', 'get', 'web_net_get_unsupported');
|
|
2205
|
-
};
|
|
2206
|
-
auraRef.net.post = typeof auraRef.net.post === 'function'
|
|
2207
|
-
? auraRef.net.post
|
|
2208
|
-
: function () {
|
|
2209
|
-
throw createUnsupportedRuntimeError('net', 'post', 'web_net_post_unsupported');
|
|
2210
|
-
};
|
|
2211
|
-
|
|
2212
|
-
auraRef.storage = auraRef.storage && typeof auraRef.storage === 'object' ? auraRef.storage : {};
|
|
2213
|
-
auraRef.storage.save = typeof auraRef.storage.save === 'function'
|
|
2214
|
-
? auraRef.storage.save
|
|
2215
|
-
: function (key, value) { return writeStorage(key, value); };
|
|
2216
|
-
auraRef.storage.load = typeof auraRef.storage.load === 'function'
|
|
2217
|
-
? auraRef.storage.load
|
|
2218
|
-
: function (key) { return readStorage(key); };
|
|
2219
|
-
auraRef.storage.delete = typeof auraRef.storage.delete === 'function'
|
|
2220
|
-
? auraRef.storage.delete
|
|
2221
|
-
: function (key) { return deleteStorage(key); };
|
|
2222
|
-
auraRef.storage.keys = typeof auraRef.storage.keys === 'function'
|
|
2223
|
-
? auraRef.storage.keys
|
|
2224
|
-
: function () {
|
|
2225
|
-
const prefix = 'aurajs:';
|
|
2226
|
-
const backend = resolveStorageBackend();
|
|
2227
|
-
const keys = [];
|
|
2228
|
-
if (backend && Number.isInteger(backend.length) && typeof backend.key === 'function') {
|
|
2229
|
-
for (let index = 0; index < backend.length; index += 1) {
|
|
2230
|
-
const nextKey = backend.key(index);
|
|
2231
|
-
if (typeof nextKey === 'string' && nextKey.startsWith(prefix)) {
|
|
2232
|
-
keys.push(nextKey.slice(prefix.length));
|
|
2233
|
-
}
|
|
2234
|
-
}
|
|
2235
|
-
keys.sort(function (a, b) { return a.localeCompare(b); });
|
|
2236
|
-
return keys;
|
|
2237
|
-
}
|
|
2238
|
-
for (const key of assetState.storageFallback.keys()) {
|
|
2239
|
-
if (key.startsWith(prefix)) {
|
|
2240
|
-
keys.push(key.slice(prefix.length));
|
|
2241
|
-
}
|
|
2242
|
-
}
|
|
2243
|
-
keys.sort(function (a, b) { return a.localeCompare(b); });
|
|
2244
|
-
return keys;
|
|
2245
|
-
};
|
|
2246
|
-
auraRef.storage.set = typeof auraRef.storage.set === 'function'
|
|
2247
|
-
? auraRef.storage.set
|
|
2248
|
-
: function (key, value) { return writeStorage(key, value); };
|
|
2249
|
-
auraRef.storage.get = typeof auraRef.storage.get === 'function'
|
|
2250
|
-
? auraRef.storage.get
|
|
2251
|
-
: function (key, fallback) {
|
|
2252
|
-
const value = readStorage(key);
|
|
2253
|
-
return value == null ? fallback : value;
|
|
2254
|
-
};
|
|
2255
|
-
|
|
2256
|
-
auraRef.audio = auraRef.audio && typeof auraRef.audio === 'object' ? auraRef.audio : {};
|
|
2257
|
-
if (auraRef.audio.supported !== true) {
|
|
2258
|
-
auraRef.audio.supported = false;
|
|
2259
|
-
}
|
|
2260
|
-
if (typeof auraRef.audio.reasonCode !== 'string') {
|
|
2261
|
-
auraRef.audio.reasonCode = 'web_audio_playback_unsupported';
|
|
2262
|
-
}
|
|
2263
|
-
if (typeof auraRef.audio.runtime !== 'string') {
|
|
2264
|
-
auraRef.audio.runtime = 'web';
|
|
2265
|
-
}
|
|
2266
|
-
auraRef.audio.play = typeof auraRef.audio.play === 'function'
|
|
2267
|
-
? auraRef.audio.play
|
|
2268
|
-
: function () {
|
|
2269
|
-
throw createUnsupportedRuntimeError('audio', 'play', 'web_audio_play_unsupported', { playbackSupported: false });
|
|
2270
|
-
};
|
|
2271
|
-
auraRef.audio.stop = typeof auraRef.audio.stop === 'function'
|
|
2272
|
-
? auraRef.audio.stop
|
|
2273
|
-
: function () {
|
|
2274
|
-
throw createUnsupportedRuntimeError('audio', 'stop', 'web_audio_stop_unsupported', { playbackSupported: false });
|
|
2275
|
-
};
|
|
2276
|
-
auraRef.audio.pause = typeof auraRef.audio.pause === 'function'
|
|
2277
|
-
? auraRef.audio.pause
|
|
2278
|
-
: function () {
|
|
2279
|
-
throw createUnsupportedRuntimeError('audio', 'pause', 'web_audio_pause_unsupported', { playbackSupported: false });
|
|
2280
|
-
};
|
|
2281
|
-
auraRef.audio.resume = typeof auraRef.audio.resume === 'function'
|
|
2282
|
-
? auraRef.audio.resume
|
|
2283
|
-
: function () {
|
|
2284
|
-
throw createUnsupportedRuntimeError('audio', 'resume', 'web_audio_resume_unsupported', { playbackSupported: false });
|
|
2285
|
-
};
|
|
2286
|
-
auraRef.audio.setVolume = typeof auraRef.audio.setVolume === 'function'
|
|
2287
|
-
? auraRef.audio.setVolume
|
|
2288
|
-
: function () {
|
|
2289
|
-
throw createUnsupportedRuntimeError('audio', 'setVolume', 'web_audio_set_volume_unsupported', { playbackSupported: false });
|
|
2290
|
-
};
|
|
2291
|
-
auraRef.audio.setMasterVolume = typeof auraRef.audio.setMasterVolume === 'function'
|
|
2292
|
-
? auraRef.audio.setMasterVolume
|
|
2293
|
-
: function () {
|
|
2294
|
-
throw createUnsupportedRuntimeError('audio', 'setMasterVolume', 'web_audio_set_master_volume_unsupported', { playbackSupported: false });
|
|
2295
|
-
};
|
|
2296
|
-
auraRef.audio.stopAll = typeof auraRef.audio.stopAll === 'function'
|
|
2297
|
-
? auraRef.audio.stopAll
|
|
2298
|
-
: function () {
|
|
2299
|
-
throw createUnsupportedRuntimeError('audio', 'stopAll', 'web_audio_stop_all_unsupported', { playbackSupported: false });
|
|
2300
|
-
};
|
|
2301
|
-
auraRef.audio.setBusVolume = typeof auraRef.audio.setBusVolume === 'function'
|
|
2302
|
-
? auraRef.audio.setBusVolume
|
|
2303
|
-
: function () {
|
|
2304
|
-
throw createUnsupportedRuntimeError('audio', 'setBusVolume', 'web_audio_set_bus_volume_unsupported', { playbackSupported: false });
|
|
2305
|
-
};
|
|
2306
|
-
auraRef.audio.assignBus = typeof auraRef.audio.assignBus === 'function'
|
|
2307
|
-
? auraRef.audio.assignBus
|
|
2308
|
-
: function () {
|
|
2309
|
-
throw createUnsupportedRuntimeError('audio', 'assignBus', 'web_audio_assign_bus_unsupported', { playbackSupported: false });
|
|
2310
|
-
};
|
|
2311
|
-
auraRef.audio.fadeTrack = typeof auraRef.audio.fadeTrack === 'function'
|
|
2312
|
-
? auraRef.audio.fadeTrack
|
|
2313
|
-
: function () {
|
|
2314
|
-
throw createUnsupportedRuntimeError('audio', 'fadeTrack', 'web_audio_fade_track_unsupported', { playbackSupported: false });
|
|
2315
|
-
};
|
|
2316
|
-
auraRef.audio.fadeBus = typeof auraRef.audio.fadeBus === 'function'
|
|
2317
|
-
? auraRef.audio.fadeBus
|
|
2318
|
-
: function () {
|
|
2319
|
-
throw createUnsupportedRuntimeError('audio', 'fadeBus', 'web_audio_fade_bus_unsupported', { playbackSupported: false });
|
|
2320
|
-
};
|
|
2321
|
-
auraRef.audio.crossfade = typeof auraRef.audio.crossfade === 'function'
|
|
2322
|
-
? auraRef.audio.crossfade
|
|
2323
|
-
: function () {
|
|
2324
|
-
throw createUnsupportedRuntimeError('audio', 'crossfade', 'web_audio_crossfade_unsupported', { playbackSupported: false });
|
|
2325
|
-
};
|
|
2326
|
-
auraRef.audio.update = typeof auraRef.audio.update === 'function'
|
|
2327
|
-
? auraRef.audio.update
|
|
2328
|
-
: function () {
|
|
2329
|
-
throw createUnsupportedRuntimeError('audio', 'update', 'web_audio_update_unsupported', { playbackSupported: false });
|
|
2330
|
-
};
|
|
2331
|
-
auraRef.audio.clearEnvelopes = typeof auraRef.audio.clearEnvelopes === 'function'
|
|
2332
|
-
? auraRef.audio.clearEnvelopes
|
|
2333
|
-
: function () {
|
|
2334
|
-
throw createUnsupportedRuntimeError('audio', 'clearEnvelopes', 'web_audio_clear_envelopes_unsupported', { playbackSupported: false });
|
|
2335
|
-
};
|
|
2336
|
-
auraRef.audio.getMixerState = typeof auraRef.audio.getMixerState === 'function'
|
|
2337
|
-
? auraRef.audio.getMixerState
|
|
2338
|
-
: function () {
|
|
2339
|
-
throw createUnsupportedRuntimeError('audio', 'getMixerState', 'web_audio_get_mixer_state_unsupported', { playbackSupported: false });
|
|
2340
|
-
};
|
|
2341
|
-
auraRef.audio.play3d = typeof auraRef.audio.play3d === 'function'
|
|
2342
|
-
? auraRef.audio.play3d
|
|
2343
|
-
: function () {
|
|
2344
|
-
throw createUnsupportedRuntimeError('audio', 'play3d', 'web_audio_play3d_unsupported', { playbackSupported: false });
|
|
2345
|
-
};
|
|
2346
|
-
auraRef.audio.setListenerTransform = typeof auraRef.audio.setListenerTransform === 'function'
|
|
2347
|
-
? auraRef.audio.setListenerTransform
|
|
2348
|
-
: function () {
|
|
2349
|
-
throw createUnsupportedRuntimeError('audio', 'setListenerTransform', 'web_audio_set_listener_transform_unsupported', { playbackSupported: false });
|
|
2350
|
-
};
|
|
2351
|
-
auraRef.audio.attachListener = typeof auraRef.audio.attachListener === 'function'
|
|
2352
|
-
? auraRef.audio.attachListener
|
|
2353
|
-
: function () {
|
|
2354
|
-
throw createUnsupportedRuntimeError('audio', 'attachListener', 'web_audio_attach_listener_unsupported', { playbackSupported: false });
|
|
2355
|
-
};
|
|
2356
|
-
auraRef.audio.detachListener = typeof auraRef.audio.detachListener === 'function'
|
|
2357
|
-
? auraRef.audio.detachListener
|
|
2358
|
-
: function () {
|
|
2359
|
-
throw createUnsupportedRuntimeError('audio', 'detachListener', 'web_audio_detach_listener_unsupported', { playbackSupported: false });
|
|
2360
|
-
};
|
|
2361
|
-
auraRef.audio.setEmitterTransform = typeof auraRef.audio.setEmitterTransform === 'function'
|
|
2362
|
-
? auraRef.audio.setEmitterTransform
|
|
2363
|
-
: function () {
|
|
2364
|
-
throw createUnsupportedRuntimeError('audio', 'setEmitterTransform', 'web_audio_set_emitter_transform_unsupported', { playbackSupported: false });
|
|
2365
|
-
};
|
|
2366
|
-
auraRef.audio.attachEmitter = typeof auraRef.audio.attachEmitter === 'function'
|
|
2367
|
-
? auraRef.audio.attachEmitter
|
|
2368
|
-
: function () {
|
|
2369
|
-
throw createUnsupportedRuntimeError('audio', 'attachEmitter', 'web_audio_attach_emitter_unsupported', { playbackSupported: false });
|
|
2370
|
-
};
|
|
2371
|
-
auraRef.audio.detachEmitter = typeof auraRef.audio.detachEmitter === 'function'
|
|
2372
|
-
? auraRef.audio.detachEmitter
|
|
2373
|
-
: function () {
|
|
2374
|
-
throw createUnsupportedRuntimeError('audio', 'detachEmitter', 'web_audio_detach_emitter_unsupported', { playbackSupported: false });
|
|
2375
|
-
};
|
|
2376
|
-
auraRef.audio.updateSpatial = typeof auraRef.audio.updateSpatial === 'function'
|
|
2377
|
-
? auraRef.audio.updateSpatial
|
|
2378
|
-
: function () {
|
|
2379
|
-
throw createUnsupportedRuntimeError('audio', 'updateSpatial', 'web_audio_update_spatial_unsupported', { playbackSupported: false });
|
|
2380
|
-
};
|
|
2381
|
-
auraRef.audio.getSpatialState = typeof auraRef.audio.getSpatialState === 'function'
|
|
2382
|
-
? auraRef.audio.getSpatialState
|
|
2383
|
-
: function () {
|
|
2384
|
-
throw createUnsupportedRuntimeError('audio', 'getSpatialState', 'web_audio_get_spatial_state_unsupported', { playbackSupported: false });
|
|
2385
|
-
};
|
|
2386
|
-
|
|
2387
|
-
auraRef.assets = auraRef.assets && typeof auraRef.assets === 'object' ? auraRef.assets : {};
|
|
2388
|
-
auraRef.assets.load = typeof auraRef.assets.load === 'function'
|
|
2389
|
-
? auraRef.assets.load
|
|
2390
|
-
: async function (source) {
|
|
2391
|
-
return await loadAssetRecord(source);
|
|
2392
|
-
};
|
|
2393
|
-
auraRef.assets.exists = typeof auraRef.assets.exists === 'function'
|
|
2394
|
-
? auraRef.assets.exists
|
|
2395
|
-
: function (name) {
|
|
2396
|
-
return !!resolveAssetEntry(name);
|
|
2397
|
-
};
|
|
2398
|
-
auraRef.assets.image = typeof auraRef.assets.image === 'function'
|
|
2399
|
-
? auraRef.assets.image
|
|
2400
|
-
: function (name) {
|
|
2401
|
-
const sourcePath = resolveAssetSourcePath(name);
|
|
2402
|
-
const loaded = resolveLoadedAsset(sourcePath);
|
|
2403
|
-
if (loaded) return loaded;
|
|
2404
|
-
const entry = resolveAssetEntry(sourcePath);
|
|
2405
|
-
return rememberLoadedAsset(sourcePath, {
|
|
2406
|
-
kind: 'image',
|
|
2407
|
-
path: sourcePath,
|
|
2408
|
-
sourcePath: sourcePath,
|
|
2409
|
-
resolvedPath: entry && typeof entry.path === 'string' ? normalizePath(entry.path) : sourcePath,
|
|
2410
|
-
mediaType: entry && typeof entry.mediaType === 'string' ? entry.mediaType : 'image/png',
|
|
2411
|
-
image: null,
|
|
2412
|
-
width: 0,
|
|
2413
|
-
height: 0
|
|
2414
|
-
});
|
|
2415
|
-
};
|
|
2416
|
-
auraRef.assets.sound = typeof auraRef.assets.sound === 'function'
|
|
2417
|
-
? auraRef.assets.sound
|
|
2418
|
-
: function (name) {
|
|
2419
|
-
const sourcePath = resolveAssetSourcePath(name);
|
|
2420
|
-
const loaded = resolveLoadedAsset(sourcePath);
|
|
2421
|
-
if (loaded) return loaded;
|
|
2422
|
-
const entry = resolveAssetEntry(sourcePath);
|
|
2423
|
-
return createBrowserSoundHandle(sourcePath, entry, null);
|
|
2424
|
-
};
|
|
2425
|
-
auraRef.assets.text = typeof auraRef.assets.text === 'function'
|
|
2426
|
-
? auraRef.assets.text
|
|
2427
|
-
: function (name) {
|
|
2428
|
-
const loaded = resolveLoadedAsset(name);
|
|
2429
|
-
return loaded && typeof loaded.text === 'string' ? loaded.text : '';
|
|
2430
|
-
};
|
|
2431
|
-
auraRef.assets.json = typeof auraRef.assets.json === 'function'
|
|
2432
|
-
? auraRef.assets.json
|
|
2433
|
-
: function (name) {
|
|
2434
|
-
const loaded = resolveLoadedAsset(name);
|
|
2435
|
-
return loaded && loaded.json && typeof loaded.json === 'object' ? loaded.json : {};
|
|
2436
|
-
};
|
|
2437
|
-
auraRef.assets.bytes = typeof auraRef.assets.bytes === 'function'
|
|
2438
|
-
? auraRef.assets.bytes
|
|
2439
|
-
: function (name) {
|
|
2440
|
-
const loaded = resolveLoadedAsset(name);
|
|
2441
|
-
return loaded && loaded.bytes instanceof Uint8Array ? loaded.bytes : new Uint8Array();
|
|
2442
|
-
};
|
|
2443
|
-
auraRef.assets.loadText = typeof auraRef.assets.loadText === 'function'
|
|
2444
|
-
? auraRef.assets.loadText
|
|
2445
|
-
: async function (name) {
|
|
2446
|
-
const loaded = await loadAssetRecord(name);
|
|
2447
|
-
return loaded && typeof loaded.text === 'string' ? loaded.text : '';
|
|
2448
|
-
};
|
|
2449
|
-
auraRef.assets.loadJson = typeof auraRef.assets.loadJson === 'function'
|
|
2450
|
-
? auraRef.assets.loadJson
|
|
2451
|
-
: async function (name) {
|
|
2452
|
-
const loaded = await loadAssetRecord(name);
|
|
2453
|
-
return loaded && loaded.json && typeof loaded.json === 'object' ? loaded.json : null;
|
|
2454
|
-
};
|
|
2455
|
-
|
|
2456
|
-
function drawResolvedImage(source, x, y, options, useSpriteFrame) {
|
|
2457
|
-
const ctx = ensureWorldTransform();
|
|
2458
|
-
if (!ctx || typeof ctx.drawImage !== 'function') return false;
|
|
2459
|
-
const handle = source && typeof source === 'object' && source.image
|
|
2460
|
-
? source
|
|
2461
|
-
: auraRef.assets.image(source);
|
|
2462
|
-
if (!handle || !handle.image) return false;
|
|
2463
|
-
const opts = options && typeof options === 'object' ? { ...options } : {};
|
|
2464
|
-
const width = normalizePositiveNumber(opts.width, handle.width || handle.image.naturalWidth || handle.image.width || 1);
|
|
2465
|
-
const height = normalizePositiveNumber(opts.height, handle.height || handle.image.naturalHeight || handle.image.height || 1);
|
|
2466
|
-
const alpha = Number.isFinite(Number(opts.alpha)) ? Math.max(0, Math.min(1, Number(opts.alpha))) : 1;
|
|
2467
|
-
const frameX = useSpriteFrame ? Math.max(0, Number(opts.frameX) || 0) : 0;
|
|
2468
|
-
const frameY = useSpriteFrame ? Math.max(0, Number(opts.frameY) || 0) : 0;
|
|
2469
|
-
const frameW = useSpriteFrame
|
|
2470
|
-
? normalizePositiveNumber(opts.frameW, handle.image.naturalWidth || handle.image.width || width)
|
|
2471
|
-
: (handle.image.naturalWidth || handle.image.width || width);
|
|
2472
|
-
const frameH = useSpriteFrame
|
|
2473
|
-
? normalizePositiveNumber(opts.frameH, handle.image.naturalHeight || handle.image.height || height)
|
|
2474
|
-
: (handle.image.naturalHeight || handle.image.height || height);
|
|
2475
|
-
const drawX = Number(x) || 0;
|
|
2476
|
-
const drawY = Number(y) || 0;
|
|
2477
|
-
const flipX = opts.flipX === true;
|
|
2478
|
-
const flipY = opts.flipY === true;
|
|
2479
|
-
if (typeof ctx.save === 'function') ctx.save();
|
|
2480
|
-
ctx.globalAlpha = alpha;
|
|
2481
|
-
if (flipX || flipY) {
|
|
2482
|
-
if (typeof ctx.translate === 'function') {
|
|
2483
|
-
ctx.translate(drawX + (flipX ? width : 0), drawY + (flipY ? height : 0));
|
|
2484
|
-
}
|
|
2485
|
-
if (typeof ctx.scale === 'function') {
|
|
2486
|
-
ctx.scale(flipX ? -1 : 1, flipY ? -1 : 1);
|
|
2487
|
-
}
|
|
2488
|
-
ctx.drawImage(handle.image, frameX, frameY, frameW, frameH, 0, 0, width, height);
|
|
2489
|
-
} else {
|
|
2490
|
-
ctx.drawImage(handle.image, frameX, frameY, frameW, frameH, drawX, drawY, width, height);
|
|
2491
|
-
}
|
|
2492
|
-
if (typeof ctx.restore === 'function') ctx.restore();
|
|
2493
|
-
return true;
|
|
2494
|
-
}
|
|
2495
|
-
|
|
2496
|
-
auraRef.draw2d = auraRef.draw2d && typeof auraRef.draw2d === 'object' ? auraRef.draw2d : {};
|
|
2497
|
-
auraRef.draw2d.clear = function (colorOrR, g, b, a) {
|
|
2498
|
-
const ctx = ensureCanvasContext();
|
|
2499
|
-
if (!ctx) return;
|
|
2500
|
-
const fillColor = arguments.length > 1
|
|
2501
|
-
? createUnitColor(colorOrR, g, b, a == null ? 1 : a)
|
|
2502
|
-
: normalizeColor(colorOrR, createUnitColor(0, 0, 0, 1));
|
|
2503
|
-
resetDrawState();
|
|
2504
|
-
ctx.clearRect(0, 0, runtime.width, runtime.height);
|
|
2505
|
-
ctx.fillStyle = colorToCss(fillColor, createUnitColor(0, 0, 0, 1));
|
|
2506
|
-
ctx.fillRect(0, 0, runtime.width, runtime.height);
|
|
2507
|
-
applyWorldTransform();
|
|
2508
|
-
};
|
|
2509
|
-
auraRef.draw2d.rect = function (x, y, w, h, color) {
|
|
2510
|
-
const ctx = ensureWorldTransform();
|
|
2511
|
-
if (!ctx) return;
|
|
2512
|
-
ctx.strokeStyle = colorToCss(color, defaultColor);
|
|
2513
|
-
ctx.lineWidth = 1;
|
|
2514
|
-
ctx.strokeRect(Number(x) || 0, Number(y) || 0, Number(w) || 0, Number(h) || 0);
|
|
2515
|
-
};
|
|
2516
|
-
auraRef.draw2d.rectOutline = auraRef.draw2d.rect;
|
|
2517
|
-
auraRef.draw2d.rectFill = function (x, y, w, h, color) {
|
|
2518
|
-
const ctx = ensureWorldTransform();
|
|
2519
|
-
if (!ctx) return;
|
|
2520
|
-
ctx.fillStyle = colorToCss(color, defaultColor);
|
|
2521
|
-
ctx.fillRect(Number(x) || 0, Number(y) || 0, Number(w) || 0, Number(h) || 0);
|
|
2522
|
-
};
|
|
2523
|
-
auraRef.draw2d.circle = function (x, y, radius, color) {
|
|
2524
|
-
const ctx = ensureWorldTransform();
|
|
2525
|
-
if (!ctx) return;
|
|
2526
|
-
ctx.beginPath();
|
|
2527
|
-
ctx.arc(Number(x) || 0, Number(y) || 0, Math.max(0, Number(radius) || 0), 0, Math.PI * 2);
|
|
2528
|
-
ctx.strokeStyle = colorToCss(color, defaultColor);
|
|
2529
|
-
ctx.lineWidth = 1;
|
|
2530
|
-
ctx.stroke();
|
|
2531
|
-
};
|
|
2532
|
-
auraRef.draw2d.circleFill = function (x, y, radius, color) {
|
|
2533
|
-
const ctx = ensureWorldTransform();
|
|
2534
|
-
if (!ctx) return;
|
|
2535
|
-
ctx.beginPath();
|
|
2536
|
-
ctx.arc(Number(x) || 0, Number(y) || 0, Math.max(0, Number(radius) || 0), 0, Math.PI * 2);
|
|
2537
|
-
ctx.fillStyle = colorToCss(color, defaultColor);
|
|
2538
|
-
ctx.fill();
|
|
2539
|
-
};
|
|
2540
|
-
auraRef.draw2d.line = function (x1, y1, x2, y2, color, width) {
|
|
2541
|
-
const ctx = ensureWorldTransform();
|
|
2542
|
-
if (!ctx) return;
|
|
2543
|
-
ctx.beginPath();
|
|
2544
|
-
ctx.moveTo(Number(x1) || 0, Number(y1) || 0);
|
|
2545
|
-
ctx.lineTo(Number(x2) || 0, Number(y2) || 0);
|
|
2546
|
-
ctx.strokeStyle = colorToCss(color, defaultColor);
|
|
2547
|
-
ctx.lineWidth = normalizePositiveNumber(width, 1);
|
|
2548
|
-
ctx.stroke();
|
|
2549
|
-
};
|
|
2550
|
-
auraRef.draw2d.text = function (text, x, y, sizeOrOptions, colorMaybe) {
|
|
2551
|
-
const options = normalizeTextOptions(sizeOrOptions, colorMaybe);
|
|
2552
|
-
return withScreenSpace(function (ctx) {
|
|
2553
|
-
const config = applyFont(options);
|
|
2554
|
-
const source = options && typeof options === 'object' ? options : {};
|
|
2555
|
-
ctx.fillStyle = colorToCss(source.color, defaultColor);
|
|
2556
|
-
ctx.textAlign = config.align;
|
|
2557
|
-
ctx.textBaseline = 'top';
|
|
2558
|
-
ctx.fillText(String(text == null ? '' : text), Number(x) || 0, Number(y) || 0);
|
|
2559
|
-
return true;
|
|
2560
|
-
});
|
|
2561
|
-
};
|
|
2562
|
-
auraRef.draw2d.measureText = function (text, sizeOrOptions, colorMaybe) {
|
|
2563
|
-
const options = normalizeTextOptions(sizeOrOptions, colorMaybe);
|
|
2564
|
-
const source = options && typeof options === 'object' ? options : {};
|
|
2565
|
-
const size = normalizePositiveNumber(source.size, 16);
|
|
2566
|
-
const ctx = ensureCanvasContext();
|
|
2567
|
-
if (!ctx) {
|
|
2568
|
-
const fallbackWidth = String(text == null ? '' : text).length * size * 0.6;
|
|
2569
|
-
return { width: Number(fallbackWidth.toFixed(3)), height: size };
|
|
2570
|
-
}
|
|
2571
|
-
const measuredWidth = withScreenSpace(function () {
|
|
2572
|
-
applyFont(options);
|
|
2573
|
-
const metrics = ctx.measureText(String(text == null ? '' : text));
|
|
2574
|
-
return Number.isFinite(metrics && metrics.width)
|
|
2575
|
-
? metrics.width
|
|
2576
|
-
: String(text == null ? '' : text).length * size * 0.6;
|
|
2577
|
-
});
|
|
2578
|
-
return { width: Number(Number(measuredWidth || 0).toFixed(3)), height: size };
|
|
2579
|
-
};
|
|
2580
|
-
auraRef.draw2d.image = typeof auraRef.draw2d.image === 'function'
|
|
2581
|
-
? auraRef.draw2d.image
|
|
2582
|
-
: function (source, x, y, options) {
|
|
2583
|
-
return drawResolvedImage(source, x, y, options, false);
|
|
2584
|
-
};
|
|
2585
|
-
auraRef.draw2d.sprite = typeof auraRef.draw2d.sprite === 'function'
|
|
2586
|
-
? auraRef.draw2d.sprite
|
|
2587
|
-
: function (source, x, y, options) {
|
|
2588
|
-
return drawResolvedImage(source, x, y, options, true);
|
|
2589
|
-
};
|
|
2590
|
-
auraRef.draw2d.pushTransform = function () {
|
|
2591
|
-
const ctx = ensureWorldTransform();
|
|
2592
|
-
if (!ctx || typeof ctx.save !== 'function') return;
|
|
2593
|
-
runtime.transformDepth += 1;
|
|
2594
|
-
ctx.save();
|
|
2595
|
-
};
|
|
2596
|
-
auraRef.draw2d.popTransform = function () {
|
|
2597
|
-
const ctx = ensureCanvasContext();
|
|
2598
|
-
if (!ctx || typeof ctx.restore !== 'function' || runtime.transformDepth <= 0) return;
|
|
2599
|
-
runtime.transformDepth -= 1;
|
|
2600
|
-
ctx.restore();
|
|
2601
|
-
};
|
|
2602
|
-
auraRef.draw2d.push = auraRef.draw2d.pushTransform;
|
|
2603
|
-
auraRef.draw2d.pop = auraRef.draw2d.popTransform;
|
|
2604
|
-
auraRef.draw2d.translate = function (x, y) {
|
|
2605
|
-
const ctx = ensureWorldTransform();
|
|
2606
|
-
if (!ctx || typeof ctx.translate !== 'function') return;
|
|
2607
|
-
ctx.translate(Number(x) || 0, Number(y) || 0);
|
|
2608
|
-
};
|
|
2609
|
-
auraRef.draw2d.rotate = function (angle) {
|
|
2610
|
-
const ctx = ensureWorldTransform();
|
|
2611
|
-
if (!ctx || typeof ctx.rotate !== 'function') return;
|
|
2612
|
-
ctx.rotate(Number(angle) || 0);
|
|
2613
|
-
};
|
|
2614
|
-
auraRef.draw2d.scale = function (x, y) {
|
|
2615
|
-
const ctx = ensureWorldTransform();
|
|
2616
|
-
if (!ctx || typeof ctx.scale !== 'function') return;
|
|
2617
|
-
const scaleX = Number.isFinite(Number(x)) ? Number(x) : 1;
|
|
2618
|
-
const scaleY = Number.isFinite(Number(y)) ? Number(y) : scaleX;
|
|
2619
|
-
ctx.scale(scaleX, scaleY);
|
|
2620
|
-
};
|
|
2621
|
-
|
|
2622
|
-
return {
|
|
2623
|
-
aura: auraRef,
|
|
2624
|
-
setRuntimeConfig(nextRuntimeConfig) {
|
|
2625
|
-
currentRuntimeConfig = nextRuntimeConfig && typeof nextRuntimeConfig === 'object' ? nextRuntimeConfig : {};
|
|
2626
|
-
currentCanvasConfig = currentRuntimeConfig.canvas && typeof currentRuntimeConfig.canvas === 'object'
|
|
2627
|
-
? currentRuntimeConfig.canvas
|
|
2628
|
-
: {};
|
|
2629
|
-
runtime.configuredWidth = normalizeCanvasSize(currentCanvasConfig.width, runtime.configuredWidth);
|
|
2630
|
-
runtime.configuredHeight = normalizeCanvasSize(currentCanvasConfig.height, runtime.configuredHeight);
|
|
2631
|
-
runtime.resizeMode = currentCanvasConfig.resizeMode === 'fixed' ? 'fixed' : 'fit-container';
|
|
2632
|
-
syncCanvasSize(false);
|
|
2633
|
-
},
|
|
2634
|
-
setManifest(nextManifest, rootUrl) {
|
|
2635
|
-
indexManifestAssets(nextManifest, rootUrl);
|
|
2636
|
-
},
|
|
2637
|
-
mount(canvas, mountTarget) {
|
|
2638
|
-
runtime.canvas = canvas || runtime.canvas;
|
|
2639
|
-
runtime.mountTarget = mountTarget || runtime.mountTarget;
|
|
2640
|
-
ensureCanvasContext();
|
|
2641
|
-
syncCanvasSize(false);
|
|
2642
|
-
resetDrawState();
|
|
2643
|
-
attachListeners();
|
|
2644
|
-
clearHeldInputState();
|
|
2645
|
-
auraRef.input.mouse.scroll = 0;
|
|
2646
|
-
applyCursorAppearance();
|
|
2647
|
-
if (runtime.canvas && typeof runtime.canvas.focus === 'function') {
|
|
2648
|
-
runtime.canvas.focus();
|
|
2649
|
-
}
|
|
2650
|
-
if (typeof auraRef.onFocus === 'function') {
|
|
2651
|
-
auraRef.onFocus();
|
|
2652
|
-
}
|
|
2653
|
-
return true;
|
|
2654
|
-
},
|
|
2655
|
-
beginFrame() {
|
|
2656
|
-
inputState.framePressed = new Set(inputState.pendingPressed);
|
|
2657
|
-
inputState.frameReleased = new Set(inputState.pendingReleased);
|
|
2658
|
-
inputState.pendingPressed.clear();
|
|
2659
|
-
inputState.pendingReleased.clear();
|
|
2660
|
-
inputState.frameMousePressed = new Set(inputState.pendingMousePressed);
|
|
2661
|
-
inputState.frameMouseReleased = new Set(inputState.pendingMouseReleased);
|
|
2662
|
-
inputState.pendingMousePressed.clear();
|
|
2663
|
-
inputState.pendingMouseReleased.clear();
|
|
2664
|
-
inputState.frameMouseDeltaX = inputState.pendingMouseDeltaX;
|
|
2665
|
-
inputState.frameMouseDeltaY = inputState.pendingMouseDeltaY;
|
|
2666
|
-
inputState.pendingMouseDeltaX = 0;
|
|
2667
|
-
inputState.pendingMouseDeltaY = 0;
|
|
2668
|
-
resetDrawState();
|
|
2669
|
-
},
|
|
2670
|
-
endFrame() {
|
|
2671
|
-
const ctx = ensureCanvasContext();
|
|
2672
|
-
if (ctx && typeof ctx.restore === 'function') {
|
|
2673
|
-
while (runtime.transformDepth > 0) {
|
|
2674
|
-
runtime.transformDepth -= 1;
|
|
2675
|
-
ctx.restore();
|
|
2676
|
-
}
|
|
2677
|
-
}
|
|
2678
|
-
},
|
|
2679
|
-
unmount() {
|
|
2680
|
-
detachListeners();
|
|
2681
|
-
clearHeldInputState();
|
|
2682
|
-
runtime.cursorLocked = false;
|
|
2683
|
-
if (globalRef.document && typeof globalRef.document.exitPointerLock === 'function') {
|
|
2684
|
-
globalRef.document.exitPointerLock();
|
|
2685
|
-
}
|
|
2686
|
-
applyCursorAppearance();
|
|
2687
|
-
runtime.mountTarget = null;
|
|
2688
|
-
runtime.canvas = null;
|
|
2689
|
-
runtime.context2d = null;
|
|
2690
|
-
runtime.transformDepth = 0;
|
|
2691
|
-
runtime.worldTransformActive = false;
|
|
2692
|
-
return true;
|
|
2693
|
-
}
|
|
2694
|
-
};
|
|
2695
|
-
}
|
|
2696
|
-
|
|
2697
|
-
function createDeterministicBootstrap() {
|
|
2698
|
-
return async function bootstrap(input) {
|
|
2699
|
-
const auraRef = auraRuntime && auraRuntime.aura
|
|
2700
|
-
? auraRuntime.aura
|
|
2701
|
-
: (globalRef.aura && typeof globalRef.aura === 'object'
|
|
2702
|
-
? globalRef.aura
|
|
2703
|
-
: (globalRef.aura = {}));
|
|
2704
|
-
const runtimeConfig = input && typeof input.runtimeConfig === 'object' && input.runtimeConfig
|
|
2705
|
-
? input.runtimeConfig
|
|
2706
|
-
: {};
|
|
2707
|
-
const loopConfig = runtimeConfig.loop && typeof runtimeConfig.loop === 'object'
|
|
2708
|
-
? runtimeConfig.loop
|
|
2709
|
-
: {};
|
|
2710
|
-
const maxDeltaSeconds = normalizePositiveNumber(loopConfig.maxDeltaMs, 50) / 1000;
|
|
2711
|
-
const fixedDeltaSeconds = Math.min(maxDeltaSeconds, 1 / 60);
|
|
2712
|
-
const requestFrame = typeof globalRef.requestAnimationFrame === 'function'
|
|
2713
|
-
? globalRef.requestAnimationFrame.bind(globalRef)
|
|
2714
|
-
: function (callback) {
|
|
2715
|
-
return globalRef.setTimeout(function () {
|
|
2716
|
-
callback(Date.now());
|
|
2717
|
-
}, 16);
|
|
2718
|
-
};
|
|
2719
|
-
const cancelFrame = typeof globalRef.cancelAnimationFrame === 'function'
|
|
2720
|
-
? globalRef.cancelAnimationFrame.bind(globalRef)
|
|
2721
|
-
: function (handle) {
|
|
2722
|
-
globalRef.clearTimeout(handle);
|
|
2723
|
-
};
|
|
2724
|
-
|
|
2725
|
-
const runtimeState = {
|
|
2726
|
-
disposed: false,
|
|
2727
|
-
running: false,
|
|
2728
|
-
setupCalls: 0,
|
|
2729
|
-
updateCalls: 0,
|
|
2730
|
-
drawCalls: 0,
|
|
2731
|
-
frameCount: 0,
|
|
2732
|
-
lastDeltaSeconds: 0,
|
|
2733
|
-
rafHandle: null
|
|
2734
|
-
};
|
|
2735
|
-
|
|
2736
|
-
function getLifecycle() {
|
|
2737
|
-
return {
|
|
2738
|
-
running: runtimeState.running && runtimeState.disposed === false,
|
|
2739
|
-
setupCalls: runtimeState.setupCalls,
|
|
2740
|
-
updateCalls: runtimeState.updateCalls,
|
|
2741
|
-
drawCalls: runtimeState.drawCalls,
|
|
2742
|
-
frameCount: runtimeState.frameCount,
|
|
2743
|
-
lastDeltaSeconds: runtimeState.lastDeltaSeconds
|
|
2744
|
-
};
|
|
2745
|
-
}
|
|
2746
|
-
|
|
2747
|
-
function syncLifecycle() {
|
|
2748
|
-
state.lifecycle = cloneLifecycle(getLifecycle());
|
|
2749
|
-
}
|
|
2750
|
-
|
|
2751
|
-
try {
|
|
2752
|
-
if (typeof auraRef.setup === 'function') {
|
|
2753
|
-
const setupResult = auraRef.setup();
|
|
2754
|
-
if (setupResult && typeof setupResult.then === 'function') {
|
|
2755
|
-
await setupResult;
|
|
2756
|
-
}
|
|
2757
|
-
runtimeState.setupCalls += 1;
|
|
2758
|
-
}
|
|
2759
|
-
} catch (error) {
|
|
2760
|
-
throw createError(
|
|
2761
|
-
'web_runtime_bootstrap_failed',
|
|
2762
|
-
'Runtime setup failed.',
|
|
2763
|
-
'runtime',
|
|
2764
|
-
true,
|
|
2765
|
-
{ stage: 'setup', cause: String(error && error.message ? error.message : error) }
|
|
2766
|
-
);
|
|
2767
|
-
}
|
|
2768
|
-
|
|
2769
|
-
runtimeState.running = true;
|
|
2770
|
-
syncLifecycle();
|
|
2771
|
-
|
|
2772
|
-
function step() {
|
|
2773
|
-
if (runtimeState.running === false || runtimeState.disposed === true) {
|
|
2774
|
-
return;
|
|
2775
|
-
}
|
|
2776
|
-
runtimeState.frameCount += 1;
|
|
2777
|
-
runtimeState.lastDeltaSeconds = fixedDeltaSeconds;
|
|
2778
|
-
|
|
2779
|
-
try {
|
|
2780
|
-
if (auraRuntime && typeof auraRuntime.beginFrame === 'function') {
|
|
2781
|
-
auraRuntime.beginFrame();
|
|
2782
|
-
}
|
|
2783
|
-
if (typeof auraRef.update === 'function') {
|
|
2784
|
-
auraRef.update(fixedDeltaSeconds);
|
|
2785
|
-
runtimeState.updateCalls += 1;
|
|
2786
|
-
}
|
|
2787
|
-
if (typeof auraRef.draw === 'function') {
|
|
2788
|
-
auraRef.draw();
|
|
2789
|
-
runtimeState.drawCalls += 1;
|
|
2790
|
-
}
|
|
2791
|
-
if (auraRuntime && typeof auraRuntime.endFrame === 'function') {
|
|
2792
|
-
auraRuntime.endFrame();
|
|
2793
|
-
}
|
|
2794
|
-
} catch (error) {
|
|
2795
|
-
runtimeState.running = false;
|
|
2796
|
-
syncLifecycle();
|
|
2797
|
-
const normalized = normalizeError(
|
|
2798
|
-
error,
|
|
2799
|
-
'web_runtime_bootstrap_failed',
|
|
2800
|
-
'Runtime lifecycle callback failed.',
|
|
2801
|
-
'runtime',
|
|
2802
|
-
true
|
|
2803
|
-
);
|
|
2804
|
-
setState('error', normalized.reasonCode, {
|
|
2805
|
-
reasonCode: normalized.reasonCode,
|
|
2806
|
-
layer: normalized.layer || 'runtime',
|
|
2807
|
-
retryable: normalized.retryable === true,
|
|
2808
|
-
details: normalized.details || {}
|
|
2809
|
-
});
|
|
2810
|
-
return;
|
|
2811
|
-
}
|
|
2812
|
-
|
|
2813
|
-
syncLifecycle();
|
|
2814
|
-
runtimeState.rafHandle = requestFrame(step);
|
|
2815
|
-
}
|
|
2816
|
-
|
|
2817
|
-
runtimeState.rafHandle = requestFrame(step);
|
|
2818
|
-
|
|
2819
|
-
return {
|
|
2820
|
-
getLifecycle,
|
|
2821
|
-
async unmount() {
|
|
2822
|
-
if (runtimeState.disposed === true) {
|
|
2823
|
-
return true;
|
|
2824
|
-
}
|
|
2825
|
-
runtimeState.disposed = true;
|
|
2826
|
-
runtimeState.running = false;
|
|
2827
|
-
if (runtimeState.rafHandle != null) {
|
|
2828
|
-
cancelFrame(runtimeState.rafHandle);
|
|
2829
|
-
runtimeState.rafHandle = null;
|
|
2830
|
-
}
|
|
2831
|
-
if (auraRuntime && typeof auraRuntime.unmount === 'function') {
|
|
2832
|
-
auraRuntime.unmount();
|
|
2833
|
-
}
|
|
2834
|
-
syncLifecycle();
|
|
2835
|
-
return true;
|
|
2836
|
-
}
|
|
2837
|
-
};
|
|
2838
|
-
};
|
|
2839
|
-
}
|
|
2840
|
-
|
|
2841
|
-
function resolveBootstrap() {
|
|
2842
|
-
if (typeof globalRef.__AURA_WEB_BOOTSTRAP__ === 'function') {
|
|
2843
|
-
return globalRef.__AURA_WEB_BOOTSTRAP__;
|
|
2844
|
-
}
|
|
2845
|
-
return createDeterministicBootstrap();
|
|
2846
|
-
}
|
|
2847
|
-
|
|
2848
|
-
function getLifecycleSnapshot() {
|
|
2849
|
-
if (mountedRuntime && typeof mountedRuntime.getLifecycle === 'function') {
|
|
2850
|
-
try {
|
|
2851
|
-
return cloneLifecycle(mountedRuntime.getLifecycle());
|
|
2852
|
-
} catch (_) {
|
|
2853
|
-
return cloneLifecycle(state.lifecycle);
|
|
2854
|
-
}
|
|
2855
|
-
}
|
|
2856
|
-
return cloneLifecycle(state.lifecycle);
|
|
2857
|
-
}
|
|
2858
|
-
|
|
2859
|
-
const loader = {
|
|
2860
|
-
async load(options) {
|
|
2861
|
-
return captureFailure(
|
|
2862
|
-
{
|
|
2863
|
-
reasonCode: 'web_loader_load_failed',
|
|
2864
|
-
message: 'Loader failed to initialize web runtime assets.',
|
|
2865
|
-
layer: 'loader',
|
|
2866
|
-
retryable: true
|
|
2867
|
-
},
|
|
2868
|
-
async function () {
|
|
2869
|
-
const opts = options || {};
|
|
2870
|
-
const rootUrl = typeof opts.rootUrl === 'string' && opts.rootUrl.length > 0
|
|
2871
|
-
? opts.rootUrl.replace(/\\/$/, '')
|
|
2872
|
-
: '.';
|
|
2873
|
-
cachedRootUrl = rootUrl;
|
|
2874
|
-
setState('loading', null, null);
|
|
2875
|
-
|
|
2876
|
-
cachedManifest = await readJson(rootUrl + '/web-build-manifest.json', 'web_manifest_missing', 'web_manifest_parse_failed');
|
|
2877
|
-
cachedRuntimeConfig = await readJson(rootUrl + '/runtime-config.json', 'web_runtime_config_missing', 'web_runtime_config_parse_failed');
|
|
2878
|
-
ensureManifestValid(cachedManifest);
|
|
2879
|
-
ensureRuntimeConfigValid(cachedRuntimeConfig);
|
|
2880
|
-
|
|
2881
|
-
if (!auraRuntime) {
|
|
2882
|
-
auraRuntime = createBrowserAuraSurface(cachedRuntimeConfig);
|
|
2883
|
-
} else if (typeof auraRuntime.setRuntimeConfig === 'function') {
|
|
2884
|
-
auraRuntime.setRuntimeConfig(cachedRuntimeConfig);
|
|
2885
|
-
}
|
|
2886
|
-
if (auraRuntime && typeof auraRuntime.setManifest === 'function') {
|
|
2887
|
-
auraRuntime.setManifest(cachedManifest, cachedRootUrl);
|
|
2888
|
-
}
|
|
2889
|
-
|
|
2890
|
-
const bundleEntry = normalizePath(cachedManifest.entrypoints.bundle);
|
|
2891
|
-
if (bundleEntry.length === 0) {
|
|
2892
|
-
throw createError('web_entrypoint_missing', 'Bundle entrypoint is empty.', 'loader', false, {});
|
|
2893
|
-
}
|
|
2894
|
-
await loadScript(rootUrl + '/' + bundleEntry);
|
|
2895
|
-
setState('loaded', null, null);
|
|
2896
|
-
return true;
|
|
2897
|
-
}
|
|
2898
|
-
);
|
|
2899
|
-
},
|
|
2900
|
-
async mount(target, options) {
|
|
2901
|
-
return captureFailure(
|
|
2902
|
-
{
|
|
2903
|
-
reasonCode: 'web_loader_mount_failed',
|
|
2904
|
-
message: 'Loader mount sequence failed.',
|
|
2905
|
-
layer: 'loader',
|
|
2906
|
-
retryable: true
|
|
2907
|
-
},
|
|
2908
|
-
async function () {
|
|
2909
|
-
if (!cachedManifest || !cachedRuntimeConfig) {
|
|
2910
|
-
await loader.load(options || {});
|
|
2911
|
-
}
|
|
2912
|
-
|
|
2913
|
-
if (mountedRuntime && typeof mountedRuntime.unmount === 'function') {
|
|
2914
|
-
await mountedRuntime.unmount();
|
|
2915
|
-
mountedRuntime = null;
|
|
2916
|
-
}
|
|
2917
|
-
|
|
2918
|
-
setState('mounting', null, null);
|
|
2919
|
-
const opts = options && typeof options === 'object' ? options : {};
|
|
2920
|
-
const targetNode = resolveTarget(target == null ? opts.mount : target);
|
|
2921
|
-
if (!targetNode) {
|
|
2922
|
-
throw createError('web_loader_mount_target_invalid', 'Mount target was not found.', 'loader', false, {});
|
|
2923
|
-
}
|
|
2924
|
-
const canvas = targetNode.querySelector && targetNode.querySelector('canvas')
|
|
2925
|
-
? targetNode.querySelector('canvas')
|
|
2926
|
-
: document.getElementById('aura-canvas');
|
|
2927
|
-
if (!canvas) {
|
|
2928
|
-
throw createError('web_loader_mount_failed', 'Canvas target was not found.', 'loader', true, {});
|
|
2929
|
-
}
|
|
2930
|
-
|
|
2931
|
-
if (!auraRuntime) {
|
|
2932
|
-
auraRuntime = createBrowserAuraSurface(cachedRuntimeConfig || {});
|
|
2933
|
-
}
|
|
2934
|
-
if (auraRuntime && typeof auraRuntime.setManifest === 'function') {
|
|
2935
|
-
auraRuntime.setManifest(cachedManifest || {}, cachedRootUrl);
|
|
2936
|
-
}
|
|
2937
|
-
ensureCapabilityDeclarationSatisfied(
|
|
2938
|
-
cachedRuntimeConfig || {},
|
|
2939
|
-
auraRuntime && auraRuntime.aura ? auraRuntime.aura : globalRef.aura,
|
|
2940
|
-
);
|
|
2941
|
-
if (typeof auraRuntime.mount === 'function') {
|
|
2942
|
-
auraRuntime.mount(canvas, targetNode);
|
|
2943
|
-
}
|
|
2944
|
-
|
|
2945
|
-
const bootstrap = resolveBootstrap();
|
|
2946
|
-
if (typeof bootstrap !== 'function') {
|
|
2947
|
-
throw createError('web_runtime_bootstrap_missing', 'Bundle did not expose required bootstrap function.', 'runtime', false, {});
|
|
2948
|
-
}
|
|
2949
|
-
|
|
2950
|
-
let runtimeResult;
|
|
2951
|
-
try {
|
|
2952
|
-
runtimeResult = await bootstrap({
|
|
2953
|
-
canvas: canvas,
|
|
2954
|
-
runtimeConfig: cachedRuntimeConfig || {},
|
|
2955
|
-
manifest: cachedManifest || {}
|
|
2956
|
-
});
|
|
2957
|
-
} catch (error) {
|
|
2958
|
-
throw normalizeError(
|
|
2959
|
-
error,
|
|
2960
|
-
'web_runtime_bootstrap_failed',
|
|
2961
|
-
'Runtime bootstrap threw an exception.',
|
|
2962
|
-
'runtime',
|
|
2963
|
-
true
|
|
2964
|
-
);
|
|
2965
|
-
}
|
|
2966
|
-
|
|
2967
|
-
if (!runtimeResult || typeof runtimeResult !== 'object') {
|
|
2968
|
-
throw createError('web_runtime_bootstrap_failed', 'Runtime bootstrap returned invalid payload.', 'runtime', false, {});
|
|
2969
|
-
}
|
|
2970
|
-
if (typeof runtimeResult.unmount !== 'function') {
|
|
2971
|
-
runtimeResult.unmount = async function () {
|
|
2972
|
-
return true;
|
|
2973
|
-
};
|
|
2974
|
-
}
|
|
2975
|
-
|
|
2976
|
-
mountedRuntime = runtimeResult;
|
|
2977
|
-
state.lifecycle = getLifecycleSnapshot();
|
|
2978
|
-
setState('mounted', null, null);
|
|
2979
|
-
return true;
|
|
2980
|
-
}
|
|
2981
|
-
);
|
|
2982
|
-
},
|
|
2983
|
-
async unmount() {
|
|
2984
|
-
return captureFailure(
|
|
2985
|
-
{
|
|
2986
|
-
reasonCode: 'web_loader_unmount_failed',
|
|
2987
|
-
message: 'Loader unmount sequence failed.',
|
|
2988
|
-
layer: 'loader',
|
|
2989
|
-
retryable: true
|
|
2990
|
-
},
|
|
2991
|
-
async function () {
|
|
2992
|
-
setState('unmounting', null, null);
|
|
2993
|
-
if (mountedRuntime && typeof mountedRuntime.unmount === 'function') {
|
|
2994
|
-
await mountedRuntime.unmount();
|
|
2995
|
-
}
|
|
2996
|
-
mountedRuntime = null;
|
|
2997
|
-
state.lifecycle = cloneLifecycle(state.lifecycle);
|
|
2998
|
-
state.lifecycle.running = false;
|
|
2999
|
-
setState('unmounted', null, null);
|
|
3000
|
-
return true;
|
|
3001
|
-
}
|
|
3002
|
-
);
|
|
3003
|
-
},
|
|
3004
|
-
getState() {
|
|
3005
|
-
return {
|
|
3006
|
-
phase: state.phase,
|
|
3007
|
-
reasonCode: state.reasonCode,
|
|
3008
|
-
lastError: state.lastError ? { ...state.lastError } : null,
|
|
3009
|
-
lifecycle: getLifecycleSnapshot()
|
|
3010
|
-
};
|
|
3011
|
-
}
|
|
3012
|
-
};
|
|
3013
|
-
|
|
3014
|
-
globalRef.AuraWebLoader = loader;
|
|
3015
|
-
})(typeof window !== 'undefined' ? window : globalThis);
|
|
3016
|
-
`.trim();
|