@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.
package/dist/web/index.js CHANGED
@@ -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'] = "web"
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, {
@@ -893,6 +887,20 @@ var Spatial = class {
893
887
  function isSSREnv() {
894
888
  return false;
895
889
  }
890
+ var PhysicalMetrics = {
891
+ pointToPhysical: (point, options) => {
892
+ return point / 1360;
893
+ },
894
+ physicalToPoint: (physical, options) => {
895
+ return physical * 1360;
896
+ },
897
+ getValue: () => ({
898
+ meterToPtUnscaled: 1360,
899
+ meterToPtScaled: 1360
900
+ }),
901
+ subscribe: (cb) => {
902
+ }
903
+ };
896
904
 
897
905
  // src/utils/getSession.ts
898
906
  var spatial = null;
@@ -938,37 +946,6 @@ function enableDebugTool() {
938
946
  });
939
947
  }
940
948
 
941
- // src/spatialized-container/transform-utils.ts
942
- function toSceneSpatial(point, spatializedElement) {
943
- return spatializedElement.__toSceneSpace(point);
944
- }
945
- function toLocalSpace(point, spatializedElement) {
946
- return spatializedElement.__toLocalSpace(point);
947
- }
948
- function convertDOMRectToSceneSpace(originalRect, matrix) {
949
- const topLeft = new DOMPoint(originalRect.left, originalRect.top);
950
- const topRight = new DOMPoint(originalRect.right, originalRect.top);
951
- const bottomRight = new DOMPoint(originalRect.right, originalRect.bottom);
952
- const bottomLeft = new DOMPoint(originalRect.left, originalRect.bottom);
953
- const transformedTopLeft = matrix.transformPoint(topLeft);
954
- const transformedTopRight = matrix.transformPoint(topRight);
955
- const transformedBottomRight = matrix.transformPoint(bottomRight);
956
- const transformedBottomLeft = matrix.transformPoint(bottomLeft);
957
- const allPoints = [
958
- transformedTopLeft,
959
- transformedTopRight,
960
- transformedBottomRight,
961
- transformedBottomLeft
962
- ];
963
- const xCoords = allPoints.map((point) => point.x);
964
- const yCoords = allPoints.map((point) => point.y);
965
- const newMinX = Math.min(...xCoords);
966
- const newMaxX = Math.max(...xCoords);
967
- const newMinY = Math.min(...yCoords);
968
- const newMaxY = Math.max(...yCoords);
969
- return new DOMRect(newMinX, newMinY, newMaxX - newMinX, newMaxY - newMinY);
970
- }
971
-
972
949
  // src/spatialized-container/context/PortalInstanceContext.ts
973
950
  var PortalInstanceObject = class {
974
951
  spatialId;
@@ -1053,40 +1030,8 @@ var PortalInstanceObject = class {
1053
1030
  isFixedPosition: computedStyle.getPropertyValue("position") === "fixed"
1054
1031
  };
1055
1032
  this.updateSpatializedElementProperties();
1056
- const __getBoundingClientCube = () => {
1057
- return this.spatializedElement?.cubeInfo;
1058
- };
1059
- const __getBoundingClientRect = () => {
1060
- if (!this.spatializedElement?.transform) {
1061
- return null;
1062
- }
1063
- const domRect = new DOMRect(
1064
- 0,
1065
- 0,
1066
- this.domRect?.width,
1067
- this.domRect?.height
1068
- );
1069
- return convertDOMRectToSceneSpace(
1070
- domRect,
1071
- this.spatializedElement?.transform
1072
- );
1073
- };
1074
- const __toSceneSpace = (point) => {
1075
- return new DOMPoint(point.x, point.y, point.z).matrixTransform(
1076
- this.spatializedElement?.transform
1077
- );
1078
- };
1079
- const __toLocalSpace = (point) => {
1080
- return new DOMPoint(point.x, point.y, point.z).matrixTransform(
1081
- this.spatializedElement?.transformInv
1082
- );
1083
- };
1084
1033
  const __innerSpatializedElement = () => this.spatializedElement;
1085
1034
  Object.assign(dom, {
1086
- __getBoundingClientCube,
1087
- __getBoundingClientRect,
1088
- __toSceneSpace,
1089
- __toLocalSpace,
1090
1035
  __innerSpatializedElement
1091
1036
  });
1092
1037
  }
@@ -1204,18 +1149,19 @@ function useSync2DFrame(spatialId, portalInstanceObject, spatializedContainerObj
1204
1149
  }
1205
1150
 
1206
1151
  // src/spatialized-container/hooks/useSpatializedElement.ts
1207
- import { useEffect as useEffect6, useState as useState3 } from "react";
1152
+ import { useEffect as useEffect6, useRef as useRef4, useState as useState3 } from "react";
1208
1153
  function useSpatializedElement(createSpatializedElement2, portalInstanceObject) {
1209
1154
  const [spatializedElement, setSpatializedElement] = useState3();
1155
+ const elementRef = useRef4(void 0);
1210
1156
  useEffect6(() => {
1211
1157
  let isDestroyed = false;
1212
- let spatializedElement2;
1213
1158
  createSpatializedElement2().then(
1214
1159
  (inSpatializedElement) => {
1160
+ if (!inSpatializedElement) return;
1215
1161
  if (!isDestroyed) {
1216
- spatializedElement2 = inSpatializedElement;
1217
- portalInstanceObject.attachSpatializedElement(spatializedElement2);
1218
- setSpatializedElement(spatializedElement2);
1162
+ elementRef.current = inSpatializedElement;
1163
+ portalInstanceObject.attachSpatializedElement(inSpatializedElement);
1164
+ setSpatializedElement(inSpatializedElement);
1219
1165
  } else {
1220
1166
  inSpatializedElement?.destroy();
1221
1167
  }
@@ -1223,9 +1169,11 @@ function useSpatializedElement(createSpatializedElement2, portalInstanceObject)
1223
1169
  );
1224
1170
  return () => {
1225
1171
  isDestroyed = true;
1226
- if (spatializedElement2) {
1227
- spatializedElement2.destroy();
1228
- spatializedElement2 = void 0;
1172
+ const el = elementRef.current;
1173
+ if (el) {
1174
+ el.destroy();
1175
+ elementRef.current = void 0;
1176
+ setSpatializedElement(void 0);
1229
1177
  }
1230
1178
  };
1231
1179
  }, [createSpatializedElement2, portalInstanceObject]);
@@ -1234,6 +1182,18 @@ function useSpatializedElement(createSpatializedElement2, portalInstanceObject)
1234
1182
 
1235
1183
  // src/spatialized-container/PortalSpatializedContainer.tsx
1236
1184
  import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
1185
+ function constrainedAxisToVec3(input) {
1186
+ if (input == null) return { x: 0, y: 0, z: 0 };
1187
+ if (Array.isArray(input)) {
1188
+ return { x: input[0] ?? 0, y: input[1] ?? 0, z: input[2] ?? 0 };
1189
+ }
1190
+ const v = input;
1191
+ return { x: v.x, y: v.y, z: v.z };
1192
+ }
1193
+ function constrainedAxisKey(input) {
1194
+ const v = constrainedAxisToVec3(input);
1195
+ return `${v.x},${v.y},${v.z}`;
1196
+ }
1237
1197
  function renderPlaceholderInSubPortal(portalInstanceObject, El) {
1238
1198
  const spatialId = portalInstanceObject.spatialId;
1239
1199
  const inPortalInstanceEnv = !!portalInstanceObject.parentPortalInstanceObject;
@@ -1272,6 +1232,7 @@ function PortalSpatializedContainer(props) {
1272
1232
  onSpatialRotateEnd,
1273
1233
  onSpatialMagnify,
1274
1234
  onSpatialMagnifyEnd,
1235
+ spatialEventOptions,
1275
1236
  [SpatialID]: spatialId,
1276
1237
  ...restProps
1277
1238
  } = props;
@@ -1343,6 +1304,14 @@ function PortalSpatializedContainer(props) {
1343
1304
  spatializedElement.onSpatialDragStart = onSpatialDragStart;
1344
1305
  }
1345
1306
  }, [spatializedElement, onSpatialDragStart]);
1307
+ const rotateConstraintKey = constrainedAxisKey(
1308
+ spatialEventOptions?.constrainedToAxis
1309
+ );
1310
+ useEffect7(() => {
1311
+ if (!spatializedElement) return;
1312
+ const axis = constrainedAxisToVec3(spatialEventOptions?.constrainedToAxis);
1313
+ void spatializedElement.updateProperties({ rotateConstrainedToAxis: axis });
1314
+ }, [spatializedElement, rotateConstraintKey]);
1346
1315
  return /* @__PURE__ */ jsxs(PortalInstanceContext.Provider, { value: portalInstanceObject, children: [
1347
1316
  spatializedElement && portalInstanceObject.dom && /* @__PURE__ */ jsx3(Content, { spatializedElement, ...restProps }),
1348
1317
  PlaceholderEl
@@ -1602,6 +1571,7 @@ function DegradedContainer({
1602
1571
  onSpatialRotateEnd: _onSpatialRotateEnd,
1603
1572
  onSpatialMagnify: _onSpatialMagnify,
1604
1573
  onSpatialMagnifyEnd: _onSpatialMagnifyEnd,
1574
+ spatialEventOptions: _spatialEventOptions,
1605
1575
  spatializedContent: _content,
1606
1576
  createSpatializedElement: _create,
1607
1577
  getExtraSpatializedElementProperties: _getExtra,
@@ -1688,6 +1658,7 @@ function SpatializedContainerBase(inprops, ref) {
1688
1658
  spatializedContent,
1689
1659
  createSpatializedElement: createSpatializedElement2,
1690
1660
  getExtraSpatializedElementProperties: getExtraSpatializedElementProperties2,
1661
+ spatialEventOptions: _nestedSpatialEventOptions,
1691
1662
  ...restProps
1692
1663
  } = props;
1693
1664
  return /* @__PURE__ */ jsxs2(SpatialLayerContext.Provider, { value: layer, children: [
@@ -1738,6 +1709,7 @@ function SpatializedContainerBase(inprops, ref) {
1738
1709
  spatializedContent,
1739
1710
  createSpatializedElement: createSpatializedElement2,
1740
1711
  getExtraSpatializedElementProperties: getExtraSpatializedElementProperties2,
1712
+ spatialEventOptions: _rootSpatialEventOptions,
1741
1713
  ...restProps
1742
1714
  } = props;
1743
1715
  return /* @__PURE__ */ jsx6(SpatialLayerContext.Provider, { value: layer, children: /* @__PURE__ */ jsxs2(
@@ -2052,7 +2024,7 @@ import {
2052
2024
  useContext as useContext9,
2053
2025
  useEffect as useEffect13,
2054
2026
  useMemo as useMemo3,
2055
- useRef as useRef4
2027
+ useRef as useRef5
2056
2028
  } from "react";
2057
2029
  import { Fragment as Fragment2, jsx as jsx8 } from "react/jsx-runtime";
2058
2030
  function getAbsoluteURL(url) {
@@ -2127,7 +2099,7 @@ function SpatializedContent2(props) {
2127
2099
  return /* @__PURE__ */ jsx8(Fragment2, {});
2128
2100
  }
2129
2101
  function SpatializedStatic3DElementContainerBase(props, ref) {
2130
- const promiseRef = useRef4(null);
2102
+ const promiseRef = useRef5(null);
2131
2103
  const createSpatializedElement2 = useCallback6(() => {
2132
2104
  const url = getAbsoluteURL(props.src);
2133
2105
  promiseRef.current = getSession().createSpatializedStatic3DElement(url);
@@ -2223,9 +2195,9 @@ function initScene(name, callback) {
2223
2195
  import { forwardRef as forwardRef9 } from "react";
2224
2196
 
2225
2197
  // src/spatialized-container-monitor/useMonitorDomChange.tsx
2226
- import { useRef as useRef5, useEffect as useEffect14, useMemo as useMemo4 } from "react";
2198
+ import { useRef as useRef6, useEffect as useEffect14, useMemo as useMemo4 } from "react";
2227
2199
  function useMonitorDomChange(inRef) {
2228
- const ref = useRef5(null);
2200
+ const ref = useRef6(null);
2229
2201
  useEffect14(() => {
2230
2202
  const observer = new MutationObserver((mutationsList) => {
2231
2203
  notifyDOMUpdate(mutationsList);
@@ -2355,7 +2327,11 @@ var AttachmentRegistry = class {
2355
2327
  }
2356
2328
  getContainers(name) {
2357
2329
  const map = this.containers.get(name);
2358
- return map ? Array.from(map.values()) : [];
2330
+ if (!map) return [];
2331
+ return Array.from(map, ([instanceId, container]) => ({
2332
+ instanceId,
2333
+ container
2334
+ }));
2359
2335
  }
2360
2336
  onContainersChange(name, cb) {
2361
2337
  const current = this.getContainers(name);
@@ -2383,7 +2359,7 @@ var AttachmentRegistry = class {
2383
2359
  var AttachmentContext = createContext8(null);
2384
2360
 
2385
2361
  // src/reality/hooks/useEntityTransform.tsx
2386
- import { useEffect as useEffect16, useRef as useRef6 } from "react";
2362
+ import { useEffect as useEffect16, useRef as useRef7 } from "react";
2387
2363
 
2388
2364
  // src/reality/utils/ResourceRegistry.ts
2389
2365
  var ResourceRegistry = class {
@@ -2428,6 +2404,20 @@ function shallowEqualRotation(a, b) {
2428
2404
  if (!a || !b) return false;
2429
2405
  return a.x === b.x && a.y === b.y && a.z === b.z && ("w" in a ? a.w === b.w : true);
2430
2406
  }
2407
+ function shallowEqualObject(a, b) {
2408
+ if (a === b) return true;
2409
+ if (!a || !b) return false;
2410
+ const keysA = Object.keys(a);
2411
+ const keysB = Object.keys(b);
2412
+ if (keysA.length !== keysB.length) return false;
2413
+ return keysA.every((key) => a[key] === b[key]);
2414
+ }
2415
+ function shallowEqualArray(a, b) {
2416
+ if (a === b) return true;
2417
+ if (!a || !b) return false;
2418
+ if (a.length !== b.length) return false;
2419
+ return a.every((val, i) => val === b[i]);
2420
+ }
2431
2421
 
2432
2422
  // src/reality/utils/AbortResourceManager.ts
2433
2423
  var AbortResourceManager = class {
@@ -2464,7 +2454,7 @@ var AbortResourceManager = class {
2464
2454
 
2465
2455
  // src/reality/hooks/useEntityTransform.tsx
2466
2456
  function useEntityTransform(entity, { position, rotation, scale }) {
2467
- const last = useRef6({});
2457
+ const last = useRef7({});
2468
2458
  useEffect16(() => {
2469
2459
  if (!entity) return;
2470
2460
  const shouldUpdate = !shallowEqualVec3(last.current.position, position) || !shallowEqualRotation(last.current.rotation, rotation) || !shallowEqualVec3(last.current.scale, scale);
@@ -2484,7 +2474,7 @@ function useEntityTransform(entity, { position, rotation, scale }) {
2484
2474
  }
2485
2475
 
2486
2476
  // src/reality/hooks/useEntityEvent.tsx
2487
- import { useEffect as useEffect18, useRef as useRef8 } from "react";
2477
+ import { useEffect as useEffect18, useRef as useRef9 } from "react";
2488
2478
 
2489
2479
  // src/reality/type.ts
2490
2480
  var eventMap = {
@@ -2495,11 +2485,9 @@ var eventMap = {
2495
2485
  onSpatialDrag: "spatialdrag",
2496
2486
  onSpatialDragEnd: "spatialdragend",
2497
2487
  // rotate
2498
- onSpatialRotateStart: "spatialrotatestart",
2499
2488
  onSpatialRotate: "spatialrotate",
2500
2489
  onSpatialRotateEnd: "spatialrotateend",
2501
2490
  // magnify
2502
- onSpatialMagnifyStart: "spatialmagnifystart",
2503
2491
  onSpatialMagnify: "spatialmagnify",
2504
2492
  onSpatialMagnifyEnd: "spatialmagnifyend"
2505
2493
  };
@@ -2688,7 +2676,7 @@ function createEventProxy2(ev, instance) {
2688
2676
  });
2689
2677
  }
2690
2678
  var useEntityEvent = ({ instance, ...handlers }) => {
2691
- const eventsSetRef = useRef8(/* @__PURE__ */ new Set());
2679
+ const eventsSetRef = useRef9(/* @__PURE__ */ new Set());
2692
2680
  useEffect18(() => {
2693
2681
  const entity = instance.entity;
2694
2682
  if (!entity) return;
@@ -2715,11 +2703,147 @@ var useEntityEvent = ({ instance, ...handlers }) => {
2715
2703
  return null;
2716
2704
  };
2717
2705
 
2706
+ // src/reality/hooks/useRealityEvents.tsx
2707
+ import { useEffect as useEffect19, useRef as useRef10 } from "react";
2708
+ function createEventProxy3(ev, instance) {
2709
+ return new Proxy(ev, {
2710
+ get(target, prop) {
2711
+ if (prop === "currentTarget") {
2712
+ return instance;
2713
+ }
2714
+ if (prop === "target") {
2715
+ const origin = target.__origin;
2716
+ if (origin) {
2717
+ return new EntityRef(origin, null);
2718
+ }
2719
+ return instance;
2720
+ }
2721
+ if (prop === "bubbles") {
2722
+ return true;
2723
+ }
2724
+ if (prop === "offsetX") {
2725
+ const type = target.type;
2726
+ if (type === "spatialtap") {
2727
+ return target.detail?.location3D?.x ?? 0;
2728
+ }
2729
+ if (type === "spatialdragstart") {
2730
+ return target.detail?.startLocation3D?.x ?? 0;
2731
+ }
2732
+ return void 0;
2733
+ }
2734
+ if (prop === "offsetY") {
2735
+ const type = target.type;
2736
+ if (type === "spatialtap") {
2737
+ return target.detail?.location3D?.y ?? 0;
2738
+ }
2739
+ if (type === "spatialdragstart") {
2740
+ return target.detail?.startLocation3D?.y ?? 0;
2741
+ }
2742
+ return void 0;
2743
+ }
2744
+ if (prop === "offsetZ") {
2745
+ const type = target.type;
2746
+ if (type === "spatialtap") {
2747
+ return target.detail?.location3D?.z ?? 0;
2748
+ }
2749
+ if (type === "spatialdragstart") {
2750
+ return target.detail?.startLocation3D?.z ?? 0;
2751
+ }
2752
+ return void 0;
2753
+ }
2754
+ if (prop === "translationX") {
2755
+ const type = target.type;
2756
+ if (type === "spatialdrag") {
2757
+ return target.detail?.translation3D?.x ?? 0;
2758
+ }
2759
+ return void 0;
2760
+ }
2761
+ if (prop === "translationY") {
2762
+ const type = target.type;
2763
+ if (type === "spatialdrag") {
2764
+ return target.detail?.translation3D?.y ?? 0;
2765
+ }
2766
+ return void 0;
2767
+ }
2768
+ if (prop === "translationZ") {
2769
+ const type = target.type;
2770
+ if (type === "spatialdrag") {
2771
+ return target.detail?.translation3D?.z ?? 0;
2772
+ }
2773
+ return void 0;
2774
+ }
2775
+ if (prop === "quaternion") {
2776
+ const type = target.type;
2777
+ if (type === "spatialrotate") {
2778
+ return target.detail?.quaternion ?? {
2779
+ x: 0,
2780
+ y: 0,
2781
+ z: 0,
2782
+ w: 1
2783
+ };
2784
+ }
2785
+ return void 0;
2786
+ }
2787
+ if (prop === "magnification") {
2788
+ const type = target.type;
2789
+ if (type === "spatialmagnify") {
2790
+ return target.detail?.magnification ?? 1;
2791
+ }
2792
+ return void 0;
2793
+ }
2794
+ if (prop === "clientX") {
2795
+ const type = target.type;
2796
+ if (type === "spatialtap" || type === "spatialdragstart") {
2797
+ return target.detail?.globalLocation3D?.x ?? 0;
2798
+ }
2799
+ return void 0;
2800
+ }
2801
+ if (prop === "clientY") {
2802
+ const type = target.type;
2803
+ if (type === "spatialtap" || type === "spatialdragstart") {
2804
+ return target.detail?.globalLocation3D?.y ?? 0;
2805
+ }
2806
+ return void 0;
2807
+ }
2808
+ if (prop === "clientZ") {
2809
+ const type = target.type;
2810
+ if (type === "spatialtap" || type === "spatialdragstart") {
2811
+ return target.detail?.globalLocation3D?.z ?? 0;
2812
+ }
2813
+ return void 0;
2814
+ }
2815
+ const val = target[prop];
2816
+ return typeof val === "function" ? val.bind(target) : val;
2817
+ }
2818
+ });
2819
+ }
2820
+ var useRealityEvents = ({ instance, ...handlers }) => {
2821
+ const eventsSetRef = useRef10(/* @__PURE__ */ new Set());
2822
+ useEffect19(() => {
2823
+ if (!instance) return;
2824
+ Object.entries(eventMap).forEach(([reactKey, spatialEvent]) => {
2825
+ const handlerFn = handlers[reactKey];
2826
+ if (!handlerFn) return;
2827
+ const wrapped = (ev) => handlerFn(createEventProxy3(ev, instance));
2828
+ instance.addEvent(spatialEvent, wrapped);
2829
+ eventsSetRef.current.add(spatialEvent);
2830
+ });
2831
+ return () => {
2832
+ if (instance) {
2833
+ for (let x of eventsSetRef.current) {
2834
+ instance.removeEvent(x);
2835
+ }
2836
+ eventsSetRef.current.clear();
2837
+ }
2838
+ };
2839
+ }, [instance, ...Object.values(handlers)]);
2840
+ };
2841
+
2718
2842
  // src/reality/hooks/useEntityId.tsx
2719
- import { useEffect as useEffect19 } from "react";
2843
+ import { useEffect as useEffect20 } from "react";
2720
2844
  var useEntityId = ({ id, entity }) => {
2721
2845
  const ctx = useRealityContext();
2722
- useEffect19(() => {
2846
+ useEffect20(() => {
2723
2847
  if (!id || !entity || !ctx) return;
2724
2848
  ctx.resourceRegistry.add(id, Promise.resolve(entity));
2725
2849
  return () => {
@@ -2730,31 +2854,30 @@ var useEntityId = ({ id, entity }) => {
2730
2854
  };
2731
2855
 
2732
2856
  // src/reality/hooks/useEntity.tsx
2733
- import { useEffect as useEffect20, useRef as useRef9 } from "react";
2857
+ import { useEffect as useEffect21, useRef as useRef11 } from "react";
2734
2858
  var useEntity = ({
2735
2859
  ref,
2736
2860
  id,
2737
2861
  position,
2738
2862
  rotation,
2739
2863
  scale,
2864
+ enableInput,
2740
2865
  onSpatialTap,
2741
2866
  onSpatialDragStart,
2742
2867
  onSpatialDrag,
2743
2868
  onSpatialDragEnd,
2744
- // onSpatialRotateStart,
2745
2869
  onSpatialRotate,
2746
2870
  onSpatialRotateEnd,
2747
- // onSpatialMagnifyStart,
2748
2871
  onSpatialMagnify,
2749
2872
  onSpatialMagnifyEnd,
2750
- // TODO: add other event handlers
2751
- createEntity
2873
+ createEntity,
2874
+ recreateKey
2752
2875
  }) => {
2753
2876
  const ctx = useRealityContext();
2754
2877
  const parent = useParentContext();
2755
- const instanceRef = useRef9(new EntityRef(null, ctx));
2878
+ const instanceRef = useRef11(new EntityRef(null, ctx));
2756
2879
  const forceUpdate = useForceUpdate2();
2757
- useEffect20(() => {
2880
+ useEffect21(() => {
2758
2881
  if (!ctx) return;
2759
2882
  const controller = new AbortController();
2760
2883
  const init = async () => {
@@ -2765,6 +2888,11 @@ var useEntity = ({
2765
2888
  ent.destroy();
2766
2889
  return;
2767
2890
  }
2891
+ await ent.updateTransform({ position, rotation, scale });
2892
+ if (controller.signal.aborted) {
2893
+ ent.destroy();
2894
+ return;
2895
+ }
2768
2896
  if (parent) {
2769
2897
  const result = await parent.addEntity(ent);
2770
2898
  if (!result.success) throw new Error("parent.addEntity failed");
@@ -2783,7 +2911,7 @@ var useEntity = ({
2783
2911
  controller.abort();
2784
2912
  instanceRef.current?.destroy();
2785
2913
  };
2786
- }, [ctx, parent]);
2914
+ }, [ctx, parent, recreateKey]);
2787
2915
  useEntityId({ id, entity: instanceRef.current.entity });
2788
2916
  useEntityTransform(instanceRef.current.entity, { position, rotation, scale });
2789
2917
  useEntityRef(ref, instanceRef.current);
@@ -2793,31 +2921,37 @@ var useEntity = ({
2793
2921
  onSpatialDragStart,
2794
2922
  onSpatialDrag,
2795
2923
  onSpatialDragEnd,
2796
- // onSpatialRotateStart,
2797
2924
  onSpatialRotate,
2798
2925
  onSpatialRotateEnd,
2799
- // onSpatialMagnifyStart,
2800
2926
  onSpatialMagnify,
2801
2927
  onSpatialMagnifyEnd
2802
2928
  });
2929
+ useEffect21(() => {
2930
+ const ent = instanceRef.current.entity;
2931
+ if (!ent) return;
2932
+ if (enableInput !== void 0) {
2933
+ ent.enableInput = !!enableInput;
2934
+ }
2935
+ }, [instanceRef.current.entity, enableInput]);
2803
2936
  return instanceRef.current.entity;
2804
2937
  };
2805
2938
 
2806
2939
  // src/reality/hooks/useForceUpdate.tsx
2807
- import { useCallback as useCallback7, useState as useState7 } from "react";
2940
+ import { useCallback as useCallback7, useState as useState6 } from "react";
2808
2941
  var useForceUpdate2 = () => {
2809
- const [, setTick] = useState7(0);
2942
+ const [, setTick] = useState6(0);
2810
2943
  return useCallback7(() => setTick((tick) => tick + 1), []);
2811
2944
  };
2812
2945
 
2813
2946
  // src/reality/components/BaseEntity.tsx
2814
2947
  import { jsx as jsx12 } from "react/jsx-runtime";
2815
2948
  var BaseEntity = forwardRef10(
2816
- ({ children, createEntity, ...rest }, ref) => {
2949
+ ({ children, createEntity, recreateKey, ...rest }, ref) => {
2817
2950
  const ctx = useRealityContext();
2818
2951
  const entity = useEntity({
2819
2952
  ...rest,
2820
2953
  ref,
2954
+ recreateKey,
2821
2955
  createEntity: (signal) => createEntity(ctx, signal)
2822
2956
  });
2823
2957
  if (!entity) return null;
@@ -2845,35 +2979,102 @@ var Entity = forwardRef11((props, ref) => {
2845
2979
  import { forwardRef as forwardRef13 } from "react";
2846
2980
 
2847
2981
  // src/reality/components/GeometryEntity.tsx
2848
- import { forwardRef as forwardRef12 } from "react";
2982
+ import { forwardRef as forwardRef12, useEffect as useEffect22, useRef as useRef12 } from "react";
2849
2983
  import { jsx as jsx14 } from "react/jsx-runtime";
2850
2984
  var GeometryEntity = forwardRef12(
2851
2985
  ({ id, children, name, materials, geometryOptions, createGeometry, ...rest }, ref) => {
2986
+ const ctx = useRealityContext();
2987
+ const entityRef = useRef12(null);
2988
+ const componentRef = useRef12(null);
2989
+ const mutableRef = useRef12({
2990
+ lastSnapshot: null,
2991
+ rebuildGen: 0
2992
+ });
2993
+ useEffect22(() => {
2994
+ const { lastSnapshot } = mutableRef.current;
2995
+ if (!ctx || !entityRef.current || lastSnapshot === null) return;
2996
+ const geometryChanged = !shallowEqualObject(
2997
+ lastSnapshot.geometryOptions,
2998
+ geometryOptions
2999
+ );
3000
+ const materialsChanged = !shallowEqualArray(
3001
+ lastSnapshot.materials,
3002
+ materials
3003
+ );
3004
+ if (!geometryChanged && !materialsChanged) return;
3005
+ mutableRef.current.lastSnapshot = { geometryOptions, materials };
3006
+ mutableRef.current.rebuildGen += 1;
3007
+ const gen = mutableRef.current.rebuildGen;
3008
+ const rebuild = async () => {
3009
+ const entity = entityRef.current;
3010
+ if (!entity) return;
3011
+ try {
3012
+ const oldComponent = componentRef.current;
3013
+ if (oldComponent) {
3014
+ await entity.removeComponent(oldComponent);
3015
+ await oldComponent.destroy();
3016
+ componentRef.current = null;
3017
+ if (gen !== mutableRef.current.rebuildGen) return;
3018
+ }
3019
+ const geometry = await createGeometry(geometryOptions);
3020
+ if (gen !== mutableRef.current.rebuildGen) {
3021
+ await geometry.destroy();
3022
+ return;
3023
+ }
3024
+ const materialList = await Promise.all(
3025
+ materials?.map((mid) => ctx.resourceRegistry.get(mid)).filter(Boolean) ?? []
3026
+ );
3027
+ if (gen !== mutableRef.current.rebuildGen) {
3028
+ await geometry.destroy();
3029
+ return;
3030
+ }
3031
+ const modelComponent = await ctx.session.createModelComponent({
3032
+ mesh: geometry,
3033
+ materials: materialList
3034
+ });
3035
+ if (gen !== mutableRef.current.rebuildGen) {
3036
+ await modelComponent.destroy();
3037
+ await geometry.destroy();
3038
+ return;
3039
+ }
3040
+ await entity.addComponent(modelComponent);
3041
+ componentRef.current = modelComponent;
3042
+ } catch (error) {
3043
+ if (gen === mutableRef.current.rebuildGen) {
3044
+ console.error("GeometryEntity: rebuild failed", error);
3045
+ }
3046
+ }
3047
+ };
3048
+ rebuild();
3049
+ }, [ctx, geometryOptions, materials, createGeometry]);
2852
3050
  return /* @__PURE__ */ jsx14(
2853
3051
  BaseEntity,
2854
3052
  {
2855
3053
  ...rest,
2856
3054
  id,
2857
3055
  ref,
2858
- createEntity: async (ctx, signal) => {
3056
+ createEntity: async (ctx2, signal) => {
2859
3057
  const manager = new AbortResourceManager(signal);
2860
3058
  try {
2861
3059
  const ent = await manager.addResource(
2862
- () => ctx.session.createEntity({ id, name })
3060
+ () => ctx2.session.createEntity({ id, name })
2863
3061
  );
2864
3062
  const geometry = await manager.addResource(
2865
3063
  () => createGeometry(geometryOptions)
2866
3064
  );
2867
3065
  const materialList = await Promise.all(
2868
- materials?.map((id2) => ctx.resourceRegistry.get(id2)).filter(Boolean) ?? []
3066
+ materials?.map((id2) => ctx2.resourceRegistry.get(id2)).filter(Boolean) ?? []
2869
3067
  );
2870
3068
  const modelComponent = await manager.addResource(
2871
- () => ctx.session.createModelComponent({
3069
+ () => ctx2.session.createModelComponent({
2872
3070
  mesh: geometry,
2873
3071
  materials: materialList
2874
3072
  })
2875
3073
  );
2876
3074
  await ent.addComponent(modelComponent);
3075
+ entityRef.current = ent;
3076
+ componentRef.current = modelComponent;
3077
+ mutableRef.current.lastSnapshot = { geometryOptions, materials };
2877
3078
  return ent;
2878
3079
  } catch (error) {
2879
3080
  await manager.dispose();
@@ -2911,11 +3112,15 @@ var BoxEntity = forwardRef13(
2911
3112
  );
2912
3113
 
2913
3114
  // src/reality/components/UnlitMaterial.tsx
2914
- import { useEffect as useEffect21, useRef as useRef10 } from "react";
2915
- var UnlitMaterial = ({ children, ...options }) => {
3115
+ import { useEffect as useEffect23, useRef as useRef13 } from "react";
3116
+ var UnlitMaterial = ({
3117
+ children,
3118
+ ...options
3119
+ }) => {
2916
3120
  const ctx = useRealityContext();
2917
- const materialRef = useRef10();
2918
- useEffect21(() => {
3121
+ const materialRef = useRef13();
3122
+ const isInitializedRef = useRef13(false);
3123
+ useEffect23(() => {
2919
3124
  if (!ctx) return;
2920
3125
  const { session, reality, resourceRegistry } = ctx;
2921
3126
  const init = async () => {
@@ -2924,6 +3129,7 @@ var UnlitMaterial = ({ children, ...options }) => {
2924
3129
  try {
2925
3130
  const mat = await materialPromise;
2926
3131
  materialRef.current = mat;
3132
+ isInitializedRef.current = true;
2927
3133
  } catch (error) {
2928
3134
  console.error(" ~ UnlitMaterial ~ error:", error);
2929
3135
  }
@@ -2931,8 +3137,21 @@ var UnlitMaterial = ({ children, ...options }) => {
2931
3137
  init();
2932
3138
  return () => {
2933
3139
  resourceRegistry.removeAndDestroy(options.id);
3140
+ materialRef.current = void 0;
3141
+ isInitializedRef.current = false;
2934
3142
  };
2935
3143
  }, [ctx]);
3144
+ useEffect23(() => {
3145
+ if (!isInitializedRef.current || !materialRef.current) return;
3146
+ const updates = {};
3147
+ if (options.color !== void 0) updates.color = options.color;
3148
+ if (options.transparent !== void 0)
3149
+ updates.transparent = options.transparent;
3150
+ if (options.opacity !== void 0) updates.opacity = options.opacity;
3151
+ if (Object.keys(updates).length > 0) {
3152
+ materialRef.current.updateProperties(updates);
3153
+ }
3154
+ }, [options.color, options.transparent, options.opacity]);
2936
3155
  return null;
2937
3156
  };
2938
3157
 
@@ -3031,7 +3250,7 @@ var SceneGraph = ({ children }) => {
3031
3250
  };
3032
3251
 
3033
3252
  // src/reality/components/ModelAsset.tsx
3034
- import { useEffect as useEffect22, useRef as useRef11 } from "react";
3253
+ import { useEffect as useEffect24, useRef as useRef14 } from "react";
3035
3254
  var resolveAssetUrl = (url) => {
3036
3255
  if (url.startsWith("http://") || url.startsWith("https://")) {
3037
3256
  return url;
@@ -3040,8 +3259,8 @@ var resolveAssetUrl = (url) => {
3040
3259
  };
3041
3260
  var ModelAsset = ({ children, ...options }) => {
3042
3261
  const ctx = useRealityContext();
3043
- const materialRef = useRef11();
3044
- useEffect22(() => {
3262
+ const materialRef = useRef14();
3263
+ useEffect24(() => {
3045
3264
  const controller = new AbortController();
3046
3265
  if (!ctx) return;
3047
3266
  const { session, reality, resourceRegistry } = ctx;
@@ -3071,29 +3290,66 @@ var ModelAsset = ({ children, ...options }) => {
3071
3290
  };
3072
3291
 
3073
3292
  // src/reality/components/ModelEntity.tsx
3074
- import { forwardRef as forwardRef18 } from "react";
3293
+ import { forwardRef as forwardRef18, useEffect as useEffect25, useRef as useRef15 } from "react";
3075
3294
  import { jsx as jsx21 } from "react/jsx-runtime";
3076
3295
  var ModelEntity = forwardRef18(
3077
- ({ id, model, children, name, ...rest }, ref) => {
3296
+ ({ id, model, children, name, materials, ...rest }, ref) => {
3297
+ const ctx = useRealityContext();
3298
+ const entityRef = useRef15(null);
3299
+ const lastMaterialsRef = useRef15(void 0);
3300
+ useEffect25(() => {
3301
+ if (!ctx || !entityRef.current) return;
3302
+ const next = materials ?? [];
3303
+ const prev = lastMaterialsRef.current ?? [];
3304
+ if (shallowEqualArray(prev, next)) return;
3305
+ lastMaterialsRef.current = next;
3306
+ const apply = async () => {
3307
+ try {
3308
+ const materialList = (await Promise.all(
3309
+ next.map((mid) => ctx.resourceRegistry.get(mid))
3310
+ )).filter(Boolean);
3311
+ if (entityRef.current) {
3312
+ await entityRef.current.setMaterials(materialList);
3313
+ }
3314
+ } catch (error) {
3315
+ console.error("ModelEntity: failed to set materials", error);
3316
+ }
3317
+ };
3318
+ apply();
3319
+ }, [ctx, materials]);
3078
3320
  return /* @__PURE__ */ jsx21(
3079
3321
  BaseEntity,
3080
3322
  {
3081
3323
  ...rest,
3082
3324
  id,
3083
3325
  ref,
3084
- createEntity: async (ctx, signal) => {
3326
+ recreateKey: model,
3327
+ createEntity: async (ctx2, signal) => {
3085
3328
  try {
3086
- const modelAsset = await ctx.resourceRegistry.get(model);
3329
+ const modelAsset = await ctx2.resourceRegistry.get(model);
3087
3330
  if (!modelAsset)
3088
3331
  throw new Error(`ModelEntity: model not found ${model}`);
3089
3332
  if (signal.aborted) return null;
3090
- return ctx.session.createSpatialModelEntity(
3333
+ const ent = await ctx2.session.createSpatialModelEntity(
3091
3334
  {
3092
3335
  modelAssetId: modelAsset.id,
3093
3336
  name
3094
3337
  },
3095
3338
  { id, name }
3096
3339
  );
3340
+ entityRef.current = ent;
3341
+ if (materials && materials.length > 0) {
3342
+ const materialList = (await Promise.all(
3343
+ materials.map(
3344
+ (mid) => ctx2.resourceRegistry.get(mid)
3345
+ )
3346
+ )).filter(Boolean);
3347
+ if (materialList.length > 0 && !signal.aborted) {
3348
+ await ent.setMaterials(materialList);
3349
+ }
3350
+ }
3351
+ lastMaterialsRef.current = materials ?? [];
3352
+ return ent;
3097
3353
  } catch (error) {
3098
3354
  return null;
3099
3355
  }
@@ -3108,9 +3364,9 @@ var ModelEntity = forwardRef18(
3108
3364
  import {
3109
3365
  forwardRef as forwardRef19,
3110
3366
  useCallback as useCallback8,
3111
- useEffect as useEffect23,
3112
- useRef as useRef12,
3113
- useState as useState8
3367
+ useEffect as useEffect26,
3368
+ useRef as useRef16,
3369
+ useState as useState7
3114
3370
  } from "react";
3115
3371
  import { Fragment as Fragment3, jsx as jsx22, jsxs as jsxs3 } from "react/jsx-runtime";
3116
3372
  var Reality = forwardRef19(
@@ -3133,9 +3389,9 @@ var Reality = forwardRef19(
3133
3389
  onSpatialMagnifyEnd,
3134
3390
  ...props
3135
3391
  } = inProps;
3136
- const ctxRef = useRef12(null);
3137
- const creationId = useRef12(0);
3138
- const [isReady, setIsReady] = useState8(false);
3392
+ const ctxRef = useRef16(null);
3393
+ const creationId = useRef16(0);
3394
+ const [isReady, setIsReady] = useState7(false);
3139
3395
  const cleanupReality = useCallback8(() => {
3140
3396
  ctxRef.current?.attachmentRegistry.destroy();
3141
3397
  ctxRef.current?.resourceRegistry.destroy();
@@ -3143,7 +3399,7 @@ var Reality = forwardRef19(
3143
3399
  ctxRef.current = null;
3144
3400
  setIsReady(false);
3145
3401
  }, []);
3146
- useEffect23(() => {
3402
+ useEffect26(() => {
3147
3403
  return () => {
3148
3404
  creationId.current++;
3149
3405
  cleanupReality();
@@ -3193,6 +3449,17 @@ var Reality = forwardRef19(
3193
3449
  }
3194
3450
  }, [cleanupReality]);
3195
3451
  const content = useCallback8(() => /* @__PURE__ */ jsx22(Fragment3, {}), []);
3452
+ useRealityEvents({
3453
+ instance: ctxRef.current?.reality ?? null,
3454
+ onSpatialTap,
3455
+ onSpatialDragStart,
3456
+ onSpatialDrag,
3457
+ onSpatialDragEnd,
3458
+ onSpatialRotate,
3459
+ onSpatialRotateEnd,
3460
+ onSpatialMagnify,
3461
+ onSpatialMagnifyEnd
3462
+ });
3196
3463
  return /* @__PURE__ */ jsxs3(RealityContext.Provider, { value: ctxRef.current, children: [
3197
3464
  /* @__PURE__ */ jsx22(
3198
3465
  SpatializedContainer,
@@ -3210,7 +3477,7 @@ var Reality = forwardRef19(
3210
3477
  );
3211
3478
 
3212
3479
  // src/reality/components/AttachmentAsset.tsx
3213
- import { useEffect as useEffect24, useState as useState9 } from "react";
3480
+ import { useEffect as useEffect27, useState as useState8 } from "react";
3214
3481
  import { createPortal as createPortal3 } from "react-dom";
3215
3482
  import { jsx as jsx23 } from "react/jsx-runtime";
3216
3483
  var AttachmentAsset = ({
@@ -3218,17 +3485,19 @@ var AttachmentAsset = ({
3218
3485
  children
3219
3486
  }) => {
3220
3487
  const ctx = useRealityContext();
3221
- const [containers, setContainers] = useState9([]);
3222
- useEffect24(() => {
3488
+ const [containers, setContainers] = useState8([]);
3489
+ useEffect27(() => {
3223
3490
  if (!ctx) return;
3224
3491
  return ctx.attachmentRegistry.onContainersChange(name, setContainers);
3225
3492
  }, [ctx, name]);
3226
3493
  if (!containers.length) return null;
3227
- return /* @__PURE__ */ jsx23(InsideAttachmentContext.Provider, { value: true, children: containers.map((c, idx) => createPortal3(children, c, `${name}-${idx}`)) });
3494
+ return /* @__PURE__ */ jsx23(InsideAttachmentContext.Provider, { value: true, children: containers.map(
3495
+ ({ instanceId, container }) => createPortal3(children, container, instanceId)
3496
+ ) });
3228
3497
  };
3229
3498
 
3230
3499
  // src/reality/components/AttachmentEntity.tsx
3231
- import { useEffect as useEffect25, useRef as useRef13, useState as useState10 } from "react";
3500
+ import { useEffect as useEffect28, useRef as useRef17, useState as useState9 } from "react";
3232
3501
  var instanceCounter = 0;
3233
3502
  var AttachmentEntity = ({
3234
3503
  attachment: attachmentName,
@@ -3237,13 +3506,14 @@ var AttachmentEntity = ({
3237
3506
  }) => {
3238
3507
  const ctx = useRealityContext();
3239
3508
  const parent = useParentContext();
3240
- const attachmentRef = useRef13(null);
3241
- const parentIdRef = useRef13(null);
3242
- const instanceIdRef = useRef13(`att_${++instanceCounter}`);
3243
- const attachmentNameRef = useRef13(attachmentName);
3244
- const [childWindow, setChildWindow] = useState10(null);
3245
- useEffect25(() => {
3509
+ const attachmentRef = useRef17(null);
3510
+ const parentIdRef = useRef17(null);
3511
+ const instanceIdRef = useRef17(`att_${++instanceCounter}`);
3512
+ const attachmentNameRef = useRef17(attachmentName);
3513
+ const [childWindow, setChildWindow] = useState9(null);
3514
+ useEffect28(() => {
3246
3515
  if (!ctx || !parent) return;
3516
+ if (attachmentRef.current) return;
3247
3517
  const parentId = parent.id;
3248
3518
  parentIdRef.current = parentId;
3249
3519
  let cancelled = false;
@@ -3252,7 +3522,8 @@ var AttachmentEntity = ({
3252
3522
  const att = await ctx.session.createAttachmentEntity({
3253
3523
  parentEntityId: parentId,
3254
3524
  position: position ?? [0, 0, 0],
3255
- size
3525
+ size,
3526
+ ownerViewId: ctx.reality.id
3256
3527
  });
3257
3528
  if (cancelled) {
3258
3529
  att.destroy();
@@ -3264,7 +3535,6 @@ var AttachmentEntity = ({
3264
3535
  windowProxy.document.body.style.minWidth = "100%";
3265
3536
  windowProxy.document.body.style.maxWidth = "100%";
3266
3537
  windowProxy.document.body.style.minHeight = "100%";
3267
- await syncParentHeadToChild(windowProxy);
3268
3538
  const viewport = windowProxy.document.querySelector(
3269
3539
  'meta[name="viewport"]'
3270
3540
  );
@@ -3303,7 +3573,7 @@ var AttachmentEntity = ({
3303
3573
  }
3304
3574
  };
3305
3575
  }, [ctx, parent]);
3306
- useEffect25(() => {
3576
+ useEffect28(() => {
3307
3577
  if (!ctx) return;
3308
3578
  const att = attachmentRef.current;
3309
3579
  const prevName = attachmentNameRef.current;
@@ -3320,16 +3590,26 @@ var AttachmentEntity = ({
3320
3590
  }
3321
3591
  }, [ctx, attachmentName]);
3322
3592
  useSyncHeadStyles(childWindow, { subtree: false });
3323
- useEffect25(() => {
3593
+ useEffect28(() => {
3324
3594
  if (!attachmentRef.current) return;
3325
3595
  attachmentRef.current.update({ position, size });
3326
3596
  }, [position?.[0], position?.[1], position?.[2], size?.width, size?.height]);
3327
3597
  return null;
3328
3598
  };
3329
3599
 
3600
+ // src/reality/components/Material.tsx
3601
+ import { jsx as jsx24 } from "react/jsx-runtime";
3602
+ var Material = (props) => {
3603
+ if (props.type === "unlit") {
3604
+ const { type, ...rest } = props;
3605
+ return /* @__PURE__ */ jsx24(UnlitMaterial, { ...rest });
3606
+ }
3607
+ return null;
3608
+ };
3609
+
3330
3610
  // src/Model.tsx
3331
3611
  import { forwardRef as forwardRef20 } from "react";
3332
- import { jsx as jsx24 } from "react/jsx-runtime";
3612
+ import { jsx as jsx25 } from "react/jsx-runtime";
3333
3613
  var spatial2 = new Spatial();
3334
3614
  function ModelBase(props, ref) {
3335
3615
  const insideAttachment = useInsideAttachment();
@@ -3344,30 +3624,125 @@ function ModelBase(props, ref) {
3344
3624
  onSpatialRotateEnd,
3345
3625
  onSpatialMagnify,
3346
3626
  onSpatialMagnifyEnd,
3627
+ spatialEventOptions: _spatialEventOptions,
3347
3628
  ...modelProps
3348
3629
  } = restProps;
3349
- return /* @__PURE__ */ jsx24("model", { ref, ...modelProps });
3630
+ return /* @__PURE__ */ jsx25("model", { ref, ...modelProps });
3350
3631
  }
3351
- return /* @__PURE__ */ jsx24(SpatializedStatic3DElementContainer, { ref, ...restProps });
3632
+ return /* @__PURE__ */ jsx25(SpatializedStatic3DElementContainer, { ref, ...restProps });
3352
3633
  }
3353
3634
  var Model = withSSRSupported(forwardRef20(ModelBase));
3354
3635
  Model.displayName = "Model";
3355
3636
 
3637
+ // src/useMetrics.tsx
3638
+ import { useSyncExternalStore } from "react";
3639
+ function useMetrics() {
3640
+ useSyncExternalStore(PhysicalMetrics.subscribe, PhysicalMetrics.getValue);
3641
+ const { pointToPhysical, physicalToPoint } = PhysicalMetrics;
3642
+ return { pointToPhysical, physicalToPoint };
3643
+ }
3644
+
3645
+ // src/jsx/jsx-shared.ts
3646
+ import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
3647
+ import reactJSXRuntime from "react/jsx-runtime";
3648
+ import { createElement as reactCreateElement } from "react";
3649
+ var attributeFlag = "enable-xr";
3650
+ var styleFlag = "enableXr";
3651
+ var classFlag = "__enableXr__";
3652
+ var xrMonitorFlag = "enable-xr-monitor";
3653
+ function replaceToSpatialPrimitiveType(type, props) {
3654
+ if (type === Model) {
3655
+ return type;
3656
+ }
3657
+ const propsObject = props;
3658
+ if (attributeFlag in propsObject) {
3659
+ delete propsObject[attributeFlag];
3660
+ return withSpatialized2DElementContainer(type);
3661
+ }
3662
+ if (xrMonitorFlag in propsObject) {
3663
+ delete propsObject[xrMonitorFlag];
3664
+ return withSpatialMonitor(type);
3665
+ }
3666
+ if (propsObject && propsObject.style && styleFlag in propsObject.style) {
3667
+ delete propsObject.style[styleFlag];
3668
+ return withSpatialized2DElementContainer(type);
3669
+ }
3670
+ if (propsObject && typeof propsObject.className === "string") {
3671
+ const originalClassNames = propsObject.className.split(" ");
3672
+ const idx = originalClassNames.indexOf(classFlag);
3673
+ if (idx !== -1) {
3674
+ originalClassNames.splice(idx, 1);
3675
+ propsObject.className = originalClassNames.join(" ");
3676
+ return withSpatialized2DElementContainer(type);
3677
+ }
3678
+ }
3679
+ return type;
3680
+ }
3681
+ function createElement(...args) {
3682
+ const [type, props, ...rest] = args;
3683
+ const newType = replaceToSpatialPrimitiveType(type, props);
3684
+ return reactCreateElement(newType, props, ...rest);
3685
+ }
3686
+
3687
+ // src/utils/convertCoordinate.ts
3688
+ function resolveSpatialObjectId(target) {
3689
+ if (typeof window !== "undefined" && target === window) {
3690
+ const scene = getSession()?.getSpatialScene();
3691
+ return scene?.id ?? "";
3692
+ }
3693
+ const maybeEntity = target;
3694
+ if (maybeEntity && typeof maybeEntity === "object" && "entity" in maybeEntity) {
3695
+ return maybeEntity.entity?.id ?? null;
3696
+ }
3697
+ const dom = target?.__raw ?? target;
3698
+ if (dom && typeof dom === "object") {
3699
+ const spatializedElement = dom.__spatializedElement ?? dom.__innerSpatializedElement?.();
3700
+ if (spatializedElement && spatializedElement.id) {
3701
+ return spatializedElement.id;
3702
+ }
3703
+ }
3704
+ return null;
3705
+ }
3706
+ async function convertCoordinate(position, { from, to }) {
3707
+ try {
3708
+ const fromId = resolveSpatialObjectId(from);
3709
+ const toId = resolveSpatialObjectId(to);
3710
+ if (fromId === null || toId === null) {
3711
+ console.warn(
3712
+ "convertCoordinate error: from or to is not a valid coordinate convertible"
3713
+ );
3714
+ return position;
3715
+ }
3716
+ const spatialScene = getSession()?.getSpatialScene();
3717
+ if (!spatialScene) return position;
3718
+ const ret = await spatialScene.convertCoordinate(position, fromId, toId);
3719
+ return ret ?? position;
3720
+ } catch (error) {
3721
+ console.warn("convertCoordinate error:", error);
3722
+ return position;
3723
+ }
3724
+ }
3725
+
3356
3726
  // src/index.ts
3357
- var version = "1.3.0";
3727
+ var version = "1.5.0";
3358
3728
  if (typeof window !== "undefined") {
3359
3729
  initPolyfill();
3360
3730
  }
3361
3731
  export {
3362
3732
  AttachmentAsset,
3363
3733
  AttachmentEntity,
3734
+ BoxEntity as Box,
3364
3735
  BoxEntity,
3736
+ ConeEntity as Cone,
3365
3737
  ConeEntity,
3738
+ CylinderEntity as Cylinder,
3366
3739
  CylinderEntity,
3367
3740
  Entity,
3741
+ Material,
3368
3742
  Model,
3369
3743
  ModelAsset,
3370
3744
  ModelEntity,
3745
+ PlaneEntity as Plane,
3371
3746
  PlaneEntity,
3372
3747
  Reality,
3373
3748
  SSRProvider,
@@ -3376,14 +3751,17 @@ export {
3376
3751
  Spatialized2DElementContainer,
3377
3752
  SpatializedContainer,
3378
3753
  SpatializedStatic3DElementContainer,
3754
+ SphereEntity as Sphere,
3379
3755
  SphereEntity,
3380
3756
  UnlitMaterial,
3757
+ SceneGraph as World,
3758
+ convertCoordinate,
3759
+ createElement,
3381
3760
  enableDebugTool,
3382
3761
  eventMap,
3383
3762
  initPolyfill,
3384
3763
  initScene,
3385
- toLocalSpace,
3386
- toSceneSpatial,
3764
+ useMetrics,
3387
3765
  version,
3388
3766
  withSpatialMonitor,
3389
3767
  withSpatialized2DElementContainer