@webspatial/react-sdk 1.3.0 → 1.4.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.4.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 {
@@ -2423,7 +2385,7 @@ var AbortResourceManager = class {
2423
2385
 
2424
2386
  // src/reality/hooks/useEntityTransform.tsx
2425
2387
  function useEntityTransform(entity, { position, rotation, scale }) {
2426
- const last = useRef6({});
2388
+ const last = useRef7({});
2427
2389
  useEffect16(() => {
2428
2390
  if (!entity) return;
2429
2391
  const shouldUpdate = !shallowEqualVec3(last.current.position, position) || !shallowEqualRotation(last.current.rotation, rotation) || !shallowEqualVec3(last.current.scale, scale);
@@ -2443,7 +2405,7 @@ function useEntityTransform(entity, { position, rotation, scale }) {
2443
2405
  }
2444
2406
 
2445
2407
  // src/reality/hooks/useEntityEvent.tsx
2446
- import { useEffect as useEffect18, useRef as useRef8 } from "react";
2408
+ import { useEffect as useEffect18, useRef as useRef9 } from "react";
2447
2409
 
2448
2410
  // src/reality/type.ts
2449
2411
  var eventMap = {
@@ -2454,11 +2416,9 @@ var eventMap = {
2454
2416
  onSpatialDrag: "spatialdrag",
2455
2417
  onSpatialDragEnd: "spatialdragend",
2456
2418
  // rotate
2457
- onSpatialRotateStart: "spatialrotatestart",
2458
2419
  onSpatialRotate: "spatialrotate",
2459
2420
  onSpatialRotateEnd: "spatialrotateend",
2460
2421
  // magnify
2461
- onSpatialMagnifyStart: "spatialmagnifystart",
2462
2422
  onSpatialMagnify: "spatialmagnify",
2463
2423
  onSpatialMagnifyEnd: "spatialmagnifyend"
2464
2424
  };
@@ -2533,7 +2493,8 @@ var EntityRef = class {
2533
2493
  }
2534
2494
  };
2535
2495
 
2536
- // src/reality/hooks/useEntityEvent.tsx
2496
+ // src/reality/hooks/useRealityEvents.tsx
2497
+ import { useEffect as useEffect19, useRef as useRef10 } from "react";
2537
2498
  function createEventProxy2(ev, instance) {
2538
2499
  return new Proxy(ev, {
2539
2500
  get(target, prop) {
@@ -2646,39 +2607,33 @@ function createEventProxy2(ev, instance) {
2646
2607
  }
2647
2608
  });
2648
2609
  }
2649
- var useEntityEvent = ({ instance, ...handlers }) => {
2650
- const eventsSetRef = useRef8(/* @__PURE__ */ new Set());
2651
- useEffect18(() => {
2652
- const entity = instance.entity;
2653
- if (!entity) return;
2610
+ var useRealityEvents = ({ instance, ...handlers }) => {
2611
+ const eventsSetRef = useRef10(/* @__PURE__ */ new Set());
2612
+ useEffect19(() => {
2613
+ if (!instance) return;
2654
2614
  Object.entries(eventMap).forEach(([reactKey, spatialEvent]) => {
2655
2615
  const handlerFn = handlers[reactKey];
2656
2616
  if (!handlerFn) return;
2657
2617
  const wrapped = (ev) => handlerFn(createEventProxy2(ev, instance));
2658
- entity.addEvent(spatialEvent, wrapped);
2659
- eventsSetRef.current.add(reactKey);
2618
+ instance.addEvent(spatialEvent, wrapped);
2619
+ eventsSetRef.current.add(spatialEvent);
2660
2620
  });
2661
2621
  return () => {
2662
- };
2663
- }, [instance.entity, ...Object.values(handlers)]);
2664
- useEffect18(() => {
2665
- const entity = instance.entity;
2666
- if (!entity) return;
2667
- return () => {
2668
- for (let x of eventsSetRef.current) {
2669
- entity.removeEvent(x);
2622
+ if (instance) {
2623
+ for (let x of eventsSetRef.current) {
2624
+ instance.removeEvent(x);
2625
+ }
2626
+ eventsSetRef.current.clear();
2670
2627
  }
2671
- eventsSetRef.current.clear();
2672
2628
  };
2673
- }, [instance.entity]);
2674
- return null;
2629
+ }, [instance, ...Object.values(handlers)]);
2675
2630
  };
2676
2631
 
2677
2632
  // src/reality/hooks/useEntityId.tsx
2678
- import { useEffect as useEffect19 } from "react";
2633
+ import { useEffect as useEffect20 } from "react";
2679
2634
  var useEntityId = ({ id, entity }) => {
2680
2635
  const ctx = useRealityContext();
2681
- useEffect19(() => {
2636
+ useEffect20(() => {
2682
2637
  if (!id || !entity || !ctx) return;
2683
2638
  ctx.resourceRegistry.add(id, Promise.resolve(entity));
2684
2639
  return () => {
@@ -2689,31 +2644,21 @@ var useEntityId = ({ id, entity }) => {
2689
2644
  };
2690
2645
 
2691
2646
  // src/reality/hooks/useEntity.tsx
2692
- import { useEffect as useEffect20, useRef as useRef9 } from "react";
2647
+ import { useEffect as useEffect21, useRef as useRef11 } from "react";
2693
2648
  var useEntity = ({
2694
2649
  ref,
2695
2650
  id,
2696
2651
  position,
2697
2652
  rotation,
2698
2653
  scale,
2699
- onSpatialTap,
2700
- onSpatialDragStart,
2701
- onSpatialDrag,
2702
- onSpatialDragEnd,
2703
- // onSpatialRotateStart,
2704
- onSpatialRotate,
2705
- onSpatialRotateEnd,
2706
- // onSpatialMagnifyStart,
2707
- onSpatialMagnify,
2708
- onSpatialMagnifyEnd,
2709
- // TODO: add other event handlers
2654
+ enableInput,
2710
2655
  createEntity
2711
2656
  }) => {
2712
2657
  const ctx = useRealityContext();
2713
2658
  const parent = useParentContext();
2714
- const instanceRef = useRef9(new EntityRef(null, ctx));
2659
+ const instanceRef = useRef11(new EntityRef(null, ctx));
2715
2660
  const forceUpdate = useForceUpdate2();
2716
- useEffect20(() => {
2661
+ useEffect21(() => {
2717
2662
  if (!ctx) return;
2718
2663
  const controller = new AbortController();
2719
2664
  const init = async () => {
@@ -2746,19 +2691,13 @@ var useEntity = ({
2746
2691
  useEntityId({ id, entity: instanceRef.current.entity });
2747
2692
  useEntityTransform(instanceRef.current.entity, { position, rotation, scale });
2748
2693
  useEntityRef(ref, instanceRef.current);
2749
- useEntityEvent({
2750
- instance: instanceRef.current,
2751
- onSpatialTap,
2752
- onSpatialDragStart,
2753
- onSpatialDrag,
2754
- onSpatialDragEnd,
2755
- // onSpatialRotateStart,
2756
- onSpatialRotate,
2757
- onSpatialRotateEnd,
2758
- // onSpatialMagnifyStart,
2759
- onSpatialMagnify,
2760
- onSpatialMagnifyEnd
2761
- });
2694
+ useEffect21(() => {
2695
+ const ent = instanceRef.current.entity;
2696
+ if (!ent) return;
2697
+ if (enableInput !== void 0) {
2698
+ ent.enableInput = !!enableInput;
2699
+ }
2700
+ }, [instanceRef.current.entity, enableInput]);
2762
2701
  return instanceRef.current.entity;
2763
2702
  };
2764
2703
 
@@ -2870,11 +2809,14 @@ var BoxEntity = forwardRef13(
2870
2809
  );
2871
2810
 
2872
2811
  // src/reality/components/UnlitMaterial.tsx
2873
- import { useEffect as useEffect21, useRef as useRef10 } from "react";
2874
- var UnlitMaterial = ({ children, ...options }) => {
2812
+ import { useEffect as useEffect22, useRef as useRef12 } from "react";
2813
+ var UnlitMaterial = ({
2814
+ children,
2815
+ ...options
2816
+ }) => {
2875
2817
  const ctx = useRealityContext();
2876
- const materialRef = useRef10();
2877
- useEffect21(() => {
2818
+ const materialRef = useRef12();
2819
+ useEffect22(() => {
2878
2820
  if (!ctx) return;
2879
2821
  const { session, reality, resourceRegistry } = ctx;
2880
2822
  const init = async () => {
@@ -2990,7 +2932,7 @@ var SceneGraph = ({ children }) => {
2990
2932
  };
2991
2933
 
2992
2934
  // src/reality/components/ModelAsset.tsx
2993
- import { useEffect as useEffect22, useRef as useRef11 } from "react";
2935
+ import { useEffect as useEffect23, useRef as useRef13 } from "react";
2994
2936
  var resolveAssetUrl = (url) => {
2995
2937
  if (url.startsWith("http://") || url.startsWith("https://")) {
2996
2938
  return url;
@@ -2999,8 +2941,8 @@ var resolveAssetUrl = (url) => {
2999
2941
  };
3000
2942
  var ModelAsset = ({ children, ...options }) => {
3001
2943
  const ctx = useRealityContext();
3002
- const materialRef = useRef11();
3003
- useEffect22(() => {
2944
+ const materialRef = useRef13();
2945
+ useEffect23(() => {
3004
2946
  const controller = new AbortController();
3005
2947
  if (!ctx) return;
3006
2948
  const { session, reality, resourceRegistry } = ctx;
@@ -3067,8 +3009,8 @@ var ModelEntity = forwardRef18(
3067
3009
  import {
3068
3010
  forwardRef as forwardRef19,
3069
3011
  useCallback as useCallback8,
3070
- useEffect as useEffect23,
3071
- useRef as useRef12,
3012
+ useEffect as useEffect24,
3013
+ useRef as useRef14,
3072
3014
  useState as useState8
3073
3015
  } from "react";
3074
3016
  import { Fragment as Fragment3, jsx as jsx22, jsxs as jsxs3 } from "react/jsx-runtime";
@@ -3092,8 +3034,8 @@ var Reality = forwardRef19(
3092
3034
  onSpatialMagnifyEnd,
3093
3035
  ...props
3094
3036
  } = inProps;
3095
- const ctxRef = useRef12(null);
3096
- const creationId = useRef12(0);
3037
+ const ctxRef = useRef14(null);
3038
+ const creationId = useRef14(0);
3097
3039
  const [isReady, setIsReady] = useState8(false);
3098
3040
  const cleanupReality = useCallback8(() => {
3099
3041
  ctxRef.current?.attachmentRegistry.destroy();
@@ -3102,7 +3044,7 @@ var Reality = forwardRef19(
3102
3044
  ctxRef.current = null;
3103
3045
  setIsReady(false);
3104
3046
  }, []);
3105
- useEffect23(() => {
3047
+ useEffect24(() => {
3106
3048
  return () => {
3107
3049
  creationId.current++;
3108
3050
  cleanupReality();
@@ -3152,6 +3094,17 @@ var Reality = forwardRef19(
3152
3094
  }
3153
3095
  }, [cleanupReality]);
3154
3096
  const content = useCallback8(() => /* @__PURE__ */ jsx22(Fragment3, {}), []);
3097
+ useRealityEvents({
3098
+ instance: ctxRef.current?.reality ?? null,
3099
+ onSpatialTap,
3100
+ onSpatialDragStart,
3101
+ onSpatialDrag,
3102
+ onSpatialDragEnd,
3103
+ onSpatialRotate,
3104
+ onSpatialRotateEnd,
3105
+ onSpatialMagnify,
3106
+ onSpatialMagnifyEnd
3107
+ });
3155
3108
  return /* @__PURE__ */ jsxs3(RealityContext.Provider, { value: ctxRef.current, children: [
3156
3109
  /* @__PURE__ */ jsx22(
3157
3110
  SpatializedContainer,
@@ -3169,7 +3122,7 @@ var Reality = forwardRef19(
3169
3122
  );
3170
3123
 
3171
3124
  // src/reality/components/AttachmentAsset.tsx
3172
- import { useEffect as useEffect24, useState as useState9 } from "react";
3125
+ import { useEffect as useEffect25, useState as useState9 } from "react";
3173
3126
  import { createPortal as createPortal3 } from "react-dom";
3174
3127
  import { jsx as jsx23 } from "react/jsx-runtime";
3175
3128
  var AttachmentAsset = ({
@@ -3178,16 +3131,18 @@ var AttachmentAsset = ({
3178
3131
  }) => {
3179
3132
  const ctx = useRealityContext();
3180
3133
  const [containers, setContainers] = useState9([]);
3181
- useEffect24(() => {
3134
+ useEffect25(() => {
3182
3135
  if (!ctx) return;
3183
3136
  return ctx.attachmentRegistry.onContainersChange(name, setContainers);
3184
3137
  }, [ctx, name]);
3185
3138
  if (!containers.length) return null;
3186
- return /* @__PURE__ */ jsx23(InsideAttachmentContext.Provider, { value: true, children: containers.map((c, idx) => createPortal3(children, c, `${name}-${idx}`)) });
3139
+ return /* @__PURE__ */ jsx23(InsideAttachmentContext.Provider, { value: true, children: containers.map(
3140
+ ({ instanceId, container }) => createPortal3(children, container, instanceId)
3141
+ ) });
3187
3142
  };
3188
3143
 
3189
3144
  // src/reality/components/AttachmentEntity.tsx
3190
- import { useEffect as useEffect25, useRef as useRef13, useState as useState10 } from "react";
3145
+ import { useEffect as useEffect26, useRef as useRef15, useState as useState10 } from "react";
3191
3146
  var instanceCounter = 0;
3192
3147
  var AttachmentEntity = ({
3193
3148
  attachment: attachmentName,
@@ -3196,13 +3151,14 @@ var AttachmentEntity = ({
3196
3151
  }) => {
3197
3152
  const ctx = useRealityContext();
3198
3153
  const parent = useParentContext();
3199
- const attachmentRef = useRef13(null);
3200
- const parentIdRef = useRef13(null);
3201
- const instanceIdRef = useRef13(`att_${++instanceCounter}`);
3202
- const attachmentNameRef = useRef13(attachmentName);
3154
+ const attachmentRef = useRef15(null);
3155
+ const parentIdRef = useRef15(null);
3156
+ const instanceIdRef = useRef15(`att_${++instanceCounter}`);
3157
+ const attachmentNameRef = useRef15(attachmentName);
3203
3158
  const [childWindow, setChildWindow] = useState10(null);
3204
- useEffect25(() => {
3159
+ useEffect26(() => {
3205
3160
  if (!ctx || !parent) return;
3161
+ if (attachmentRef.current) return;
3206
3162
  const parentId = parent.id;
3207
3163
  parentIdRef.current = parentId;
3208
3164
  let cancelled = false;
@@ -3211,7 +3167,8 @@ var AttachmentEntity = ({
3211
3167
  const att = await ctx.session.createAttachmentEntity({
3212
3168
  parentEntityId: parentId,
3213
3169
  position: position ?? [0, 0, 0],
3214
- size
3170
+ size,
3171
+ ownerViewId: ctx.reality.id
3215
3172
  });
3216
3173
  if (cancelled) {
3217
3174
  att.destroy();
@@ -3223,7 +3180,6 @@ var AttachmentEntity = ({
3223
3180
  windowProxy.document.body.style.minWidth = "100%";
3224
3181
  windowProxy.document.body.style.maxWidth = "100%";
3225
3182
  windowProxy.document.body.style.minHeight = "100%";
3226
- await syncParentHeadToChild(windowProxy);
3227
3183
  const viewport = windowProxy.document.querySelector(
3228
3184
  'meta[name="viewport"]'
3229
3185
  );
@@ -3262,7 +3218,7 @@ var AttachmentEntity = ({
3262
3218
  }
3263
3219
  };
3264
3220
  }, [ctx, parent]);
3265
- useEffect25(() => {
3221
+ useEffect26(() => {
3266
3222
  if (!ctx) return;
3267
3223
  const att = attachmentRef.current;
3268
3224
  const prevName = attachmentNameRef.current;
@@ -3279,17 +3235,27 @@ var AttachmentEntity = ({
3279
3235
  }
3280
3236
  }, [ctx, attachmentName]);
3281
3237
  useSyncHeadStyles(childWindow, { subtree: false });
3282
- useEffect25(() => {
3238
+ useEffect26(() => {
3283
3239
  if (!attachmentRef.current) return;
3284
3240
  attachmentRef.current.update({ position, size });
3285
3241
  }, [position?.[0], position?.[1], position?.[2], size?.width, size?.height]);
3286
3242
  return null;
3287
3243
  };
3288
3244
 
3245
+ // src/reality/components/Material.tsx
3246
+ import { jsx as jsx24 } from "react/jsx-runtime";
3247
+ var Material = (props) => {
3248
+ if (props.type === "unlit") {
3249
+ const { type, ...rest } = props;
3250
+ return /* @__PURE__ */ jsx24(UnlitMaterial, { ...rest });
3251
+ }
3252
+ return null;
3253
+ };
3254
+
3289
3255
  // src/Model.tsx
3290
3256
  import { forwardRef as forwardRef20 } from "react";
3291
3257
  import { Spatial as Spatial2 } from "@webspatial/core-sdk";
3292
- import { jsx as jsx24 } from "react/jsx-runtime";
3258
+ import { jsx as jsx25 } from "react/jsx-runtime";
3293
3259
  var spatial2 = new Spatial2();
3294
3260
  function ModelBase(props, ref) {
3295
3261
  const insideAttachment = useInsideAttachment();
@@ -3304,30 +3270,126 @@ function ModelBase(props, ref) {
3304
3270
  onSpatialRotateEnd,
3305
3271
  onSpatialMagnify,
3306
3272
  onSpatialMagnifyEnd,
3273
+ spatialEventOptions: _spatialEventOptions,
3307
3274
  ...modelProps
3308
3275
  } = restProps;
3309
- return /* @__PURE__ */ jsx24("model", { ref, ...modelProps });
3276
+ return /* @__PURE__ */ jsx25("model", { ref, ...modelProps });
3310
3277
  }
3311
- return /* @__PURE__ */ jsx24(SpatializedStatic3DElementContainer, { ref, ...restProps });
3278
+ return /* @__PURE__ */ jsx25(SpatializedStatic3DElementContainer, { ref, ...restProps });
3312
3279
  }
3313
3280
  var Model = withSSRSupported(forwardRef20(ModelBase));
3314
3281
  Model.displayName = "Model";
3315
3282
 
3283
+ // src/useMetrics.tsx
3284
+ import { useSyncExternalStore } from "react";
3285
+ import { PhysicalMetrics } from "@webspatial/core-sdk";
3286
+ function useMetrics() {
3287
+ useSyncExternalStore(PhysicalMetrics.subscribe, PhysicalMetrics.getValue);
3288
+ const { pointToPhysical, physicalToPoint } = PhysicalMetrics;
3289
+ return { pointToPhysical, physicalToPoint };
3290
+ }
3291
+
3292
+ // src/jsx/jsx-shared.ts
3293
+ import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
3294
+ import reactJSXRuntime from "react/jsx-runtime";
3295
+ import { createElement as reactCreateElement } from "react";
3296
+ var attributeFlag = "enable-xr";
3297
+ var styleFlag = "enableXr";
3298
+ var classFlag = "__enableXr__";
3299
+ var xrMonitorFlag = "enable-xr-monitor";
3300
+ function replaceToSpatialPrimitiveType(type, props) {
3301
+ if (type === Model) {
3302
+ return type;
3303
+ }
3304
+ const propsObject = props;
3305
+ if (attributeFlag in propsObject) {
3306
+ delete propsObject[attributeFlag];
3307
+ return withSpatialized2DElementContainer(type);
3308
+ }
3309
+ if (xrMonitorFlag in propsObject) {
3310
+ delete propsObject[xrMonitorFlag];
3311
+ return withSpatialMonitor(type);
3312
+ }
3313
+ if (propsObject && propsObject.style && styleFlag in propsObject.style) {
3314
+ delete propsObject.style[styleFlag];
3315
+ return withSpatialized2DElementContainer(type);
3316
+ }
3317
+ if (propsObject && typeof propsObject.className === "string") {
3318
+ const originalClassNames = propsObject.className.split(" ");
3319
+ const idx = originalClassNames.indexOf(classFlag);
3320
+ if (idx !== -1) {
3321
+ originalClassNames.splice(idx, 1);
3322
+ propsObject.className = originalClassNames.join(" ");
3323
+ return withSpatialized2DElementContainer(type);
3324
+ }
3325
+ }
3326
+ return type;
3327
+ }
3328
+ function createElement(...args) {
3329
+ const [type, props, ...rest] = args;
3330
+ const newType = replaceToSpatialPrimitiveType(type, props);
3331
+ return reactCreateElement(newType, props, ...rest);
3332
+ }
3333
+
3334
+ // src/utils/convertCoordinate.ts
3335
+ function resolveSpatialObjectId(target) {
3336
+ if (typeof window !== "undefined" && target === window) {
3337
+ const scene = getSession()?.getSpatialScene();
3338
+ return scene?.id ?? "";
3339
+ }
3340
+ const maybeEntity = target;
3341
+ if (maybeEntity && typeof maybeEntity === "object" && "entity" in maybeEntity) {
3342
+ return maybeEntity.entity?.id ?? null;
3343
+ }
3344
+ const dom = target?.__raw ?? target;
3345
+ if (dom && typeof dom === "object") {
3346
+ const spatializedElement = dom.__spatializedElement ?? dom.__innerSpatializedElement?.();
3347
+ if (spatializedElement && spatializedElement.id) {
3348
+ return spatializedElement.id;
3349
+ }
3350
+ }
3351
+ return null;
3352
+ }
3353
+ async function convertCoordinate(position, { from, to }) {
3354
+ try {
3355
+ const fromId = resolveSpatialObjectId(from);
3356
+ const toId = resolveSpatialObjectId(to);
3357
+ if (fromId === null || toId === null) {
3358
+ console.warn(
3359
+ "convertCoordinate error: from or to is not a valid coordinate convertible"
3360
+ );
3361
+ return position;
3362
+ }
3363
+ const spatialScene = getSession()?.getSpatialScene();
3364
+ if (!spatialScene) return position;
3365
+ const ret = await spatialScene.convertCoordinate(position, fromId, toId);
3366
+ return ret ?? position;
3367
+ } catch (error) {
3368
+ console.warn("convertCoordinate error:", error);
3369
+ return position;
3370
+ }
3371
+ }
3372
+
3316
3373
  // src/index.ts
3317
- var version = "1.3.0";
3374
+ var version = "1.4.0";
3318
3375
  if (typeof window !== "undefined") {
3319
3376
  initPolyfill();
3320
3377
  }
3321
3378
  export {
3322
3379
  AttachmentAsset,
3323
3380
  AttachmentEntity,
3381
+ BoxEntity as Box,
3324
3382
  BoxEntity,
3383
+ ConeEntity as Cone,
3325
3384
  ConeEntity,
3385
+ CylinderEntity as Cylinder,
3326
3386
  CylinderEntity,
3327
3387
  Entity,
3388
+ Material,
3328
3389
  Model,
3329
3390
  ModelAsset,
3330
3391
  ModelEntity,
3392
+ PlaneEntity as Plane,
3331
3393
  PlaneEntity,
3332
3394
  Reality,
3333
3395
  SSRProvider,
@@ -3336,14 +3398,17 @@ export {
3336
3398
  Spatialized2DElementContainer,
3337
3399
  SpatializedContainer,
3338
3400
  SpatializedStatic3DElementContainer,
3401
+ SphereEntity as Sphere,
3339
3402
  SphereEntity,
3340
3403
  UnlitMaterial,
3404
+ SceneGraph as World,
3405
+ convertCoordinate,
3406
+ createElement,
3341
3407
  enableDebugTool,
3342
3408
  eventMap,
3343
3409
  initPolyfill,
3344
3410
  initScene,
3345
- toLocalSpace,
3346
- toSceneSpatial,
3411
+ useMetrics,
3347
3412
  version,
3348
3413
  withSpatialMonitor,
3349
3414
  withSpatialized2DElementContainer