@jkwd/inbase 0.1.20 → 0.1.21

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.
@@ -17,9 +17,18 @@ export function toPosix(filePath) {
17
17
  return filePath.split(path.sep).join('/')
18
18
  }
19
19
 
20
+ function isViteDepCache(parts) {
21
+ const viteAt = parts.indexOf('vite')
22
+ if (viteAt < 0) return false
23
+ return parts
24
+ .slice(viteAt + 1)
25
+ .some((part) => part === 'deps' || part.startsWith('deps_temp'))
26
+ }
27
+
20
28
  /** True when any path segment is ignored, e.g. apps/web/node_modules/pkg/index.js. */
21
29
  export function shouldIgnoreRelativePath(relative) {
22
30
  const parts = toPosix(relative).split('/').filter(Boolean)
31
+ if (isViteDepCache(parts)) return true
23
32
  if (
24
33
  parts.some(
25
34
  (part) =>
@@ -1451,6 +1451,13 @@ function Explorer({
1451
1451
  shadows={false}
1452
1452
  dpr={[1, 1.5]}
1453
1453
  gl={{ antialias: true, toneMappingExposure: 1.25 }}
1454
+ onCreated={({ gl }) => {
1455
+ gl.domElement.addEventListener(
1456
+ 'webglcontextlost',
1457
+ (event) => event.preventDefault(),
1458
+ { once: false },
1459
+ )
1460
+ }}
1454
1461
  camera={{
1455
1462
  position: layout.spawn,
1456
1463
  fov: 70,
@@ -64,6 +64,15 @@ button {
64
64
  font-size: 15px;
65
65
  }
66
66
 
67
+ .canvas-error {
68
+ position: absolute;
69
+ inset: 0;
70
+ z-index: 2;
71
+ display: grid;
72
+ place-items: center;
73
+ background: var(--vc-chrome);
74
+ }
75
+
67
76
  .canvas-error .hud-button {
68
77
  margin-top: 12px;
69
78
  }
@@ -11,6 +11,7 @@ import {
11
11
  import { CONFIG, WORLD_VOID, type ChangeKind } from '../theme'
12
12
  import { shouldIgnoreShortcut } from '../keyboard'
13
13
  import type { CodebaseGraph, PlacedFile, PlacedFolder, WorldLayout } from '../types'
14
+ import { CanvasErrorBoundary } from '../ui/CanvasErrorBoundary'
14
15
  import { FileBlock } from './FileBlock'
15
16
  import { FolderArea } from './FolderArea'
16
17
  import { RelationLines } from './RelationLines'
@@ -645,6 +646,7 @@ export function SelectionThumbnail({
645
646
  const [zoom, setZoom] = useState(1)
646
647
  const [panning, setPanning] = useState(false)
647
648
  const [orbiting, setOrbiting] = useState(false)
649
+ const [canvasReady, setCanvasReady] = useState(false)
648
650
  const [visibleLabelIds, setVisibleLabelIds] = useState<Set<string>>(
649
651
  () => new Set(),
650
652
  )
@@ -670,6 +672,11 @@ export function SelectionThumbnail({
670
672
 
671
673
  const panningRef = useRef(false)
672
674
 
675
+ useEffect(() => {
676
+ const frame = window.requestAnimationFrame(() => setCanvasReady(true))
677
+ return () => window.cancelAnimationFrame(frame)
678
+ }, [])
679
+
673
680
  useEffect(() => {
674
681
  zoomRef.current = 1
675
682
  panRef.current = ZERO_PAN
@@ -973,37 +980,49 @@ export function SelectionThumbnail({
973
980
  data-panning={panning}
974
981
  data-orbiting={orbiting}
975
982
  >
976
- <Canvas
977
- shadows={false}
978
- dpr={[1, 1.5]}
979
- resize={{ offsetSize: true }}
980
- gl={{ antialias: true, toneMappingExposure: 1.25 }}
981
- camera={{
982
- fov: 50,
983
- near: 0.1,
984
- far: 400,
985
- position: target.camera.position,
986
- }}
987
- >
988
- <ThumbnailScene
989
- graph={graph}
990
- layout={layout}
991
- importedBy={importedBy}
992
- target={target}
993
- highlightedFolders={highlightedFolders}
994
- planned={planned}
995
- created={created}
996
- deleted={deleted}
997
- zoom={zoom}
998
- zoomRef={zoomRef}
999
- panRef={panRef}
1000
- orbitRef={orbitRef}
1001
- cameraRef={cameraRef}
1002
- frozenRef={panningRef}
1003
- visibleLabelIds={visibleLabelIds}
1004
- onVisibleLabels={setVisibleLabelIds}
1005
- />
1006
- </Canvas>
983
+ {canvasReady ? (
984
+ <CanvasErrorBoundary
985
+ fallback={
986
+ <div className="hud-thumbnail-hint">3D preview unavailable</div>
987
+ }
988
+ >
989
+ <Canvas
990
+ shadows={false}
991
+ dpr={[1, 1]}
992
+ resize={{ offsetSize: true }}
993
+ gl={{
994
+ antialias: false,
995
+ powerPreference: 'low-power',
996
+ toneMappingExposure: 1.25,
997
+ }}
998
+ camera={{
999
+ fov: 50,
1000
+ near: 0.1,
1001
+ far: 400,
1002
+ position: target.camera.position,
1003
+ }}
1004
+ >
1005
+ <ThumbnailScene
1006
+ graph={graph}
1007
+ layout={layout}
1008
+ importedBy={importedBy}
1009
+ target={target}
1010
+ highlightedFolders={highlightedFolders}
1011
+ planned={planned}
1012
+ created={created}
1013
+ deleted={deleted}
1014
+ zoom={zoom}
1015
+ zoomRef={zoomRef}
1016
+ panRef={panRef}
1017
+ orbitRef={orbitRef}
1018
+ cameraRef={cameraRef}
1019
+ frozenRef={panningRef}
1020
+ visibleLabelIds={visibleLabelIds}
1021
+ onVisibleLabels={setVisibleLabelIds}
1022
+ />
1023
+ </Canvas>
1024
+ </CanvasErrorBoundary>
1025
+ ) : null}
1007
1026
  <div className="hud-thumbnail-hint">
1008
1027
  Scroll zoom · drag pan · ⌘ drag rotate
1009
1028
  </div>
@@ -2,6 +2,7 @@ import { Component, type ReactNode } from 'react'
2
2
 
3
3
  type Props = {
4
4
  children: ReactNode
5
+ fallback?: ReactNode
5
6
  }
6
7
 
7
8
  type State = {
@@ -21,6 +22,7 @@ export class CanvasErrorBoundary extends Component<Props, State> {
21
22
 
22
23
  render() {
23
24
  if (this.state.failed) {
25
+ if (this.props.fallback !== undefined) return this.props.fallback
24
26
  return (
25
27
  <div className="canvas-error">
26
28
  <div className="hud-gate-card">
@@ -2,6 +2,7 @@ import { useEffect, useRef, useState, type ReactNode } from 'react'
2
2
  import { persistAddContextFiles, persistInitialInstruction, persistRemoveContextFile } from '../agentIntent'
3
3
  import { NameInput } from './NameInput'
4
4
  import { SelectionThumbnail } from '../scene/SelectionThumbnail'
5
+ import { CanvasErrorBoundary } from './CanvasErrorBoundary'
5
6
  import {
6
7
  canStopSession,
7
8
  isReviewingIntent,
@@ -2776,7 +2777,8 @@ export function HUD({
2776
2777
  )}
2777
2778
 
2778
2779
  {mapping && thumbnailVisible && (
2779
- <SelectionThumbnail
2780
+ <CanvasErrorBoundary fallback={null}>
2781
+ <SelectionThumbnail
2780
2782
  graph={graph}
2781
2783
  layout={layout}
2782
2784
  selectedId={selectedId}
@@ -2816,6 +2818,7 @@ export function HUD({
2816
2818
  setThumbnailMaximized(false)
2817
2819
  }}
2818
2820
  />
2821
+ </CanvasErrorBoundary>
2819
2822
  )}
2820
2823
  </div>
2821
2824
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jkwd/inbase",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "A first-person 3D map of a codebase, with a visual coding workflow for Cursor.",
5
5
  "license": "MIT",
6
6
  "author": "Joris Kuijper",