@webspatial/react-sdk 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@
2
2
  (function(){
3
3
  if(typeof window === 'undefined') return;
4
4
  if(!window.__webspatialsdk__) window.__webspatialsdk__ = {}
5
- window.__webspatialsdk__['react-sdk-version'] = "1.3.0"
5
+ window.__webspatialsdk__['react-sdk-version'] = "1.5.0"
6
6
  window.__webspatialsdk__['XR_ENV'] = "avp"
7
7
  })()
8
8
 
@@ -170,18 +170,12 @@ var SpatialContainerRefProxy = class {
170
170
  if (prop === "__raw") {
171
171
  return target;
172
172
  }
173
- if (prop === "clientDepth") {
173
+ if (prop === "xrClientDepth") {
174
174
  return target.style.getPropertyValue(SpatialCustomStyleVars.depth);
175
175
  }
176
- if (prop === "offsetBack") {
176
+ if (prop === "xrOffsetBack") {
177
177
  return target.style.getPropertyValue(SpatialCustomStyleVars.back);
178
178
  }
179
- if (prop === "getBoundingClientRect") {
180
- return dom.__getBoundingClientRect;
181
- }
182
- if (prop === "getBoundingClientCube") {
183
- return dom.__getBoundingClientCube;
184
- }
185
179
  if (prop === "style") {
186
180
  if (!self.styleProxy) {
187
181
  self.styleProxy = new Proxy(target.style, {
@@ -897,37 +891,6 @@ function enableDebugTool() {
897
891
  });
898
892
  }
899
893
 
900
- // src/spatialized-container/transform-utils.ts
901
- function toSceneSpatial(point, spatializedElement) {
902
- return spatializedElement.__toSceneSpace(point);
903
- }
904
- function toLocalSpace(point, spatializedElement) {
905
- return spatializedElement.__toLocalSpace(point);
906
- }
907
- function convertDOMRectToSceneSpace(originalRect, matrix) {
908
- const topLeft = new DOMPoint(originalRect.left, originalRect.top);
909
- const topRight = new DOMPoint(originalRect.right, originalRect.top);
910
- const bottomRight = new DOMPoint(originalRect.right, originalRect.bottom);
911
- const bottomLeft = new DOMPoint(originalRect.left, originalRect.bottom);
912
- const transformedTopLeft = matrix.transformPoint(topLeft);
913
- const transformedTopRight = matrix.transformPoint(topRight);
914
- const transformedBottomRight = matrix.transformPoint(bottomRight);
915
- const transformedBottomLeft = matrix.transformPoint(bottomLeft);
916
- const allPoints = [
917
- transformedTopLeft,
918
- transformedTopRight,
919
- transformedBottomRight,
920
- transformedBottomLeft
921
- ];
922
- const xCoords = allPoints.map((point) => point.x);
923
- const yCoords = allPoints.map((point) => point.y);
924
- const newMinX = Math.min(...xCoords);
925
- const newMaxX = Math.max(...xCoords);
926
- const newMinY = Math.min(...yCoords);
927
- const newMaxY = Math.max(...yCoords);
928
- return new DOMRect(newMinX, newMinY, newMaxX - newMinX, newMaxY - newMinY);
929
- }
930
-
931
894
  // src/spatialized-container/context/PortalInstanceContext.ts
932
895
  var PortalInstanceObject = class {
933
896
  spatialId;
@@ -1012,40 +975,8 @@ var PortalInstanceObject = class {
1012
975
  isFixedPosition: computedStyle.getPropertyValue("position") === "fixed"
1013
976
  };
1014
977
  this.updateSpatializedElementProperties();
1015
- const __getBoundingClientCube = () => {
1016
- return this.spatializedElement?.cubeInfo;
1017
- };
1018
- const __getBoundingClientRect = () => {
1019
- if (!this.spatializedElement?.transform) {
1020
- return null;
1021
- }
1022
- const domRect = new DOMRect(
1023
- 0,
1024
- 0,
1025
- this.domRect?.width,
1026
- this.domRect?.height
1027
- );
1028
- return convertDOMRectToSceneSpace(
1029
- domRect,
1030
- this.spatializedElement?.transform
1031
- );
1032
- };
1033
- const __toSceneSpace = (point) => {
1034
- return new DOMPoint(point.x, point.y, point.z).matrixTransform(
1035
- this.spatializedElement?.transform
1036
- );
1037
- };
1038
- const __toLocalSpace = (point) => {
1039
- return new DOMPoint(point.x, point.y, point.z).matrixTransform(
1040
- this.spatializedElement?.transformInv
1041
- );
1042
- };
1043
978
  const __innerSpatializedElement = () => this.spatializedElement;
1044
979
  Object.assign(dom, {
1045
- __getBoundingClientCube,
1046
- __getBoundingClientRect,
1047
- __toSceneSpace,
1048
- __toLocalSpace,
1049
980
  __innerSpatializedElement
1050
981
  });
1051
982
  }
@@ -1163,18 +1094,19 @@ function useSync2DFrame(spatialId, portalInstanceObject, spatializedContainerObj
1163
1094
  }
1164
1095
 
1165
1096
  // src/spatialized-container/hooks/useSpatializedElement.ts
1166
- import { useEffect as useEffect6, useState as useState3 } from "react";
1097
+ import { useEffect as useEffect6, useRef as useRef4, useState as useState3 } from "react";
1167
1098
  function useSpatializedElement(createSpatializedElement2, portalInstanceObject) {
1168
1099
  const [spatializedElement, setSpatializedElement] = useState3();
1100
+ const elementRef = useRef4(void 0);
1169
1101
  useEffect6(() => {
1170
1102
  let isDestroyed = false;
1171
- let spatializedElement2;
1172
1103
  createSpatializedElement2().then(
1173
1104
  (inSpatializedElement) => {
1105
+ if (!inSpatializedElement) return;
1174
1106
  if (!isDestroyed) {
1175
- spatializedElement2 = inSpatializedElement;
1176
- portalInstanceObject.attachSpatializedElement(spatializedElement2);
1177
- setSpatializedElement(spatializedElement2);
1107
+ elementRef.current = inSpatializedElement;
1108
+ portalInstanceObject.attachSpatializedElement(inSpatializedElement);
1109
+ setSpatializedElement(inSpatializedElement);
1178
1110
  } else {
1179
1111
  inSpatializedElement?.destroy();
1180
1112
  }
@@ -1182,9 +1114,11 @@ function useSpatializedElement(createSpatializedElement2, portalInstanceObject)
1182
1114
  );
1183
1115
  return () => {
1184
1116
  isDestroyed = true;
1185
- if (spatializedElement2) {
1186
- spatializedElement2.destroy();
1187
- spatializedElement2 = void 0;
1117
+ const el = elementRef.current;
1118
+ if (el) {
1119
+ el.destroy();
1120
+ elementRef.current = void 0;
1121
+ setSpatializedElement(void 0);
1188
1122
  }
1189
1123
  };
1190
1124
  }, [createSpatializedElement2, portalInstanceObject]);
@@ -1193,6 +1127,18 @@ function useSpatializedElement(createSpatializedElement2, portalInstanceObject)
1193
1127
 
1194
1128
  // src/spatialized-container/PortalSpatializedContainer.tsx
1195
1129
  import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
1130
+ function constrainedAxisToVec3(input) {
1131
+ if (input == null) return { x: 0, y: 0, z: 0 };
1132
+ if (Array.isArray(input)) {
1133
+ return { x: input[0] ?? 0, y: input[1] ?? 0, z: input[2] ?? 0 };
1134
+ }
1135
+ const v = input;
1136
+ return { x: v.x, y: v.y, z: v.z };
1137
+ }
1138
+ function constrainedAxisKey(input) {
1139
+ const v = constrainedAxisToVec3(input);
1140
+ return `${v.x},${v.y},${v.z}`;
1141
+ }
1196
1142
  function renderPlaceholderInSubPortal(portalInstanceObject, El) {
1197
1143
  const spatialId = portalInstanceObject.spatialId;
1198
1144
  const inPortalInstanceEnv = !!portalInstanceObject.parentPortalInstanceObject;
@@ -1231,6 +1177,7 @@ function PortalSpatializedContainer(props) {
1231
1177
  onSpatialRotateEnd,
1232
1178
  onSpatialMagnify,
1233
1179
  onSpatialMagnifyEnd,
1180
+ spatialEventOptions,
1234
1181
  [SpatialID]: spatialId,
1235
1182
  ...restProps
1236
1183
  } = props;
@@ -1302,6 +1249,14 @@ function PortalSpatializedContainer(props) {
1302
1249
  spatializedElement.onSpatialDragStart = onSpatialDragStart;
1303
1250
  }
1304
1251
  }, [spatializedElement, onSpatialDragStart]);
1252
+ const rotateConstraintKey = constrainedAxisKey(
1253
+ spatialEventOptions?.constrainedToAxis
1254
+ );
1255
+ useEffect7(() => {
1256
+ if (!spatializedElement) return;
1257
+ const axis = constrainedAxisToVec3(spatialEventOptions?.constrainedToAxis);
1258
+ void spatializedElement.updateProperties({ rotateConstrainedToAxis: axis });
1259
+ }, [spatializedElement, rotateConstraintKey]);
1305
1260
  return /* @__PURE__ */ jsxs(PortalInstanceContext.Provider, { value: portalInstanceObject, children: [
1306
1261
  spatializedElement && portalInstanceObject.dom && /* @__PURE__ */ jsx3(Content, { spatializedElement, ...restProps }),
1307
1262
  PlaceholderEl
@@ -1561,6 +1516,7 @@ function DegradedContainer({
1561
1516
  onSpatialRotateEnd: _onSpatialRotateEnd,
1562
1517
  onSpatialMagnify: _onSpatialMagnify,
1563
1518
  onSpatialMagnifyEnd: _onSpatialMagnifyEnd,
1519
+ spatialEventOptions: _spatialEventOptions,
1564
1520
  spatializedContent: _content,
1565
1521
  createSpatializedElement: _create,
1566
1522
  getExtraSpatializedElementProperties: _getExtra,
@@ -1647,6 +1603,7 @@ function SpatializedContainerBase(inprops, ref) {
1647
1603
  spatializedContent,
1648
1604
  createSpatializedElement: createSpatializedElement2,
1649
1605
  getExtraSpatializedElementProperties: getExtraSpatializedElementProperties2,
1606
+ spatialEventOptions: _nestedSpatialEventOptions,
1650
1607
  ...restProps
1651
1608
  } = props;
1652
1609
  return /* @__PURE__ */ jsxs2(SpatialLayerContext.Provider, { value: layer, children: [
@@ -1697,6 +1654,7 @@ function SpatializedContainerBase(inprops, ref) {
1697
1654
  spatializedContent,
1698
1655
  createSpatializedElement: createSpatializedElement2,
1699
1656
  getExtraSpatializedElementProperties: getExtraSpatializedElementProperties2,
1657
+ spatialEventOptions: _rootSpatialEventOptions,
1700
1658
  ...restProps
1701
1659
  } = props;
1702
1660
  return /* @__PURE__ */ jsx6(SpatialLayerContext.Provider, { value: layer, children: /* @__PURE__ */ jsxs2(
@@ -2011,7 +1969,7 @@ import {
2011
1969
  useContext as useContext9,
2012
1970
  useEffect as useEffect13,
2013
1971
  useMemo as useMemo3,
2014
- useRef as useRef4
1972
+ useRef as useRef5
2015
1973
  } from "react";
2016
1974
  import { Fragment as Fragment2, jsx as jsx8 } from "react/jsx-runtime";
2017
1975
  function getAbsoluteURL(url) {
@@ -2086,7 +2044,7 @@ function SpatializedContent2(props) {
2086
2044
  return /* @__PURE__ */ jsx8(Fragment2, {});
2087
2045
  }
2088
2046
  function SpatializedStatic3DElementContainerBase(props, ref) {
2089
- const promiseRef = useRef4(null);
2047
+ const promiseRef = useRef5(null);
2090
2048
  const createSpatializedElement2 = useCallback6(() => {
2091
2049
  const url = getAbsoluteURL(props.src);
2092
2050
  promiseRef.current = getSession().createSpatializedStatic3DElement(url);
@@ -2182,9 +2140,9 @@ function initScene(name, callback, options) {
2182
2140
  import { forwardRef as forwardRef9 } from "react";
2183
2141
 
2184
2142
  // src/spatialized-container-monitor/useMonitorDomChange.tsx
2185
- import { useRef as useRef5, useEffect as useEffect14, useMemo as useMemo4 } from "react";
2143
+ import { useRef as useRef6, useEffect as useEffect14, useMemo as useMemo4 } from "react";
2186
2144
  function useMonitorDomChange(inRef) {
2187
- const ref = useRef5(null);
2145
+ const ref = useRef6(null);
2188
2146
  useEffect14(() => {
2189
2147
  const observer = new MutationObserver((mutationsList) => {
2190
2148
  notifyDOMUpdate(mutationsList);
@@ -2314,7 +2272,11 @@ var AttachmentRegistry = class {
2314
2272
  }
2315
2273
  getContainers(name) {
2316
2274
  const map = this.containers.get(name);
2317
- return map ? Array.from(map.values()) : [];
2275
+ if (!map) return [];
2276
+ return Array.from(map, ([instanceId, container]) => ({
2277
+ instanceId,
2278
+ container
2279
+ }));
2318
2280
  }
2319
2281
  onContainersChange(name, cb) {
2320
2282
  const current = this.getContainers(name);
@@ -2342,7 +2304,7 @@ var AttachmentRegistry = class {
2342
2304
  var AttachmentContext = createContext8(null);
2343
2305
 
2344
2306
  // src/reality/hooks/useEntityTransform.tsx
2345
- import { useEffect as useEffect16, useRef as useRef6 } from "react";
2307
+ import { useEffect as useEffect16, useRef as useRef7 } from "react";
2346
2308
 
2347
2309
  // src/reality/utils/ResourceRegistry.ts
2348
2310
  var ResourceRegistry = class {
@@ -2387,6 +2349,20 @@ function shallowEqualRotation(a, b) {
2387
2349
  if (!a || !b) return false;
2388
2350
  return a.x === b.x && a.y === b.y && a.z === b.z && ("w" in a ? a.w === b.w : true);
2389
2351
  }
2352
+ function shallowEqualObject(a, b) {
2353
+ if (a === b) return true;
2354
+ if (!a || !b) return false;
2355
+ const keysA = Object.keys(a);
2356
+ const keysB = Object.keys(b);
2357
+ if (keysA.length !== keysB.length) return false;
2358
+ return keysA.every((key) => a[key] === b[key]);
2359
+ }
2360
+ function shallowEqualArray(a, b) {
2361
+ if (a === b) return true;
2362
+ if (!a || !b) return false;
2363
+ if (a.length !== b.length) return false;
2364
+ return a.every((val, i) => val === b[i]);
2365
+ }
2390
2366
 
2391
2367
  // src/reality/utils/AbortResourceManager.ts
2392
2368
  var AbortResourceManager = class {
@@ -2423,7 +2399,7 @@ var AbortResourceManager = class {
2423
2399
 
2424
2400
  // src/reality/hooks/useEntityTransform.tsx
2425
2401
  function useEntityTransform(entity, { position, rotation, scale }) {
2426
- const last = useRef6({});
2402
+ const last = useRef7({});
2427
2403
  useEffect16(() => {
2428
2404
  if (!entity) return;
2429
2405
  const shouldUpdate = !shallowEqualVec3(last.current.position, position) || !shallowEqualRotation(last.current.rotation, rotation) || !shallowEqualVec3(last.current.scale, scale);
@@ -2443,7 +2419,7 @@ function useEntityTransform(entity, { position, rotation, scale }) {
2443
2419
  }
2444
2420
 
2445
2421
  // src/reality/hooks/useEntityEvent.tsx
2446
- import { useEffect as useEffect18, useRef as useRef8 } from "react";
2422
+ import { useEffect as useEffect18, useRef as useRef9 } from "react";
2447
2423
 
2448
2424
  // src/reality/type.ts
2449
2425
  var eventMap = {
@@ -2454,11 +2430,9 @@ var eventMap = {
2454
2430
  onSpatialDrag: "spatialdrag",
2455
2431
  onSpatialDragEnd: "spatialdragend",
2456
2432
  // rotate
2457
- onSpatialRotateStart: "spatialrotatestart",
2458
2433
  onSpatialRotate: "spatialrotate",
2459
2434
  onSpatialRotateEnd: "spatialrotateend",
2460
2435
  // magnify
2461
- onSpatialMagnifyStart: "spatialmagnifystart",
2462
2436
  onSpatialMagnify: "spatialmagnify",
2463
2437
  onSpatialMagnifyEnd: "spatialmagnifyend"
2464
2438
  };
@@ -2647,7 +2621,7 @@ function createEventProxy2(ev, instance) {
2647
2621
  });
2648
2622
  }
2649
2623
  var useEntityEvent = ({ instance, ...handlers }) => {
2650
- const eventsSetRef = useRef8(/* @__PURE__ */ new Set());
2624
+ const eventsSetRef = useRef9(/* @__PURE__ */ new Set());
2651
2625
  useEffect18(() => {
2652
2626
  const entity = instance.entity;
2653
2627
  if (!entity) return;
@@ -2674,11 +2648,147 @@ var useEntityEvent = ({ instance, ...handlers }) => {
2674
2648
  return null;
2675
2649
  };
2676
2650
 
2651
+ // src/reality/hooks/useRealityEvents.tsx
2652
+ import { useEffect as useEffect19, useRef as useRef10 } from "react";
2653
+ function createEventProxy3(ev, instance) {
2654
+ return new Proxy(ev, {
2655
+ get(target, prop) {
2656
+ if (prop === "currentTarget") {
2657
+ return instance;
2658
+ }
2659
+ if (prop === "target") {
2660
+ const origin = target.__origin;
2661
+ if (origin) {
2662
+ return new EntityRef(origin, null);
2663
+ }
2664
+ return instance;
2665
+ }
2666
+ if (prop === "bubbles") {
2667
+ return true;
2668
+ }
2669
+ if (prop === "offsetX") {
2670
+ const type = target.type;
2671
+ if (type === "spatialtap") {
2672
+ return target.detail?.location3D?.x ?? 0;
2673
+ }
2674
+ if (type === "spatialdragstart") {
2675
+ return target.detail?.startLocation3D?.x ?? 0;
2676
+ }
2677
+ return void 0;
2678
+ }
2679
+ if (prop === "offsetY") {
2680
+ const type = target.type;
2681
+ if (type === "spatialtap") {
2682
+ return target.detail?.location3D?.y ?? 0;
2683
+ }
2684
+ if (type === "spatialdragstart") {
2685
+ return target.detail?.startLocation3D?.y ?? 0;
2686
+ }
2687
+ return void 0;
2688
+ }
2689
+ if (prop === "offsetZ") {
2690
+ const type = target.type;
2691
+ if (type === "spatialtap") {
2692
+ return target.detail?.location3D?.z ?? 0;
2693
+ }
2694
+ if (type === "spatialdragstart") {
2695
+ return target.detail?.startLocation3D?.z ?? 0;
2696
+ }
2697
+ return void 0;
2698
+ }
2699
+ if (prop === "translationX") {
2700
+ const type = target.type;
2701
+ if (type === "spatialdrag") {
2702
+ return target.detail?.translation3D?.x ?? 0;
2703
+ }
2704
+ return void 0;
2705
+ }
2706
+ if (prop === "translationY") {
2707
+ const type = target.type;
2708
+ if (type === "spatialdrag") {
2709
+ return target.detail?.translation3D?.y ?? 0;
2710
+ }
2711
+ return void 0;
2712
+ }
2713
+ if (prop === "translationZ") {
2714
+ const type = target.type;
2715
+ if (type === "spatialdrag") {
2716
+ return target.detail?.translation3D?.z ?? 0;
2717
+ }
2718
+ return void 0;
2719
+ }
2720
+ if (prop === "quaternion") {
2721
+ const type = target.type;
2722
+ if (type === "spatialrotate") {
2723
+ return target.detail?.quaternion ?? {
2724
+ x: 0,
2725
+ y: 0,
2726
+ z: 0,
2727
+ w: 1
2728
+ };
2729
+ }
2730
+ return void 0;
2731
+ }
2732
+ if (prop === "magnification") {
2733
+ const type = target.type;
2734
+ if (type === "spatialmagnify") {
2735
+ return target.detail?.magnification ?? 1;
2736
+ }
2737
+ return void 0;
2738
+ }
2739
+ if (prop === "clientX") {
2740
+ const type = target.type;
2741
+ if (type === "spatialtap" || type === "spatialdragstart") {
2742
+ return target.detail?.globalLocation3D?.x ?? 0;
2743
+ }
2744
+ return void 0;
2745
+ }
2746
+ if (prop === "clientY") {
2747
+ const type = target.type;
2748
+ if (type === "spatialtap" || type === "spatialdragstart") {
2749
+ return target.detail?.globalLocation3D?.y ?? 0;
2750
+ }
2751
+ return void 0;
2752
+ }
2753
+ if (prop === "clientZ") {
2754
+ const type = target.type;
2755
+ if (type === "spatialtap" || type === "spatialdragstart") {
2756
+ return target.detail?.globalLocation3D?.z ?? 0;
2757
+ }
2758
+ return void 0;
2759
+ }
2760
+ const val = target[prop];
2761
+ return typeof val === "function" ? val.bind(target) : val;
2762
+ }
2763
+ });
2764
+ }
2765
+ var useRealityEvents = ({ instance, ...handlers }) => {
2766
+ const eventsSetRef = useRef10(/* @__PURE__ */ new Set());
2767
+ useEffect19(() => {
2768
+ if (!instance) return;
2769
+ Object.entries(eventMap).forEach(([reactKey, spatialEvent]) => {
2770
+ const handlerFn = handlers[reactKey];
2771
+ if (!handlerFn) return;
2772
+ const wrapped = (ev) => handlerFn(createEventProxy3(ev, instance));
2773
+ instance.addEvent(spatialEvent, wrapped);
2774
+ eventsSetRef.current.add(spatialEvent);
2775
+ });
2776
+ return () => {
2777
+ if (instance) {
2778
+ for (let x of eventsSetRef.current) {
2779
+ instance.removeEvent(x);
2780
+ }
2781
+ eventsSetRef.current.clear();
2782
+ }
2783
+ };
2784
+ }, [instance, ...Object.values(handlers)]);
2785
+ };
2786
+
2677
2787
  // src/reality/hooks/useEntityId.tsx
2678
- import { useEffect as useEffect19 } from "react";
2788
+ import { useEffect as useEffect20 } from "react";
2679
2789
  var useEntityId = ({ id, entity }) => {
2680
2790
  const ctx = useRealityContext();
2681
- useEffect19(() => {
2791
+ useEffect20(() => {
2682
2792
  if (!id || !entity || !ctx) return;
2683
2793
  ctx.resourceRegistry.add(id, Promise.resolve(entity));
2684
2794
  return () => {
@@ -2689,31 +2799,30 @@ var useEntityId = ({ id, entity }) => {
2689
2799
  };
2690
2800
 
2691
2801
  // src/reality/hooks/useEntity.tsx
2692
- import { useEffect as useEffect20, useRef as useRef9 } from "react";
2802
+ import { useEffect as useEffect21, useRef as useRef11 } from "react";
2693
2803
  var useEntity = ({
2694
2804
  ref,
2695
2805
  id,
2696
2806
  position,
2697
2807
  rotation,
2698
2808
  scale,
2809
+ enableInput,
2699
2810
  onSpatialTap,
2700
2811
  onSpatialDragStart,
2701
2812
  onSpatialDrag,
2702
2813
  onSpatialDragEnd,
2703
- // onSpatialRotateStart,
2704
2814
  onSpatialRotate,
2705
2815
  onSpatialRotateEnd,
2706
- // onSpatialMagnifyStart,
2707
2816
  onSpatialMagnify,
2708
2817
  onSpatialMagnifyEnd,
2709
- // TODO: add other event handlers
2710
- createEntity
2818
+ createEntity,
2819
+ recreateKey
2711
2820
  }) => {
2712
2821
  const ctx = useRealityContext();
2713
2822
  const parent = useParentContext();
2714
- const instanceRef = useRef9(new EntityRef(null, ctx));
2823
+ const instanceRef = useRef11(new EntityRef(null, ctx));
2715
2824
  const forceUpdate = useForceUpdate2();
2716
- useEffect20(() => {
2825
+ useEffect21(() => {
2717
2826
  if (!ctx) return;
2718
2827
  const controller = new AbortController();
2719
2828
  const init = async () => {
@@ -2724,6 +2833,11 @@ var useEntity = ({
2724
2833
  ent.destroy();
2725
2834
  return;
2726
2835
  }
2836
+ await ent.updateTransform({ position, rotation, scale });
2837
+ if (controller.signal.aborted) {
2838
+ ent.destroy();
2839
+ return;
2840
+ }
2727
2841
  if (parent) {
2728
2842
  const result = await parent.addEntity(ent);
2729
2843
  if (!result.success) throw new Error("parent.addEntity failed");
@@ -2742,7 +2856,7 @@ var useEntity = ({
2742
2856
  controller.abort();
2743
2857
  instanceRef.current?.destroy();
2744
2858
  };
2745
- }, [ctx, parent]);
2859
+ }, [ctx, parent, recreateKey]);
2746
2860
  useEntityId({ id, entity: instanceRef.current.entity });
2747
2861
  useEntityTransform(instanceRef.current.entity, { position, rotation, scale });
2748
2862
  useEntityRef(ref, instanceRef.current);
@@ -2752,31 +2866,37 @@ var useEntity = ({
2752
2866
  onSpatialDragStart,
2753
2867
  onSpatialDrag,
2754
2868
  onSpatialDragEnd,
2755
- // onSpatialRotateStart,
2756
2869
  onSpatialRotate,
2757
2870
  onSpatialRotateEnd,
2758
- // onSpatialMagnifyStart,
2759
2871
  onSpatialMagnify,
2760
2872
  onSpatialMagnifyEnd
2761
2873
  });
2874
+ useEffect21(() => {
2875
+ const ent = instanceRef.current.entity;
2876
+ if (!ent) return;
2877
+ if (enableInput !== void 0) {
2878
+ ent.enableInput = !!enableInput;
2879
+ }
2880
+ }, [instanceRef.current.entity, enableInput]);
2762
2881
  return instanceRef.current.entity;
2763
2882
  };
2764
2883
 
2765
2884
  // src/reality/hooks/useForceUpdate.tsx
2766
- import { useCallback as useCallback7, useState as useState7 } from "react";
2885
+ import { useCallback as useCallback7, useState as useState6 } from "react";
2767
2886
  var useForceUpdate2 = () => {
2768
- const [, setTick] = useState7(0);
2887
+ const [, setTick] = useState6(0);
2769
2888
  return useCallback7(() => setTick((tick) => tick + 1), []);
2770
2889
  };
2771
2890
 
2772
2891
  // src/reality/components/BaseEntity.tsx
2773
2892
  import { jsx as jsx12 } from "react/jsx-runtime";
2774
2893
  var BaseEntity = forwardRef10(
2775
- ({ children, createEntity, ...rest }, ref) => {
2894
+ ({ children, createEntity, recreateKey, ...rest }, ref) => {
2776
2895
  const ctx = useRealityContext();
2777
2896
  const entity = useEntity({
2778
2897
  ...rest,
2779
2898
  ref,
2899
+ recreateKey,
2780
2900
  createEntity: (signal) => createEntity(ctx, signal)
2781
2901
  });
2782
2902
  if (!entity) return null;
@@ -2804,35 +2924,102 @@ var Entity = forwardRef11((props, ref) => {
2804
2924
  import { forwardRef as forwardRef13 } from "react";
2805
2925
 
2806
2926
  // src/reality/components/GeometryEntity.tsx
2807
- import { forwardRef as forwardRef12 } from "react";
2927
+ import { forwardRef as forwardRef12, useEffect as useEffect22, useRef as useRef12 } from "react";
2808
2928
  import { jsx as jsx14 } from "react/jsx-runtime";
2809
2929
  var GeometryEntity = forwardRef12(
2810
2930
  ({ id, children, name, materials, geometryOptions, createGeometry, ...rest }, ref) => {
2931
+ const ctx = useRealityContext();
2932
+ const entityRef = useRef12(null);
2933
+ const componentRef = useRef12(null);
2934
+ const mutableRef = useRef12({
2935
+ lastSnapshot: null,
2936
+ rebuildGen: 0
2937
+ });
2938
+ useEffect22(() => {
2939
+ const { lastSnapshot } = mutableRef.current;
2940
+ if (!ctx || !entityRef.current || lastSnapshot === null) return;
2941
+ const geometryChanged = !shallowEqualObject(
2942
+ lastSnapshot.geometryOptions,
2943
+ geometryOptions
2944
+ );
2945
+ const materialsChanged = !shallowEqualArray(
2946
+ lastSnapshot.materials,
2947
+ materials
2948
+ );
2949
+ if (!geometryChanged && !materialsChanged) return;
2950
+ mutableRef.current.lastSnapshot = { geometryOptions, materials };
2951
+ mutableRef.current.rebuildGen += 1;
2952
+ const gen = mutableRef.current.rebuildGen;
2953
+ const rebuild = async () => {
2954
+ const entity = entityRef.current;
2955
+ if (!entity) return;
2956
+ try {
2957
+ const oldComponent = componentRef.current;
2958
+ if (oldComponent) {
2959
+ await entity.removeComponent(oldComponent);
2960
+ await oldComponent.destroy();
2961
+ componentRef.current = null;
2962
+ if (gen !== mutableRef.current.rebuildGen) return;
2963
+ }
2964
+ const geometry = await createGeometry(geometryOptions);
2965
+ if (gen !== mutableRef.current.rebuildGen) {
2966
+ await geometry.destroy();
2967
+ return;
2968
+ }
2969
+ const materialList = await Promise.all(
2970
+ materials?.map((mid) => ctx.resourceRegistry.get(mid)).filter(Boolean) ?? []
2971
+ );
2972
+ if (gen !== mutableRef.current.rebuildGen) {
2973
+ await geometry.destroy();
2974
+ return;
2975
+ }
2976
+ const modelComponent = await ctx.session.createModelComponent({
2977
+ mesh: geometry,
2978
+ materials: materialList
2979
+ });
2980
+ if (gen !== mutableRef.current.rebuildGen) {
2981
+ await modelComponent.destroy();
2982
+ await geometry.destroy();
2983
+ return;
2984
+ }
2985
+ await entity.addComponent(modelComponent);
2986
+ componentRef.current = modelComponent;
2987
+ } catch (error) {
2988
+ if (gen === mutableRef.current.rebuildGen) {
2989
+ console.error("GeometryEntity: rebuild failed", error);
2990
+ }
2991
+ }
2992
+ };
2993
+ rebuild();
2994
+ }, [ctx, geometryOptions, materials, createGeometry]);
2811
2995
  return /* @__PURE__ */ jsx14(
2812
2996
  BaseEntity,
2813
2997
  {
2814
2998
  ...rest,
2815
2999
  id,
2816
3000
  ref,
2817
- createEntity: async (ctx, signal) => {
3001
+ createEntity: async (ctx2, signal) => {
2818
3002
  const manager = new AbortResourceManager(signal);
2819
3003
  try {
2820
3004
  const ent = await manager.addResource(
2821
- () => ctx.session.createEntity({ id, name })
3005
+ () => ctx2.session.createEntity({ id, name })
2822
3006
  );
2823
3007
  const geometry = await manager.addResource(
2824
3008
  () => createGeometry(geometryOptions)
2825
3009
  );
2826
3010
  const materialList = await Promise.all(
2827
- materials?.map((id2) => ctx.resourceRegistry.get(id2)).filter(Boolean) ?? []
3011
+ materials?.map((id2) => ctx2.resourceRegistry.get(id2)).filter(Boolean) ?? []
2828
3012
  );
2829
3013
  const modelComponent = await manager.addResource(
2830
- () => ctx.session.createModelComponent({
3014
+ () => ctx2.session.createModelComponent({
2831
3015
  mesh: geometry,
2832
3016
  materials: materialList
2833
3017
  })
2834
3018
  );
2835
3019
  await ent.addComponent(modelComponent);
3020
+ entityRef.current = ent;
3021
+ componentRef.current = modelComponent;
3022
+ mutableRef.current.lastSnapshot = { geometryOptions, materials };
2836
3023
  return ent;
2837
3024
  } catch (error) {
2838
3025
  await manager.dispose();
@@ -2870,11 +3057,15 @@ var BoxEntity = forwardRef13(
2870
3057
  );
2871
3058
 
2872
3059
  // src/reality/components/UnlitMaterial.tsx
2873
- import { useEffect as useEffect21, useRef as useRef10 } from "react";
2874
- var UnlitMaterial = ({ children, ...options }) => {
3060
+ import { useEffect as useEffect23, useRef as useRef13 } from "react";
3061
+ var UnlitMaterial = ({
3062
+ children,
3063
+ ...options
3064
+ }) => {
2875
3065
  const ctx = useRealityContext();
2876
- const materialRef = useRef10();
2877
- useEffect21(() => {
3066
+ const materialRef = useRef13();
3067
+ const isInitializedRef = useRef13(false);
3068
+ useEffect23(() => {
2878
3069
  if (!ctx) return;
2879
3070
  const { session, reality, resourceRegistry } = ctx;
2880
3071
  const init = async () => {
@@ -2883,6 +3074,7 @@ var UnlitMaterial = ({ children, ...options }) => {
2883
3074
  try {
2884
3075
  const mat = await materialPromise;
2885
3076
  materialRef.current = mat;
3077
+ isInitializedRef.current = true;
2886
3078
  } catch (error) {
2887
3079
  console.error(" ~ UnlitMaterial ~ error:", error);
2888
3080
  }
@@ -2890,8 +3082,21 @@ var UnlitMaterial = ({ children, ...options }) => {
2890
3082
  init();
2891
3083
  return () => {
2892
3084
  resourceRegistry.removeAndDestroy(options.id);
3085
+ materialRef.current = void 0;
3086
+ isInitializedRef.current = false;
2893
3087
  };
2894
3088
  }, [ctx]);
3089
+ useEffect23(() => {
3090
+ if (!isInitializedRef.current || !materialRef.current) return;
3091
+ const updates = {};
3092
+ if (options.color !== void 0) updates.color = options.color;
3093
+ if (options.transparent !== void 0)
3094
+ updates.transparent = options.transparent;
3095
+ if (options.opacity !== void 0) updates.opacity = options.opacity;
3096
+ if (Object.keys(updates).length > 0) {
3097
+ materialRef.current.updateProperties(updates);
3098
+ }
3099
+ }, [options.color, options.transparent, options.opacity]);
2895
3100
  return null;
2896
3101
  };
2897
3102
 
@@ -2990,7 +3195,7 @@ var SceneGraph = ({ children }) => {
2990
3195
  };
2991
3196
 
2992
3197
  // src/reality/components/ModelAsset.tsx
2993
- import { useEffect as useEffect22, useRef as useRef11 } from "react";
3198
+ import { useEffect as useEffect24, useRef as useRef14 } from "react";
2994
3199
  var resolveAssetUrl = (url) => {
2995
3200
  if (url.startsWith("http://") || url.startsWith("https://")) {
2996
3201
  return url;
@@ -2999,8 +3204,8 @@ var resolveAssetUrl = (url) => {
2999
3204
  };
3000
3205
  var ModelAsset = ({ children, ...options }) => {
3001
3206
  const ctx = useRealityContext();
3002
- const materialRef = useRef11();
3003
- useEffect22(() => {
3207
+ const materialRef = useRef14();
3208
+ useEffect24(() => {
3004
3209
  const controller = new AbortController();
3005
3210
  if (!ctx) return;
3006
3211
  const { session, reality, resourceRegistry } = ctx;
@@ -3030,29 +3235,66 @@ var ModelAsset = ({ children, ...options }) => {
3030
3235
  };
3031
3236
 
3032
3237
  // src/reality/components/ModelEntity.tsx
3033
- import { forwardRef as forwardRef18 } from "react";
3238
+ import { forwardRef as forwardRef18, useEffect as useEffect25, useRef as useRef15 } from "react";
3034
3239
  import { jsx as jsx21 } from "react/jsx-runtime";
3035
3240
  var ModelEntity = forwardRef18(
3036
- ({ id, model, children, name, ...rest }, ref) => {
3241
+ ({ id, model, children, name, materials, ...rest }, ref) => {
3242
+ const ctx = useRealityContext();
3243
+ const entityRef = useRef15(null);
3244
+ const lastMaterialsRef = useRef15(void 0);
3245
+ useEffect25(() => {
3246
+ if (!ctx || !entityRef.current) return;
3247
+ const next = materials ?? [];
3248
+ const prev = lastMaterialsRef.current ?? [];
3249
+ if (shallowEqualArray(prev, next)) return;
3250
+ lastMaterialsRef.current = next;
3251
+ const apply = async () => {
3252
+ try {
3253
+ const materialList = (await Promise.all(
3254
+ next.map((mid) => ctx.resourceRegistry.get(mid))
3255
+ )).filter(Boolean);
3256
+ if (entityRef.current) {
3257
+ await entityRef.current.setMaterials(materialList);
3258
+ }
3259
+ } catch (error) {
3260
+ console.error("ModelEntity: failed to set materials", error);
3261
+ }
3262
+ };
3263
+ apply();
3264
+ }, [ctx, materials]);
3037
3265
  return /* @__PURE__ */ jsx21(
3038
3266
  BaseEntity,
3039
3267
  {
3040
3268
  ...rest,
3041
3269
  id,
3042
3270
  ref,
3043
- createEntity: async (ctx, signal) => {
3271
+ recreateKey: model,
3272
+ createEntity: async (ctx2, signal) => {
3044
3273
  try {
3045
- const modelAsset = await ctx.resourceRegistry.get(model);
3274
+ const modelAsset = await ctx2.resourceRegistry.get(model);
3046
3275
  if (!modelAsset)
3047
3276
  throw new Error(`ModelEntity: model not found ${model}`);
3048
3277
  if (signal.aborted) return null;
3049
- return ctx.session.createSpatialModelEntity(
3278
+ const ent = await ctx2.session.createSpatialModelEntity(
3050
3279
  {
3051
3280
  modelAssetId: modelAsset.id,
3052
3281
  name
3053
3282
  },
3054
3283
  { id, name }
3055
3284
  );
3285
+ entityRef.current = ent;
3286
+ if (materials && materials.length > 0) {
3287
+ const materialList = (await Promise.all(
3288
+ materials.map(
3289
+ (mid) => ctx2.resourceRegistry.get(mid)
3290
+ )
3291
+ )).filter(Boolean);
3292
+ if (materialList.length > 0 && !signal.aborted) {
3293
+ await ent.setMaterials(materialList);
3294
+ }
3295
+ }
3296
+ lastMaterialsRef.current = materials ?? [];
3297
+ return ent;
3056
3298
  } catch (error) {
3057
3299
  return null;
3058
3300
  }
@@ -3067,9 +3309,9 @@ var ModelEntity = forwardRef18(
3067
3309
  import {
3068
3310
  forwardRef as forwardRef19,
3069
3311
  useCallback as useCallback8,
3070
- useEffect as useEffect23,
3071
- useRef as useRef12,
3072
- useState as useState8
3312
+ useEffect as useEffect26,
3313
+ useRef as useRef16,
3314
+ useState as useState7
3073
3315
  } from "react";
3074
3316
  import { Fragment as Fragment3, jsx as jsx22, jsxs as jsxs3 } from "react/jsx-runtime";
3075
3317
  var Reality = forwardRef19(
@@ -3092,9 +3334,9 @@ var Reality = forwardRef19(
3092
3334
  onSpatialMagnifyEnd,
3093
3335
  ...props
3094
3336
  } = inProps;
3095
- const ctxRef = useRef12(null);
3096
- const creationId = useRef12(0);
3097
- const [isReady, setIsReady] = useState8(false);
3337
+ const ctxRef = useRef16(null);
3338
+ const creationId = useRef16(0);
3339
+ const [isReady, setIsReady] = useState7(false);
3098
3340
  const cleanupReality = useCallback8(() => {
3099
3341
  ctxRef.current?.attachmentRegistry.destroy();
3100
3342
  ctxRef.current?.resourceRegistry.destroy();
@@ -3102,7 +3344,7 @@ var Reality = forwardRef19(
3102
3344
  ctxRef.current = null;
3103
3345
  setIsReady(false);
3104
3346
  }, []);
3105
- useEffect23(() => {
3347
+ useEffect26(() => {
3106
3348
  return () => {
3107
3349
  creationId.current++;
3108
3350
  cleanupReality();
@@ -3152,6 +3394,17 @@ var Reality = forwardRef19(
3152
3394
  }
3153
3395
  }, [cleanupReality]);
3154
3396
  const content = useCallback8(() => /* @__PURE__ */ jsx22(Fragment3, {}), []);
3397
+ useRealityEvents({
3398
+ instance: ctxRef.current?.reality ?? null,
3399
+ onSpatialTap,
3400
+ onSpatialDragStart,
3401
+ onSpatialDrag,
3402
+ onSpatialDragEnd,
3403
+ onSpatialRotate,
3404
+ onSpatialRotateEnd,
3405
+ onSpatialMagnify,
3406
+ onSpatialMagnifyEnd
3407
+ });
3155
3408
  return /* @__PURE__ */ jsxs3(RealityContext.Provider, { value: ctxRef.current, children: [
3156
3409
  /* @__PURE__ */ jsx22(
3157
3410
  SpatializedContainer,
@@ -3169,7 +3422,7 @@ var Reality = forwardRef19(
3169
3422
  );
3170
3423
 
3171
3424
  // src/reality/components/AttachmentAsset.tsx
3172
- import { useEffect as useEffect24, useState as useState9 } from "react";
3425
+ import { useEffect as useEffect27, useState as useState8 } from "react";
3173
3426
  import { createPortal as createPortal3 } from "react-dom";
3174
3427
  import { jsx as jsx23 } from "react/jsx-runtime";
3175
3428
  var AttachmentAsset = ({
@@ -3177,17 +3430,19 @@ var AttachmentAsset = ({
3177
3430
  children
3178
3431
  }) => {
3179
3432
  const ctx = useRealityContext();
3180
- const [containers, setContainers] = useState9([]);
3181
- useEffect24(() => {
3433
+ const [containers, setContainers] = useState8([]);
3434
+ useEffect27(() => {
3182
3435
  if (!ctx) return;
3183
3436
  return ctx.attachmentRegistry.onContainersChange(name, setContainers);
3184
3437
  }, [ctx, name]);
3185
3438
  if (!containers.length) return null;
3186
- return /* @__PURE__ */ jsx23(InsideAttachmentContext.Provider, { value: true, children: containers.map((c, idx) => createPortal3(children, c, `${name}-${idx}`)) });
3439
+ return /* @__PURE__ */ jsx23(InsideAttachmentContext.Provider, { value: true, children: containers.map(
3440
+ ({ instanceId, container }) => createPortal3(children, container, instanceId)
3441
+ ) });
3187
3442
  };
3188
3443
 
3189
3444
  // src/reality/components/AttachmentEntity.tsx
3190
- import { useEffect as useEffect25, useRef as useRef13, useState as useState10 } from "react";
3445
+ import { useEffect as useEffect28, useRef as useRef17, useState as useState9 } from "react";
3191
3446
  var instanceCounter = 0;
3192
3447
  var AttachmentEntity = ({
3193
3448
  attachment: attachmentName,
@@ -3196,13 +3451,14 @@ var AttachmentEntity = ({
3196
3451
  }) => {
3197
3452
  const ctx = useRealityContext();
3198
3453
  const parent = useParentContext();
3199
- const attachmentRef = useRef13(null);
3200
- const parentIdRef = useRef13(null);
3201
- const instanceIdRef = useRef13(`att_${++instanceCounter}`);
3202
- const attachmentNameRef = useRef13(attachmentName);
3203
- const [childWindow, setChildWindow] = useState10(null);
3204
- useEffect25(() => {
3454
+ const attachmentRef = useRef17(null);
3455
+ const parentIdRef = useRef17(null);
3456
+ const instanceIdRef = useRef17(`att_${++instanceCounter}`);
3457
+ const attachmentNameRef = useRef17(attachmentName);
3458
+ const [childWindow, setChildWindow] = useState9(null);
3459
+ useEffect28(() => {
3205
3460
  if (!ctx || !parent) return;
3461
+ if (attachmentRef.current) return;
3206
3462
  const parentId = parent.id;
3207
3463
  parentIdRef.current = parentId;
3208
3464
  let cancelled = false;
@@ -3211,7 +3467,8 @@ var AttachmentEntity = ({
3211
3467
  const att = await ctx.session.createAttachmentEntity({
3212
3468
  parentEntityId: parentId,
3213
3469
  position: position ?? [0, 0, 0],
3214
- size
3470
+ size,
3471
+ ownerViewId: ctx.reality.id
3215
3472
  });
3216
3473
  if (cancelled) {
3217
3474
  att.destroy();
@@ -3223,7 +3480,6 @@ var AttachmentEntity = ({
3223
3480
  windowProxy.document.body.style.minWidth = "100%";
3224
3481
  windowProxy.document.body.style.maxWidth = "100%";
3225
3482
  windowProxy.document.body.style.minHeight = "100%";
3226
- await syncParentHeadToChild(windowProxy);
3227
3483
  const viewport = windowProxy.document.querySelector(
3228
3484
  'meta[name="viewport"]'
3229
3485
  );
@@ -3262,7 +3518,7 @@ var AttachmentEntity = ({
3262
3518
  }
3263
3519
  };
3264
3520
  }, [ctx, parent]);
3265
- useEffect25(() => {
3521
+ useEffect28(() => {
3266
3522
  if (!ctx) return;
3267
3523
  const att = attachmentRef.current;
3268
3524
  const prevName = attachmentNameRef.current;
@@ -3279,17 +3535,27 @@ var AttachmentEntity = ({
3279
3535
  }
3280
3536
  }, [ctx, attachmentName]);
3281
3537
  useSyncHeadStyles(childWindow, { subtree: false });
3282
- useEffect25(() => {
3538
+ useEffect28(() => {
3283
3539
  if (!attachmentRef.current) return;
3284
3540
  attachmentRef.current.update({ position, size });
3285
3541
  }, [position?.[0], position?.[1], position?.[2], size?.width, size?.height]);
3286
3542
  return null;
3287
3543
  };
3288
3544
 
3545
+ // src/reality/components/Material.tsx
3546
+ import { jsx as jsx24 } from "react/jsx-runtime";
3547
+ var Material = (props) => {
3548
+ if (props.type === "unlit") {
3549
+ const { type, ...rest } = props;
3550
+ return /* @__PURE__ */ jsx24(UnlitMaterial, { ...rest });
3551
+ }
3552
+ return null;
3553
+ };
3554
+
3289
3555
  // src/Model.tsx
3290
3556
  import { forwardRef as forwardRef20 } from "react";
3291
3557
  import { Spatial as Spatial2 } from "@webspatial/core-sdk";
3292
- import { jsx as jsx24 } from "react/jsx-runtime";
3558
+ import { jsx as jsx25 } from "react/jsx-runtime";
3293
3559
  var spatial2 = new Spatial2();
3294
3560
  function ModelBase(props, ref) {
3295
3561
  const insideAttachment = useInsideAttachment();
@@ -3304,30 +3570,126 @@ function ModelBase(props, ref) {
3304
3570
  onSpatialRotateEnd,
3305
3571
  onSpatialMagnify,
3306
3572
  onSpatialMagnifyEnd,
3573
+ spatialEventOptions: _spatialEventOptions,
3307
3574
  ...modelProps
3308
3575
  } = restProps;
3309
- return /* @__PURE__ */ jsx24("model", { ref, ...modelProps });
3576
+ return /* @__PURE__ */ jsx25("model", { ref, ...modelProps });
3310
3577
  }
3311
- return /* @__PURE__ */ jsx24(SpatializedStatic3DElementContainer, { ref, ...restProps });
3578
+ return /* @__PURE__ */ jsx25(SpatializedStatic3DElementContainer, { ref, ...restProps });
3312
3579
  }
3313
3580
  var Model = withSSRSupported(forwardRef20(ModelBase));
3314
3581
  Model.displayName = "Model";
3315
3582
 
3583
+ // src/useMetrics.tsx
3584
+ import { useSyncExternalStore } from "react";
3585
+ import { PhysicalMetrics } from "@webspatial/core-sdk";
3586
+ function useMetrics() {
3587
+ useSyncExternalStore(PhysicalMetrics.subscribe, PhysicalMetrics.getValue);
3588
+ const { pointToPhysical, physicalToPoint } = PhysicalMetrics;
3589
+ return { pointToPhysical, physicalToPoint };
3590
+ }
3591
+
3592
+ // src/jsx/jsx-shared.ts
3593
+ import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
3594
+ import reactJSXRuntime from "react/jsx-runtime";
3595
+ import { createElement as reactCreateElement } from "react";
3596
+ var attributeFlag = "enable-xr";
3597
+ var styleFlag = "enableXr";
3598
+ var classFlag = "__enableXr__";
3599
+ var xrMonitorFlag = "enable-xr-monitor";
3600
+ function replaceToSpatialPrimitiveType(type, props) {
3601
+ if (type === Model) {
3602
+ return type;
3603
+ }
3604
+ const propsObject = props;
3605
+ if (attributeFlag in propsObject) {
3606
+ delete propsObject[attributeFlag];
3607
+ return withSpatialized2DElementContainer(type);
3608
+ }
3609
+ if (xrMonitorFlag in propsObject) {
3610
+ delete propsObject[xrMonitorFlag];
3611
+ return withSpatialMonitor(type);
3612
+ }
3613
+ if (propsObject && propsObject.style && styleFlag in propsObject.style) {
3614
+ delete propsObject.style[styleFlag];
3615
+ return withSpatialized2DElementContainer(type);
3616
+ }
3617
+ if (propsObject && typeof propsObject.className === "string") {
3618
+ const originalClassNames = propsObject.className.split(" ");
3619
+ const idx = originalClassNames.indexOf(classFlag);
3620
+ if (idx !== -1) {
3621
+ originalClassNames.splice(idx, 1);
3622
+ propsObject.className = originalClassNames.join(" ");
3623
+ return withSpatialized2DElementContainer(type);
3624
+ }
3625
+ }
3626
+ return type;
3627
+ }
3628
+ function createElement(...args) {
3629
+ const [type, props, ...rest] = args;
3630
+ const newType = replaceToSpatialPrimitiveType(type, props);
3631
+ return reactCreateElement(newType, props, ...rest);
3632
+ }
3633
+
3634
+ // src/utils/convertCoordinate.ts
3635
+ function resolveSpatialObjectId(target) {
3636
+ if (typeof window !== "undefined" && target === window) {
3637
+ const scene = getSession()?.getSpatialScene();
3638
+ return scene?.id ?? "";
3639
+ }
3640
+ const maybeEntity = target;
3641
+ if (maybeEntity && typeof maybeEntity === "object" && "entity" in maybeEntity) {
3642
+ return maybeEntity.entity?.id ?? null;
3643
+ }
3644
+ const dom = target?.__raw ?? target;
3645
+ if (dom && typeof dom === "object") {
3646
+ const spatializedElement = dom.__spatializedElement ?? dom.__innerSpatializedElement?.();
3647
+ if (spatializedElement && spatializedElement.id) {
3648
+ return spatializedElement.id;
3649
+ }
3650
+ }
3651
+ return null;
3652
+ }
3653
+ async function convertCoordinate(position, { from, to }) {
3654
+ try {
3655
+ const fromId = resolveSpatialObjectId(from);
3656
+ const toId = resolveSpatialObjectId(to);
3657
+ if (fromId === null || toId === null) {
3658
+ console.warn(
3659
+ "convertCoordinate error: from or to is not a valid coordinate convertible"
3660
+ );
3661
+ return position;
3662
+ }
3663
+ const spatialScene = getSession()?.getSpatialScene();
3664
+ if (!spatialScene) return position;
3665
+ const ret = await spatialScene.convertCoordinate(position, fromId, toId);
3666
+ return ret ?? position;
3667
+ } catch (error) {
3668
+ console.warn("convertCoordinate error:", error);
3669
+ return position;
3670
+ }
3671
+ }
3672
+
3316
3673
  // src/index.ts
3317
- var version = "1.3.0";
3674
+ var version = "1.5.0";
3318
3675
  if (typeof window !== "undefined") {
3319
3676
  initPolyfill();
3320
3677
  }
3321
3678
  export {
3322
3679
  AttachmentAsset,
3323
3680
  AttachmentEntity,
3681
+ BoxEntity as Box,
3324
3682
  BoxEntity,
3683
+ ConeEntity as Cone,
3325
3684
  ConeEntity,
3685
+ CylinderEntity as Cylinder,
3326
3686
  CylinderEntity,
3327
3687
  Entity,
3688
+ Material,
3328
3689
  Model,
3329
3690
  ModelAsset,
3330
3691
  ModelEntity,
3692
+ PlaneEntity as Plane,
3331
3693
  PlaneEntity,
3332
3694
  Reality,
3333
3695
  SSRProvider,
@@ -3336,14 +3698,17 @@ export {
3336
3698
  Spatialized2DElementContainer,
3337
3699
  SpatializedContainer,
3338
3700
  SpatializedStatic3DElementContainer,
3701
+ SphereEntity as Sphere,
3339
3702
  SphereEntity,
3340
3703
  UnlitMaterial,
3704
+ SceneGraph as World,
3705
+ convertCoordinate,
3706
+ createElement,
3341
3707
  enableDebugTool,
3342
3708
  eventMap,
3343
3709
  initPolyfill,
3344
3710
  initScene,
3345
- toLocalSpace,
3346
- toSceneSpatial,
3711
+ useMetrics,
3347
3712
  version,
3348
3713
  withSpatialMonitor,
3349
3714
  withSpatialized2DElementContainer