@auraindustry/aurajs 0.0.6 → 0.1.0
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 +103 -7
- package/benchmarks/perf-thresholds.json +54 -0
- package/package.json +4 -7
- package/src/asset-pack.mjs +5 -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 +4825 -1512
- package/src/commands/project-authoring.mjs +434 -0
- package/src/config.mjs +27 -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 +438 -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 +40 -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 +14 -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 +443 -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 +60 -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 +1187 -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
|
@@ -4,7 +4,7 @@ export const GAME_STATE_SCHEMA_VERSION = 'aurajs.game-state.v1';
|
|
|
4
4
|
|
|
5
5
|
const CANONICAL_TOP_LEVEL_ORDER = ['schemaVersion', 'export', 'state'];
|
|
6
6
|
const CANONICAL_EXPORT_ORDER = ['mode', 'seed', 'frameIndex', 'elapsedSeconds', 'fingerprint', 'capturedAt'];
|
|
7
|
-
const CANONICAL_STATE_SECTION_ORDER = ['globals', 'camera', 'scene3d', 'physics', 'ecs', 'tilemap'];
|
|
7
|
+
const CANONICAL_STATE_SECTION_ORDER = ['globals', 'camera', 'project', 'scene3d', 'physics', 'ecs', 'tilemap'];
|
|
8
8
|
const SUPPORTED_TOP_LEVEL_KEYS = new Set(CANONICAL_TOP_LEVEL_ORDER);
|
|
9
9
|
const SUPPORTED_STATE_SECTION_KEYS = new Set(CANONICAL_STATE_SECTION_ORDER);
|
|
10
10
|
const SUPPORTED_PATCH_MUTATION_OPS = new Set(['set', 'delete']);
|
|
@@ -15,6 +15,7 @@ const DEFAULT_MUTATION_MAX_RUNTIME_MS = 200;
|
|
|
15
15
|
export const STATE_MUTATION_ALLOWLIST_PREFIXES = Object.freeze([
|
|
16
16
|
'/state/globals',
|
|
17
17
|
'/state/camera',
|
|
18
|
+
'/state/project',
|
|
18
19
|
'/state/scene3d',
|
|
19
20
|
'/state/physics',
|
|
20
21
|
'/state/ecs',
|
|
@@ -31,7 +32,7 @@ export const DEFAULT_STATE_MUTATION_GUARDRAILS = Object.freeze({
|
|
|
31
32
|
export function installStateRestoreRuntimeBootstrap(aura) {
|
|
32
33
|
const schemaVersion = 'aurajs.game-state.v1';
|
|
33
34
|
const knownTopLevel = Object.freeze(['schemaVersion', 'export', 'state']);
|
|
34
|
-
const knownStateSections = Object.freeze(['globals', 'camera', 'scene3d', 'physics', 'ecs', 'tilemap']);
|
|
35
|
+
const knownStateSections = Object.freeze(['globals', 'camera', 'project', 'scene3d', 'physics', 'ecs', 'tilemap']);
|
|
35
36
|
|
|
36
37
|
const isObject = (value) => (
|
|
37
38
|
!!value
|
|
@@ -49,7 +50,7 @@ export function installStateRestoreRuntimeBootstrap(aura) {
|
|
|
49
50
|
}
|
|
50
51
|
if (isObject(value)) {
|
|
51
52
|
const out = {};
|
|
52
|
-
for (const key of Object.keys(value).sort(
|
|
53
|
+
for (const key of Object.keys(value).sort()) {
|
|
53
54
|
const next = sanitizeJsonValueLocal(value[key]);
|
|
54
55
|
if (next === undefined) continue;
|
|
55
56
|
out[key] = next;
|
|
@@ -61,7 +62,7 @@ export function installStateRestoreRuntimeBootstrap(aura) {
|
|
|
61
62
|
const sanitizeObjectLocal = (value) => {
|
|
62
63
|
const out = {};
|
|
63
64
|
const source = isObject(value) ? value : {};
|
|
64
|
-
for (const key of Object.keys(source).sort(
|
|
65
|
+
for (const key of Object.keys(source).sort()) {
|
|
65
66
|
const next = sanitizeJsonValueLocal(source[key]);
|
|
66
67
|
if (next === undefined) continue;
|
|
67
68
|
out[key] = next;
|
|
@@ -82,9 +83,33 @@ export function installStateRestoreRuntimeBootstrap(aura) {
|
|
|
82
83
|
};
|
|
83
84
|
const resolveGlobalsMapLocal = () => {
|
|
84
85
|
const storage = aura?.storage && typeof aura.storage === 'object' ? aura.storage : null;
|
|
86
|
+
if (storage && typeof storage.save === 'function' && typeof storage.set !== 'function') {
|
|
87
|
+
storage.set = (key, value) => storage.save(key, value);
|
|
88
|
+
}
|
|
89
|
+
if (storage && typeof storage.load === 'function' && typeof storage.get !== 'function') {
|
|
90
|
+
storage.get = (key, fallback = null) => {
|
|
91
|
+
const value = storage.load(key);
|
|
92
|
+
return value == null ? fallback : value;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
85
95
|
if (storage && storage._store instanceof Map) {
|
|
86
96
|
return storage._store;
|
|
87
97
|
}
|
|
98
|
+
if (storage && typeof storage.keys === 'function' && typeof storage.load === 'function') {
|
|
99
|
+
const map = new Map();
|
|
100
|
+
try {
|
|
101
|
+
const keys = storage.keys();
|
|
102
|
+
if (Array.isArray(keys)) {
|
|
103
|
+
for (const key of [...keys].map((entry) => String(entry)).sort()) {
|
|
104
|
+
map.set(key, sanitizeJsonValueLocal(storage.load(key)));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
} catch {}
|
|
108
|
+
if (aura && typeof aura === 'object') {
|
|
109
|
+
aura.__gameStateGlobals = map;
|
|
110
|
+
}
|
|
111
|
+
return map;
|
|
112
|
+
}
|
|
88
113
|
if (aura && aura.__gameStateGlobals instanceof Map) {
|
|
89
114
|
return aura.__gameStateGlobals;
|
|
90
115
|
}
|
|
@@ -101,10 +126,20 @@ export function installStateRestoreRuntimeBootstrap(aura) {
|
|
|
101
126
|
const globalsMap = resolveGlobalsMapLocal();
|
|
102
127
|
globalsMap.clear();
|
|
103
128
|
const normalized = sanitizeObjectLocal(sectionValue);
|
|
129
|
+
const storage = aura?.storage && typeof aura.storage === 'object' ? aura.storage : null;
|
|
130
|
+
if (storage && typeof storage.keys === 'function' && typeof storage.delete === 'function') {
|
|
131
|
+
try {
|
|
132
|
+
const existingKeys = storage.keys();
|
|
133
|
+
if (Array.isArray(existingKeys)) {
|
|
134
|
+
for (const key of existingKeys) {
|
|
135
|
+
storage.delete(key);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
} catch {}
|
|
139
|
+
}
|
|
104
140
|
for (const [key, value] of Object.entries(normalized)) {
|
|
105
141
|
globalsMap.set(key, value);
|
|
106
142
|
}
|
|
107
|
-
const storage = aura?.storage && typeof aura.storage === 'object' ? aura.storage : null;
|
|
108
143
|
if (storage && typeof storage.set === 'function') {
|
|
109
144
|
for (const [key, value] of globalsMap.entries()) {
|
|
110
145
|
storage.set(key, value);
|
|
@@ -222,17 +257,175 @@ export function installStateRestoreRuntimeBootstrap(aura) {
|
|
|
222
257
|
state: collectCanonicalStateFromPayloadLocal(payload.state),
|
|
223
258
|
};
|
|
224
259
|
};
|
|
260
|
+
const mapToObjectLocal = (map) => {
|
|
261
|
+
const out = {};
|
|
262
|
+
const rows = [...map.entries()].map(([key, value]) => [String(key), sanitizeJsonValueLocal(value)]);
|
|
263
|
+
rows.sort((a, b) => (
|
|
264
|
+
a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0
|
|
265
|
+
));
|
|
266
|
+
for (const [key, value] of rows) {
|
|
267
|
+
out[key] = value;
|
|
268
|
+
}
|
|
269
|
+
return out;
|
|
270
|
+
};
|
|
271
|
+
const collectCameraSnapshotLocal = () => {
|
|
272
|
+
if (!aura?.camera || typeof aura.camera !== 'object') {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
let source = null;
|
|
277
|
+
if (typeof aura.camera.getState === 'function') {
|
|
278
|
+
try {
|
|
279
|
+
source = aura.camera.getState();
|
|
280
|
+
} catch {
|
|
281
|
+
source = null;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (!isObject(source)) {
|
|
286
|
+
source = {
|
|
287
|
+
x: aura.camera.x,
|
|
288
|
+
y: aura.camera.y,
|
|
289
|
+
zoom: aura.camera.zoom,
|
|
290
|
+
rotation: aura.camera.rotation,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (!isObject(source)) {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const camera = {};
|
|
299
|
+
if (Number.isFinite(source.x)) camera.x = Number(source.x);
|
|
300
|
+
if (Number.isFinite(source.y)) camera.y = Number(source.y);
|
|
301
|
+
if (Number.isFinite(source.zoom) && source.zoom > 0) camera.zoom = Number(source.zoom);
|
|
302
|
+
if (Number.isFinite(source.rotation)) camera.rotation = Number(source.rotation);
|
|
303
|
+
if (typeof source.following === 'boolean') camera.following = source.following;
|
|
304
|
+
if (Number.isInteger(source.activeEffects) && source.activeEffects >= 0) {
|
|
305
|
+
camera.activeEffects = Number(source.activeEffects);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return Object.keys(camera).length > 0 ? camera : null;
|
|
309
|
+
};
|
|
310
|
+
const collectObjectSectionLocal = (section) => {
|
|
311
|
+
if (!section || typeof section !== 'object') {
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
if (typeof section.getState === 'function') {
|
|
315
|
+
try {
|
|
316
|
+
const state = section.getState();
|
|
317
|
+
if (state && typeof state === 'object') {
|
|
318
|
+
return state;
|
|
319
|
+
}
|
|
320
|
+
} catch {
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return null;
|
|
325
|
+
};
|
|
326
|
+
const collectStateSectionsLocal = () => collectCanonicalStateFromPayloadLocal({
|
|
327
|
+
globals: mapToObjectLocal(resolveGlobalsMapLocal()),
|
|
328
|
+
camera: collectCameraSnapshotLocal(),
|
|
329
|
+
project: collectObjectSectionLocal(aura?.project),
|
|
330
|
+
scene3d: collectObjectSectionLocal(aura?.scene3d),
|
|
331
|
+
physics: collectObjectSectionLocal(aura?.physics),
|
|
332
|
+
ecs: collectObjectSectionLocal(aura?.ecs),
|
|
333
|
+
tilemap: collectObjectSectionLocal(aura?.tilemap),
|
|
334
|
+
});
|
|
335
|
+
const normalizeIntLocal = (value, fallback = 0) => (
|
|
336
|
+
Number.isInteger(Number(value)) && Number(value) >= 0
|
|
337
|
+
? Number(value)
|
|
338
|
+
: Number(fallback)
|
|
339
|
+
);
|
|
340
|
+
const normalizeModeLocal = (value) => {
|
|
341
|
+
const normalized = typeof value === 'string' ? value.trim().toLowerCase() : '';
|
|
342
|
+
if (normalized === 'headless' || normalized === 'shim') {
|
|
343
|
+
return normalized;
|
|
344
|
+
}
|
|
345
|
+
return 'native';
|
|
346
|
+
};
|
|
347
|
+
const normalizeElapsedSecondsLocal = (value) => (
|
|
348
|
+
Number.isFinite(Number(value)) && Number(value) >= 0
|
|
349
|
+
? Number(value)
|
|
350
|
+
: 0
|
|
351
|
+
);
|
|
352
|
+
const normalizeCapturedAtLocal = (value) => (
|
|
353
|
+
typeof value === 'string' && value.trim()
|
|
354
|
+
? value.trim()
|
|
355
|
+
: new Date().toISOString()
|
|
356
|
+
);
|
|
357
|
+
const stableStringifyLocal = (value) => JSON.stringify(sanitizeJsonValueLocal(value));
|
|
358
|
+
const hashHex64Local = (value) => {
|
|
359
|
+
const text = String(value || '');
|
|
360
|
+
let hash = 2166136261;
|
|
361
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
362
|
+
hash ^= text.charCodeAt(i);
|
|
363
|
+
hash = Math.imul(hash, 16777619);
|
|
364
|
+
}
|
|
365
|
+
const chunk = (hash >>> 0).toString(16).padStart(8, '0');
|
|
366
|
+
return chunk.repeat(8);
|
|
367
|
+
};
|
|
368
|
+
const orderExportPayloadLocal = (payload) => {
|
|
369
|
+
const orderedExport = {
|
|
370
|
+
mode: payload.export.mode,
|
|
371
|
+
seed: payload.export.seed,
|
|
372
|
+
frameIndex: payload.export.frameIndex,
|
|
373
|
+
elapsedSeconds: payload.export.elapsedSeconds,
|
|
374
|
+
fingerprint: payload.export.fingerprint,
|
|
375
|
+
capturedAt: payload.export.capturedAt,
|
|
376
|
+
};
|
|
377
|
+
return {
|
|
378
|
+
schemaVersion: payload.schemaVersion,
|
|
379
|
+
export: orderedExport,
|
|
380
|
+
state: payload.state,
|
|
381
|
+
};
|
|
382
|
+
};
|
|
383
|
+
const exportPayload = (options = {}) => {
|
|
384
|
+
const state = collectStateSectionsLocal();
|
|
385
|
+
const payload = {
|
|
386
|
+
schemaVersion,
|
|
387
|
+
export: {
|
|
388
|
+
mode: normalizeModeLocal(options.mode),
|
|
389
|
+
seed: normalizeIntLocal(options.seed, 0),
|
|
390
|
+
frameIndex: normalizeIntLocal(options.frameIndex, 0),
|
|
391
|
+
elapsedSeconds: normalizeElapsedSecondsLocal(options.elapsedSeconds),
|
|
392
|
+
fingerprint: hashHex64Local(stableStringifyLocal(state)),
|
|
393
|
+
capturedAt: normalizeCapturedAtLocal(options.capturedAt),
|
|
394
|
+
},
|
|
395
|
+
state,
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
return {
|
|
399
|
+
ok: true,
|
|
400
|
+
reasonCode: 'state_export_ok',
|
|
401
|
+
payload: orderExportPayloadLocal(payload),
|
|
402
|
+
};
|
|
403
|
+
};
|
|
225
404
|
|
|
226
405
|
if (!aura || typeof aura !== 'object') {
|
|
227
406
|
return {
|
|
407
|
+
export() {
|
|
408
|
+
return { ok: false, reasonCode: 'state_export_failed', detail: 'aura runtime unavailable' };
|
|
409
|
+
},
|
|
410
|
+
exportState() {
|
|
411
|
+
return { ok: false, reasonCode: 'state_export_failed', detail: 'aura runtime unavailable' };
|
|
412
|
+
},
|
|
228
413
|
apply() {
|
|
229
414
|
return { ok: false, reasonCode: 'invalid_schema_payload', detail: 'aura runtime unavailable' };
|
|
230
415
|
},
|
|
416
|
+
applyState() {
|
|
417
|
+
return { ok: false, reasonCode: 'invalid_schema_payload', detail: 'aura runtime unavailable' };
|
|
418
|
+
},
|
|
231
419
|
};
|
|
232
420
|
}
|
|
233
421
|
|
|
234
422
|
const stateNamespace = aura.state && typeof aura.state === 'object' ? aura.state : {};
|
|
235
|
-
if (
|
|
423
|
+
if (
|
|
424
|
+
typeof stateNamespace.apply === 'function'
|
|
425
|
+
&& typeof stateNamespace.applyState === 'function'
|
|
426
|
+
&& typeof stateNamespace.export === 'function'
|
|
427
|
+
&& typeof stateNamespace.exportState === 'function'
|
|
428
|
+
) {
|
|
236
429
|
stateNamespace.schemaVersion = schemaVersion;
|
|
237
430
|
aura.state = stateNamespace;
|
|
238
431
|
return stateNamespace;
|
|
@@ -274,6 +467,12 @@ export function installStateRestoreRuntimeBootstrap(aura) {
|
|
|
274
467
|
};
|
|
275
468
|
|
|
276
469
|
stateNamespace.schemaVersion = schemaVersion;
|
|
470
|
+
if (typeof stateNamespace.export !== 'function') {
|
|
471
|
+
stateNamespace.export = exportPayload;
|
|
472
|
+
}
|
|
473
|
+
if (typeof stateNamespace.exportState !== 'function') {
|
|
474
|
+
stateNamespace.exportState = exportPayload;
|
|
475
|
+
}
|
|
277
476
|
if (typeof stateNamespace.apply !== 'function') {
|
|
278
477
|
stateNamespace.apply = applyPayload;
|
|
279
478
|
}
|
|
@@ -665,6 +864,7 @@ function collectStateSections(aura) {
|
|
|
665
864
|
const raw = {
|
|
666
865
|
globals,
|
|
667
866
|
camera,
|
|
867
|
+
project: collectObjectSection(aura.project),
|
|
668
868
|
scene3d: collectObjectSection(aura.scene3d),
|
|
669
869
|
physics: collectObjectSection(aura.physics),
|
|
670
870
|
ecs: collectObjectSection(aura.ecs),
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import vm from 'node:vm';
|
|
4
|
+
|
|
5
|
+
import { bundleProject } from './bundler.mjs';
|
|
6
|
+
import {
|
|
7
|
+
HeadlessTestError,
|
|
8
|
+
createHeadlessAura,
|
|
9
|
+
createRuntimeContext,
|
|
10
|
+
executeSetup,
|
|
11
|
+
executeFrameSteps,
|
|
12
|
+
} from './headless-test.mjs';
|
|
13
|
+
|
|
14
|
+
function createHeadlessActionTestState() {
|
|
15
|
+
return {
|
|
16
|
+
failures: [],
|
|
17
|
+
passes: 0,
|
|
18
|
+
drawCalls: 0,
|
|
19
|
+
audioCalls: 0,
|
|
20
|
+
logs: [],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function runHeadlessActionSchema(options = {}) {
|
|
25
|
+
const runtime = await bootHeadlessActionRuntime(options, '.aura/test/action-schema.bundle.js');
|
|
26
|
+
const schemaResult = resolveActionSchemaResult(runtime.aura);
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
ok: true,
|
|
30
|
+
entryFile: runtime.entryFile,
|
|
31
|
+
bundle: runtime.bundle,
|
|
32
|
+
frames: 0,
|
|
33
|
+
width: runtime.width,
|
|
34
|
+
height: runtime.height,
|
|
35
|
+
schemaResult,
|
|
36
|
+
passes: runtime.testState.passes,
|
|
37
|
+
drawCalls: runtime.testState.drawCalls,
|
|
38
|
+
audioCalls: runtime.testState.audioCalls,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function runHeadlessActionRun(options = {}) {
|
|
43
|
+
const runtime = await bootHeadlessActionRuntime(options, '.aura/test/action-run.bundle.js');
|
|
44
|
+
const frames = options.frames ?? 0;
|
|
45
|
+
const request = options.request;
|
|
46
|
+
let seedStateApplyResult = null;
|
|
47
|
+
|
|
48
|
+
if (!request || typeof request !== 'object' || Array.isArray(request)) {
|
|
49
|
+
throw new HeadlessTestError('Headless action run failed: request must be an object.');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (options.statePayload != null) {
|
|
53
|
+
if (!runtime.aura.state || typeof runtime.aura.state.apply !== 'function') {
|
|
54
|
+
throw new HeadlessTestError('Headless action run failed: aura.state.apply hook is unavailable.');
|
|
55
|
+
}
|
|
56
|
+
seedStateApplyResult = runtime.aura.state.apply(options.statePayload);
|
|
57
|
+
if (!seedStateApplyResult || typeof seedStateApplyResult !== 'object') {
|
|
58
|
+
throw new HeadlessTestError('Headless action run failed: aura.state.apply returned invalid result.');
|
|
59
|
+
}
|
|
60
|
+
if (seedStateApplyResult.ok !== true) {
|
|
61
|
+
return {
|
|
62
|
+
ok: true,
|
|
63
|
+
entryFile: runtime.entryFile,
|
|
64
|
+
bundle: runtime.bundle,
|
|
65
|
+
frames,
|
|
66
|
+
width: runtime.width,
|
|
67
|
+
height: runtime.height,
|
|
68
|
+
actionResult: null,
|
|
69
|
+
stateResult: null,
|
|
70
|
+
seedStateApplyResult,
|
|
71
|
+
passes: runtime.testState.passes,
|
|
72
|
+
drawCalls: runtime.testState.drawCalls,
|
|
73
|
+
audioCalls: runtime.testState.audioCalls,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const actionNs = runtime.aura.action && typeof runtime.aura.action === 'object'
|
|
79
|
+
? runtime.aura.action
|
|
80
|
+
: null;
|
|
81
|
+
if (!actionNs || typeof actionNs.run !== 'function') {
|
|
82
|
+
throw new HeadlessTestError('Headless action run failed: aura.action.run hook is unavailable.');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let actionResult;
|
|
86
|
+
try {
|
|
87
|
+
actionResult = await Promise.resolve(actionNs.run(request));
|
|
88
|
+
} catch (error) {
|
|
89
|
+
throw new HeadlessTestError(`Headless action run failed: ${error.message}`, {
|
|
90
|
+
stack: error.stack,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
let stateResult = null;
|
|
95
|
+
if (options.includeState === true || frames > 0) {
|
|
96
|
+
if (!runtime.aura.state || typeof runtime.aura.state.exportState !== 'function') {
|
|
97
|
+
throw new HeadlessTestError('Headless action run failed: aura.state.exportState hook is unavailable.');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
await executeFrameSteps(runtime.aura, frames);
|
|
101
|
+
|
|
102
|
+
stateResult = runtime.aura.state.exportState({
|
|
103
|
+
mode: options.mode,
|
|
104
|
+
seed: options.seed,
|
|
105
|
+
frameIndex: options.frameIndex ?? frames,
|
|
106
|
+
elapsedSeconds: options.elapsedSeconds,
|
|
107
|
+
capturedAt: options.capturedAt ?? null,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
ok: true,
|
|
113
|
+
entryFile: runtime.entryFile,
|
|
114
|
+
bundle: runtime.bundle,
|
|
115
|
+
frames,
|
|
116
|
+
width: runtime.width,
|
|
117
|
+
height: runtime.height,
|
|
118
|
+
actionResult,
|
|
119
|
+
stateResult,
|
|
120
|
+
seedStateApplyResult,
|
|
121
|
+
passes: runtime.testState.passes,
|
|
122
|
+
drawCalls: runtime.testState.drawCalls,
|
|
123
|
+
audioCalls: runtime.testState.audioCalls,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function bootHeadlessActionRuntime(options, outFile) {
|
|
128
|
+
const projectRoot = resolve(options.projectRoot || process.cwd());
|
|
129
|
+
const entryFile = resolve(projectRoot, options.file || 'src/main.js');
|
|
130
|
+
const width = options.width ?? 1280;
|
|
131
|
+
const height = options.height ?? 720;
|
|
132
|
+
|
|
133
|
+
if (!existsSync(entryFile)) {
|
|
134
|
+
throw new HeadlessTestError(`Action entry file not found: ${entryFile}`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const bundle = bundleProject({
|
|
138
|
+
projectRoot,
|
|
139
|
+
mode: 'test',
|
|
140
|
+
entryFile,
|
|
141
|
+
outFile: resolve(projectRoot, outFile),
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const testState = createHeadlessActionTestState();
|
|
145
|
+
const aura = createHeadlessAura({ width, height, testState });
|
|
146
|
+
const context = vm.createContext(createRuntimeContext(aura, testState));
|
|
147
|
+
|
|
148
|
+
const source = readFileSync(bundle.outFile, 'utf8');
|
|
149
|
+
const script = new vm.Script(source, {
|
|
150
|
+
filename: bundle.outFile,
|
|
151
|
+
displayErrors: true,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
script.runInContext(context, { timeout: 5000 });
|
|
156
|
+
await executeSetup(aura);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
throw new HeadlessTestError(`Headless action execution failed: ${error.message}`, {
|
|
159
|
+
stack: error.stack,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
aura,
|
|
165
|
+
bundle,
|
|
166
|
+
entryFile,
|
|
167
|
+
width,
|
|
168
|
+
height,
|
|
169
|
+
testState,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function resolveActionSchemaResult(aura) {
|
|
174
|
+
const actionNs = aura.action && typeof aura.action === 'object' ? aura.action : null;
|
|
175
|
+
if (!actionNs || typeof actionNs.getSchema !== 'function') {
|
|
176
|
+
throw new HeadlessTestError('Headless action schema failed: aura.action.getSchema hook is unavailable.');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
return actionNs.getSchema();
|
|
181
|
+
} catch (error) {
|
|
182
|
+
throw new HeadlessTestError(`Headless action schema failed: ${error.message}`, {
|
|
183
|
+
stack: error.stack,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|