@tscircuit/3d-viewer 0.0.531 → 0.0.532

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +186 -117
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -14432,7 +14432,7 @@ var require_browser = __commonJS({
14432
14432
  });
14433
14433
 
14434
14434
  // src/CadViewer.tsx
14435
- import { useState as useState36, useCallback as useCallback21, useRef as useRef26, useEffect as useEffect44 } from "react";
14435
+ import { useState as useState36, useCallback as useCallback21, useRef as useRef26, useEffect as useEffect45 } from "react";
14436
14436
  import * as THREE39 from "three";
14437
14437
 
14438
14438
  // src/CadViewerJscad.tsx
@@ -14441,7 +14441,7 @@ import { forwardRef as forwardRef3, useMemo as useMemo20 } from "react";
14441
14441
 
14442
14442
  // src/AnyCadComponent.tsx
14443
14443
  import { su as su2 } from "@tscircuit/circuit-json-util";
14444
- import { useCallback as useCallback3, useMemo as useMemo8, useState as useState7 } from "react";
14444
+ import { useCallback as useCallback3, useEffect as useEffect11, useMemo as useMemo8, useState as useState7 } from "react";
14445
14445
 
14446
14446
  // src/contexts/LayerVisibilityContext.tsx
14447
14447
  import {
@@ -28577,8 +28577,35 @@ var resolveModelUrl = (modelUrl, resolveStaticAsset) => {
28577
28577
  // src/utils/tuple.ts
28578
28578
  var tuple = (...args) => args;
28579
28579
 
28580
+ // src/three-components/ThreeErrorBoundary.tsx
28581
+ import React6 from "react";
28582
+ var ThreeErrorBoundary = class extends React6.Component {
28583
+ constructor(props) {
28584
+ super(props);
28585
+ this.state = { hasError: false, error: null };
28586
+ }
28587
+ static getDerivedStateFromError(error) {
28588
+ return { hasError: true, error };
28589
+ }
28590
+ render() {
28591
+ if (this.state.hasError && this.state.error) {
28592
+ return this.props.fallback({ error: this.state.error });
28593
+ }
28594
+ return this.props.children;
28595
+ }
28596
+ };
28597
+
28580
28598
  // src/AnyCadComponent.tsx
28581
28599
  import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs2 } from "react/jsx-runtime";
28600
+ var ModelLoadErrorReporter = ({
28601
+ error,
28602
+ onError
28603
+ }) => {
28604
+ useEffect11(() => {
28605
+ onError(error);
28606
+ }, [error, onError]);
28607
+ return null;
28608
+ };
28582
28609
  var AnyCadComponent = ({
28583
28610
  cad_component,
28584
28611
  circuitJson,
@@ -28625,6 +28652,12 @@ var AnyCadComponent = ({
28625
28652
  const stepUrl = resolveModelUrlWithStaticResolver(
28626
28653
  cad_component.model_step_url
28627
28654
  );
28655
+ const [fallbackModelIndex, setFallbackModelIndex] = useState7(0);
28656
+ const [lastModelError, setLastModelError] = useState7(null);
28657
+ useEffect11(() => {
28658
+ setFallbackModelIndex(0);
28659
+ setLastModelError(null);
28660
+ }, [cad_component.cad_component_id, url, gltfUrl, stepUrl]);
28628
28661
  const pcbComponent = circuitJson.find(
28629
28662
  (elm) => elm.type === "pcb_component" && elm.source_component_id === cad_component.source_component_id
28630
28663
  );
@@ -28651,50 +28684,104 @@ var AnyCadComponent = ({
28651
28684
  }
28652
28685
  return [cad_component.position.x, cad_component.position.y, z18];
28653
28686
  }, [cad_component.position, layer, pcbThickness]);
28687
+ const fallbackModelComponents = useMemo8(() => {
28688
+ const components = [];
28689
+ if (url) {
28690
+ components.push(
28691
+ /* @__PURE__ */ jsx10(
28692
+ MixedStlModel,
28693
+ {
28694
+ url,
28695
+ position: adjustedPosition,
28696
+ rotation: rotationOffset,
28697
+ scale: cad_component.model_unit_to_mm_scale_factor,
28698
+ onHover: handleHover,
28699
+ onUnhover: handleUnhover,
28700
+ isHovered,
28701
+ isTranslucent: cad_component.show_as_translucent_model
28702
+ },
28703
+ `${cad_component.cad_component_id}-mixed-${url}`
28704
+ )
28705
+ );
28706
+ }
28707
+ if (gltfUrl) {
28708
+ components.push(
28709
+ /* @__PURE__ */ jsx10(
28710
+ GltfModel,
28711
+ {
28712
+ gltfUrl,
28713
+ position: adjustedPosition,
28714
+ rotation: rotationOffset,
28715
+ scale: cad_component.model_unit_to_mm_scale_factor,
28716
+ onHover: handleHover,
28717
+ onUnhover: handleUnhover,
28718
+ isHovered,
28719
+ isTranslucent: cad_component.show_as_translucent_model
28720
+ },
28721
+ `${cad_component.cad_component_id}-gltf-${gltfUrl}`
28722
+ )
28723
+ );
28724
+ }
28725
+ if (stepUrl && !cad_component.model_jscad && !cad_component.footprinter_string) {
28726
+ components.push(
28727
+ /* @__PURE__ */ jsx10(
28728
+ StepModel,
28729
+ {
28730
+ stepUrl,
28731
+ position: adjustedPosition,
28732
+ rotation: rotationOffset,
28733
+ scale: cad_component.model_unit_to_mm_scale_factor,
28734
+ onHover: handleHover,
28735
+ onUnhover: handleUnhover,
28736
+ isHovered,
28737
+ isTranslucent: cad_component.show_as_translucent_model
28738
+ },
28739
+ `${cad_component.cad_component_id}-step-${stepUrl}`
28740
+ )
28741
+ );
28742
+ }
28743
+ return components;
28744
+ }, [
28745
+ adjustedPosition,
28746
+ cad_component.cad_component_id,
28747
+ cad_component.footprinter_string,
28748
+ cad_component.model_jscad,
28749
+ cad_component.model_unit_to_mm_scale_factor,
28750
+ cad_component.show_as_translucent_model,
28751
+ gltfUrl,
28752
+ handleHover,
28753
+ handleUnhover,
28754
+ isHovered,
28755
+ rotationOffset,
28756
+ stepUrl,
28757
+ url
28758
+ ]);
28654
28759
  let modelComponent = null;
28655
- if (url) {
28656
- modelComponent = /* @__PURE__ */ jsx10(
28657
- MixedStlModel,
28658
- {
28659
- url,
28660
- position: adjustedPosition,
28661
- rotation: rotationOffset,
28662
- scale: cad_component.model_unit_to_mm_scale_factor,
28663
- onHover: handleHover,
28664
- onUnhover: handleUnhover,
28665
- isHovered,
28666
- isTranslucent: cad_component.show_as_translucent_model
28667
- },
28668
- cad_component.cad_component_id
28669
- );
28670
- } else if (gltfUrl) {
28760
+ if (fallbackModelComponents.length > 0) {
28761
+ if (fallbackModelIndex >= fallbackModelComponents.length) {
28762
+ if (lastModelError) {
28763
+ throw lastModelError;
28764
+ }
28765
+ return null;
28766
+ }
28671
28767
  modelComponent = /* @__PURE__ */ jsx10(
28672
- GltfModel,
28768
+ ThreeErrorBoundary,
28673
28769
  {
28674
- gltfUrl,
28675
- position: adjustedPosition,
28676
- rotation: rotationOffset,
28677
- scale: cad_component.model_unit_to_mm_scale_factor,
28678
- onHover: handleHover,
28679
- onUnhover: handleUnhover,
28680
- isHovered,
28681
- isTranslucent: cad_component.show_as_translucent_model
28770
+ fallback: ({ error }) => /* @__PURE__ */ jsx10(
28771
+ ModelLoadErrorReporter,
28772
+ {
28773
+ error,
28774
+ onError: (nextError) => {
28775
+ setLastModelError(nextError);
28776
+ setFallbackModelIndex(
28777
+ (current) => Math.max(current, fallbackModelIndex + 1)
28778
+ );
28779
+ }
28780
+ }
28781
+ ),
28782
+ children: fallbackModelComponents[fallbackModelIndex]
28682
28783
  },
28683
- cad_component.cad_component_id
28684
- );
28685
- } else if (stepUrl && !cad_component.model_jscad && !cad_component.footprinter_string) {
28686
- modelComponent = /* @__PURE__ */ jsx10(
28687
- StepModel,
28688
- {
28689
- stepUrl,
28690
- position: adjustedPosition,
28691
- rotation: rotationOffset,
28692
- scale: cad_component.model_unit_to_mm_scale_factor,
28693
- onHover: handleHover,
28694
- onUnhover: handleUnhover,
28695
- isHovered,
28696
- isTranslucent: cad_component.show_as_translucent_model
28697
- }
28784
+ `${cad_component.cad_component_id}-fallback-${fallbackModelIndex}`
28698
28785
  );
28699
28786
  } else if (cad_component.model_jscad) {
28700
28787
  modelComponent = /* @__PURE__ */ jsx10(
@@ -28763,13 +28850,13 @@ var AnyCadComponent = ({
28763
28850
  };
28764
28851
 
28765
28852
  // src/CadViewerContainer.tsx
28766
- import { forwardRef as forwardRef2, useEffect as useEffect17, useMemo as useMemo14, useState as useState10 } from "react";
28853
+ import { forwardRef as forwardRef2, useEffect as useEffect18, useMemo as useMemo14, useState as useState10 } from "react";
28767
28854
  import * as THREE16 from "three";
28768
28855
 
28769
28856
  // package.json
28770
28857
  var package_default = {
28771
28858
  name: "@tscircuit/3d-viewer",
28772
- version: "0.0.530",
28859
+ version: "0.0.531",
28773
28860
  main: "./dist/index.js",
28774
28861
  module: "./dist/index.js",
28775
28862
  type: "module",
@@ -28847,7 +28934,7 @@ var package_default = {
28847
28934
  // src/react-three/Canvas.tsx
28848
28935
  import {
28849
28936
  useRef as useRef4,
28850
- useEffect as useEffect11,
28937
+ useEffect as useEffect12,
28851
28938
  useState as useState9,
28852
28939
  useCallback as useCallback5,
28853
28940
  forwardRef,
@@ -29114,7 +29201,7 @@ var Canvas = forwardRef(
29114
29201
  }
29115
29202
  const rootObject = useRef4(new THREE10.Object3D());
29116
29203
  useImperativeHandle(ref, () => rootObject.current);
29117
- useEffect11(() => {
29204
+ useEffect12(() => {
29118
29205
  if (!mountRef.current) return;
29119
29206
  removeExistingCanvases(mountRef.current);
29120
29207
  const renderer = new THREE10.WebGLRenderer({ antialias: true, alpha: true });
@@ -29214,7 +29301,7 @@ var Canvas = forwardRef(
29214
29301
  );
29215
29302
 
29216
29303
  // src/react-three/OrbitControls.tsx
29217
- import { useEffect as useEffect12, useMemo as useMemo11 } from "react";
29304
+ import { useEffect as useEffect13, useMemo as useMemo11 } from "react";
29218
29305
  import * as THREE11 from "three";
29219
29306
  import { OrbitControls as ThreeOrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
29220
29307
  var OrbitControls = ({
@@ -29234,11 +29321,11 @@ var OrbitControls = ({
29234
29321
  if (!camera || !renderer) return null;
29235
29322
  return new ThreeOrbitControls(camera, renderer.domElement);
29236
29323
  }, [camera, renderer]);
29237
- useEffect12(() => {
29324
+ useEffect13(() => {
29238
29325
  onControlsChange?.(controls ?? null);
29239
29326
  return () => onControlsChange?.(null);
29240
29327
  }, [controls, onControlsChange]);
29241
- useEffect12(() => {
29328
+ useEffect13(() => {
29242
29329
  if (!controls) return;
29243
29330
  const handleChange = () => {
29244
29331
  onControlsChange?.(controls);
@@ -29248,7 +29335,7 @@ var OrbitControls = ({
29248
29335
  controls.removeEventListener("change", handleChange);
29249
29336
  };
29250
29337
  }, [controls, onControlsChange]);
29251
- useEffect12(() => {
29338
+ useEffect13(() => {
29252
29339
  if (!controls) return;
29253
29340
  controls.autoRotate = autoRotate || false;
29254
29341
  controls.autoRotateSpeed = autoRotateSpeed || 1;
@@ -29281,14 +29368,14 @@ var OrbitControls = ({
29281
29368
  dampingFactor,
29282
29369
  target
29283
29370
  ]);
29284
- useEffect12(() => {
29371
+ useEffect13(() => {
29285
29372
  if (!controls || !onStart) return;
29286
29373
  controls.addEventListener("start", onStart);
29287
29374
  return () => {
29288
29375
  controls.removeEventListener("start", onStart);
29289
29376
  };
29290
29377
  }, [controls, onStart]);
29291
- useEffect12(() => {
29378
+ useEffect13(() => {
29292
29379
  if (!controls) return;
29293
29380
  return () => {
29294
29381
  controls.dispose();
@@ -29301,7 +29388,7 @@ var OrbitControls = ({
29301
29388
  };
29302
29389
 
29303
29390
  // src/react-three/Grid.tsx
29304
- import { useEffect as useEffect13, useMemo as useMemo12 } from "react";
29391
+ import { useEffect as useEffect14, useMemo as useMemo12 } from "react";
29305
29392
  import * as THREE12 from "three";
29306
29393
  var vertexShader = `
29307
29394
  varying vec3 worldPosition;
@@ -29376,7 +29463,7 @@ var Grid = ({
29376
29463
  gridMesh.position.set(camera.position.x, camera.position.y, 0);
29377
29464
  }
29378
29465
  });
29379
- useEffect13(() => {
29466
+ useEffect14(() => {
29380
29467
  if (!scene || !gridMesh) return;
29381
29468
  scene.add(gridMesh);
29382
29469
  return () => {
@@ -29393,7 +29480,7 @@ var Grid = ({
29393
29480
  };
29394
29481
 
29395
29482
  // src/react-three/Lights.tsx
29396
- import { useEffect as useEffect14, useMemo as useMemo13 } from "react";
29483
+ import { useEffect as useEffect15, useMemo as useMemo13 } from "react";
29397
29484
  import * as THREE13 from "three";
29398
29485
  var Lights = () => {
29399
29486
  const { scene } = useThree();
@@ -29407,7 +29494,7 @@ var Lights = () => {
29407
29494
  light.decay = 0;
29408
29495
  return light;
29409
29496
  }, []);
29410
- useEffect14(() => {
29497
+ useEffect15(() => {
29411
29498
  if (!scene) return;
29412
29499
  scene.add(ambientLight);
29413
29500
  scene.add(pointLight);
@@ -29420,7 +29507,7 @@ var Lights = () => {
29420
29507
  };
29421
29508
 
29422
29509
  // src/hooks/cameraAnimation.ts
29423
- import { useCallback as useCallback6, useEffect as useEffect15, useRef as useRef5 } from "react";
29510
+ import { useCallback as useCallback6, useEffect as useEffect16, useRef as useRef5 } from "react";
29424
29511
  import * as THREE14 from "three";
29425
29512
  var easeInOutCubic = (t) => t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
29426
29513
  var CameraAnimatorWithContext = () => {
@@ -29492,7 +29579,7 @@ var CameraAnimatorWithContext = () => {
29492
29579
  },
29493
29580
  [animateTo, getPresetConfig]
29494
29581
  );
29495
- useEffect15(() => {
29582
+ useEffect16(() => {
29496
29583
  if (!mainCameraRef.current) return;
29497
29584
  const controller = {
29498
29585
  animateTo,
@@ -29605,7 +29692,7 @@ var useCameraSession = () => {
29605
29692
  };
29606
29693
 
29607
29694
  // src/three-components/OrientationCubeCanvas.tsx
29608
- import { useEffect as useEffect16, useRef as useRef7 } from "react";
29695
+ import { useEffect as useEffect17, useRef as useRef7 } from "react";
29609
29696
  import * as THREE15 from "three";
29610
29697
  import { Text as TroikaText } from "troika-three-text";
29611
29698
  import { jsx as jsx13 } from "react/jsx-runtime";
@@ -29626,7 +29713,7 @@ var OrientationCubeCanvas = () => {
29626
29713
  const sceneRef = useRef7(null);
29627
29714
  const cameraRef = useRef7(null);
29628
29715
  const animationFrameRef = useRef7(null);
29629
- useEffect16(() => {
29716
+ useEffect17(() => {
29630
29717
  if (!containerRef.current) return;
29631
29718
  const canvas = document.createElement("canvas");
29632
29719
  canvasRef.current = canvas;
@@ -29793,7 +29880,7 @@ var CadViewerContainer = forwardRef2(
29793
29880
  handleCameraCreated,
29794
29881
  handleControlsChange: handleSessionControlsChange
29795
29882
  } = useCameraSession();
29796
- useEffect17(() => {
29883
+ useEffect18(() => {
29797
29884
  if (onCameraControllerReady) {
29798
29885
  onCameraControllerReady(controller);
29799
29886
  }
@@ -29930,12 +30017,12 @@ var useConvertChildrenToCircuitJson = (children) => {
29930
30017
  };
29931
30018
 
29932
30019
  // src/hooks/use-stls-from-geom.ts
29933
- import { useState as useState11, useEffect as useEffect18 } from "react";
30020
+ import { useState as useState11, useEffect as useEffect19 } from "react";
29934
30021
  import stlSerializer from "@jscad/stl-serializer";
29935
30022
  var useStlsFromGeom = (geom) => {
29936
30023
  const [stls, setStls] = useState11([]);
29937
30024
  const [loading, setLoading] = useState11(true);
29938
- useEffect18(() => {
30025
+ useEffect19(() => {
29939
30026
  if (!geom) return;
29940
30027
  const generateStls = async () => {
29941
30028
  setLoading(true);
@@ -29964,7 +30051,7 @@ var useStlsFromGeom = (geom) => {
29964
30051
  };
29965
30052
 
29966
30053
  // src/hooks/useBoardGeomBuilder.ts
29967
- import { useState as useState12, useEffect as useEffect19, useRef as useRef8 } from "react";
30054
+ import { useState as useState12, useEffect as useEffect20, useRef as useRef8 } from "react";
29968
30055
 
29969
30056
  // src/soup-to-3d/index.ts
29970
30057
  var import_primitives2 = __toESM(require_primitives(), 1);
@@ -31309,7 +31396,7 @@ var BoardGeomBuilder = class {
31309
31396
  var useBoardGeomBuilder = (circuitJson) => {
31310
31397
  const [boardGeom, setBoardGeom] = useState12(null);
31311
31398
  const isProcessingRef = useRef8(false);
31312
- useEffect19(() => {
31399
+ useEffect20(() => {
31313
31400
  let isCancelled = false;
31314
31401
  if (!circuitJson) {
31315
31402
  setBoardGeom(null);
@@ -31355,10 +31442,10 @@ var useBoardGeomBuilder = (circuitJson) => {
31355
31442
  };
31356
31443
 
31357
31444
  // src/three-components/Error3d.tsx
31358
- import { useState as useState13, useCallback as useCallback8, useEffect as useEffect21, useMemo as useMemo17 } from "react";
31445
+ import { useState as useState13, useCallback as useCallback8, useEffect as useEffect22, useMemo as useMemo17 } from "react";
31359
31446
 
31360
31447
  // src/react-three/Text.tsx
31361
- import { useEffect as useEffect20, useMemo as useMemo16 } from "react";
31448
+ import { useEffect as useEffect21, useMemo as useMemo16 } from "react";
31362
31449
  import { Text as TroikaText2 } from "troika-three-text";
31363
31450
  var Text = ({
31364
31451
  children,
@@ -31398,7 +31485,7 @@ var Text = ({
31398
31485
  anchorY,
31399
31486
  depthOffset
31400
31487
  ]);
31401
- useEffect20(() => {
31488
+ useEffect21(() => {
31402
31489
  const parentObject = parent || rootObject;
31403
31490
  if (!parentObject || !mesh) return;
31404
31491
  parentObject.add(mesh);
@@ -31449,7 +31536,7 @@ var Error3d = ({
31449
31536
  g.position.fromArray(position);
31450
31537
  return g;
31451
31538
  }, [position]);
31452
- useEffect21(() => {
31539
+ useEffect22(() => {
31453
31540
  if (!rootObject) return;
31454
31541
  rootObject.add(group);
31455
31542
  return () => {
@@ -31518,7 +31605,7 @@ var ErrorBox = ({ parent }) => {
31518
31605
  m.rotation.fromArray([Math.PI / 4, Math.PI / 4, 0]);
31519
31606
  return m;
31520
31607
  }, []);
31521
- useEffect21(() => {
31608
+ useEffect22(() => {
31522
31609
  parent.add(mesh);
31523
31610
  return () => {
31524
31611
  parent.remove(mesh);
@@ -31528,7 +31615,7 @@ var ErrorBox = ({ parent }) => {
31528
31615
  };
31529
31616
 
31530
31617
  // src/three-components/STLModel.tsx
31531
- import { useState as useState14, useEffect as useEffect22, useMemo as useMemo18 } from "react";
31618
+ import { useState as useState14, useEffect as useEffect23, useMemo as useMemo18 } from "react";
31532
31619
  import * as THREE18 from "three";
31533
31620
  import { STLLoader } from "three-stdlib";
31534
31621
  function STLModel({
@@ -31541,7 +31628,7 @@ function STLModel({
31541
31628
  }) {
31542
31629
  const { rootObject } = useThree();
31543
31630
  const [geom, setGeom] = useState14(null);
31544
- useEffect22(() => {
31631
+ useEffect23(() => {
31545
31632
  const loader = new STLLoader();
31546
31633
  if (stlData) {
31547
31634
  try {
@@ -31574,7 +31661,7 @@ function STLModel({
31574
31661
  createdMesh.renderOrder = isBoardLayer ? -1 : 1;
31575
31662
  return createdMesh;
31576
31663
  }, [geom, color, opacity, layerType]);
31577
- useEffect22(() => {
31664
+ useEffect23(() => {
31578
31665
  if (!rootObject || !mesh) return;
31579
31666
  rootObject.add(mesh);
31580
31667
  return () => {
@@ -31625,27 +31712,9 @@ function VisibleSTLModel({
31625
31712
  );
31626
31713
  }
31627
31714
 
31628
- // src/three-components/ThreeErrorBoundary.tsx
31629
- import React11 from "react";
31630
- var ThreeErrorBoundary = class extends React11.Component {
31631
- constructor(props) {
31632
- super(props);
31633
- this.state = { hasError: false, error: null };
31634
- }
31635
- static getDerivedStateFromError(error) {
31636
- return { hasError: true, error };
31637
- }
31638
- render() {
31639
- if (this.state.hasError && this.state.error) {
31640
- return this.props.fallback({ error: this.state.error });
31641
- }
31642
- return this.props.children;
31643
- }
31644
- };
31645
-
31646
31715
  // src/three-components/JscadBoardTextures.tsx
31647
31716
  import { su as su8 } from "@tscircuit/circuit-json-util";
31648
- import { useEffect as useEffect23, useMemo as useMemo19 } from "react";
31717
+ import { useEffect as useEffect24, useMemo as useMemo19 } from "react";
31649
31718
 
31650
31719
  // src/textures/create-combined-board-textures.ts
31651
31720
  import * as THREE28 from "three";
@@ -33219,7 +33288,7 @@ function JscadBoardTextures({
33219
33288
  visibility
33220
33289
  });
33221
33290
  }, [circuitJson, boardData, traceTextureResolution, visibility]);
33222
- useEffect23(() => {
33291
+ useEffect24(() => {
33223
33292
  if (!rootObject || !boardData || !textures) return;
33224
33293
  const meshes = [];
33225
33294
  const disposeTextureMaterial = (material) => {
@@ -33541,12 +33610,12 @@ var CadViewerJscad = forwardRef3(
33541
33610
 
33542
33611
  // src/CadViewerManifold.tsx
33543
33612
  import { su as su17 } from "@tscircuit/circuit-json-util";
33544
- import { useEffect as useEffect25, useMemo as useMemo22, useState as useState16 } from "react";
33613
+ import { useEffect as useEffect26, useMemo as useMemo22, useState as useState16 } from "react";
33545
33614
  import * as THREE38 from "three";
33546
33615
 
33547
33616
  // src/hooks/useManifoldBoardBuilder.ts
33548
33617
  import { su as su16 } from "@tscircuit/circuit-json-util";
33549
- import { useEffect as useEffect24, useMemo as useMemo21, useRef as useRef9, useState as useState15 } from "react";
33618
+ import { useEffect as useEffect25, useMemo as useMemo21, useRef as useRef9, useState as useState15 } from "react";
33550
33619
  import * as THREE35 from "three";
33551
33620
 
33552
33621
  // src/utils/manifold/create-manifold-board.ts
@@ -34692,7 +34761,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
34692
34761
  if (!boardData) return TRACE_TEXTURE_RESOLUTION;
34693
34762
  return getLayerTextureResolution(boardData, TRACE_TEXTURE_RESOLUTION);
34694
34763
  }, [boardData]);
34695
- useEffect24(() => {
34764
+ useEffect25(() => {
34696
34765
  if (!manifoldJSModule || !boardData) {
34697
34766
  setGeoms(null);
34698
34767
  setPcbThickness(null);
@@ -35016,7 +35085,7 @@ var BoardMeshes = ({
35016
35085
  material.dispose();
35017
35086
  }
35018
35087
  };
35019
- useEffect25(() => {
35088
+ useEffect26(() => {
35020
35089
  if (!rootObject) return;
35021
35090
  geometryMeshes.forEach((mesh) => {
35022
35091
  let shouldShow = true;
@@ -35038,7 +35107,7 @@ var BoardMeshes = ({
35038
35107
  });
35039
35108
  };
35040
35109
  }, [rootObject, geometryMeshes, visibility]);
35041
- useEffect25(() => {
35110
+ useEffect26(() => {
35042
35111
  if (!rootObject) return;
35043
35112
  textureMeshes.forEach((mesh) => {
35044
35113
  rootObject.add(mesh);
@@ -35072,7 +35141,7 @@ var CadViewerManifold = ({
35072
35141
  const [manifoldJSModule, setManifoldJSModule] = useState16(null);
35073
35142
  const [manifoldLoadingError, setManifoldLoadingError] = useState16(null);
35074
35143
  const { visibility } = useLayerVisibility();
35075
- useEffect25(() => {
35144
+ useEffect26(() => {
35076
35145
  if (window.ManifoldModule && typeof window.ManifoldModule === "object" && window.ManifoldModule.setup) {
35077
35146
  setManifoldJSModule(window.ManifoldModule);
35078
35147
  return;
@@ -35258,7 +35327,7 @@ try {
35258
35327
  var CadViewerManifold_default = CadViewerManifold;
35259
35328
 
35260
35329
  // src/hooks/useContextMenu.ts
35261
- import { useState as useState17, useCallback as useCallback9, useRef as useRef10, useEffect as useEffect26 } from "react";
35330
+ import { useState as useState17, useCallback as useCallback9, useRef as useRef10, useEffect as useEffect27 } from "react";
35262
35331
  var useContextMenu = ({ containerRef }) => {
35263
35332
  const [menuVisible, setMenuVisible] = useState17(false);
35264
35333
  const [menuPos, setMenuPos] = useState17({
@@ -35373,7 +35442,7 @@ var useContextMenu = ({ containerRef }) => {
35373
35442
  }
35374
35443
  setMenuVisible(false);
35375
35444
  }, []);
35376
- useEffect26(() => {
35445
+ useEffect27(() => {
35377
35446
  if (menuVisible) {
35378
35447
  document.addEventListener("mousedown", handleClickAway);
35379
35448
  document.addEventListener("touchstart", handleClickAway);
@@ -35476,7 +35545,7 @@ var useGlobalDownloadGltf = () => {
35476
35545
  };
35477
35546
 
35478
35547
  // src/hooks/useRegisteredHotkey.ts
35479
- import { useEffect as useEffect27, useMemo as useMemo23, useRef as useRef11, useState as useState18 } from "react";
35548
+ import { useEffect as useEffect28, useMemo as useMemo23, useRef as useRef11, useState as useState18 } from "react";
35480
35549
  var hotkeyRegistry = /* @__PURE__ */ new Map();
35481
35550
  var subscribers = /* @__PURE__ */ new Set();
35482
35551
  var isListenerAttached = false;
@@ -35607,7 +35676,7 @@ var useRegisteredHotkey = (id, handler, metadata) => {
35607
35676
  }),
35608
35677
  [metadata.shortcut, metadata.description]
35609
35678
  );
35610
- useEffect27(() => {
35679
+ useEffect28(() => {
35611
35680
  const registration = {
35612
35681
  id,
35613
35682
  ...normalizedMetadata,
@@ -35623,7 +35692,7 @@ var useHotkeyRegistry = () => {
35623
35692
  const [entries, setEntries] = useState18(
35624
35693
  () => Array.from(hotkeyRegistry.values())
35625
35694
  );
35626
- useEffect27(() => subscribeToRegistry(setEntries), []);
35695
+ useEffect28(() => subscribeToRegistry(setEntries), []);
35627
35696
  return entries;
35628
35697
  };
35629
35698
  var registerHotkeyViewer = (element) => {
@@ -41759,7 +41828,7 @@ var ContextMenu = ({
41759
41828
  };
41760
41829
 
41761
41830
  // src/components/KeyboardShortcutsDialog.tsx
41762
- import { useEffect as useEffect43, useMemo as useMemo29, useRef as useRef25, useState as useState35 } from "react";
41831
+ import { useEffect as useEffect44, useMemo as useMemo29, useRef as useRef25, useState as useState35 } from "react";
41763
41832
  import { jsx as jsx37, jsxs as jsxs10 } from "react/jsx-runtime";
41764
41833
  var KeyboardShortcutsDialog = ({
41765
41834
  open,
@@ -41768,7 +41837,7 @@ var KeyboardShortcutsDialog = ({
41768
41837
  const [query, setQuery] = useState35("");
41769
41838
  const inputRef = useRef25(null);
41770
41839
  const hotkeys = useHotkeyRegistry();
41771
- useEffect43(() => {
41840
+ useEffect44(() => {
41772
41841
  if (!open) return void 0;
41773
41842
  const handleKeyDown = (event) => {
41774
41843
  if (event.key === "Escape") {
@@ -41779,7 +41848,7 @@ var KeyboardShortcutsDialog = ({
41779
41848
  window.addEventListener("keydown", handleKeyDown);
41780
41849
  return () => window.removeEventListener("keydown", handleKeyDown);
41781
41850
  }, [open, onClose]);
41782
- useEffect43(() => {
41851
+ useEffect44(() => {
41783
41852
  if (open) {
41784
41853
  setTimeout(() => {
41785
41854
  inputRef.current?.focus();
@@ -42075,36 +42144,36 @@ var CadViewerInner = (props) => {
42075
42144
  description: "Toggle translucent components"
42076
42145
  }
42077
42146
  );
42078
- useEffect44(() => {
42147
+ useEffect45(() => {
42079
42148
  if (containerRef.current) {
42080
42149
  registerHotkeyViewer(containerRef.current);
42081
42150
  }
42082
42151
  }, []);
42083
- useEffect44(() => {
42152
+ useEffect45(() => {
42084
42153
  const stored = window.localStorage.getItem("cadViewerEngine");
42085
42154
  if (stored === "jscad" || stored === "manifold") {
42086
42155
  setEngine(stored);
42087
42156
  }
42088
42157
  }, []);
42089
- useEffect44(() => {
42158
+ useEffect45(() => {
42090
42159
  window.localStorage.setItem("cadViewerEngine", engine);
42091
42160
  }, [engine]);
42092
- useEffect44(() => {
42161
+ useEffect45(() => {
42093
42162
  window.localStorage.setItem("cadViewerAutoRotate", String(autoRotate));
42094
42163
  }, [autoRotate]);
42095
- useEffect44(() => {
42164
+ useEffect45(() => {
42096
42165
  window.localStorage.setItem(
42097
42166
  "cadViewerAutoRotateUserToggled",
42098
42167
  String(autoRotateUserToggled)
42099
42168
  );
42100
42169
  }, [autoRotateUserToggled]);
42101
- useEffect44(() => {
42170
+ useEffect45(() => {
42102
42171
  const stored = window.localStorage.getItem("cadViewerCameraType");
42103
42172
  if (stored === "orthographic" || stored === "perspective") {
42104
42173
  setCameraType(stored);
42105
42174
  }
42106
42175
  }, [setCameraType]);
42107
- useEffect44(() => {
42176
+ useEffect45(() => {
42108
42177
  window.localStorage.setItem("cadViewerCameraType", cameraType);
42109
42178
  }, [cameraType]);
42110
42179
  const viewerKey = props.circuitJson ? JSON.stringify(props.circuitJson) : void 0;
@@ -42504,7 +42573,7 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
42504
42573
 
42505
42574
  // src/hooks/exporter/gltf.ts
42506
42575
  import { GLTFExporter as GLTFExporter3 } from "three-stdlib";
42507
- import { useEffect as useEffect45, useState as useState37, useMemo as useMemo30, useCallback as useCallback22 } from "react";
42576
+ import { useEffect as useEffect46, useState as useState37, useMemo as useMemo30, useCallback as useCallback22 } from "react";
42508
42577
  function useSaveGltfAs(options = {}) {
42509
42578
  const parse2 = useParser(options);
42510
42579
  const link = useMemo30(() => document.createElement("a"), []);
@@ -42517,7 +42586,7 @@ function useSaveGltfAs(options = {}) {
42517
42586
  link.dispatchEvent(new MouseEvent("click"));
42518
42587
  URL.revokeObjectURL(url);
42519
42588
  };
42520
- useEffect45(
42589
+ useEffect46(
42521
42590
  () => () => {
42522
42591
  link.remove();
42523
42592
  instance = null;
@@ -42538,7 +42607,7 @@ function useExportGltfUrl(options = {}) {
42538
42607
  (instance) => parse2(instance).then(setUrl).catch(setError),
42539
42608
  []
42540
42609
  );
42541
- useEffect45(() => () => URL.revokeObjectURL(url), [url]);
42610
+ useEffect46(() => () => URL.revokeObjectURL(url), [url]);
42542
42611
  return [ref, url, error];
42543
42612
  }
42544
42613
  function useParser(options = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/3d-viewer",
3
- "version": "0.0.531",
3
+ "version": "0.0.532",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",