@relu-interactives/spatial-ecs 0.2.20 → 0.2.22

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.
Files changed (51) hide show
  1. package/dist/{System-BjwOBx81.d.cts → System-CYWZ_Zx5.d.cts} +9 -4
  2. package/dist/{System-BjwOBx81.d.ts → System-CYWZ_Zx5.d.ts} +9 -4
  3. package/dist/{Video-B8yVI1tF.d.cts → Video-C1IOat7L.d.ts} +38 -9
  4. package/dist/{Video-B9z5AtIf.d.ts → Video-ppAXaKt0.d.cts} +38 -9
  5. package/dist/{chunk-HUHN6IFD.js → chunk-52CHDPRQ.js} +118 -92
  6. package/dist/chunk-52CHDPRQ.js.map +1 -0
  7. package/dist/{chunk-67MFQDHX.js → chunk-GZ2NKSMV.js} +609 -90
  8. package/dist/chunk-GZ2NKSMV.js.map +1 -0
  9. package/dist/{chunk-Z6OMYEXU.js → chunk-JHCPRVBC.js} +34 -5
  10. package/dist/chunk-JHCPRVBC.js.map +1 -0
  11. package/dist/{chunk-DY4ETMP2.js → chunk-WKGCC7YL.js} +3 -3
  12. package/dist/{chunk-DY4ETMP2.js.map → chunk-WKGCC7YL.js.map} +1 -1
  13. package/dist/components/index.cjs +31 -2
  14. package/dist/components/index.cjs.map +1 -1
  15. package/dist/components/index.d.cts +3 -3
  16. package/dist/components/index.d.ts +3 -3
  17. package/dist/components/index.js +1 -1
  18. package/dist/docs/guide/authoring-a-behaviour.md +3 -40
  19. package/dist/docs/guide/authoring-a-script-object.md +102 -0
  20. package/dist/docs/guide/behaviour-lifecycle.md +4 -4
  21. package/dist/docs/guide/prefabs.md +24 -5
  22. package/dist/docs/guide/spawning/script-object.md +36 -0
  23. package/dist/docs/guide/systems/_sidebar.json +4 -0
  24. package/dist/docs/guide/systems/script-behaviour-system.md +1 -17
  25. package/dist/docs/guide/systems/script-object-system.md +44 -0
  26. package/dist/factories/index.cjs +164 -117
  27. package/dist/factories/index.cjs.map +1 -1
  28. package/dist/factories/index.d.cts +5 -3
  29. package/dist/factories/index.d.ts +5 -3
  30. package/dist/factories/index.js +3 -3
  31. package/dist/{index-LHLKpJhZ.d.cts → index-Cu2Pt7wN.d.cts} +33 -14
  32. package/dist/{index-BBI2YdCu.d.ts → index-DdiWu1b6.d.ts} +33 -14
  33. package/dist/index.cjs +1132 -302
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +219 -32
  36. package/dist/index.d.ts +219 -32
  37. package/dist/index.js +254 -11
  38. package/dist/index.js.map +1 -1
  39. package/dist/systems/index.cjs +429 -43
  40. package/dist/systems/index.cjs.map +1 -1
  41. package/dist/systems/index.d.cts +44 -3
  42. package/dist/systems/index.d.ts +44 -3
  43. package/dist/systems/index.js +3 -3
  44. package/dist/types.d.cts +1 -1
  45. package/dist/types.d.ts +1 -1
  46. package/dist/worldSnapshotUtils.d.cts +1 -1
  47. package/dist/worldSnapshotUtils.d.ts +1 -1
  48. package/package.json +1 -1
  49. package/dist/chunk-67MFQDHX.js.map +0 -1
  50. package/dist/chunk-HUHN6IFD.js.map +0 -1
  51. package/dist/chunk-Z6OMYEXU.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var THREE35 = require('three');
3
+ var THREE36 = require('three');
4
4
  var SkeletonUtils_js = require('three/examples/jsm/utils/SkeletonUtils.js');
5
5
  var RectAreaLightHelper_js = require('three/examples/jsm/helpers/RectAreaLightHelper.js');
6
6
  var DRACOLoader_js = require('three/examples/jsm/loaders/DRACOLoader.js');
@@ -39,7 +39,7 @@ function _interopNamespace(e) {
39
39
  return Object.freeze(n);
40
40
  }
41
41
 
42
- var THREE35__namespace = /*#__PURE__*/_interopNamespace(THREE35);
42
+ var THREE36__namespace = /*#__PURE__*/_interopNamespace(THREE36);
43
43
 
44
44
  var __defProp = Object.defineProperty;
45
45
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
@@ -593,14 +593,14 @@ var _AnimationComponent = class _AnimationComponent extends Component {
593
593
  return;
594
594
  }
595
595
  this.importedClips = clips.map((entry) => {
596
- if (entry instanceof THREE35__namespace.AnimationClip) {
596
+ if (entry instanceof THREE36__namespace.AnimationClip) {
597
597
  return { clip: entry, sourceUrl: null };
598
598
  }
599
599
  if (!entry || typeof entry !== "object") {
600
600
  return null;
601
601
  }
602
602
  const candidate = entry;
603
- if (!(candidate.clip instanceof THREE35__namespace.AnimationClip)) {
603
+ if (!(candidate.clip instanceof THREE36__namespace.AnimationClip)) {
604
604
  return null;
605
605
  }
606
606
  return {
@@ -808,11 +808,11 @@ function normalizeDistanceModel(distanceModel) {
808
808
  }
809
809
  __name(normalizeDistanceModel, "normalizeDistanceModel");
810
810
  function createConfiguredAudio(listener, options) {
811
- const sound = options.positional ? new THREE35__namespace.PositionalAudio(listener) : new THREE35__namespace.Audio(listener);
811
+ const sound = options.positional ? new THREE36__namespace.PositionalAudio(listener) : new THREE36__namespace.Audio(listener);
812
812
  sound.setLoop(options.loop);
813
813
  sound.setVolume(options.volume);
814
814
  sound.setPlaybackRate(options.pitch);
815
- if (sound instanceof THREE35__namespace.PositionalAudio) {
815
+ if (sound instanceof THREE36__namespace.PositionalAudio) {
816
816
  sound.setRefDistance(options.refDistance);
817
817
  sound.setDistanceModel(normalizeDistanceModel(options.distanceModel));
818
818
  sound.setRolloffFactor(options.rolloffFactor);
@@ -822,16 +822,16 @@ function createConfiguredAudio(listener, options) {
822
822
  __name(createConfiguredAudio, "createConfiguredAudio");
823
823
  function createAudioEditorHelper() {
824
824
  if (typeof document === "undefined") {
825
- const geometry = new THREE35__namespace.EdgesGeometry(
826
- new THREE35__namespace.OctahedronGeometry(0.22, 0)
825
+ const geometry = new THREE36__namespace.EdgesGeometry(
826
+ new THREE36__namespace.OctahedronGeometry(0.22, 0)
827
827
  );
828
- const material2 = new THREE35__namespace.LineBasicMaterial({
828
+ const material2 = new THREE36__namespace.LineBasicMaterial({
829
829
  color: "#8bc8ff",
830
830
  transparent: true,
831
831
  opacity: 0.95,
832
832
  depthTest: false
833
833
  });
834
- const fallback = new THREE35__namespace.LineSegments(geometry, material2);
834
+ const fallback = new THREE36__namespace.LineSegments(geometry, material2);
835
835
  fallback.renderOrder = 10;
836
836
  fallback.userData.ecsHelper = true;
837
837
  fallback.visible = false;
@@ -843,7 +843,7 @@ function createAudioEditorHelper() {
843
843
  canvas.height = size;
844
844
  const ctx = canvas.getContext("2d");
845
845
  if (!ctx) {
846
- return new THREE35__namespace.Object3D();
846
+ return new THREE36__namespace.Object3D();
847
847
  }
848
848
  ctx.clearRect(0, 0, size, size);
849
849
  ctx.fillStyle = "rgba(27, 35, 52, 0.9)";
@@ -874,14 +874,14 @@ function createAudioEditorHelper() {
874
874
  ctx.beginPath();
875
875
  ctx.arc(56, 48, 16, -0.8, 0.8);
876
876
  ctx.stroke();
877
- const texture = new THREE35__namespace.CanvasTexture(canvas);
877
+ const texture = new THREE36__namespace.CanvasTexture(canvas);
878
878
  texture.needsUpdate = true;
879
- const material = new THREE35__namespace.SpriteMaterial({
879
+ const material = new THREE36__namespace.SpriteMaterial({
880
880
  map: texture,
881
881
  transparent: true,
882
882
  depthTest: false
883
883
  });
884
- const helper = new THREE35__namespace.Sprite(material);
884
+ const helper = new THREE36__namespace.Sprite(material);
885
885
  helper.scale.set(0.68, 0.68, 0.68);
886
886
  helper.renderOrder = 10;
887
887
  helper.userData.ecsHelper = true;
@@ -915,7 +915,7 @@ var DEFAULT_ORTHO_TOP = 5;
915
915
  var DEFAULT_ORTHO_BOTTOM = -5;
916
916
  var DEFAULT_ZOOM = 1;
917
917
  function inferProjection(camera) {
918
- if (camera instanceof THREE35__namespace.OrthographicCamera) {
918
+ if (camera instanceof THREE36__namespace.OrthographicCamera) {
919
919
  return "orthographic";
920
920
  }
921
921
  return "perspective";
@@ -936,7 +936,7 @@ function readCameraFar(camera) {
936
936
  }
937
937
  __name(readCameraFar, "readCameraFar");
938
938
  function inferFov(camera) {
939
- if (camera instanceof THREE35__namespace.PerspectiveCamera && Number.isFinite(camera.fov)) {
939
+ if (camera instanceof THREE36__namespace.PerspectiveCamera && Number.isFinite(camera.fov)) {
940
940
  return camera.fov;
941
941
  }
942
942
  return DEFAULT_FOV;
@@ -959,28 +959,28 @@ function inferFar(camera) {
959
959
  }
960
960
  __name(inferFar, "inferFar");
961
961
  function inferOrthoLeft(camera) {
962
- if (camera instanceof THREE35__namespace.OrthographicCamera && Number.isFinite(camera.left)) {
962
+ if (camera instanceof THREE36__namespace.OrthographicCamera && Number.isFinite(camera.left)) {
963
963
  return camera.left;
964
964
  }
965
965
  return DEFAULT_ORTHO_LEFT;
966
966
  }
967
967
  __name(inferOrthoLeft, "inferOrthoLeft");
968
968
  function inferOrthoRight(camera) {
969
- if (camera instanceof THREE35__namespace.OrthographicCamera && Number.isFinite(camera.right)) {
969
+ if (camera instanceof THREE36__namespace.OrthographicCamera && Number.isFinite(camera.right)) {
970
970
  return camera.right;
971
971
  }
972
972
  return DEFAULT_ORTHO_RIGHT;
973
973
  }
974
974
  __name(inferOrthoRight, "inferOrthoRight");
975
975
  function inferOrthoTop(camera) {
976
- if (camera instanceof THREE35__namespace.OrthographicCamera && Number.isFinite(camera.top)) {
976
+ if (camera instanceof THREE36__namespace.OrthographicCamera && Number.isFinite(camera.top)) {
977
977
  return camera.top;
978
978
  }
979
979
  return DEFAULT_ORTHO_TOP;
980
980
  }
981
981
  __name(inferOrthoTop, "inferOrthoTop");
982
982
  function inferOrthoBottom(camera) {
983
- if (camera instanceof THREE35__namespace.OrthographicCamera && Number.isFinite(camera.bottom)) {
983
+ if (camera instanceof THREE36__namespace.OrthographicCamera && Number.isFinite(camera.bottom)) {
984
984
  return camera.bottom;
985
985
  }
986
986
  return DEFAULT_ORTHO_BOTTOM;
@@ -996,7 +996,7 @@ __name(inferZoom, "inferZoom");
996
996
  var _CameraComponent = class _CameraComponent extends Component {
997
997
  constructor(payload = {}) {
998
998
  super();
999
- this.camera = payload.camera ?? new THREE35__namespace.PerspectiveCamera();
999
+ this.camera = payload.camera ?? new THREE36__namespace.PerspectiveCamera();
1000
1000
  this.type = payload.type ?? "3d";
1001
1001
  this.isDefault = typeof payload.isDefault === "boolean" ? payload.isDefault : false;
1002
1002
  this.projection = payload.projection ?? inferProjection(payload.camera);
@@ -1027,7 +1027,7 @@ var Object3DRef = _Object3DRef;
1027
1027
  // core/factories/components/CameraFactory.ts
1028
1028
  function createCameraComponent(world, entityId, payload = {}) {
1029
1029
  const object = world.getComponent(entityId, Object3DRef)?.object;
1030
- const objectCamera = object instanceof THREE35__namespace.Camera ? object : void 0;
1030
+ const objectCamera = object instanceof THREE36__namespace.Camera ? object : void 0;
1031
1031
  const component = new CameraComponent({
1032
1032
  ...payload,
1033
1033
  camera: payload.camera ?? objectCamera
@@ -1588,15 +1588,15 @@ function createValueState(light) {
1588
1588
  castShadow: light.castShadow ?? false,
1589
1589
  frustumCulling: light.frustumCulled
1590
1590
  };
1591
- if (light instanceof THREE35__namespace.PointLight) {
1591
+ if (light instanceof THREE36__namespace.PointLight) {
1592
1592
  base.distance = light.distance;
1593
1593
  base.decay = light.decay;
1594
- } else if (light instanceof THREE35__namespace.SpotLight) {
1594
+ } else if (light instanceof THREE36__namespace.SpotLight) {
1595
1595
  base.distance = light.distance;
1596
1596
  base.decay = light.decay;
1597
1597
  base.angle = light.angle;
1598
1598
  base.penumbra = light.penumbra;
1599
- } else if (light instanceof THREE35__namespace.RectAreaLight) {
1599
+ } else if (light instanceof THREE36__namespace.RectAreaLight) {
1600
1600
  base.width = light.width;
1601
1601
  base.height = light.height;
1602
1602
  }
@@ -1639,13 +1639,13 @@ function toHexColor2(value, fallback) {
1639
1639
  }
1640
1640
  __name(toHexColor2, "toHexColor");
1641
1641
  function getMaterialType(material) {
1642
- if (material instanceof THREE35__namespace.MeshPhysicalMaterial) {
1642
+ if (material instanceof THREE36__namespace.MeshPhysicalMaterial) {
1643
1643
  return "physical";
1644
1644
  }
1645
- if (material instanceof THREE35__namespace.MeshPhongMaterial) {
1645
+ if (material instanceof THREE36__namespace.MeshPhongMaterial) {
1646
1646
  return "phong";
1647
1647
  }
1648
- if (material instanceof THREE35__namespace.MeshBasicMaterial) {
1648
+ if (material instanceof THREE36__namespace.MeshBasicMaterial) {
1649
1649
  return "basic";
1650
1650
  }
1651
1651
  return "standard";
@@ -1664,8 +1664,8 @@ function createMaterialValue(material) {
1664
1664
  opacity: typeof materialRecord.opacity === "number" ? materialRecord.opacity : 1,
1665
1665
  emissive: toHexColor2(materialRecord.emissive, "#000000"),
1666
1666
  emissiveIntensity: typeof materialRecord.emissiveIntensity === "number" ? materialRecord.emissiveIntensity : 0,
1667
- side: typeof materialRecord.side === "number" ? materialRecord.side : THREE35__namespace.FrontSide,
1668
- blending: typeof materialRecord.blending === "number" ? materialRecord.blending : THREE35__namespace.NormalBlending,
1667
+ side: typeof materialRecord.side === "number" ? materialRecord.side : THREE36__namespace.FrontSide,
1668
+ blending: typeof materialRecord.blending === "number" ? materialRecord.blending : THREE36__namespace.NormalBlending,
1669
1669
  depthTest: materialRecord.depthTest !== false,
1670
1670
  depthWrite: materialRecord.depthWrite !== false,
1671
1671
  wireframe: Boolean(materialRecord.wireframe),
@@ -1681,7 +1681,7 @@ function createMaterialValue(material) {
1681
1681
  displacementMap: materialRecord.displacementMap?.image?.src,
1682
1682
  lightMap: materialRecord.lightMap?.image?.src,
1683
1683
  envMap: materialRecord.envMap?.image?.src,
1684
- textureFiltering: map?.magFilter === THREE35__namespace.NearestFilter ? "sharp" : "smooth",
1684
+ textureFiltering: map?.magFilter === THREE36__namespace.NearestFilter ? "sharp" : "smooth",
1685
1685
  useMipmaps: map?.generateMipmaps !== false
1686
1686
  };
1687
1687
  }
@@ -1696,8 +1696,8 @@ function defaultMaterialValue() {
1696
1696
  opacity: 1,
1697
1697
  emissive: "#000000",
1698
1698
  emissiveIntensity: 0,
1699
- side: THREE35__namespace.FrontSide,
1700
- blending: THREE35__namespace.NormalBlending,
1699
+ side: THREE36__namespace.FrontSide,
1700
+ blending: THREE36__namespace.NormalBlending,
1701
1701
  depthTest: true,
1702
1702
  depthWrite: true,
1703
1703
  wireframe: false,
@@ -2118,7 +2118,6 @@ var _ScriptComponent = class _ScriptComponent extends Component {
2118
2118
  className: typeof entry.className === "string" ? entry.className : "",
2119
2119
  scriptUrl: typeof entry.scriptUrl === "string" ? entry.scriptUrl : "",
2120
2120
  enabled: typeof entry.enabled === "boolean" ? entry.enabled : true,
2121
- executeInEditor: typeof entry.executeInEditor === "boolean" ? entry.executeInEditor : false,
2122
2121
  data: entry.data && typeof entry.data === "object" && !Array.isArray(entry.data) ? entry.data : {},
2123
2122
  runtimeState: entry.runtimeState,
2124
2123
  runtimeMessage: typeof entry.runtimeMessage === "string" ? entry.runtimeMessage : void 0
@@ -2157,6 +2156,35 @@ function createScriptComponent(world, entityId, payload = {}) {
2157
2156
  }
2158
2157
  __name(createScriptComponent, "createScriptComponent");
2159
2158
 
2159
+ // core/components/ScriptObjectComponent.ts
2160
+ var _ScriptObjectComponent = class _ScriptObjectComponent extends Component {
2161
+ constructor(input = {}) {
2162
+ super();
2163
+ this.scriptUrl = typeof input.scriptUrl === "string" && input.scriptUrl.length > 0 ? input.scriptUrl : null;
2164
+ this.className = typeof input.className === "string" && input.className.length > 0 ? input.className : null;
2165
+ this.enabled = typeof input.enabled === "boolean" ? input.enabled : true;
2166
+ this.data = input.data && typeof input.data === "object" && !Array.isArray(input.data) ? input.data : {};
2167
+ this.runtimeState = input.runtimeState === "idle" || input.runtimeState === "loading" || input.runtimeState === "ready" || input.runtimeState === "error" ? input.runtimeState : "idle";
2168
+ this.runtimeMessage = typeof input.runtimeMessage === "string" ? input.runtimeMessage : void 0;
2169
+ Object.defineProperty(this, "instance", {
2170
+ value: null,
2171
+ writable: true,
2172
+ configurable: true,
2173
+ enumerable: false
2174
+ });
2175
+ }
2176
+ };
2177
+ __name(_ScriptObjectComponent, "ScriptObjectComponent");
2178
+ var ScriptObjectComponent = _ScriptObjectComponent;
2179
+
2180
+ // core/factories/components/ScriptObjectComponentFactory.ts
2181
+ function createScriptObjectComponent(world, entityId, payload = {}) {
2182
+ const component = new ScriptObjectComponent(payload);
2183
+ world.addComponent(entityId, component);
2184
+ return component;
2185
+ }
2186
+ __name(createScriptObjectComponent, "createScriptObjectComponent");
2187
+
2160
2188
  // core/components/Selectable.ts
2161
2189
  var _Selectable = class _Selectable extends Component {
2162
2190
  constructor(enabled = true) {
@@ -2246,14 +2274,14 @@ var _TransformComponent = class _TransformComponent extends Component {
2246
2274
  z: scale.z ?? 1
2247
2275
  };
2248
2276
  }
2249
- toPositionVector3(target = new THREE35.Vector3()) {
2277
+ toPositionVector3(target = new THREE36.Vector3()) {
2250
2278
  return target.set(this.position.x, this.position.y, this.position.z);
2251
2279
  }
2252
- toRotationEuler(target = new THREE35.Euler(), order = "XYZ") {
2280
+ toRotationEuler(target = new THREE36.Euler(), order = "XYZ") {
2253
2281
  return target.set(this.rotation.x, this.rotation.y, this.rotation.z, order);
2254
2282
  }
2255
- toRotationQuaternion(target = new THREE35.Quaternion(), order = "XYZ") {
2256
- const euler = new THREE35.Euler(
2283
+ toRotationQuaternion(target = new THREE36.Quaternion(), order = "XYZ") {
2284
+ const euler = new THREE36.Euler(
2257
2285
  this.rotation.x,
2258
2286
  this.rotation.y,
2259
2287
  this.rotation.z,
@@ -2261,7 +2289,7 @@ var _TransformComponent = class _TransformComponent extends Component {
2261
2289
  );
2262
2290
  return target.setFromEuler(euler);
2263
2291
  }
2264
- toScaleVector3(target = new THREE35.Vector3()) {
2292
+ toScaleVector3(target = new THREE36.Vector3()) {
2265
2293
  return target.set(this.scale.x, this.scale.y, this.scale.z);
2266
2294
  }
2267
2295
  setPosition(input) {
@@ -2279,8 +2307,8 @@ var _TransformComponent = class _TransformComponent extends Component {
2279
2307
  return this;
2280
2308
  }
2281
2309
  setRotation(input, order = "XYZ") {
2282
- if (input instanceof THREE35.Quaternion) {
2283
- const euler = new THREE35.Euler().setFromQuaternion(input, order);
2310
+ if (input instanceof THREE36.Quaternion) {
2311
+ const euler = new THREE36.Euler().setFromQuaternion(input, order);
2284
2312
  this.rotation.x = euler.x;
2285
2313
  this.rotation.y = euler.y;
2286
2314
  this.rotation.z = euler.z;
@@ -2518,6 +2546,10 @@ function registerDefaultComponentFactories(objectManagementSystem) {
2518
2546
  createPostprocessingComponent
2519
2547
  );
2520
2548
  objectManagementSystem.registerComponentFactory("script", createScriptComponent);
2549
+ objectManagementSystem.registerComponentFactory(
2550
+ "scriptObject",
2551
+ createScriptObjectComponent
2552
+ );
2521
2553
  objectManagementSystem.registerComponentFactory("selectable", createSelectableComponent);
2522
2554
  objectManagementSystem.registerComponentFactory(
2523
2555
  "selectionTransformState",
@@ -2533,7 +2565,7 @@ var SHARED_MODEL_RESOURCE_FLAG = "spatialEcsSharedModelResource";
2533
2565
  var modelCache = /* @__PURE__ */ new Map();
2534
2566
  function markSharedResources(root) {
2535
2567
  root.traverse((child) => {
2536
- if (!(child instanceof THREE35__namespace.Mesh)) {
2568
+ if (!(child instanceof THREE36__namespace.Mesh)) {
2537
2569
  return;
2538
2570
  }
2539
2571
  if (child.geometry) {
@@ -2612,10 +2644,10 @@ var _ObjectManagementSystem = class _ObjectManagementSystem {
2612
2644
  }
2613
2645
  getOrCreateAudioListener() {
2614
2646
  const existing = this.camera.userData.ecsAudioListener;
2615
- if (existing instanceof THREE35__namespace.AudioListener) {
2647
+ if (existing instanceof THREE36__namespace.AudioListener) {
2616
2648
  return existing;
2617
2649
  }
2618
- const listener = new THREE35__namespace.AudioListener();
2650
+ const listener = new THREE36__namespace.AudioListener();
2619
2651
  this.camera.add(listener);
2620
2652
  this.camera.userData.ecsAudioListener = listener;
2621
2653
  return listener;
@@ -2689,7 +2721,7 @@ var _ObjectManagementSystem = class _ObjectManagementSystem {
2689
2721
  }
2690
2722
  if (dispose && object3d) {
2691
2723
  object3d.traverse((child) => {
2692
- if (child instanceof THREE35__namespace.Mesh) {
2724
+ if (child instanceof THREE36__namespace.Mesh) {
2693
2725
  if (!child.geometry?.userData?.[SHARED_MODEL_RESOURCE_FLAG]) {
2694
2726
  child.geometry?.dispose();
2695
2727
  }
@@ -2826,10 +2858,10 @@ __name(createBaseEntity, "createBaseEntity");
2826
2858
  // core/factories/objects/AudioFactory.ts
2827
2859
  function getOrCreateListener(camera) {
2828
2860
  const existing = camera.userData.ecsAudioListener;
2829
- if (existing instanceof THREE35__namespace.AudioListener) {
2861
+ if (existing instanceof THREE36__namespace.AudioListener) {
2830
2862
  return existing;
2831
2863
  }
2832
- const listener = new THREE35__namespace.AudioListener();
2864
+ const listener = new THREE36__namespace.AudioListener();
2833
2865
  camera.add(listener);
2834
2866
  camera.userData.ecsAudioListener = listener;
2835
2867
  return listener;
@@ -2842,7 +2874,7 @@ function createAudio({
2842
2874
  payload,
2843
2875
  isEditor
2844
2876
  }) {
2845
- const anchor = new THREE35__namespace.Object3D();
2877
+ const anchor = new THREE36__namespace.Object3D();
2846
2878
  const entityId = createBaseEntity(world, anchor, {
2847
2879
  label: payload.name ?? "Audio",
2848
2880
  entityType: "audio",
@@ -2864,7 +2896,7 @@ function createAudio({
2864
2896
  return entityId;
2865
2897
  }
2866
2898
  if (!isEditor) {
2867
- const loader = new THREE35__namespace.AudioLoader();
2899
+ const loader = new THREE36__namespace.AudioLoader();
2868
2900
  loader.load(
2869
2901
  audio.path,
2870
2902
  (buffer) => {
@@ -2939,7 +2971,7 @@ function applyCameraSettings(camera, options) {
2939
2971
  const near = typeof options.near === "number" ? options.near : DEFAULT_NEAR2;
2940
2972
  const far = typeof options.far === "number" ? options.far : DEFAULT_FAR2;
2941
2973
  const projection = options.projection;
2942
- if (camera instanceof THREE35__namespace.PerspectiveCamera) {
2974
+ if (camera instanceof THREE36__namespace.PerspectiveCamera) {
2943
2975
  if (!projection || projection === "perspective") {
2944
2976
  camera.fov = typeof options.fov === "number" ? options.fov : DEFAULT_FOV2;
2945
2977
  }
@@ -2949,7 +2981,7 @@ function applyCameraSettings(camera, options) {
2949
2981
  camera.updateProjectionMatrix();
2950
2982
  return;
2951
2983
  }
2952
- if (camera instanceof THREE35__namespace.OrthographicCamera) {
2984
+ if (camera instanceof THREE36__namespace.OrthographicCamera) {
2953
2985
  camera.left = typeof options.left === "number" ? options.left : -DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
2954
2986
  camera.right = typeof options.right === "number" ? options.right : DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
2955
2987
  camera.top = typeof options.top === "number" ? options.top : DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
@@ -2970,7 +3002,7 @@ function createCameraObject(options) {
2970
3002
  const bottom = options.bottom ?? -DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
2971
3003
  const left = options.left ?? -DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
2972
3004
  const right = options.right ?? DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
2973
- const camera = new THREE35__namespace.OrthographicCamera(
3005
+ const camera = new THREE36__namespace.OrthographicCamera(
2974
3006
  left,
2975
3007
  right,
2976
3008
  top,
@@ -2982,7 +3014,7 @@ function createCameraObject(options) {
2982
3014
  camera.updateProjectionMatrix();
2983
3015
  return camera;
2984
3016
  }
2985
- return new THREE35__namespace.PerspectiveCamera(
3017
+ return new THREE36__namespace.PerspectiveCamera(
2986
3018
  options.fov ?? DEFAULT_FOV2,
2987
3019
  readViewportAspect(),
2988
3020
  near,
@@ -3000,7 +3032,7 @@ function createCamera({ world, scene, camera, payload, isEditor }) {
3000
3032
  transformInput: payload.transform
3001
3033
  });
3002
3034
  const objectRef = world.getComponent(entityId, Object3DRef);
3003
- if (objectRef?.object instanceof THREE35__namespace.Camera) {
3035
+ if (objectRef?.object instanceof THREE36__namespace.Camera) {
3004
3036
  objectRef.object.userData.entityId = entityId;
3005
3037
  }
3006
3038
  const componentOptions = {
@@ -3017,20 +3049,11 @@ function createCamera({ world, scene, camera, payload, isEditor }) {
3017
3049
  bottom: options.bottom,
3018
3050
  zoom: options.zoom
3019
3051
  };
3020
- const component = createCameraComponent(world, entityId, componentOptions);
3052
+ createCameraComponent(world, entityId, componentOptions);
3021
3053
  if (useWorldCamera) {
3022
3054
  applyCameraSettings(object, options);
3023
3055
  } else {
3024
3056
  applyCameraSettings(object, options);
3025
- if (isEditor && component.isDefault) {
3026
- const helper = new THREE35__namespace.CameraHelper(object);
3027
- helper.onBeforeRender = () => {
3028
- helper.update();
3029
- };
3030
- helper.userData.ecsHelper = true;
3031
- helper.visible = false;
3032
- object.add(helper);
3033
- }
3034
3057
  scene.add(object);
3035
3058
  }
3036
3059
  return entityId;
@@ -3041,9 +3064,9 @@ function createCapsule({
3041
3064
  scene,
3042
3065
  payload
3043
3066
  }) {
3044
- const geometry = new THREE35__namespace.CapsuleGeometry(0.5, 1, 4, 8);
3045
- const material = new THREE35__namespace.MeshStandardMaterial({ color: "#ffffff" });
3046
- const mesh = new THREE35__namespace.Mesh(geometry, material);
3067
+ const geometry = new THREE36__namespace.CapsuleGeometry(0.5, 1, 4, 8);
3068
+ const material = new THREE36__namespace.MeshStandardMaterial({ color: "#ffffff" });
3069
+ const mesh = new THREE36__namespace.Mesh(geometry, material);
3047
3070
  const entityId = createBaseEntity(world, mesh, {
3048
3071
  label: payload.name ?? "Capsule",
3049
3072
  entityType: "capsule",
@@ -3063,9 +3086,9 @@ function createCapsule({
3063
3086
  }
3064
3087
  __name(createCapsule, "createCapsule");
3065
3088
  function createCube({ world, scene, payload }) {
3066
- const geometry = new THREE35__namespace.BoxGeometry(1, 1, 1);
3067
- const material = new THREE35__namespace.MeshStandardMaterial({ color: "#ffffff" });
3068
- const mesh = new THREE35__namespace.Mesh(geometry, material);
3089
+ const geometry = new THREE36__namespace.BoxGeometry(1, 1, 1);
3090
+ const material = new THREE36__namespace.MeshStandardMaterial({ color: "#ffffff" });
3091
+ const mesh = new THREE36__namespace.Mesh(geometry, material);
3069
3092
  const entityId = createBaseEntity(world, mesh, {
3070
3093
  label: payload.name ?? "Cube",
3071
3094
  entityType: "cube",
@@ -3090,9 +3113,9 @@ function createCylinder({
3090
3113
  scene,
3091
3114
  payload
3092
3115
  }) {
3093
- const geometry = new THREE35__namespace.CylinderGeometry(0.5, 0.5, 1, 20);
3094
- const material = new THREE35__namespace.MeshStandardMaterial({ color: "#ffffff" });
3095
- const mesh = new THREE35__namespace.Mesh(geometry, material);
3116
+ const geometry = new THREE36__namespace.CylinderGeometry(0.5, 0.5, 1, 20);
3117
+ const material = new THREE36__namespace.MeshStandardMaterial({ color: "#ffffff" });
3118
+ const mesh = new THREE36__namespace.Mesh(geometry, material);
3096
3119
  const entityId = createBaseEntity(world, mesh, {
3097
3120
  label: payload.name ?? "Cylinder",
3098
3121
  entityType: "cylinder",
@@ -3112,7 +3135,7 @@ function createCylinder({
3112
3135
  }
3113
3136
  __name(createCylinder, "createCylinder");
3114
3137
  function createEmpty({ world, scene, payload, isEditor }) {
3115
- const object = new THREE35__namespace.Group();
3138
+ const object = new THREE36__namespace.Group();
3116
3139
  const entityId = createBaseEntity(world, object, {
3117
3140
  label: payload.name ?? "Empty",
3118
3141
  entityType: "empty",
@@ -3123,7 +3146,7 @@ function createEmpty({ world, scene, payload, isEditor }) {
3123
3146
  }
3124
3147
  __name(createEmpty, "createEmpty");
3125
3148
  function createImage({ world, scene, payload }) {
3126
- const anchor = new THREE35__namespace.Object3D();
3149
+ const anchor = new THREE36__namespace.Object3D();
3127
3150
  const imagePath = payload.path ?? "";
3128
3151
  const entityId = createBaseEntity(world, anchor, {
3129
3152
  label: payload.name ?? "Image",
@@ -3136,7 +3159,7 @@ function createImage({ world, scene, payload }) {
3136
3159
  if (!imagePath) {
3137
3160
  return entityId;
3138
3161
  }
3139
- const loader = new THREE35__namespace.TextureLoader();
3162
+ const loader = new THREE36__namespace.TextureLoader();
3140
3163
  loader.load(
3141
3164
  imagePath,
3142
3165
  (texture) => {
@@ -3144,13 +3167,13 @@ function createImage({ world, scene, payload }) {
3144
3167
  texture.dispose();
3145
3168
  return;
3146
3169
  }
3147
- const material = new THREE35__namespace.MeshBasicMaterial({
3170
+ const material = new THREE36__namespace.MeshBasicMaterial({
3148
3171
  map: texture,
3149
3172
  transparent: true,
3150
- side: THREE35__namespace.DoubleSide
3173
+ side: THREE36__namespace.DoubleSide
3151
3174
  });
3152
- const geometry = new THREE35__namespace.PlaneGeometry(1, 1);
3153
- const plane = new THREE35__namespace.Mesh(geometry, material);
3175
+ const geometry = new THREE36__namespace.PlaneGeometry(1, 1);
3176
+ const plane = new THREE36__namespace.Mesh(geometry, material);
3154
3177
  plane.userData.entityId = entityId;
3155
3178
  const textureImage = texture.image;
3156
3179
  const width = textureImage?.width ?? 1;
@@ -3196,7 +3219,7 @@ function createImageTarget({
3196
3219
  payload,
3197
3220
  isEditor
3198
3221
  }) {
3199
- const anchor = new THREE35__namespace.Object3D();
3222
+ const anchor = new THREE36__namespace.Object3D();
3200
3223
  const imagePath = payload.path ?? "";
3201
3224
  const entityId = createBaseEntity(world, anchor, {
3202
3225
  label: payload.name ?? "Image Target",
@@ -3213,7 +3236,7 @@ function createImageTarget({
3213
3236
  if (!isEditor || !imagePath) {
3214
3237
  return entityId;
3215
3238
  }
3216
- const loader = new THREE35__namespace.TextureLoader();
3239
+ const loader = new THREE36__namespace.TextureLoader();
3217
3240
  loader.load(
3218
3241
  imagePath,
3219
3242
  (texture) => {
@@ -3221,13 +3244,13 @@ function createImageTarget({
3221
3244
  texture.dispose();
3222
3245
  return;
3223
3246
  }
3224
- const material = new THREE35__namespace.MeshBasicMaterial({
3247
+ const material = new THREE36__namespace.MeshBasicMaterial({
3225
3248
  map: texture,
3226
3249
  transparent: true,
3227
- side: THREE35__namespace.DoubleSide
3250
+ side: THREE36__namespace.DoubleSide
3228
3251
  });
3229
- const geometry = new THREE35__namespace.PlaneGeometry(1, 1);
3230
- const plane = new THREE35__namespace.Mesh(geometry, material);
3252
+ const geometry = new THREE36__namespace.PlaneGeometry(1, 1);
3253
+ const plane = new THREE36__namespace.Mesh(geometry, material);
3231
3254
  plane.userData.entityId = entityId;
3232
3255
  const textureImage = texture.image;
3233
3256
  const width = textureImage?.width ?? 1;
@@ -3278,7 +3301,7 @@ function createInstancedMesh({
3278
3301
  scene,
3279
3302
  payload
3280
3303
  }) {
3281
- const anchor = new THREE35__namespace.Object3D();
3304
+ const anchor = new THREE36__namespace.Object3D();
3282
3305
  const opts = payload.options ?? {};
3283
3306
  const meshKind = isInstancedMeshKind(opts.meshKind) ? opts.meshKind : "cube";
3284
3307
  const meshParameters = opts.meshParameters && typeof opts.meshParameters === "object" ? opts.meshParameters : void 0;
@@ -3349,7 +3372,7 @@ function createAmbientLight({
3349
3372
  scene,
3350
3373
  payload
3351
3374
  }) {
3352
- const light = new THREE35__namespace.AmbientLight("#ffffff", 0.6);
3375
+ const light = new THREE36__namespace.AmbientLight("#ffffff", 0.6);
3353
3376
  const entityId = createBaseEntity(world, light, {
3354
3377
  label: payload.name ?? "Ambient Light",
3355
3378
  entityType: "ambientLight",
@@ -3366,7 +3389,7 @@ function createAreaLight({
3366
3389
  payload,
3367
3390
  isEditor
3368
3391
  }) {
3369
- const light = new THREE35__namespace.RectAreaLight("#ffffff", 5, 4, 4);
3392
+ const light = new THREE36__namespace.RectAreaLight("#ffffff", 5, 4, 4);
3370
3393
  light.lookAt(0, 0, 0);
3371
3394
  const entityId = createBaseEntity(world, light, {
3372
3395
  label: payload.name ?? "Area Light",
@@ -3395,7 +3418,7 @@ function createDirectionalLight({
3395
3418
  payload,
3396
3419
  isEditor
3397
3420
  }) {
3398
- const light = new THREE35__namespace.DirectionalLight("#ffffff", 1.5);
3421
+ const light = new THREE36__namespace.DirectionalLight("#ffffff", 1.5);
3399
3422
  light.castShadow = true;
3400
3423
  const entityId = createBaseEntity(world, light, {
3401
3424
  label: payload.name ?? "Directional Light",
@@ -3406,7 +3429,7 @@ function createDirectionalLight({
3406
3429
  });
3407
3430
  createLightComponent(world, entityId, light);
3408
3431
  if (isEditor) {
3409
- const helper = new THREE35__namespace.DirectionalLightHelper(light, 1.8, "#38bdf8");
3432
+ const helper = new THREE36__namespace.DirectionalLightHelper(light, 1.8, "#38bdf8");
3410
3433
  helper.onBeforeRender = () => {
3411
3434
  helper.update();
3412
3435
  };
@@ -3424,7 +3447,7 @@ function createPointLight({
3424
3447
  payload,
3425
3448
  isEditor
3426
3449
  }) {
3427
- const light = new THREE35__namespace.PointLight("#ffffff", 1, 10);
3450
+ const light = new THREE36__namespace.PointLight("#ffffff", 1, 10);
3428
3451
  const entityId = createBaseEntity(world, light, {
3429
3452
  label: payload.name ?? "Point Light",
3430
3453
  entityType: "pointLight",
@@ -3434,7 +3457,7 @@ function createPointLight({
3434
3457
  });
3435
3458
  createLightComponent(world, entityId, light);
3436
3459
  if (isEditor) {
3437
- const helper = new THREE35__namespace.PointLightHelper(light, 0.35, "#fbbf24");
3460
+ const helper = new THREE36__namespace.PointLightHelper(light, 0.35, "#fbbf24");
3438
3461
  helper.onBeforeRender = () => {
3439
3462
  helper.update();
3440
3463
  };
@@ -3452,7 +3475,7 @@ function createSpotLight({
3452
3475
  payload,
3453
3476
  isEditor
3454
3477
  }) {
3455
- const light = new THREE35__namespace.SpotLight("#ffffff", 1, 20, Math.PI / 6, 0.1, 1);
3478
+ const light = new THREE36__namespace.SpotLight("#ffffff", 1, 20, Math.PI / 6, 0.1, 1);
3456
3479
  const entityId = createBaseEntity(world, light, {
3457
3480
  label: payload.name ?? "Spot Light",
3458
3481
  entityType: "spotLight",
@@ -3462,7 +3485,7 @@ function createSpotLight({
3462
3485
  });
3463
3486
  createLightComponent(world, entityId, light);
3464
3487
  if (isEditor) {
3465
- const helper = new THREE35__namespace.SpotLightHelper(light, "#f59e0b");
3488
+ const helper = new THREE36__namespace.SpotLightHelper(light, "#f59e0b");
3466
3489
  helper.onBeforeRender = () => {
3467
3490
  helper.update();
3468
3491
  };
@@ -3540,6 +3563,7 @@ __export(components_exports, {
3540
3563
  PrefabInstance: () => PrefabInstance,
3541
3564
  PrefabNode: () => PrefabNode,
3542
3565
  ScriptComponent: () => ScriptComponent,
3566
+ ScriptObjectComponent: () => ScriptObjectComponent,
3543
3567
  Selectable: () => Selectable,
3544
3568
  SelectionTransformState: () => SelectionTransformState,
3545
3569
  SpriteComponent: () => SpriteComponent,
@@ -3550,11 +3574,19 @@ __export(components_exports, {
3550
3574
  });
3551
3575
 
3552
3576
  // core/components/PrefabInstance.ts
3577
+ var generateInstanceId = /* @__PURE__ */ __name(() => {
3578
+ try {
3579
+ return crypto.randomUUID();
3580
+ } catch {
3581
+ return `i-${Math.random().toString(36).slice(2, 10)}${Date.now().toString(36)}`;
3582
+ }
3583
+ }, "generateInstanceId");
3553
3584
  var _PrefabInstance = class _PrefabInstance extends Component {
3554
- constructor(url, overrides = []) {
3585
+ constructor(url, overrides = [], instanceId) {
3555
3586
  super();
3556
3587
  this.url = url;
3557
3588
  this.overrides = overrides;
3589
+ this.instanceId = typeof instanceId === "string" && instanceId.length > 0 ? instanceId : generateInstanceId();
3558
3590
  }
3559
3591
  };
3560
3592
  __name(_PrefabInstance, "PrefabInstance");
@@ -3594,7 +3626,7 @@ function createModel({
3594
3626
  payload,
3595
3627
  isEditor
3596
3628
  }) {
3597
- const anchor = new THREE35__namespace.Object3D();
3629
+ const anchor = new THREE36__namespace.Object3D();
3598
3630
  const modelPath = payload.path ?? "";
3599
3631
  const entityId = createBaseEntity(world, anchor, {
3600
3632
  label: payload.name ?? "Model",
@@ -3660,12 +3692,12 @@ function createModel({
3660
3692
  }
3661
3693
  __name(createModel, "createModel");
3662
3694
  function createPlane({ world, scene, payload }) {
3663
- const geometry = new THREE35__namespace.PlaneGeometry(100, 100);
3664
- const material = new THREE35__namespace.MeshStandardMaterial({
3695
+ const geometry = new THREE36__namespace.PlaneGeometry(100, 100);
3696
+ const material = new THREE36__namespace.MeshStandardMaterial({
3665
3697
  color: "#ffffff",
3666
- side: THREE35__namespace.DoubleSide
3698
+ side: THREE36__namespace.DoubleSide
3667
3699
  });
3668
- const mesh = new THREE35__namespace.Mesh(geometry, material);
3700
+ const mesh = new THREE36__namespace.Mesh(geometry, material);
3669
3701
  const entityId = createBaseEntity(
3670
3702
  world,
3671
3703
  mesh,
@@ -3696,8 +3728,30 @@ function createPlane({ world, scene, payload }) {
3696
3728
  return entityId;
3697
3729
  }
3698
3730
  __name(createPlane, "createPlane");
3731
+ function createScriptObject({
3732
+ world,
3733
+ scene,
3734
+ payload
3735
+ }) {
3736
+ const object = new THREE36__namespace.Group();
3737
+ const entityId = createBaseEntity(world, object, {
3738
+ label: payload.name ?? "Script Object",
3739
+ entityType: "scriptObject",
3740
+ transformInput: payload.transform
3741
+ });
3742
+ const options = payload.options ?? {};
3743
+ createScriptObjectComponent(world, entityId, {
3744
+ scriptUrl: typeof options.scriptUrl === "string" ? options.scriptUrl : null,
3745
+ className: typeof options.className === "string" ? options.className : null,
3746
+ enabled: typeof options.enabled === "boolean" ? options.enabled : true,
3747
+ data: options.data && typeof options.data === "object" && !Array.isArray(options.data) ? options.data : {}
3748
+ });
3749
+ scene.add(object);
3750
+ return entityId;
3751
+ }
3752
+ __name(createScriptObject, "createScriptObject");
3699
3753
  function createSprite({ world, scene, payload }) {
3700
- const anchor = new THREE35__namespace.Object3D();
3754
+ const anchor = new THREE36__namespace.Object3D();
3701
3755
  const imagePath = payload.path ?? "";
3702
3756
  const entityId = createBaseEntity(world, anchor, {
3703
3757
  label: payload.name ?? "Sprite",
@@ -3709,7 +3763,7 @@ function createSprite({ world, scene, payload }) {
3709
3763
  if (!imagePath) {
3710
3764
  return entityId;
3711
3765
  }
3712
- const loader = new THREE35__namespace.TextureLoader();
3766
+ const loader = new THREE36__namespace.TextureLoader();
3713
3767
  loader.load(
3714
3768
  imagePath,
3715
3769
  (texture) => {
@@ -3717,11 +3771,11 @@ function createSprite({ world, scene, payload }) {
3717
3771
  texture.dispose();
3718
3772
  return;
3719
3773
  }
3720
- const material = new THREE35__namespace.SpriteMaterial({
3774
+ const material = new THREE36__namespace.SpriteMaterial({
3721
3775
  map: texture,
3722
3776
  transparent: true
3723
3777
  });
3724
- const sprite = new THREE35__namespace.Sprite(material);
3778
+ const sprite = new THREE36__namespace.Sprite(material);
3725
3779
  sprite.userData.entityId = entityId;
3726
3780
  const textureImage = texture.image;
3727
3781
  spriteComponent.width = textureImage?.width ?? 1;
@@ -3739,9 +3793,9 @@ function createSprite({ world, scene, payload }) {
3739
3793
  }
3740
3794
  __name(createSprite, "createSprite");
3741
3795
  function createSphere({ world, scene, payload }) {
3742
- const geometry = new THREE35__namespace.SphereGeometry(0.5, 24, 24);
3743
- const material = new THREE35__namespace.MeshStandardMaterial({ color: "#ffffff" });
3744
- const mesh = new THREE35__namespace.Mesh(geometry, material);
3796
+ const geometry = new THREE36__namespace.SphereGeometry(0.5, 24, 24);
3797
+ const material = new THREE36__namespace.MeshStandardMaterial({ color: "#ffffff" });
3798
+ const mesh = new THREE36__namespace.Mesh(geometry, material);
3745
3799
  const entityId = createBaseEntity(world, mesh, {
3746
3800
  label: payload.name ?? "Sphere",
3747
3801
  entityType: "sphere",
@@ -3761,10 +3815,10 @@ function createSphere({ world, scene, payload }) {
3761
3815
  __name(createSphere, "createSphere");
3762
3816
  function getOrCreateListener2(camera) {
3763
3817
  const existing = camera.userData.ecsAudioListener;
3764
- if (existing instanceof THREE35__namespace.AudioListener) {
3818
+ if (existing instanceof THREE36__namespace.AudioListener) {
3765
3819
  return existing;
3766
3820
  }
3767
- const listener = new THREE35__namespace.AudioListener();
3821
+ const listener = new THREE36__namespace.AudioListener();
3768
3822
  camera.add(listener);
3769
3823
  camera.userData.ecsAudioListener = listener;
3770
3824
  return listener;
@@ -3814,10 +3868,10 @@ function normalizeOptions(input) {
3814
3868
  }
3815
3869
  __name(normalizeOptions, "normalizeOptions");
3816
3870
  function createChromaMaterial(texture, options) {
3817
- return new THREE35__namespace.ShaderMaterial({
3871
+ return new THREE36__namespace.ShaderMaterial({
3818
3872
  uniforms: {
3819
3873
  tex: { value: texture },
3820
- keyColor: { value: new THREE35__namespace.Color(options.backgroundColor) },
3874
+ keyColor: { value: new THREE36__namespace.Color(options.backgroundColor) },
3821
3875
  similarity: { value: options.similarity },
3822
3876
  smoothness: { value: options.smoothness },
3823
3877
  spill: { value: options.spill }
@@ -3849,22 +3903,22 @@ function createChromaMaterial(texture, options) {
3849
3903
  }
3850
3904
  `,
3851
3905
  transparent: true,
3852
- side: THREE35__namespace.DoubleSide
3906
+ side: THREE36__namespace.DoubleSide
3853
3907
  });
3854
3908
  }
3855
3909
  __name(createChromaMaterial, "createChromaMaterial");
3856
3910
  function createStandardMaterial(texture) {
3857
- return new THREE35__namespace.MeshBasicMaterial({
3911
+ return new THREE36__namespace.MeshBasicMaterial({
3858
3912
  map: texture,
3859
3913
  transparent: true,
3860
- side: THREE35__namespace.DoubleSide
3914
+ side: THREE36__namespace.DoubleSide
3861
3915
  });
3862
3916
  }
3863
3917
  __name(createStandardMaterial, "createStandardMaterial");
3864
3918
  function createVideoMesh(entityId, texture, options) {
3865
- const geometry = new THREE35__namespace.PlaneGeometry(1, 1);
3919
+ const geometry = new THREE36__namespace.PlaneGeometry(1, 1);
3866
3920
  const material = options.isGreenScreen ? createChromaMaterial(texture, options) : createStandardMaterial(texture);
3867
- const mesh = new THREE35__namespace.Mesh(geometry, material);
3921
+ const mesh = new THREE36__namespace.Mesh(geometry, material);
3868
3922
  mesh.userData.entityId = entityId;
3869
3923
  mesh.scale.set(options.width, options.height, 1);
3870
3924
  return { mesh, material };
@@ -3899,7 +3953,7 @@ function createVideo({
3899
3953
  payload,
3900
3954
  isEditor
3901
3955
  }) {
3902
- const anchor = new THREE35__namespace.Object3D();
3956
+ const anchor = new THREE36__namespace.Object3D();
3903
3957
  const path = payload.path ?? "";
3904
3958
  const options = normalizeOptions(payload.options);
3905
3959
  const entityId = createBaseEntity(world, anchor, {
@@ -3914,8 +3968,8 @@ function createVideo({
3914
3968
  return entityId;
3915
3969
  }
3916
3970
  const video = createVideoElement(path, options);
3917
- const texture = new THREE35__namespace.VideoTexture(video);
3918
- texture.colorSpace = THREE35__namespace.SRGBColorSpace;
3971
+ const texture = new THREE36__namespace.VideoTexture(video);
3972
+ texture.colorSpace = THREE36__namespace.SRGBColorSpace;
3919
3973
  texture.needsUpdate = true;
3920
3974
  const { mesh, material } = createVideoMesh(entityId, texture, options);
3921
3975
  anchor.add(mesh);
@@ -3931,7 +3985,7 @@ function createVideo({
3931
3985
  });
3932
3986
  if (!isEditor && options.positional) {
3933
3987
  const listener = getOrCreateListener2(camera);
3934
- const audioNode = new THREE35__namespace.PositionalAudio(listener);
3988
+ const audioNode = new THREE36__namespace.PositionalAudio(listener);
3935
3989
  audioNode.setVolume(options.volume);
3936
3990
  audioNode.setRefDistance(options.refDistance);
3937
3991
  audioNode.setDistanceModel(normalizeDistanceModel2(options.distanceModel));
@@ -3970,6 +4024,7 @@ function registerDefaultFactories(objectManagementSystem) {
3970
4024
  objectManagementSystem.register("pointLight", createPointLight);
3971
4025
  objectManagementSystem.register("spotLight", createSpotLight);
3972
4026
  objectManagementSystem.register("areaLight", createAreaLight);
4027
+ objectManagementSystem.register("scriptObject", createScriptObject);
3973
4028
  registerDefaultComponentFactories(objectManagementSystem);
3974
4029
  }
3975
4030
  __name(registerDefaultFactories, "registerDefaultFactories");
@@ -4098,6 +4153,10 @@ function buildComponentValueMaps(snapshot) {
4098
4153
  animationValues: readByComponent(snapshot.components, "AnimationComponent"),
4099
4154
  imageTargetAnchorValues: readByComponent(snapshot.components, "ImageTargetAnchor"),
4100
4155
  scriptValues: readByComponent(snapshot.components, "ScriptComponent"),
4156
+ scriptObjectValues: readByComponent(
4157
+ snapshot.components,
4158
+ "ScriptObjectComponent"
4159
+ ),
4101
4160
  instancedMeshValues: readByComponent(snapshot.components, "InstancedMeshComponent"),
4102
4161
  instanceSlotValues: readByComponent(snapshot.components, "InstanceSlotComponent"),
4103
4162
  prefabNodeValues: readByComponent(snapshot.components, "PrefabNode"),
@@ -4215,6 +4274,14 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
4215
4274
  new ScriptComponent(entries)
4216
4275
  );
4217
4276
  }
4277
+ const sourceScriptObject = asRecord3(values.scriptObjectValues.get(sourceEntityId));
4278
+ if (sourceScriptObject) {
4279
+ const soc = world.getComponent(targetEntityId, ScriptObjectComponent);
4280
+ const data = asRecord3(sourceScriptObject.data);
4281
+ if (soc && data) {
4282
+ soc.data = remapEntityRefsInScriptData(data, idMap);
4283
+ }
4284
+ }
4218
4285
  {
4219
4286
  const imComponent = world.getComponent(targetEntityId, InstancedMeshComponent);
4220
4287
  if (imComponent && imComponent.instanceEntityIds.length > 0) {
@@ -4767,7 +4834,13 @@ function restoreComponentState(world, objectManagementSystem, targetEntityId, so
4767
4834
  ) : [];
4768
4835
  world.addComponent(
4769
4836
  targetEntityId,
4770
- new PrefabInstance(sourcePrefabInstance.url, overrides)
4837
+ new PrefabInstance(
4838
+ sourcePrefabInstance.url,
4839
+ overrides,
4840
+ // Preserve the placement identity; the constructor generates a
4841
+ // fresh one for legacy snapshots that predate instanceId.
4842
+ typeof sourcePrefabInstance.instanceId === "string" && sourcePrefabInstance.instanceId.length > 0 ? sourcePrefabInstance.instanceId : void 0
4843
+ )
4771
4844
  );
4772
4845
  }
4773
4846
  }
@@ -4795,7 +4868,8 @@ var HYDRATABLE_ENTITY_KINDS = /* @__PURE__ */ new Set([
4795
4868
  "spotLight",
4796
4869
  "areaLight",
4797
4870
  "instancedMesh",
4798
- "instanceSlot"
4871
+ "instanceSlot",
4872
+ "scriptObject"
4799
4873
  ]);
4800
4874
 
4801
4875
  // core/hydration/hydrateWorld.ts
@@ -4897,6 +4971,16 @@ function buildEntityCreationPayload(sourceEntityId, kind, componentValues) {
4897
4971
  };
4898
4972
  }
4899
4973
  }
4974
+ if (kind === "scriptObject") {
4975
+ const so = asRecord3(componentValues.scriptObjectValues.get(sourceEntityId));
4976
+ if (so) {
4977
+ payload.options = {
4978
+ scriptUrl: typeof so.scriptUrl === "string" ? so.scriptUrl : null,
4979
+ className: typeof so.className === "string" ? so.className : null,
4980
+ enabled: typeof so.enabled === "boolean" ? so.enabled : true
4981
+ };
4982
+ }
4983
+ }
4900
4984
  return payload;
4901
4985
  }
4902
4986
  __name(buildEntityCreationPayload, "buildEntityCreationPayload");
@@ -5014,6 +5098,148 @@ function hydrateWorldFromSnapshot(snapshot, world, objectManagementSystem) {
5014
5098
  }
5015
5099
  __name(hydrateWorldFromSnapshot, "hydrateWorldFromSnapshot");
5016
5100
 
5101
+ // core/prefab/nodeKeys.ts
5102
+ var NODE_KEY_SEPARATOR = "/";
5103
+ var ADDED_NODE_MARKER_COMPONENT = "+node";
5104
+ var asRecord4 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null, "asRecord");
5105
+ var readBlock = /* @__PURE__ */ __name((snapshot, component) => {
5106
+ const map = /* @__PURE__ */ new Map();
5107
+ const block = snapshot.components.find((b) => b.component === component);
5108
+ for (const entry of block?.entries ?? []) {
5109
+ const record = asRecord4(entry.value);
5110
+ if (record) {
5111
+ map.set(entry.entityId, record);
5112
+ }
5113
+ }
5114
+ return map;
5115
+ }, "readBlock");
5116
+ var fallbackInstanceId = /* @__PURE__ */ __name((entityId) => `e${entityId}`, "fallbackInstanceId");
5117
+ function buildNodeKeyMapsFromSnapshot(snapshot, options) {
5118
+ const parentValues = readBlock(snapshot, "ParentId");
5119
+ const nodeValues = readBlock(snapshot, "PrefabNode");
5120
+ const instanceValues = readBlock(snapshot, "PrefabInstance");
5121
+ const inDocument = new Set(snapshot.entities);
5122
+ const childrenByParent = /* @__PURE__ */ new Map();
5123
+ const rootIds = [];
5124
+ for (const entityId of snapshot.entities) {
5125
+ const parent = parentValues.get(entityId)?.value;
5126
+ if (typeof parent === "number" && inDocument.has(parent)) {
5127
+ const siblings = childrenByParent.get(parent);
5128
+ if (siblings) siblings.push(entityId);
5129
+ else childrenByParent.set(parent, [entityId]);
5130
+ } else {
5131
+ rootIds.push(entityId);
5132
+ }
5133
+ }
5134
+ const scopeRoots = options?.scopeRootEntityId !== void 0 ? [options.scopeRootEntityId] : rootIds;
5135
+ const idToKey = /* @__PURE__ */ new Map();
5136
+ const keyToId = /* @__PURE__ */ new Map();
5137
+ const boundaryIds = /* @__PURE__ */ new Map();
5138
+ const scopeRootSet = new Set(scopeRoots);
5139
+ const queue = scopeRoots.map(
5140
+ (entityId) => ({ entityId, prefix: "" })
5141
+ );
5142
+ while (queue.length > 0) {
5143
+ const { entityId, prefix } = queue.shift();
5144
+ const instance = instanceValues.get(entityId);
5145
+ const isBoundary = Boolean(
5146
+ instance && typeof instance.url === "string" && !scopeRootSet.has(entityId)
5147
+ );
5148
+ let ownPrefix = prefix;
5149
+ let childPrefix = prefix;
5150
+ if (isBoundary && instance) {
5151
+ const instanceId = typeof instance.instanceId === "string" && instance.instanceId.length > 0 ? instance.instanceId : fallbackInstanceId(entityId);
5152
+ childPrefix = `${prefix}${instanceId}${NODE_KEY_SEPARATOR}`;
5153
+ ownPrefix = childPrefix;
5154
+ boundaryIds.set(entityId, {
5155
+ url: instance.url,
5156
+ instanceId
5157
+ });
5158
+ }
5159
+ const nodeId = nodeValues.get(entityId)?.nodeId;
5160
+ if (typeof nodeId === "string" && nodeId.length > 0) {
5161
+ const key = `${ownPrefix}${nodeId}`;
5162
+ idToKey.set(entityId, key);
5163
+ keyToId.set(key, entityId);
5164
+ }
5165
+ for (const child of childrenByParent.get(entityId) ?? []) {
5166
+ queue.push({ entityId: child, prefix: childPrefix });
5167
+ }
5168
+ }
5169
+ const rootEntityId = scopeRoots[0];
5170
+ const rootNodeId = rootEntityId !== void 0 ? nodeValues.get(rootEntityId)?.nodeId : void 0;
5171
+ return {
5172
+ idToKey,
5173
+ keyToId,
5174
+ rootKey: typeof rootNodeId === "string" && rootNodeId.length > 0 ? rootNodeId : null,
5175
+ boundaryIds
5176
+ };
5177
+ }
5178
+ __name(buildNodeKeyMapsFromSnapshot, "buildNodeKeyMapsFromSnapshot");
5179
+ function collectSnapshotSubtreeIds(snapshot, rootEntityId) {
5180
+ const parentValues = readBlock(snapshot, "ParentId");
5181
+ const childrenByParent = /* @__PURE__ */ new Map();
5182
+ for (const entityId of snapshot.entities) {
5183
+ const parent = parentValues.get(entityId)?.value;
5184
+ if (typeof parent === "number") {
5185
+ const siblings = childrenByParent.get(parent);
5186
+ if (siblings) siblings.push(entityId);
5187
+ else childrenByParent.set(parent, [entityId]);
5188
+ }
5189
+ }
5190
+ const ordered = [];
5191
+ const seen = /* @__PURE__ */ new Set();
5192
+ const queue = [rootEntityId];
5193
+ while (queue.length > 0) {
5194
+ const entityId = queue.shift();
5195
+ if (seen.has(entityId)) continue;
5196
+ seen.add(entityId);
5197
+ ordered.push(entityId);
5198
+ queue.push(...childrenByParent.get(entityId) ?? []);
5199
+ }
5200
+ return ordered;
5201
+ }
5202
+ __name(collectSnapshotSubtreeIds, "collectSnapshotSubtreeIds");
5203
+ function findTopLevelNestedRegions(snapshot) {
5204
+ const parentValues = readBlock(snapshot, "ParentId");
5205
+ const instanceValues = readBlock(snapshot, "PrefabInstance");
5206
+ const inDocument = new Set(snapshot.entities);
5207
+ const roots = new Set(
5208
+ snapshot.entities.filter((entityId) => {
5209
+ const parent = parentValues.get(entityId)?.value;
5210
+ return typeof parent !== "number" || !inDocument.has(parent);
5211
+ })
5212
+ );
5213
+ const regions = [];
5214
+ for (const [entityId, instance] of instanceValues) {
5215
+ if (roots.has(entityId)) continue;
5216
+ if (typeof instance.url !== "string" || instance.url.length === 0) continue;
5217
+ let ancestor = parentValues.get(entityId)?.value;
5218
+ let nestedDeeper = false;
5219
+ let hops = 0;
5220
+ while (typeof ancestor === "number" && hops < 512) {
5221
+ if (instanceValues.has(ancestor) && !roots.has(ancestor)) {
5222
+ nestedDeeper = true;
5223
+ break;
5224
+ }
5225
+ ancestor = parentValues.get(ancestor)?.value;
5226
+ hops += 1;
5227
+ }
5228
+ if (nestedDeeper) continue;
5229
+ regions.push({
5230
+ rootEntityId: entityId,
5231
+ url: instance.url,
5232
+ instanceId: typeof instance.instanceId === "string" && instance.instanceId.length > 0 ? instance.instanceId : fallbackInstanceId(entityId),
5233
+ overrides: Array.isArray(instance.overrides) ? instance.overrides.filter(
5234
+ (entry) => typeof entry === "string"
5235
+ ) : []
5236
+ });
5237
+ }
5238
+ regions.sort((a, b) => a.rootEntityId - b.rootEntityId);
5239
+ return regions;
5240
+ }
5241
+ __name(findTopLevelNestedRegions, "findTopLevelNestedRegions");
5242
+
5017
5243
  // core/prefab/overrides.ts
5018
5244
  var OVERRIDE_DIFF_EXCLUDED_COMPONENTS = /* @__PURE__ */ new Set([
5019
5245
  "PrefabNode",
@@ -5027,10 +5253,10 @@ var OVERRIDE_ROOT_EXCLUDED_COMPONENTS = /* @__PURE__ */ new Set([
5027
5253
  "Name",
5028
5254
  "ParentId"
5029
5255
  ]);
5030
- var asRecord4 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null, "asRecord");
5256
+ var asRecord5 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null, "asRecord");
5031
5257
  var clone = /* @__PURE__ */ __name((value) => value === void 0 ? value : structuredClone(value), "clone");
5032
5258
  var isNodeRef = /* @__PURE__ */ __name((value) => {
5033
- const record = asRecord4(value);
5259
+ const record = asRecord5(value);
5034
5260
  return Boolean(
5035
5261
  record && typeof record.$node === "string" && Object.keys(record).length === 1
5036
5262
  );
@@ -5042,7 +5268,7 @@ function findSnapshotRootEntityIds(snapshot) {
5042
5268
  );
5043
5269
  const parentByEntity = /* @__PURE__ */ new Map();
5044
5270
  for (const entry of parentBlock?.entries ?? []) {
5045
- parentByEntity.set(entry.entityId, asRecord4(entry.value)?.value ?? null);
5271
+ parentByEntity.set(entry.entityId, asRecord5(entry.value)?.value ?? null);
5046
5272
  }
5047
5273
  return snapshot.entities.filter(
5048
5274
  (entityId) => typeof parentByEntity.get(entityId) !== "number"
@@ -5056,7 +5282,7 @@ function buildNodeMapsFromSnapshot(snapshot) {
5056
5282
  (block) => block.component === "PrefabNode"
5057
5283
  );
5058
5284
  for (const entry of nodeBlock?.entries ?? []) {
5059
- const nodeId = asRecord4(entry.value)?.nodeId;
5285
+ const nodeId = asRecord5(entry.value)?.nodeId;
5060
5286
  if (typeof nodeId === "string" && nodeId.length > 0) {
5061
5287
  idToNode.set(entry.entityId, nodeId);
5062
5288
  nodeToId.set(nodeId, entry.entityId);
@@ -5086,9 +5312,36 @@ var toRefOrRaw = /* @__PURE__ */ __name((id, idToNode) => {
5086
5312
  const nodeId = idToNode.get(id);
5087
5313
  return nodeId !== void 0 ? makeNodeRef(nodeId) : id;
5088
5314
  }, "toRefOrRaw");
5315
+ function canonicalizeScriptDataFields(data, idToNode) {
5316
+ const canonicalData = {};
5317
+ for (const [key, fieldValue] of Object.entries(data)) {
5318
+ const field = asRecord5(fieldValue);
5319
+ if (field?.type === "entity" && typeof field.value === "number") {
5320
+ canonicalData[key] = {
5321
+ ...field,
5322
+ value: toRefOrRaw(field.value, idToNode)
5323
+ };
5324
+ continue;
5325
+ }
5326
+ const componentRef = asRecord5(field?.value);
5327
+ if (field?.type === "component" && componentRef && typeof componentRef.entityId === "number") {
5328
+ canonicalData[key] = {
5329
+ ...field,
5330
+ value: {
5331
+ ...componentRef,
5332
+ entityId: toRefOrRaw(componentRef.entityId, idToNode)
5333
+ }
5334
+ };
5335
+ continue;
5336
+ }
5337
+ canonicalData[key] = fieldValue;
5338
+ }
5339
+ return canonicalData;
5340
+ }
5341
+ __name(canonicalizeScriptDataFields, "canonicalizeScriptDataFields");
5089
5342
  function canonicalizeComponentValue(componentName, value, idToNode) {
5090
5343
  const cloned = clone(value);
5091
- const record = asRecord4(cloned);
5344
+ const record = asRecord5(cloned);
5092
5345
  if (!record) {
5093
5346
  return cloned;
5094
5347
  }
@@ -5107,43 +5360,27 @@ function canonicalizeComponentValue(componentName, value, idToNode) {
5107
5360
  const entries = Array.isArray(record.entries) ? record.entries : [];
5108
5361
  return {
5109
5362
  entries: entries.map((rawEntry) => {
5110
- const entry = asRecord4(rawEntry);
5363
+ const entry = asRecord5(rawEntry);
5111
5364
  if (!entry) {
5112
5365
  return rawEntry;
5113
5366
  }
5114
- const data = asRecord4(entry.data) ?? {};
5115
- const canonicalData = {};
5116
- for (const [key, fieldValue] of Object.entries(data)) {
5117
- const field = asRecord4(fieldValue);
5118
- if (field?.type === "entity" && typeof field.value === "number") {
5119
- canonicalData[key] = {
5120
- ...field,
5121
- value: toRefOrRaw(field.value, idToNode)
5122
- };
5123
- continue;
5124
- }
5125
- const componentRef = asRecord4(field?.value);
5126
- if (field?.type === "component" && componentRef && typeof componentRef.entityId === "number") {
5127
- canonicalData[key] = {
5128
- ...field,
5129
- value: {
5130
- ...componentRef,
5131
- entityId: toRefOrRaw(componentRef.entityId, idToNode)
5132
- }
5133
- };
5134
- continue;
5135
- }
5136
- canonicalData[key] = fieldValue;
5137
- }
5138
5367
  return {
5139
5368
  className: typeof entry.className === "string" ? entry.className : "",
5140
5369
  scriptUrl: typeof entry.scriptUrl === "string" ? entry.scriptUrl : "",
5141
5370
  enabled: typeof entry.enabled === "boolean" ? entry.enabled : true,
5142
- data: canonicalData
5371
+ data: canonicalizeScriptDataFields(asRecord5(entry.data) ?? {}, idToNode)
5143
5372
  };
5144
5373
  })
5145
5374
  };
5146
5375
  }
5376
+ if (componentName === "ScriptObjectComponent") {
5377
+ return {
5378
+ scriptUrl: typeof record.scriptUrl === "string" ? record.scriptUrl : null,
5379
+ className: typeof record.className === "string" ? record.className : null,
5380
+ enabled: typeof record.enabled === "boolean" ? record.enabled : true,
5381
+ data: canonicalizeScriptDataFields(asRecord5(record.data) ?? {}, idToNode)
5382
+ };
5383
+ }
5147
5384
  if (componentName === "InstancedMeshComponent") {
5148
5385
  if (Array.isArray(record.instanceEntityIds)) {
5149
5386
  record.instanceEntityIds = record.instanceEntityIds.map(
@@ -5168,7 +5405,7 @@ function decanonicalizeComponentValue(value, nodeToId) {
5168
5405
  if (Array.isArray(value)) {
5169
5406
  return value.map((item) => decanonicalizeComponentValue(item, nodeToId));
5170
5407
  }
5171
- const record = asRecord4(value);
5408
+ const record = asRecord5(value);
5172
5409
  if (record) {
5173
5410
  const result = {};
5174
5411
  for (const [key, item] of Object.entries(record)) {
@@ -5271,15 +5508,20 @@ function collectDiffPaths(base, current, prefix = "", out = []) {
5271
5508
  return out;
5272
5509
  }
5273
5510
  __name(collectDiffPaths, "collectDiffPaths");
5274
- function computeInstanceOverrides(baseSnapshot, instanceSnapshot) {
5275
- const baseMaps = buildNodeMapsFromSnapshot(baseSnapshot);
5276
- const instanceMaps = buildNodeMapsFromSnapshot(instanceSnapshot);
5511
+ function computeInstanceOverrides(baseSnapshot, instanceSnapshot, options) {
5512
+ const baseMaps = buildNodeKeyMapsFromSnapshot(baseSnapshot);
5513
+ const instanceMaps = buildNodeKeyMapsFromSnapshot(instanceSnapshot);
5277
5514
  const baseByEntity = indexSnapshotByEntity(baseSnapshot);
5278
5515
  const instanceByEntity = indexSnapshotByEntity(instanceSnapshot);
5279
5516
  const overrides = [];
5280
- for (const [nodeId, instanceEntityId] of instanceMaps.nodeToId) {
5281
- const baseEntityId = baseMaps.nodeToId.get(nodeId);
5517
+ for (const [nodeKey, instanceEntityId] of instanceMaps.keyToId) {
5518
+ const baseEntityId = baseMaps.keyToId.get(nodeKey);
5282
5519
  if (baseEntityId === void 0) {
5520
+ if (options?.emitAdditionMarkers) {
5521
+ overrides.push(
5522
+ encodeOverride(nodeKey, ADDED_NODE_MARKER_COMPONENT, "")
5523
+ );
5524
+ }
5283
5525
  continue;
5284
5526
  }
5285
5527
  const baseComponents = baseByEntity.get(baseEntityId);
@@ -5287,7 +5529,7 @@ function computeInstanceOverrides(baseSnapshot, instanceSnapshot) {
5287
5529
  if (!baseComponents) {
5288
5530
  continue;
5289
5531
  }
5290
- const isRoot = nodeId === baseMaps.rootNodeId;
5532
+ const isRoot = nodeKey === baseMaps.rootKey;
5291
5533
  for (const [componentName, baseRaw] of baseComponents) {
5292
5534
  if (OVERRIDE_DIFF_EXCLUDED_COMPONENTS.has(componentName)) {
5293
5535
  continue;
@@ -5302,15 +5544,15 @@ function computeInstanceOverrides(baseSnapshot, instanceSnapshot) {
5302
5544
  const baseCanonical = canonicalizeComponentValue(
5303
5545
  componentName,
5304
5546
  baseRaw,
5305
- baseMaps.idToNode
5547
+ baseMaps.idToKey
5306
5548
  );
5307
5549
  const instanceCanonical = canonicalizeComponentValue(
5308
5550
  componentName,
5309
5551
  instanceRaw,
5310
- instanceMaps.idToNode
5552
+ instanceMaps.idToKey
5311
5553
  );
5312
5554
  for (const path of collectDiffPaths(baseCanonical, instanceCanonical)) {
5313
- overrides.push(encodeOverride(nodeId, componentName, path));
5555
+ overrides.push(encodeOverride(nodeKey, componentName, path));
5314
5556
  }
5315
5557
  }
5316
5558
  }
@@ -5324,7 +5566,7 @@ function getAtPath(value, tokens) {
5324
5566
  if (Array.isArray(cursor)) {
5325
5567
  cursor = cursor[Number(token)];
5326
5568
  } else {
5327
- const record = asRecord4(cursor);
5569
+ const record = asRecord5(cursor);
5328
5570
  if (!record) {
5329
5571
  return void 0;
5330
5572
  }
@@ -5344,7 +5586,7 @@ function setAtPath(target, tokens, value) {
5344
5586
  if (Array.isArray(cursor)) {
5345
5587
  cursor = cursor[Number(token)];
5346
5588
  } else {
5347
- const record = asRecord4(cursor);
5589
+ const record = asRecord5(cursor);
5348
5590
  if (!record) {
5349
5591
  return;
5350
5592
  }
@@ -5358,7 +5600,7 @@ function setAtPath(target, tokens, value) {
5358
5600
  if (Array.isArray(cursor)) {
5359
5601
  cursor[Number(last)] = value;
5360
5602
  } else {
5361
- const record = asRecord4(cursor);
5603
+ const record = asRecord5(cursor);
5362
5604
  if (record) {
5363
5605
  if (value === void 0) {
5364
5606
  delete record[last];
@@ -5390,15 +5632,20 @@ __name(mergeComponentValue, "mergeComponentValue");
5390
5632
  var INSTANTIATE_EXCLUDED_COMPONENTS = /* @__PURE__ */ new Set([
5391
5633
  "Environment",
5392
5634
  "Postprocessing",
5393
- "SelectionTransformState",
5394
- "PrefabInstance"
5635
+ "SelectionTransformState"
5395
5636
  ]);
5396
5637
  function instantiateSubtree(world, objectManagementSystem, snapshot) {
5638
+ const snapshotRootIds = new Set(findSnapshotRootEntityIds(snapshot));
5397
5639
  const safeSnapshot = {
5398
5640
  entities: snapshot.entities,
5399
- components: snapshot.components.filter(
5400
- (block) => !INSTANTIATE_EXCLUDED_COMPONENTS.has(block.component)
5401
- )
5641
+ components: snapshot.components.filter((block) => !INSTANTIATE_EXCLUDED_COMPONENTS.has(block.component)).map(
5642
+ (block) => block.component === "PrefabInstance" ? {
5643
+ component: block.component,
5644
+ entries: block.entries.filter(
5645
+ (entry) => !snapshotRootIds.has(entry.entityId)
5646
+ )
5647
+ } : block
5648
+ ).filter((block) => block.entries.length > 0)
5402
5649
  };
5403
5650
  const result = hydrateWorldFromSnapshotDetailed(
5404
5651
  safeSnapshot,
@@ -5418,6 +5665,11 @@ __name(instantiateSubtree, "instantiateSubtree");
5418
5665
 
5419
5666
  // core/prefab/types.ts
5420
5667
  var PREFAB_FILE_VERSION = 1;
5668
+ var PREFAB_FILE_VERSION_NESTED = 2;
5669
+ function prefabFileVersionFor(snapshot) {
5670
+ return findTopLevelNestedRegions(snapshot).length > 0 ? PREFAB_FILE_VERSION_NESTED : PREFAB_FILE_VERSION;
5671
+ }
5672
+ __name(prefabFileVersionFor, "prefabFileVersionFor");
5421
5673
  var isRecord = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value), "isRecord");
5422
5674
  function parsePrefabAsset(json) {
5423
5675
  if (!isRecord(json)) {
@@ -5721,7 +5973,7 @@ function transitionToClip(runtime, nextClipId, crossFadeDuration) {
5721
5973
  }
5722
5974
  __name(transitionToClip, "transitionToClip");
5723
5975
  function applyActionState(action, component, paused, shouldLoop) {
5724
- const loopMode = shouldLoop ? THREE35__namespace.LoopRepeat : THREE35__namespace.LoopOnce;
5976
+ const loopMode = shouldLoop ? THREE36__namespace.LoopRepeat : THREE36__namespace.LoopOnce;
5725
5977
  const repetitions = shouldLoop ? Infinity : 1;
5726
5978
  action.setLoop(loopMode, repetitions);
5727
5979
  action.clampWhenFinished = !shouldLoop;
@@ -5894,7 +6146,7 @@ var _AnimationSystem = class _AnimationSystem {
5894
6146
  if (runtime) {
5895
6147
  stopAllActions(runtime);
5896
6148
  }
5897
- const mixer = new THREE35__namespace.AnimationMixer(root);
6149
+ const mixer = new THREE36__namespace.AnimationMixer(root);
5898
6150
  const entries2 = readRuntimeClipEntries(animation);
5899
6151
  const indexedActions = createActions(mixer, entries2);
5900
6152
  runtime = {
@@ -6020,11 +6272,11 @@ function normalizeOrthoBounds(component) {
6020
6272
  }
6021
6273
  __name(normalizeOrthoBounds, "normalizeOrthoBounds");
6022
6274
  function isPerspectiveCamera(camera) {
6023
- return camera instanceof THREE35__namespace.PerspectiveCamera;
6275
+ return camera instanceof THREE36__namespace.PerspectiveCamera;
6024
6276
  }
6025
6277
  __name(isPerspectiveCamera, "isPerspectiveCamera");
6026
6278
  function isOrthographicCamera(camera) {
6027
- return camera instanceof THREE35__namespace.OrthographicCamera;
6279
+ return camera instanceof THREE36__namespace.OrthographicCamera;
6028
6280
  }
6029
6281
  __name(isOrthographicCamera, "isOrthographicCamera");
6030
6282
  function readWindowAspect() {
@@ -6077,7 +6329,7 @@ var _CameraSyncSystem = class _CameraSyncSystem {
6077
6329
  continue;
6078
6330
  }
6079
6331
  const camera = objectRef.object;
6080
- if (!(camera instanceof THREE35__namespace.Camera)) {
6332
+ if (!(camera instanceof THREE36__namespace.Camera)) {
6081
6333
  continue;
6082
6334
  }
6083
6335
  const nextSignature = buildSignature(component, camera, windowAspect);
@@ -6141,7 +6393,7 @@ var MIN_DENSITY = 0;
6141
6393
  function createGradientTexture(effect, colors) {
6142
6394
  if (typeof document === "undefined") {
6143
6395
  const pixel = new Uint8Array([30, 30, 30, 255]);
6144
- const fallback = new THREE35__namespace.DataTexture(pixel, 1, 1, THREE35__namespace.RGBAFormat);
6396
+ const fallback = new THREE36__namespace.DataTexture(pixel, 1, 1, THREE36__namespace.RGBAFormat);
6145
6397
  fallback.needsUpdate = true;
6146
6398
  return fallback;
6147
6399
  }
@@ -6150,7 +6402,7 @@ function createGradientTexture(effect, colors) {
6150
6402
  canvas.height = 512;
6151
6403
  const context = canvas.getContext("2d");
6152
6404
  if (!context) {
6153
- const fallback = new THREE35__namespace.CanvasTexture(canvas);
6405
+ const fallback = new THREE36__namespace.CanvasTexture(canvas);
6154
6406
  fallback.needsUpdate = true;
6155
6407
  return fallback;
6156
6408
  }
@@ -6178,15 +6430,15 @@ function createGradientTexture(effect, colors) {
6178
6430
  context.fillRect(0, 0, 512, 512);
6179
6431
  context.globalCompositeOperation = "source-over";
6180
6432
  }
6181
- const texture = new THREE35__namespace.CanvasTexture(canvas);
6182
- texture.colorSpace = THREE35__namespace.SRGBColorSpace;
6433
+ const texture = new THREE36__namespace.CanvasTexture(canvas);
6434
+ texture.colorSpace = THREE36__namespace.SRGBColorSpace;
6183
6435
  texture.needsUpdate = true;
6184
6436
  return texture;
6185
6437
  }
6186
6438
  __name(createGradientTexture, "createGradientTexture");
6187
6439
  var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
6188
6440
  constructor(scene) {
6189
- this.textureLoader = new THREE35__namespace.TextureLoader();
6441
+ this.textureLoader = new THREE36__namespace.TextureLoader();
6190
6442
  this.signature = null;
6191
6443
  this.activeTexture = null;
6192
6444
  this.pendingImageUrl = null;
@@ -6209,7 +6461,7 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
6209
6461
  if (skybox.type === "color") {
6210
6462
  this.disposeActiveTexture();
6211
6463
  this.pendingImageUrl = null;
6212
- this.scene.background = new THREE35__namespace.Color(skybox.color || "#1e1e1e");
6464
+ this.scene.background = new THREE36__namespace.Color(skybox.color || "#1e1e1e");
6213
6465
  return;
6214
6466
  }
6215
6467
  if (skybox.type === "gradient") {
@@ -6243,7 +6495,7 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
6243
6495
  texture.dispose();
6244
6496
  return;
6245
6497
  }
6246
- texture.colorSpace = THREE35__namespace.SRGBColorSpace;
6498
+ texture.colorSpace = THREE36__namespace.SRGBColorSpace;
6247
6499
  this.activeTexture = texture;
6248
6500
  this.scene.background = texture;
6249
6501
  },
@@ -6262,16 +6514,16 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
6262
6514
  this.scene.fog = null;
6263
6515
  return;
6264
6516
  }
6265
- const fogColor = new THREE35__namespace.Color(fog.color || "#1e1e1e");
6517
+ const fogColor = new THREE36__namespace.Color(fog.color || "#1e1e1e");
6266
6518
  if (fog.type === "linear") {
6267
6519
  const near = Number.isFinite(fog.linear.near) ? fog.linear.near : 1;
6268
6520
  const farCandidate = Number.isFinite(fog.linear.far) ? fog.linear.far : near + 10;
6269
6521
  const far = Math.max(near + MIN_FOG_DELTA, farCandidate);
6270
- this.scene.fog = new THREE35__namespace.Fog(fogColor, near, far);
6522
+ this.scene.fog = new THREE36__namespace.Fog(fogColor, near, far);
6271
6523
  return;
6272
6524
  }
6273
6525
  const density = Number.isFinite(fog.exponential.density) ? Math.max(MIN_DENSITY, fog.exponential.density) : 2e-3;
6274
- this.scene.fog = new THREE35__namespace.FogExp2(fogColor, density);
6526
+ this.scene.fog = new THREE36__namespace.FogExp2(fogColor, density);
6275
6527
  }
6276
6528
  update(world) {
6277
6529
  const entityIds = world.query(Environment);
@@ -6353,10 +6605,10 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
6353
6605
  );
6354
6606
  }
6355
6607
  if (values.bloom.enabled) {
6356
- const size = this.renderer.getSize(new THREE35__namespace.Vector2());
6608
+ const size = this.renderer.getSize(new THREE36__namespace.Vector2());
6357
6609
  composer.addPass(
6358
6610
  new UnrealBloomPass_js.UnrealBloomPass(
6359
- new THREE35__namespace.Vector2(size.width, size.height),
6611
+ new THREE36__namespace.Vector2(size.width, size.height),
6360
6612
  values.bloom.intensity,
6361
6613
  values.bloom.radius,
6362
6614
  values.bloom.threshold
@@ -6401,7 +6653,7 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
6401
6653
  if (values.dotScreen.enabled) {
6402
6654
  composer.addPass(
6403
6655
  new DotScreenPass_js.DotScreenPass(
6404
- new THREE35__namespace.Vector2(0, 0),
6656
+ new THREE36__namespace.Vector2(0, 0),
6405
6657
  values.dotScreen.angle ?? values.dotScreen.dotScreenAngle,
6406
6658
  values.dotScreen.scale ?? values.dotScreen.dotScreenScale
6407
6659
  )
@@ -6475,7 +6727,7 @@ function computeColliderState(colliderValues, object) {
6475
6727
  if (!object) {
6476
6728
  return colliderValues;
6477
6729
  }
6478
- const scale = new THREE35__namespace.Vector3();
6730
+ const scale = new THREE36__namespace.Vector3();
6479
6731
  object.getWorldScale(scale);
6480
6732
  return {
6481
6733
  ...colliderValues,
@@ -6526,8 +6778,8 @@ function createColliderDesc(RAPIER, values, triMeshData) {
6526
6778
  values.offsetPosition.y,
6527
6779
  values.offsetPosition.z
6528
6780
  );
6529
- const offsetQuaternion = new THREE35__namespace.Quaternion().setFromEuler(
6530
- new THREE35__namespace.Euler(
6781
+ const offsetQuaternion = new THREE36__namespace.Quaternion().setFromEuler(
6782
+ new THREE36__namespace.Euler(
6531
6783
  values.offsetRotation.x,
6532
6784
  values.offsetRotation.y,
6533
6785
  values.offsetRotation.z
@@ -6538,7 +6790,7 @@ function createColliderDesc(RAPIER, values, triMeshData) {
6538
6790
  }
6539
6791
  __name(createColliderDesc, "createColliderDesc");
6540
6792
  function findFirstMeshWithGeometry(object) {
6541
- if (object instanceof THREE35__namespace.Mesh && object.geometry) {
6793
+ if (object instanceof THREE36__namespace.Mesh && object.geometry) {
6542
6794
  return object;
6543
6795
  }
6544
6796
  let found = null;
@@ -6546,7 +6798,7 @@ function findFirstMeshWithGeometry(object) {
6546
6798
  if (found) {
6547
6799
  return;
6548
6800
  }
6549
- if (child instanceof THREE35__namespace.Mesh && child.geometry) {
6801
+ if (child instanceof THREE36__namespace.Mesh && child.geometry) {
6550
6802
  found = child;
6551
6803
  }
6552
6804
  });
@@ -6572,13 +6824,13 @@ function createTriMeshData(object) {
6572
6824
  }
6573
6825
  object.updateWorldMatrix(true, true);
6574
6826
  mesh.updateWorldMatrix(true, true);
6575
- const worldToObject = new THREE35__namespace.Matrix4().copy(object.matrixWorld).invert();
6576
- const relativeMatrix = new THREE35__namespace.Matrix4().multiplyMatrices(
6827
+ const worldToObject = new THREE36__namespace.Matrix4().copy(object.matrixWorld).invert();
6828
+ const relativeMatrix = new THREE36__namespace.Matrix4().multiplyMatrices(
6577
6829
  worldToObject,
6578
6830
  mesh.matrixWorld
6579
6831
  );
6580
6832
  const vertices = new Float32Array(positionCount * 3);
6581
- const point = new THREE35__namespace.Vector3();
6833
+ const point = new THREE36__namespace.Vector3();
6582
6834
  for (let index = 0; index < positionCount; index += 1) {
6583
6835
  point.set(
6584
6836
  positionAttribute.getX(index),
@@ -6616,8 +6868,8 @@ function createTriMeshData(object) {
6616
6868
  }
6617
6869
  __name(createTriMeshData, "createTriMeshData");
6618
6870
  function syncBodyFromTransform(body, transform) {
6619
- const quaternion = new THREE35__namespace.Quaternion().setFromEuler(
6620
- new THREE35__namespace.Euler(transform.rotation.x, transform.rotation.y, transform.rotation.z)
6871
+ const quaternion = new THREE36__namespace.Quaternion().setFromEuler(
6872
+ new THREE36__namespace.Euler(transform.rotation.x, transform.rotation.y, transform.rotation.z)
6621
6873
  );
6622
6874
  body.setTranslation(
6623
6875
  {
@@ -6644,8 +6896,8 @@ function syncTransformFromBody(transform, body) {
6644
6896
  transform.position.x = position.x;
6645
6897
  transform.position.y = position.y;
6646
6898
  transform.position.z = position.z;
6647
- const euler = new THREE35__namespace.Euler().setFromQuaternion(
6648
- new THREE35__namespace.Quaternion(rotation.x, rotation.y, rotation.z, rotation.w)
6899
+ const euler = new THREE36__namespace.Euler().setFromQuaternion(
6900
+ new THREE36__namespace.Quaternion(rotation.x, rotation.y, rotation.z, rotation.w)
6649
6901
  );
6650
6902
  transform.rotation.x = euler.x;
6651
6903
  transform.rotation.y = euler.y;
@@ -6757,8 +7009,8 @@ var _PhysicsSyncSystem = class _PhysicsSyncSystem {
6757
7009
  transform.position.y,
6758
7010
  transform.position.z
6759
7011
  );
6760
- const quaternion = new THREE35__namespace.Quaternion().setFromEuler(
6761
- new THREE35__namespace.Euler(
7012
+ const quaternion = new THREE36__namespace.Quaternion().setFromEuler(
7013
+ new THREE36__namespace.Euler(
6762
7014
  transform.rotation.x,
6763
7015
  transform.rotation.y,
6764
7016
  transform.rotation.z
@@ -7333,7 +7585,7 @@ function applyLightValues(lightComponent) {
7333
7585
  values.castShadow
7334
7586
  );
7335
7587
  }
7336
- if (light instanceof THREE35__namespace.PointLight) {
7588
+ if (light instanceof THREE36__namespace.PointLight) {
7337
7589
  if (typeof values.distance === "number" && Number.isFinite(values.distance)) {
7338
7590
  light.distance = Math.max(MIN_LIGHT_DISTANCE, values.distance);
7339
7591
  }
@@ -7341,7 +7593,7 @@ function applyLightValues(lightComponent) {
7341
7593
  light.decay = Math.max(0, values.decay);
7342
7594
  }
7343
7595
  }
7344
- if (light instanceof THREE35__namespace.SpotLight) {
7596
+ if (light instanceof THREE36__namespace.SpotLight) {
7345
7597
  if (typeof values.distance === "number" && Number.isFinite(values.distance)) {
7346
7598
  light.distance = Math.max(MIN_LIGHT_DISTANCE, values.distance);
7347
7599
  }
@@ -7355,7 +7607,7 @@ function applyLightValues(lightComponent) {
7355
7607
  light.penumbra = Math.max(0, Math.min(1, values.penumbra));
7356
7608
  }
7357
7609
  }
7358
- if (light instanceof THREE35__namespace.RectAreaLight) {
7610
+ if (light instanceof THREE36__namespace.RectAreaLight) {
7359
7611
  if (typeof values.width === "number" && Number.isFinite(values.width)) {
7360
7612
  light.width = Math.max(MIN_AREA_SIZE, values.width);
7361
7613
  }
@@ -7416,15 +7668,15 @@ function resolveMaterialPropertyKey(key) {
7416
7668
  __name(resolveMaterialPropertyKey, "resolveMaterialPropertyKey");
7417
7669
  function createMaterialByType(type) {
7418
7670
  if (type === "basic") {
7419
- return new THREE35__namespace.MeshBasicMaterial();
7671
+ return new THREE36__namespace.MeshBasicMaterial();
7420
7672
  }
7421
7673
  if (type === "phong") {
7422
- return new THREE35__namespace.MeshPhongMaterial();
7674
+ return new THREE36__namespace.MeshPhongMaterial();
7423
7675
  }
7424
7676
  if (type === "physical") {
7425
- return new THREE35__namespace.MeshPhysicalMaterial();
7677
+ return new THREE36__namespace.MeshPhysicalMaterial();
7426
7678
  }
7427
- return new THREE35__namespace.MeshStandardMaterial();
7679
+ return new THREE36__namespace.MeshStandardMaterial();
7428
7680
  }
7429
7681
  __name(createMaterialByType, "createMaterialByType");
7430
7682
  function replaceMaterialAcrossObject(object, previous, next) {
@@ -7483,12 +7735,12 @@ function applyTextureFiltering(material, filtering) {
7483
7735
  const target = material;
7484
7736
  for (const slot of materialTextureSlots) {
7485
7737
  const texture = target[slot];
7486
- if (!texture || !(texture instanceof THREE35__namespace.Texture)) {
7738
+ if (!texture || !(texture instanceof THREE36__namespace.Texture)) {
7487
7739
  continue;
7488
7740
  }
7489
7741
  const useMipmaps = texture.generateMipmaps !== false;
7490
- texture.magFilter = sharp ? THREE35__namespace.NearestFilter : THREE35__namespace.LinearFilter;
7491
- texture.minFilter = useMipmaps ? sharp ? THREE35__namespace.NearestMipmapNearestFilter : THREE35__namespace.LinearMipmapLinearFilter : sharp ? THREE35__namespace.NearestFilter : THREE35__namespace.LinearFilter;
7742
+ texture.magFilter = sharp ? THREE36__namespace.NearestFilter : THREE36__namespace.LinearFilter;
7743
+ texture.minFilter = useMipmaps ? sharp ? THREE36__namespace.NearestMipmapNearestFilter : THREE36__namespace.LinearMipmapLinearFilter : sharp ? THREE36__namespace.NearestFilter : THREE36__namespace.LinearFilter;
7492
7744
  texture.needsUpdate = true;
7493
7745
  }
7494
7746
  material.needsUpdate = true;
@@ -7498,12 +7750,12 @@ function setTextureMipmaps(material, enabled) {
7498
7750
  const target = material;
7499
7751
  for (const slot of materialTextureSlots) {
7500
7752
  const texture = target[slot];
7501
- if (!texture || !(texture instanceof THREE35__namespace.Texture)) {
7753
+ if (!texture || !(texture instanceof THREE36__namespace.Texture)) {
7502
7754
  continue;
7503
7755
  }
7504
7756
  texture.generateMipmaps = enabled;
7505
- const sharp = texture.magFilter === THREE35__namespace.NearestFilter;
7506
- texture.minFilter = enabled ? sharp ? THREE35__namespace.NearestMipmapNearestFilter : THREE35__namespace.LinearMipmapLinearFilter : sharp ? THREE35__namespace.NearestFilter : THREE35__namespace.LinearFilter;
7757
+ const sharp = texture.magFilter === THREE36__namespace.NearestFilter;
7758
+ texture.minFilter = enabled ? sharp ? THREE36__namespace.NearestMipmapNearestFilter : THREE36__namespace.LinearMipmapLinearFilter : sharp ? THREE36__namespace.NearestFilter : THREE36__namespace.LinearFilter;
7507
7759
  texture.needsUpdate = true;
7508
7760
  }
7509
7761
  material.needsUpdate = true;
@@ -7514,7 +7766,7 @@ function assignMaterialTexture(material, rawKey, url, textureCache) {
7514
7766
  const key = resolveMaterialPropertyKey(rawKey);
7515
7767
  let texture = textureCache.get(url);
7516
7768
  if (!texture) {
7517
- texture = new THREE35__namespace.TextureLoader().load(url);
7769
+ texture = new THREE36__namespace.TextureLoader().load(url);
7518
7770
  textureCache.set(url, texture);
7519
7771
  }
7520
7772
  target[key] = texture;
@@ -7712,12 +7964,12 @@ function resolvePrimaryMesh(object) {
7712
7964
  if (!object) {
7713
7965
  return null;
7714
7966
  }
7715
- if (object instanceof THREE35__namespace.Mesh) {
7967
+ if (object instanceof THREE36__namespace.Mesh) {
7716
7968
  return object;
7717
7969
  }
7718
7970
  let found = null;
7719
7971
  object.traverse((child) => {
7720
- if (!found && child instanceof THREE35__namespace.Mesh) {
7972
+ if (!found && child instanceof THREE36__namespace.Mesh) {
7721
7973
  found = child;
7722
7974
  }
7723
7975
  });
@@ -7738,22 +7990,22 @@ function applyGeometry(component) {
7738
7990
  switch (component.kind) {
7739
7991
  case "cube": {
7740
7992
  const params = sanitized;
7741
- nextGeometry = new THREE35__namespace.BoxGeometry(params.width, params.height, params.depth);
7993
+ nextGeometry = new THREE36__namespace.BoxGeometry(params.width, params.height, params.depth);
7742
7994
  break;
7743
7995
  }
7744
7996
  case "plane": {
7745
7997
  const params = sanitized;
7746
- nextGeometry = new THREE35__namespace.PlaneGeometry(params.width, params.height);
7998
+ nextGeometry = new THREE36__namespace.PlaneGeometry(params.width, params.height);
7747
7999
  break;
7748
8000
  }
7749
8001
  case "sphere": {
7750
8002
  const params = sanitized;
7751
- nextGeometry = new THREE35__namespace.SphereGeometry(params.radius, 24, 24);
8003
+ nextGeometry = new THREE36__namespace.SphereGeometry(params.radius, 24, 24);
7752
8004
  break;
7753
8005
  }
7754
8006
  case "cylinder": {
7755
8007
  const params = sanitized;
7756
- nextGeometry = new THREE35__namespace.CylinderGeometry(
8008
+ nextGeometry = new THREE36__namespace.CylinderGeometry(
7757
8009
  params.radius,
7758
8010
  params.radius,
7759
8011
  params.height,
@@ -7763,7 +8015,7 @@ function applyGeometry(component) {
7763
8015
  }
7764
8016
  case "capsule": {
7765
8017
  const params = sanitized;
7766
- nextGeometry = new THREE35__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
8018
+ nextGeometry = new THREE36__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
7767
8019
  break;
7768
8020
  }
7769
8021
  default:
@@ -7779,7 +8031,7 @@ function applyShadowFlags(component) {
7779
8031
  return;
7780
8032
  }
7781
8033
  component.object.traverse((child) => {
7782
- if (child instanceof THREE35__namespace.Mesh) {
8034
+ if (child instanceof THREE36__namespace.Mesh) {
7783
8035
  child.castShadow = component.castShadow;
7784
8036
  child.receiveShadow = component.receiveShadow;
7785
8037
  }
@@ -7862,35 +8114,35 @@ function buildGeometry(component) {
7862
8114
  switch (component.meshKind) {
7863
8115
  case "cube": {
7864
8116
  const params = p;
7865
- return new THREE35__namespace.BoxGeometry(params.width, params.height, params.depth);
8117
+ return new THREE36__namespace.BoxGeometry(params.width, params.height, params.depth);
7866
8118
  }
7867
8119
  case "plane": {
7868
8120
  const params = p;
7869
- return new THREE35__namespace.PlaneGeometry(params.width, params.height);
8121
+ return new THREE36__namespace.PlaneGeometry(params.width, params.height);
7870
8122
  }
7871
8123
  case "sphere": {
7872
8124
  const params = p;
7873
- return new THREE35__namespace.SphereGeometry(params.radius, 24, 24);
8125
+ return new THREE36__namespace.SphereGeometry(params.radius, 24, 24);
7874
8126
  }
7875
8127
  case "cylinder": {
7876
8128
  const params = p;
7877
- return new THREE35__namespace.CylinderGeometry(params.radius, params.radius, params.height, 20);
8129
+ return new THREE36__namespace.CylinderGeometry(params.radius, params.radius, params.height, 20);
7878
8130
  }
7879
8131
  case "capsule": {
7880
8132
  const params = p;
7881
- return new THREE35__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
8133
+ return new THREE36__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
7882
8134
  }
7883
8135
  default:
7884
- return new THREE35__namespace.BoxGeometry(1, 1, 1);
8136
+ return new THREE36__namespace.BoxGeometry(1, 1, 1);
7885
8137
  }
7886
8138
  }
7887
8139
  __name(buildGeometry, "buildGeometry");
7888
- var _position = new THREE35__namespace.Vector3();
7889
- var _quaternion = new THREE35__namespace.Quaternion();
7890
- var _euler = new THREE35__namespace.Euler();
7891
- var _scale = new THREE35__namespace.Vector3();
7892
- var _matrix = new THREE35__namespace.Matrix4();
7893
- var _modelMatrix = new THREE35__namespace.Matrix4();
8140
+ var _position = new THREE36__namespace.Vector3();
8141
+ var _quaternion = new THREE36__namespace.Quaternion();
8142
+ var _euler = new THREE36__namespace.Euler();
8143
+ var _scale = new THREE36__namespace.Vector3();
8144
+ var _matrix = new THREE36__namespace.Matrix4();
8145
+ var _modelMatrix = new THREE36__namespace.Matrix4();
7894
8146
  function instanceTransformFromComponent(transform, out) {
7895
8147
  _position.set(transform.position.x, transform.position.y, transform.position.z);
7896
8148
  _euler.set(transform.rotation.x, transform.rotation.y, transform.rotation.z, "XYZ");
@@ -8043,7 +8295,7 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
8043
8295
  const sourceMaterial = Array.isArray(meshChild.material) ? meshChild.material.map((m) => m.clone()) : meshChild.material.clone();
8044
8296
  meshChild.updateWorldMatrix(true, false);
8045
8297
  const localMatrix = meshChild.matrixWorld.clone();
8046
- const instancedMesh2 = new THREE35__namespace.InstancedMesh(
8298
+ const instancedMesh2 = new THREE36__namespace.InstancedMesh(
8047
8299
  geometry2,
8048
8300
  Array.isArray(sourceMaterial) ? sourceMaterial : sourceMaterial,
8049
8301
  count2
@@ -8068,7 +8320,7 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
8068
8320
  this.loadingSignatures.delete(targetEntityId);
8069
8321
  return;
8070
8322
  }
8071
- const group = new THREE35__namespace.Group();
8323
+ const group = new THREE36__namespace.Group();
8072
8324
  for (const entry of entries) {
8073
8325
  group.add(entry.instancedMesh);
8074
8326
  }
@@ -8086,8 +8338,8 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
8086
8338
  }
8087
8339
  const count = instanceCount;
8088
8340
  const geometry = buildGeometry(comp);
8089
- const material = new THREE35__namespace.MeshStandardMaterial({ color: "#ffffff" });
8090
- const instancedMesh = new THREE35__namespace.InstancedMesh(geometry, material, count);
8341
+ const material = new THREE36__namespace.MeshStandardMaterial({ color: "#ffffff" });
8342
+ const instancedMesh = new THREE36__namespace.InstancedMesh(geometry, material, count);
8091
8343
  instancedMesh.castShadow = comp.castShadow;
8092
8344
  instancedMesh.receiveShadow = comp.receiveShadow;
8093
8345
  for (let i = 0; i < count; i++) {
@@ -8270,7 +8522,7 @@ var _Behaviour = class _Behaviour {
8270
8522
  if (!this.threeRef) {
8271
8523
  return null;
8272
8524
  }
8273
- const position = new THREE35__namespace.Vector3();
8525
+ const position = new THREE36__namespace.Vector3();
8274
8526
  this.threeRef.object.getWorldPosition(position);
8275
8527
  return position;
8276
8528
  }
@@ -8282,7 +8534,7 @@ var _Behaviour = class _Behaviour {
8282
8534
  if (!this.threeRef) {
8283
8535
  return null;
8284
8536
  }
8285
- const target = new THREE35__namespace.Vector3();
8537
+ const target = new THREE36__namespace.Vector3();
8286
8538
  this.threeRef.object.getWorldDirection(target);
8287
8539
  return target;
8288
8540
  }
@@ -8344,7 +8596,7 @@ var _Behaviour = class _Behaviour {
8344
8596
  if (!this.threeRef) {
8345
8597
  return;
8346
8598
  }
8347
- const rotation = new THREE35__namespace.Quaternion();
8599
+ const rotation = new THREE36__namespace.Quaternion();
8348
8600
  this.threeRef.object.getWorldQuaternion(rotation);
8349
8601
  rotation.slerp(targetRotation, alpha);
8350
8602
  this.transform.setRotation(rotation);
@@ -8360,10 +8612,10 @@ var _Behaviour = class _Behaviour {
8360
8612
  if (!this.threeRef) {
8361
8613
  return;
8362
8614
  }
8363
- const clone2 = this.threeRef.object.clone();
8364
- const rotation = new THREE35__namespace.Quaternion();
8365
- clone2.lookAt(targetPosition);
8366
- clone2.getWorldQuaternion(rotation);
8615
+ const clone3 = this.threeRef.object.clone();
8616
+ const rotation = new THREE36__namespace.Quaternion();
8617
+ clone3.lookAt(targetPosition);
8618
+ clone3.getWorldQuaternion(rotation);
8367
8619
  this.transform.setRotation(rotation);
8368
8620
  }
8369
8621
  /** Returns every component currently attached to this entity. */
@@ -8428,22 +8680,14 @@ var _Behaviour = class _Behaviour {
8428
8680
  /**
8429
8681
  * Called once before the first {@link Behaviour.onUpdate}. Override to
8430
8682
  * default and validate {@link Behaviour.data}, cache references, or set
8431
- * initial state.
8432
- *
8433
- * @remarks
8434
- * Also called in editor mode when `executeInEditor` is `true` on the script
8435
- * entry.
8683
+ * initial state. Runs at preview/runtime only — never in the editor.
8436
8684
  */
8437
8685
  init() {
8438
8686
  }
8439
8687
  /**
8440
8688
  * Called every frame while the script is enabled. Override with the
8441
- * script's main per-frame logic.
8442
- *
8443
- * @remarks
8444
- * Also called every frame in editor mode when `executeInEditor` is `true`.
8445
- * Access the Three.js scene with `this.world.getScene()` for editor-only
8446
- * rendering work such as custom shaders or procedural geometry.
8689
+ * script's main per-frame logic. Runs at preview/runtime only — never in the
8690
+ * editor (use {@link ScriptObject} for editor-visible visuals).
8447
8691
  */
8448
8692
  onUpdate() {
8449
8693
  }
@@ -8482,7 +8726,14 @@ __name(_Behaviour, "Behaviour");
8482
8726
  _Behaviour.__reluBehaviourClass = true;
8483
8727
  var Behaviour = _Behaviour;
8484
8728
 
8485
- // core/systems/ScriptBehaviourSystem.ts
8729
+ // core/systems/scriptShared.ts
8730
+ async function defaultModuleLoader(scriptUrl) {
8731
+ return await import(
8732
+ /* webpackIgnore: true */
8733
+ scriptUrl
8734
+ );
8735
+ }
8736
+ __name(defaultModuleLoader, "defaultModuleLoader");
8486
8737
  function toErrorMessage(error) {
8487
8738
  const sanitize = /* @__PURE__ */ __name((value) => value.replace(/localasset:\/\/[^/]+\//g, "localasset://").replace(/\/Users\/[^\s)]+/g, "[local path]"), "sanitize");
8488
8739
  if (error instanceof Error && error.message) {
@@ -8494,26 +8745,22 @@ function toErrorMessage(error) {
8494
8745
  return "Unknown script error.";
8495
8746
  }
8496
8747
  __name(toErrorMessage, "toErrorMessage");
8497
- function buildInstanceKey(entityId, scriptUrl, className) {
8498
- return `${entityId}:${scriptUrl}:${className}`;
8499
- }
8500
- __name(buildInstanceKey, "buildInstanceKey");
8501
- function resolveBehaviourCtor(moduleValue, className) {
8748
+ function resolveScriptCtor(moduleValue, className, options) {
8502
8749
  const named = moduleValue[className];
8503
8750
  const fallback = moduleValue.default;
8504
8751
  const candidate = typeof named === "function" ? named : typeof fallback === "function" ? fallback : null;
8505
8752
  if (!candidate) {
8506
8753
  return null;
8507
8754
  }
8508
- if (!(candidate.prototype instanceof Behaviour)) {
8509
- const isBehaviourSubclass = !!candidate.__reluBehaviourClass;
8510
- if (!isBehaviourSubclass) {
8755
+ if (!(candidate.prototype instanceof options.baseClass)) {
8756
+ const marker = candidate[options.markerKey];
8757
+ if (!marker) {
8511
8758
  return null;
8512
8759
  }
8513
8760
  }
8514
8761
  return candidate;
8515
8762
  }
8516
- __name(resolveBehaviourCtor, "resolveBehaviourCtor");
8763
+ __name(resolveScriptCtor, "resolveScriptCtor");
8517
8764
  function normalizeScriptData(value) {
8518
8765
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
8519
8766
  }
@@ -8595,8 +8842,8 @@ function resolveInputData(world, rawData) {
8595
8842
  return resolved;
8596
8843
  }
8597
8844
  __name(resolveInputData, "resolveInputData");
8598
- function serializeDataForStorage(rawData, behaviourData) {
8599
- const result = { ...behaviourData };
8845
+ function serializeDataForStorage(rawData, instanceData) {
8846
+ const result = { ...instanceData };
8600
8847
  for (const [key, rawValue] of Object.entries(rawData)) {
8601
8848
  if (isRawEntityInput(rawValue) || isRawComponentInput(rawValue)) {
8602
8849
  result[key] = rawValue;
@@ -8605,13 +8852,25 @@ function serializeDataForStorage(rawData, behaviourData) {
8605
8852
  return result;
8606
8853
  }
8607
8854
  __name(serializeDataForStorage, "serializeDataForStorage");
8855
+
8856
+ // core/systems/ScriptBehaviourSystem.ts
8857
+ function buildInstanceKey(entityId, scriptUrl, className) {
8858
+ return `${entityId}:${scriptUrl}:${className}`;
8859
+ }
8860
+ __name(buildInstanceKey, "buildInstanceKey");
8861
+ function resolveBehaviourCtor(moduleValue, className) {
8862
+ return resolveScriptCtor(moduleValue, className, {
8863
+ baseClass: Behaviour,
8864
+ markerKey: "__reluBehaviourClass"
8865
+ });
8866
+ }
8867
+ __name(resolveBehaviourCtor, "resolveBehaviourCtor");
8608
8868
  function normalizeEntry(value, fallbackEntityId) {
8609
8869
  return {
8610
8870
  entityId: typeof value?.entityId === "number" ? value.entityId : fallbackEntityId,
8611
8871
  className: typeof value?.className === "string" ? value.className : "",
8612
8872
  scriptUrl: typeof value?.scriptUrl === "string" ? value.scriptUrl : "",
8613
8873
  enabled: typeof value?.enabled === "boolean" ? value.enabled : true,
8614
- executeInEditor: typeof value?.executeInEditor === "boolean" ? value.executeInEditor : false,
8615
8874
  data: normalizeScriptData(value?.data),
8616
8875
  runtimeState: value?.runtimeState === "idle" || value?.runtimeState === "loading" || value?.runtimeState === "ready" || value?.runtimeState === "error" ? value.runtimeState : void 0,
8617
8876
  runtimeMessage: typeof value?.runtimeMessage === "string" ? value.runtimeMessage : void 0
@@ -8634,13 +8893,6 @@ function writeScriptEntries(component, entries) {
8634
8893
  }
8635
8894
  }
8636
8895
  __name(writeScriptEntries, "writeScriptEntries");
8637
- async function defaultModuleLoader(scriptUrl) {
8638
- return await import(
8639
- /* webpackIgnore: true */
8640
- scriptUrl
8641
- );
8642
- }
8643
- __name(defaultModuleLoader, "defaultModuleLoader");
8644
8896
  var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
8645
8897
  constructor(moduleLoader, selectionContext) {
8646
8898
  this.instances = /* @__PURE__ */ new Map();
@@ -8662,8 +8914,8 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
8662
8914
  }, "onPointerUp");
8663
8915
  this.moduleLoader = moduleLoader ?? defaultModuleLoader;
8664
8916
  this.selectionCtx = selectionContext ?? null;
8665
- this.raycaster = new THREE35__namespace.Raycaster();
8666
- this.ndcPointer = new THREE35__namespace.Vector2();
8917
+ this.raycaster = new THREE36__namespace.Raycaster();
8918
+ this.ndcPointer = new THREE36__namespace.Vector2();
8667
8919
  if (this.selectionCtx) {
8668
8920
  this.selectionCtx.domElement.addEventListener("pointerdown", this.onPointerDown);
8669
8921
  this.selectionCtx.domElement.addEventListener("pointerup", this.onPointerUp);
@@ -8756,11 +9008,11 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
8756
9008
  let hasEnabledScript = false;
8757
9009
  for (let entryIndex = 0; entryIndex < nextEntries.length; entryIndex += 1) {
8758
9010
  const entry = nextEntries[entryIndex];
8759
- const skipInEditor = world.isEditorMode() && !entry.executeInEditor;
9011
+ const skipInEditor = world.isEditorMode();
8760
9012
  if (!entry.enabled || !entry.scriptUrl || skipInEditor) {
8761
9013
  nextEntries[entryIndex] = {
8762
9014
  ...entry,
8763
- runtimeState: skipInEditor ? "idle" : "idle",
9015
+ runtimeState: "idle",
8764
9016
  runtimeMessage: void 0
8765
9017
  };
8766
9018
  continue;
@@ -8947,7 +9199,7 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
8947
9199
  const mergedData = mergeDataByCurrentDefaults(defaults, currentData);
8948
9200
  const resolvedData = resolveInputData(world, mergedData);
8949
9201
  behaviour.data = resolvedData;
8950
- if (!world.isEditorMode() || liveEntry.executeInEditor === true) {
9202
+ if (!world.isEditorMode()) {
8951
9203
  behaviour.init();
8952
9204
  }
8953
9205
  liveEntries[entryIndex] = {
@@ -8975,6 +9227,328 @@ __name(_ScriptBehaviourSystem, "ScriptBehaviourSystem");
8975
9227
  _ScriptBehaviourSystem.CLICK_THRESHOLD = 6;
8976
9228
  var ScriptBehaviourSystem = _ScriptBehaviourSystem;
8977
9229
 
9230
+ // core/ScriptObject.ts
9231
+ var _ScriptObject = class _ScriptObject {
9232
+ /**
9233
+ * Engine-managed constructor. `ScriptObjectSystem` instantiates subclasses
9234
+ * with the owning world, the entity id, and the component's `data`. User code
9235
+ * should not call this directly.
9236
+ */
9237
+ constructor(world, entityId, data) {
9238
+ /**
9239
+ * The script's data payload (the `ScriptObjectComponent.data`). Declare a
9240
+ * concrete shape on subclasses with `declare data: MyShape` for type safety.
9241
+ * Use the same typed input envelopes as Behaviours (`ColorInput`,
9242
+ * `SliderInput`, `EntityInput`, …) to get inspector fields.
9243
+ */
9244
+ this.data = {};
9245
+ /**
9246
+ * The Object3D returned by {@link ScriptObject.build}. Assigned by
9247
+ * `ScriptObjectSystem` after `build()` runs; `null` until then.
9248
+ */
9249
+ this.root = null;
9250
+ this.world = world;
9251
+ this.entityId = entityId;
9252
+ if (data) this.data = data;
9253
+ }
9254
+ /**
9255
+ * REQUIRED — build and return the visual root. Called once by
9256
+ * `ScriptObjectSystem` after construction. The returned object is attached
9257
+ * under the entity's Object3D (so it inherits the entity transform, selection
9258
+ * and visibility). Subclasses MUST override.
9259
+ */
9260
+ build() {
9261
+ throw new Error("ScriptObject subclasses must implement build()");
9262
+ }
9263
+ };
9264
+ __name(_ScriptObject, "ScriptObject");
9265
+ /**
9266
+ * Static marker used by `ScriptObjectSystem` to detect `ScriptObject`
9267
+ * subclasses even when a bundler ships a second copy of the package into the
9268
+ * script blob (breaking `instanceof`). Do NOT override.
9269
+ */
9270
+ _ScriptObject.__reluScriptObjectClass = true;
9271
+ var ScriptObject = _ScriptObject;
9272
+
9273
+ // core/systems/ScriptObjectSystem.ts
9274
+ var SCRIPT_OBJECT_ROOT_FLAG = "__scriptObjectRoot";
9275
+ function setInstanceRef(component, value) {
9276
+ Object.defineProperty(component, "instance", {
9277
+ value,
9278
+ writable: true,
9279
+ configurable: true,
9280
+ enumerable: false
9281
+ });
9282
+ }
9283
+ __name(setInstanceRef, "setInstanceRef");
9284
+ function disposeBuiltObject(root) {
9285
+ root.parent?.remove(root);
9286
+ root.traverse((node) => {
9287
+ const mesh = node;
9288
+ const geometry = mesh.geometry;
9289
+ if (geometry?.dispose && !geometry.userData?.[SHARED_MODEL_RESOURCE_FLAG]) {
9290
+ geometry.dispose();
9291
+ }
9292
+ const material = mesh.material;
9293
+ const materials = Array.isArray(material) ? material : material ? [material] : [];
9294
+ for (const mat of materials) {
9295
+ if (mat.userData?.[SHARED_MODEL_RESOURCE_FLAG]) continue;
9296
+ for (const value of Object.values(mat)) {
9297
+ if (value instanceof THREE36__namespace.Texture) value.dispose();
9298
+ }
9299
+ mat.dispose?.();
9300
+ }
9301
+ });
9302
+ }
9303
+ __name(disposeBuiltObject, "disposeBuiltObject");
9304
+ var _ScriptObjectSystem = class _ScriptObjectSystem {
9305
+ constructor(moduleLoader) {
9306
+ this.instances = /* @__PURE__ */ new Map();
9307
+ this.loading = /* @__PURE__ */ new Map();
9308
+ /** Bumped by invalidate*() so in-flight loads that predate it are discarded. */
9309
+ this.epoch = 0;
9310
+ this.moduleLoader = moduleLoader ?? defaultModuleLoader;
9311
+ }
9312
+ update(world, deltaTime) {
9313
+ const active = /* @__PURE__ */ new Map();
9314
+ for (const entityId of world.query(ScriptObjectComponent)) {
9315
+ const component = world.getComponent(entityId, ScriptObjectComponent);
9316
+ if (!component) continue;
9317
+ const wantsRun = component.enabled && typeof component.scriptUrl === "string" && typeof component.className === "string";
9318
+ if (!wantsRun) {
9319
+ const record = this.instances.get(entityId);
9320
+ if (record) this.teardownRecord(world, entityId, record, false);
9321
+ this.loading.delete(entityId);
9322
+ if (component.runtimeState !== "idle") {
9323
+ component.runtimeState = "idle";
9324
+ component.runtimeMessage = void 0;
9325
+ }
9326
+ continue;
9327
+ }
9328
+ active.set(entityId, component);
9329
+ }
9330
+ for (const [entityId, record] of this.instances) {
9331
+ const component = active.get(entityId);
9332
+ const identityChanged = !component || record.scriptUrl !== component.scriptUrl || record.className !== component.className;
9333
+ if (!world.hasEntity(entityId) || identityChanged) {
9334
+ this.teardownRecord(world, entityId, record, false);
9335
+ }
9336
+ }
9337
+ for (const [entityId, component] of active) {
9338
+ const record = this.instances.get(entityId);
9339
+ if (!record || record.status !== "ready" || !record.instance) continue;
9340
+ if (!world.isEntityVisible(entityId)) continue;
9341
+ if (component.data !== record.lastWrittenData) {
9342
+ try {
9343
+ const merged = mergeDataByCurrentDefaults(
9344
+ record.rawData,
9345
+ normalizeScriptData(component.data)
9346
+ );
9347
+ record.rawData = merged;
9348
+ record.instance.data = resolveInputData(world, merged);
9349
+ const stored = serializeDataForStorage(merged, merged);
9350
+ component.data = stored;
9351
+ record.lastWrittenData = stored;
9352
+ } catch (error) {
9353
+ this.markError(world, entityId, component, error);
9354
+ continue;
9355
+ }
9356
+ }
9357
+ try {
9358
+ record.instance.update?.(deltaTime);
9359
+ } catch (error) {
9360
+ this.markError(world, entityId, component, error);
9361
+ }
9362
+ }
9363
+ for (const [entityId, component] of active) {
9364
+ if (this.instances.has(entityId) || this.loading.has(entityId)) continue;
9365
+ const scriptUrl = component.scriptUrl;
9366
+ const className = component.className;
9367
+ if (component.runtimeState !== "loading") {
9368
+ component.runtimeState = "loading";
9369
+ component.runtimeMessage = void 0;
9370
+ }
9371
+ const epochAtStart = this.epoch;
9372
+ const key = `${epochAtStart}:${scriptUrl}:${className}`;
9373
+ const promise = this.loadScriptObject(
9374
+ world,
9375
+ entityId,
9376
+ scriptUrl,
9377
+ className,
9378
+ key,
9379
+ epochAtStart
9380
+ ).catch((error) => {
9381
+ this.markError(world, entityId, void 0, error);
9382
+ console.error(
9383
+ `[ScriptObjectSystem] Failed loading ${className} (${scriptUrl})`,
9384
+ error
9385
+ );
9386
+ }).finally(() => {
9387
+ if (this.loading.get(entityId)?.key === key) {
9388
+ this.loading.delete(entityId);
9389
+ }
9390
+ });
9391
+ this.loading.set(entityId, { key, promise });
9392
+ }
9393
+ for (const entityId of this.loading.keys()) {
9394
+ if (!active.has(entityId)) this.loading.delete(entityId);
9395
+ }
9396
+ }
9397
+ async loadScriptObject(world, entityId, scriptUrl, className, key, epochAtStart) {
9398
+ const moduleValue = await this.moduleLoader(scriptUrl);
9399
+ if (this.loading.get(entityId)?.key !== key || epochAtStart !== this.epoch || !world.hasEntity(entityId)) {
9400
+ return;
9401
+ }
9402
+ const component = world.getComponent(entityId, ScriptObjectComponent);
9403
+ if (!component || !component.enabled || component.scriptUrl !== scriptUrl || component.className !== className) {
9404
+ return;
9405
+ }
9406
+ const ctor = resolveScriptCtor(moduleValue, className, {
9407
+ baseClass: ScriptObject,
9408
+ markerKey: "__reluScriptObjectClass"
9409
+ });
9410
+ if (!ctor) {
9411
+ throw new Error(
9412
+ `Missing ScriptObject export '${className}' in ${scriptUrl}`
9413
+ );
9414
+ }
9415
+ const currentData = normalizeScriptData(component.data);
9416
+ let instance;
9417
+ try {
9418
+ instance = new ctor(world, entityId, void 0);
9419
+ } catch {
9420
+ instance = new ctor(world, entityId, currentData);
9421
+ }
9422
+ const defaults = normalizeScriptData(instance.data);
9423
+ const merged = mergeDataByCurrentDefaults(defaults, currentData);
9424
+ instance.data = resolveInputData(world, merged);
9425
+ const parent = world.getComponent(entityId, Object3DRef)?.object;
9426
+ if (!parent) {
9427
+ throw new Error("Script object entity has no Object3D to attach to.");
9428
+ }
9429
+ for (const child of [...parent.children]) {
9430
+ if (child.userData?.[SCRIPT_OBJECT_ROOT_FLAG]) {
9431
+ disposeBuiltObject(child);
9432
+ }
9433
+ }
9434
+ let built;
9435
+ try {
9436
+ built = instance.build();
9437
+ } catch (error) {
9438
+ try {
9439
+ instance.dispose?.();
9440
+ } catch {
9441
+ }
9442
+ throw error;
9443
+ }
9444
+ if (!built || built.isObject3D !== true) {
9445
+ try {
9446
+ instance.dispose?.();
9447
+ } catch {
9448
+ }
9449
+ throw new Error("build() must return a THREE.Object3D.");
9450
+ }
9451
+ built.userData[SCRIPT_OBJECT_ROOT_FLAG] = true;
9452
+ parent.add(built);
9453
+ instance.root = built;
9454
+ const stored = serializeDataForStorage(merged, merged);
9455
+ component.data = stored;
9456
+ component.runtimeState = "ready";
9457
+ component.runtimeMessage = void 0;
9458
+ setInstanceRef(component, instance);
9459
+ this.instances.set(entityId, {
9460
+ entityId,
9461
+ scriptUrl,
9462
+ className,
9463
+ status: "ready",
9464
+ instance,
9465
+ root: built,
9466
+ rawData: merged,
9467
+ lastWrittenData: stored
9468
+ });
9469
+ }
9470
+ /** Dispose a record's instance + built subtree. `keepTombstone` leaves an error marker. */
9471
+ teardownRecord(world, entityId, record, keepTombstone) {
9472
+ try {
9473
+ record.instance?.dispose?.();
9474
+ } catch {
9475
+ }
9476
+ if (record.root) disposeBuiltObject(record.root);
9477
+ const component = world.getComponent(entityId, ScriptObjectComponent);
9478
+ if (component) setInstanceRef(component, null);
9479
+ if (keepTombstone) {
9480
+ this.instances.set(entityId, {
9481
+ ...record,
9482
+ status: "error",
9483
+ instance: null,
9484
+ root: null
9485
+ });
9486
+ } else {
9487
+ this.instances.delete(entityId);
9488
+ }
9489
+ }
9490
+ markError(world, entityId, component, error) {
9491
+ const comp = component ?? world.getComponent(entityId, ScriptObjectComponent) ?? null;
9492
+ if (comp) {
9493
+ comp.runtimeState = "error";
9494
+ comp.runtimeMessage = toErrorMessage(error);
9495
+ }
9496
+ const record = this.instances.get(entityId);
9497
+ if (record) {
9498
+ this.teardownRecord(world, entityId, record, true);
9499
+ } else {
9500
+ this.instances.set(entityId, {
9501
+ entityId,
9502
+ scriptUrl: comp?.scriptUrl ?? "",
9503
+ className: comp?.className ?? "",
9504
+ status: "error",
9505
+ instance: null,
9506
+ root: null,
9507
+ rawData: {},
9508
+ lastWrittenData: null
9509
+ });
9510
+ }
9511
+ }
9512
+ /** Dispose all live instances so the next update() reloads with fresh modules. */
9513
+ invalidateAll() {
9514
+ this.epoch += 1;
9515
+ for (const [entityId, record] of [...this.instances]) {
9516
+ try {
9517
+ record.instance?.dispose?.();
9518
+ } catch {
9519
+ }
9520
+ if (record.root) disposeBuiltObject(record.root);
9521
+ this.instances.delete(entityId);
9522
+ }
9523
+ this.loading.clear();
9524
+ }
9525
+ /** Invalidate only the entities whose script matches `scriptUrl`. */
9526
+ invalidate(scriptUrl) {
9527
+ this.epoch += 1;
9528
+ for (const [entityId, record] of [...this.instances]) {
9529
+ if (record.scriptUrl !== scriptUrl) continue;
9530
+ try {
9531
+ record.instance?.dispose?.();
9532
+ } catch {
9533
+ }
9534
+ if (record.root) disposeBuiltObject(record.root);
9535
+ this.instances.delete(entityId);
9536
+ }
9537
+ for (const [entityId, entry] of [...this.loading]) {
9538
+ if (entry.key.includes(`:${scriptUrl}:`)) this.loading.delete(entityId);
9539
+ }
9540
+ }
9541
+ dispose(world) {
9542
+ for (const [entityId, record] of [...this.instances]) {
9543
+ this.teardownRecord(world, entityId, record, false);
9544
+ }
9545
+ this.instances.clear();
9546
+ this.loading.clear();
9547
+ }
9548
+ };
9549
+ __name(_ScriptObjectSystem, "ScriptObjectSystem");
9550
+ var ScriptObjectSystem = _ScriptObjectSystem;
9551
+
8978
9552
  // core/systems/TransformSyncSystem.ts
8979
9553
  var _TransformSyncSystem = class _TransformSyncSystem {
8980
9554
  update(world) {
@@ -9073,7 +9647,7 @@ var _AudioSystem = class _AudioSystem {
9073
9647
  if (!prev || prev.volume !== opts.volume) {
9074
9648
  sound.setVolume(opts.volume);
9075
9649
  }
9076
- if (opts.positional && sound instanceof THREE35__namespace.PositionalAudio) {
9650
+ if (opts.positional && sound instanceof THREE36__namespace.PositionalAudio) {
9077
9651
  if (!prev || prev.refDistance !== opts.refDistance) {
9078
9652
  sound.setRefDistance(opts.refDistance);
9079
9653
  }
@@ -9199,7 +9773,7 @@ var _VideoSystem = class _VideoSystem {
9199
9773
  component.object.scale.set(opts.width, opts.height, 1);
9200
9774
  }
9201
9775
  const material = component.material;
9202
- if (material instanceof THREE35__namespace.ShaderMaterial) {
9776
+ if (material instanceof THREE36__namespace.ShaderMaterial) {
9203
9777
  if (!prev || prev.backgroundColor !== opts.backgroundColor) {
9204
9778
  material.uniforms.keyColor.value.set(opts.backgroundColor);
9205
9779
  }
@@ -9213,7 +9787,7 @@ var _VideoSystem = class _VideoSystem {
9213
9787
  material.uniforms.spill.value = opts.spill;
9214
9788
  }
9215
9789
  }
9216
- if (opts.positional && component.audioNode instanceof THREE35__namespace.PositionalAudio) {
9790
+ if (opts.positional && component.audioNode instanceof THREE36__namespace.PositionalAudio) {
9217
9791
  const posAudio = component.audioNode;
9218
9792
  if (!prev || prev.refDistance !== opts.refDistance) {
9219
9793
  posAudio.setRefDistance(opts.refDistance);
@@ -9887,8 +10461,8 @@ var _World = class _World {
9887
10461
  * ```
9888
10462
  */
9889
10463
  raycast(origin, direction, near = 0, far = Infinity) {
9890
- const rayOrigin = new THREE35__namespace.Vector3(origin.x, origin.y, origin.z);
9891
- const rayDirection = new THREE35__namespace.Vector3(
10464
+ const rayOrigin = new THREE36__namespace.Vector3(origin.x, origin.y, origin.z);
10465
+ const rayDirection = new THREE36__namespace.Vector3(
9892
10466
  direction.x,
9893
10467
  direction.y,
9894
10468
  direction.z
@@ -9897,7 +10471,7 @@ var _World = class _World {
9897
10471
  return [];
9898
10472
  }
9899
10473
  rayDirection.normalize();
9900
- const raycaster = new THREE35__namespace.Raycaster(rayOrigin, rayDirection, near, far);
10474
+ const raycaster = new THREE36__namespace.Raycaster(rayOrigin, rayDirection, near, far);
9901
10475
  const intersections = raycaster.intersectObjects(
9902
10476
  this.scene.children,
9903
10477
  true
@@ -9931,14 +10505,14 @@ var _World = class _World {
9931
10505
  if (!sourceObject) {
9932
10506
  return [];
9933
10507
  }
9934
- const rayOrigin = new THREE35__namespace.Vector3();
9935
- const rayDirection = new THREE35__namespace.Vector3();
10508
+ const rayOrigin = new THREE36__namespace.Vector3();
10509
+ const rayDirection = new THREE36__namespace.Vector3();
9936
10510
  sourceObject.getWorldPosition(rayOrigin);
9937
10511
  sourceObject.getWorldDirection(rayDirection);
9938
10512
  if (rayDirection.lengthSq() === 0) {
9939
10513
  return [];
9940
10514
  }
9941
- const raycaster = new THREE35__namespace.Raycaster(rayOrigin, rayDirection, near, far);
10515
+ const raycaster = new THREE36__namespace.Raycaster(rayOrigin, rayDirection, near, far);
9942
10516
  const intersections = raycaster.intersectObjects(
9943
10517
  this.scene.children,
9944
10518
  true
@@ -10170,11 +10744,11 @@ __name(_World, "World");
10170
10744
  var World = _World;
10171
10745
 
10172
10746
  // core/prefab/snapshotIdUtils.ts
10173
- var asRecord5 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null, "asRecord");
10747
+ var asRecord6 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null, "asRecord");
10174
10748
  function remapScriptData(data, idMap, nullExternal, onExternal) {
10175
10749
  const result = {};
10176
10750
  for (const [key, value] of Object.entries(data)) {
10177
- const record = asRecord5(value);
10751
+ const record = asRecord6(value);
10178
10752
  if (!record) {
10179
10753
  result[key] = value;
10180
10754
  continue;
@@ -10189,7 +10763,7 @@ function remapScriptData(data, idMap, nullExternal, onExternal) {
10189
10763
  }
10190
10764
  continue;
10191
10765
  }
10192
- const componentRef = asRecord5(record.value);
10766
+ const componentRef = asRecord6(record.value);
10193
10767
  if (record.type === "component" && componentRef && typeof componentRef.entityId === "number") {
10194
10768
  const mapped = idMap.get(componentRef.entityId);
10195
10769
  if (mapped !== void 0) {
@@ -10227,7 +10801,7 @@ function remapSnapshotEntityIds(snapshot, idMap, options) {
10227
10801
  });
10228
10802
  }, "warn");
10229
10803
  let value = structuredClone(entry.value);
10230
- const record = asRecord5(value);
10804
+ const record = asRecord6(value);
10231
10805
  if (block.component === "ParentId" && record) {
10232
10806
  if (typeof record.value === "number") {
10233
10807
  const mapped = idMap.get(record.value);
@@ -10243,11 +10817,11 @@ function remapSnapshotEntityIds(snapshot, idMap, options) {
10243
10817
  } else if (block.component === "ScriptComponent" && record) {
10244
10818
  if (Array.isArray(record.entries)) {
10245
10819
  record.entries = record.entries.map((rawEntry, index) => {
10246
- const entryRecord = asRecord5(rawEntry);
10820
+ const entryRecord = asRecord6(rawEntry);
10247
10821
  if (!entryRecord) {
10248
10822
  return rawEntry;
10249
10823
  }
10250
- const data = asRecord5(entryRecord.data);
10824
+ const data = asRecord6(entryRecord.data);
10251
10825
  if (!data) {
10252
10826
  return rawEntry;
10253
10827
  }
@@ -10262,6 +10836,11 @@ function remapSnapshotEntityIds(snapshot, idMap, options) {
10262
10836
  };
10263
10837
  });
10264
10838
  }
10839
+ } else if (block.component === "ScriptObjectComponent" && record) {
10840
+ const data = asRecord6(record.data);
10841
+ if (data) {
10842
+ record.data = remapScriptData(data, idMap, nullExternal, warn);
10843
+ }
10265
10844
  } else if (block.component === "InstancedMeshComponent" && record) {
10266
10845
  if (Array.isArray(record.instanceEntityIds)) {
10267
10846
  const remapped = [];
@@ -10303,12 +10882,237 @@ function remapSnapshotEntityIds(snapshot, idMap, options) {
10303
10882
  }
10304
10883
  __name(remapSnapshotEntityIds, "remapSnapshotEntityIds");
10305
10884
 
10885
+ // core/prefab/applyPrefabToSnapshot.ts
10886
+ var asRecord7 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null, "asRecord");
10887
+ var clone2 = /* @__PURE__ */ __name((value) => structuredClone(value), "clone");
10888
+ var stableStringify = /* @__PURE__ */ __name((value) => {
10889
+ try {
10890
+ return JSON.stringify(value);
10891
+ } catch {
10892
+ return "";
10893
+ }
10894
+ }, "stableStringify");
10895
+ function getBlock(snapshot, component) {
10896
+ let block = snapshot.components.find((b) => b.component === component);
10897
+ if (!block) {
10898
+ block = { component, entries: [] };
10899
+ snapshot.components.push(block);
10900
+ }
10901
+ return block;
10902
+ }
10903
+ __name(getBlock, "getBlock");
10904
+ function setEntry(snapshot, component, entityId, value) {
10905
+ const block = getBlock(snapshot, component);
10906
+ const entry = block.entries.find((e) => e.entityId === entityId);
10907
+ if (entry) {
10908
+ entry.value = value;
10909
+ } else {
10910
+ block.entries.push({ entityId, value });
10911
+ block.entries.sort((a, b) => a.entityId - b.entityId);
10912
+ }
10913
+ }
10914
+ __name(setEntry, "setEntry");
10915
+ function deleteEntities(snapshot, entityIds) {
10916
+ snapshot.entities = snapshot.entities.filter((id) => !entityIds.has(id));
10917
+ snapshot.components = snapshot.components.map((block) => ({
10918
+ component: block.component,
10919
+ entries: block.entries.filter((e) => !entityIds.has(e.entityId))
10920
+ })).filter((block) => block.entries.length > 0);
10921
+ }
10922
+ __name(deleteEntities, "deleteEntities");
10923
+ function extractRegionDoc(hostSnapshot, regionIds) {
10924
+ const idSet = new Set(regionIds);
10925
+ return {
10926
+ entities: regionIds.slice(),
10927
+ components: hostSnapshot.components.map((block) => ({
10928
+ component: block.component,
10929
+ entries: block.entries.filter((e) => idSet.has(e.entityId))
10930
+ })).filter((block) => block.entries.length > 0)
10931
+ };
10932
+ }
10933
+ __name(extractRegionDoc, "extractRegionDoc");
10934
+ function applyPrefabToSnapshotInstances(hostSnapshot, nestedUrl, newNestedSnapshot) {
10935
+ const host = clone2(hostSnapshot);
10936
+ const newMaps = buildNodeKeyMapsFromSnapshot(newNestedSnapshot);
10937
+ const newByEntity = indexSnapshotByEntity(newNestedSnapshot);
10938
+ if (!newMaps.rootKey) {
10939
+ return { snapshot: host, changed: false };
10940
+ }
10941
+ let changed = false;
10942
+ const regions = findTopLevelNestedRegions(host).filter(
10943
+ (region) => region.url === nestedUrl
10944
+ );
10945
+ for (const region of regions) {
10946
+ const before = stableStringify(
10947
+ extractRegionDoc(host, collectSnapshotSubtreeIds(host, region.rootEntityId))
10948
+ );
10949
+ patchRegion(host, region.rootEntityId, region.overrides, {
10950
+ newSnapshot: newNestedSnapshot,
10951
+ newMaps,
10952
+ newByEntity
10953
+ });
10954
+ const after = stableStringify(
10955
+ extractRegionDoc(host, collectSnapshotSubtreeIds(host, region.rootEntityId))
10956
+ );
10957
+ if (before !== after) {
10958
+ changed = true;
10959
+ }
10960
+ }
10961
+ return { snapshot: host, changed };
10962
+ }
10963
+ __name(applyPrefabToSnapshotInstances, "applyPrefabToSnapshotInstances");
10964
+ function patchRegion(host, regionRootId, storedOverrides, file) {
10965
+ const { newSnapshot, newMaps, newByEntity } = file;
10966
+ const regionIds = collectSnapshotSubtreeIds(host, regionRootId);
10967
+ const regionDoc = extractRegionDoc(host, regionIds);
10968
+ const regionMaps = buildNodeKeyMapsFromSnapshot(regionDoc, {
10969
+ scopeRootEntityId: regionRootId
10970
+ });
10971
+ const regionByEntity = indexSnapshotByEntity(regionDoc);
10972
+ const grouped = groupOverridePaths(storedOverrides);
10973
+ const overridePathsFor = /* @__PURE__ */ __name((key, component) => grouped.get(key)?.get(component), "overridePathsFor");
10974
+ const isMarkedAddition = /* @__PURE__ */ __name((key) => Boolean(grouped.get(key)?.get(ADDED_NODE_MARKER_COMPONENT)), "isMarkedAddition");
10975
+ const parentBlockNew = newSnapshot.components.find(
10976
+ (b) => b.component === "ParentId"
10977
+ );
10978
+ const keyToHostId = /* @__PURE__ */ new Map();
10979
+ for (const [hostId, key] of regionMaps.idToKey) {
10980
+ keyToHostId.set(key, hostId);
10981
+ }
10982
+ const addedFileIds = [...newMaps.keyToId.entries()].filter(([key]) => !keyToHostId.has(key)).map(([, fileId]) => fileId);
10983
+ if (addedFileIds.length > 0) {
10984
+ let nextHostId = Math.max(0, ...host.entities) + 1;
10985
+ const addedSet = new Set(addedFileIds);
10986
+ const idMap = /* @__PURE__ */ new Map();
10987
+ for (const [key, fileId] of newMaps.keyToId) {
10988
+ const hostId = keyToHostId.get(key);
10989
+ if (hostId !== void 0) {
10990
+ idMap.set(fileId, hostId);
10991
+ }
10992
+ }
10993
+ for (const fileId of addedFileIds) {
10994
+ idMap.set(fileId, nextHostId);
10995
+ nextHostId += 1;
10996
+ }
10997
+ const addedSub = {
10998
+ entities: newSnapshot.entities.filter((id) => addedSet.has(id)),
10999
+ components: newSnapshot.components.map((block) => ({
11000
+ component: block.component,
11001
+ entries: block.entries.filter((e) => addedSet.has(e.entityId))
11002
+ })).filter((block) => block.entries.length > 0)
11003
+ };
11004
+ const { snapshot: remapped } = remapSnapshotEntityIds(addedSub, idMap, {
11005
+ externalRefPolicy: "null"
11006
+ });
11007
+ host.entities = [...host.entities, ...remapped.entities];
11008
+ for (const block of remapped.components) {
11009
+ for (const entry of block.entries) {
11010
+ setEntry(host, block.component, entry.entityId, entry.value);
11011
+ }
11012
+ }
11013
+ for (const fileId of addedFileIds) {
11014
+ const hostId = idMap.get(fileId);
11015
+ const parentValue = asRecord7(
11016
+ parentBlockNew?.entries.find((e) => e.entityId === fileId)?.value
11017
+ )?.value;
11018
+ if (typeof parentValue === "number" && !addedSet.has(parentValue)) {
11019
+ const parentKey = newMaps.idToKey.get(parentValue);
11020
+ const parentHost = parentKey ? keyToHostId.get(parentKey) : void 0;
11021
+ setEntry(host, "ParentId", hostId, {
11022
+ __type: "ParentId",
11023
+ value: parentHost ?? regionRootId
11024
+ });
11025
+ }
11026
+ const key = newMaps.idToKey.get(fileId);
11027
+ if (key) {
11028
+ keyToHostId.set(key, hostId);
11029
+ }
11030
+ }
11031
+ }
11032
+ for (const [key, fileId] of newMaps.keyToId) {
11033
+ const hostId = keyToHostId.get(key);
11034
+ if (hostId === void 0) continue;
11035
+ const isRegionRoot = key === newMaps.rootKey;
11036
+ const fileComponents = newByEntity.get(fileId);
11037
+ if (!fileComponents) continue;
11038
+ const regionEntityComponents = regionByEntity.get(hostId);
11039
+ for (const [componentName, fileRaw] of fileComponents) {
11040
+ if (OVERRIDE_DIFF_EXCLUDED_COMPONENTS.has(componentName)) continue;
11041
+ if (isRegionRoot && OVERRIDE_ROOT_EXCLUDED_COMPONENTS.has(componentName))
11042
+ continue;
11043
+ const fileCanonical = canonicalizeComponentValue(
11044
+ componentName,
11045
+ fileRaw,
11046
+ newMaps.idToKey
11047
+ );
11048
+ const regionRaw = regionEntityComponents?.get(componentName);
11049
+ const regionCanonical = regionRaw === void 0 ? void 0 : canonicalizeComponentValue(
11050
+ componentName,
11051
+ regionRaw,
11052
+ regionMaps.idToKey
11053
+ );
11054
+ const merged = regionCanonical === void 0 ? fileCanonical : mergeComponentValue(
11055
+ fileCanonical,
11056
+ regionCanonical,
11057
+ overridePathsFor(key, componentName)
11058
+ );
11059
+ if (regionCanonical !== void 0 && stableStringify(merged) === stableStringify(regionCanonical)) {
11060
+ continue;
11061
+ }
11062
+ const hostValue = decanonicalizeComponentValue(merged, keyToHostId);
11063
+ setEntry(host, componentName, hostId, hostValue);
11064
+ }
11065
+ }
11066
+ const removedHostIds = /* @__PURE__ */ new Set();
11067
+ for (const [key, hostId] of keyToHostId) {
11068
+ if (newMaps.keyToId.has(key)) continue;
11069
+ if (isMarkedAddition(key)) continue;
11070
+ removedHostIds.add(hostId);
11071
+ }
11072
+ if (removedHostIds.size > 0) {
11073
+ const regionIdSet = new Set(regionIds);
11074
+ const parentBlockHost = host.components.find(
11075
+ (b) => b.component === "ParentId"
11076
+ );
11077
+ for (const entry of parentBlockHost?.entries ?? []) {
11078
+ const record = asRecord7(entry.value);
11079
+ if (!removedHostIds.has(entry.entityId) && regionIdSet.has(entry.entityId) && record && typeof record.value === "number" && removedHostIds.has(record.value)) {
11080
+ record.value = regionRootId;
11081
+ }
11082
+ }
11083
+ deleteEntities(host, removedHostIds);
11084
+ }
11085
+ const refreshedRegionIds = collectSnapshotSubtreeIds(host, regionRootId);
11086
+ const refreshedDoc = extractRegionDoc(host, refreshedRegionIds);
11087
+ const refreshedOverrides = computeInstanceOverrides(
11088
+ newSnapshot,
11089
+ refreshedDoc,
11090
+ { emitAdditionMarkers: true }
11091
+ );
11092
+ const instanceEntry = asRecord7(
11093
+ host.components.find((b) => b.component === "PrefabInstance")?.entries.find((e) => e.entityId === regionRootId)?.value
11094
+ );
11095
+ if (instanceEntry) {
11096
+ instanceEntry.overrides = refreshedOverrides;
11097
+ }
11098
+ }
11099
+ __name(patchRegion, "patchRegion");
11100
+
11101
+ // core/prefab/dependencies.ts
11102
+ function collectDirectPrefabDependencies(snapshot) {
11103
+ const urls = /* @__PURE__ */ new Set();
11104
+ for (const region of findTopLevelNestedRegions(snapshot)) {
11105
+ urls.add(region.url);
11106
+ }
11107
+ return [...urls];
11108
+ }
11109
+ __name(collectDirectPrefabDependencies, "collectDirectPrefabDependencies");
11110
+
10306
11111
  // core/prefab/serializeEntitySubtree.ts
10307
11112
  var SUBTREE_EXCLUDED_COMPONENTS = /* @__PURE__ */ new Set([
10308
11113
  "Environment",
10309
11114
  "Postprocessing",
10310
- "SelectionTransformState",
10311
- "PrefabInstance"
11115
+ "SelectionTransformState"
10312
11116
  ]);
10313
11117
  function serializeEntitySubtree(world, rootId, options) {
10314
11118
  const orderedIds = collectEntitySubtree(world, [rootId]);
@@ -10340,6 +11144,19 @@ function serializeEntitySubtree(world, rootId, options) {
10340
11144
  if (rootParentEntry && rootParentEntry.value !== null && typeof rootParentEntry.value === "object") {
10341
11145
  rootParentEntry.value.value = null;
10342
11146
  }
11147
+ const prefabInstanceBlock = snapshot.components.find(
11148
+ (block) => block.component === "PrefabInstance"
11149
+ );
11150
+ if (prefabInstanceBlock) {
11151
+ prefabInstanceBlock.entries = prefabInstanceBlock.entries.filter(
11152
+ (entry) => entry.entityId !== rootFileId
11153
+ );
11154
+ if (prefabInstanceBlock.entries.length === 0) {
11155
+ snapshot.components = snapshot.components.filter(
11156
+ (block) => block !== prefabInstanceBlock
11157
+ );
11158
+ }
11159
+ }
10343
11160
  const filteredWarnings = warnings.filter(
10344
11161
  (warning) => !(warning.component === "ParentId" && warning.entityId === rootId)
10345
11162
  );
@@ -10347,6 +11164,7 @@ function serializeEntitySubtree(world, rootId, options) {
10347
11164
  }
10348
11165
  __name(serializeEntitySubtree, "serializeEntitySubtree");
10349
11166
 
11167
+ exports.ADDED_NODE_MARKER_COMPONENT = ADDED_NODE_MARKER_COMPONENT;
10350
11168
  exports.AnimationStateMachine = AnimationStateMachine;
10351
11169
  exports.AnimationStateManager = AnimationStateManager;
10352
11170
  exports.AnimationSystem = AnimationSystem;
@@ -10363,26 +11181,35 @@ exports.KeyboardKeys = KeyboardKeys;
10363
11181
  exports.LightSyncSystem = LightSyncSystem;
10364
11182
  exports.MaterialSyncSystem = MaterialSyncSystem;
10365
11183
  exports.MeshGeometrySystem = MeshGeometrySystem;
11184
+ exports.NODE_KEY_SEPARATOR = NODE_KEY_SEPARATOR;
10366
11185
  exports.OVERRIDE_DIFF_EXCLUDED_COMPONENTS = OVERRIDE_DIFF_EXCLUDED_COMPONENTS;
10367
11186
  exports.OVERRIDE_ROOT_EXCLUDED_COMPONENTS = OVERRIDE_ROOT_EXCLUDED_COMPONENTS;
10368
11187
  exports.ObjectManagementSystem = ObjectManagementSystem;
10369
11188
  exports.ObjectVisibilitySystem = ObjectVisibilitySystem;
10370
11189
  exports.PREFAB_FILE_VERSION = PREFAB_FILE_VERSION;
11190
+ exports.PREFAB_FILE_VERSION_NESTED = PREFAB_FILE_VERSION_NESTED;
10371
11191
  exports.PhysicsSyncSystem = PhysicsSyncSystem;
10372
11192
  exports.PostprocessingSyncSystem = PostprocessingSyncSystem;
10373
11193
  exports.RenderSystem = RenderSystem;
11194
+ exports.SCRIPT_OBJECT_ROOT_FLAG = SCRIPT_OBJECT_ROOT_FLAG;
10374
11195
  exports.SHARED_MODEL_RESOURCE_FLAG = SHARED_MODEL_RESOURCE_FLAG;
10375
11196
  exports.ScriptBehaviourSystem = ScriptBehaviourSystem;
11197
+ exports.ScriptObject = ScriptObject;
11198
+ exports.ScriptObjectSystem = ScriptObjectSystem;
10376
11199
  exports.TransformSyncSystem = TransformSyncSystem;
10377
11200
  exports.VideoSystem = VideoSystem;
10378
11201
  exports.World = World;
11202
+ exports.applyPrefabToSnapshotInstances = applyPrefabToSnapshotInstances;
10379
11203
  exports.buildComponentValueMaps = buildComponentValueMaps;
11204
+ exports.buildNodeKeyMapsFromSnapshot = buildNodeKeyMapsFromSnapshot;
10380
11205
  exports.buildNodeMapsFromSnapshot = buildNodeMapsFromSnapshot;
10381
11206
  exports.canonicalizeComponentValue = canonicalizeComponentValue;
10382
11207
  exports.clearModelCache = clearModelCache;
10383
11208
  exports.clearPrefabCache = clearPrefabCache;
10384
11209
  exports.collectDiffPaths = collectDiffPaths;
11210
+ exports.collectDirectPrefabDependencies = collectDirectPrefabDependencies;
10385
11211
  exports.collectEntitySubtree = collectEntitySubtree;
11212
+ exports.collectSnapshotSubtreeIds = collectSnapshotSubtreeIds;
10386
11213
  exports.computeInstanceOverrides = computeInstanceOverrides;
10387
11214
  exports.createAnimationComponent = createAnimationComponent;
10388
11215
  exports.createAudioComponent = createAudioComponent;
@@ -10405,6 +11232,7 @@ exports.createParentIdComponent = createParentIdComponent;
10405
11232
  exports.createPhysicsComponent = createPhysicsComponent;
10406
11233
  exports.createPostprocessingComponent = createPostprocessingComponent;
10407
11234
  exports.createScriptComponent = createScriptComponent;
11235
+ exports.createScriptObjectComponent = createScriptObjectComponent;
10408
11236
  exports.createSelectableComponent = createSelectableComponent;
10409
11237
  exports.createSelectionTransformStateComponent = createSelectionTransformStateComponent;
10410
11238
  exports.createSpriteComponent = createSpriteComponent;
@@ -10414,6 +11242,7 @@ exports.decanonicalizeComponentValue = decanonicalizeComponentValue;
10414
11242
  exports.despawnPrefab = despawnPrefab;
10415
11243
  exports.encodeOverride = encodeOverride;
10416
11244
  exports.findSnapshotRootEntityIds = findSnapshotRootEntityIds;
11245
+ exports.findTopLevelNestedRegions = findTopLevelNestedRegions;
10417
11246
  exports.groupOverridePaths = groupOverridePaths;
10418
11247
  exports.hydrateWorldFromSnapshot = hydrateWorldFromSnapshot;
10419
11248
  exports.hydrateWorldFromSnapshotDetailed = hydrateWorldFromSnapshotDetailed;
@@ -10424,6 +11253,7 @@ exports.loadSharedGltf = loadSharedGltf;
10424
11253
  exports.mergeComponentValue = mergeComponentValue;
10425
11254
  exports.parseOverride = parseOverride;
10426
11255
  exports.parsePrefabAsset = parsePrefabAsset;
11256
+ exports.prefabFileVersionFor = prefabFileVersionFor;
10427
11257
  exports.registerDefaultComponentFactories = registerDefaultComponentFactories;
10428
11258
  exports.registerDefaultFactories = registerDefaultFactories;
10429
11259
  exports.remapSnapshotEntityIds = remapSnapshotEntityIds;