{"_rev":"3-ee3376c8c40dc6e040660fe459ec339c","time":{"created":"2026-01-08T11:48:48.311Z","modified":"2026-01-08T11:48:49.090Z","1.0.0":"2026-01-08T10:20:42.341Z","1.0.1":"2026-01-08T11:48:48.571Z"},"_id":"@3lens/vue-bridge","name":"@3lens/vue-bridge","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.1":{"name":"@3lens/vue-bridge","version":"1.0.1","description":"Vue and TresJS integration for 3Lens - the three.js devtool","keywords":["three.js","threejs","vue","tresjs","devtools","debugging"],"homepage":"https://github.com/adriandarian/3Lens","repository":{"type":"git","url":"git+https://github.com/adriandarian/3Lens.git","directory":"packages/vue-bridge"},"license":"MIT","author":{"name":"Adrian Darian","email":"adrian.the.hactus@gmail.com","url":"https://github.com/adriandarian"},"type":"module","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"main":"./dist/index.js","types":"./dist/index.d.ts","dependencies":{"@3lens/core":"1.0.1"},"devDependencies":{"@tresjs/core":"^4.0.0","@vue/test-utils":"^2.4.6","jsdom":"^27.4.0","three":"^0.160.0","vue":"^3.4.0"},"peerDependencies":{"three":">=0.150.0","vue":">=3.3.0"},"peerDependenciesMeta":{"@tresjs/core":{"optional":true}},"scripts":{"build":"vite build","dev":"vite build --watch","typecheck":"tsc --noEmit","clean":"rm -rf dist"},"_id":"@3lens/vue-bridge@1.0.1","bugs":{"url":"https://github.com/adriandarian/3Lens/issues"},"_integrity":"sha512-mfOQcomt/xLDd1U7ZnDf8C+QjDSGWC6h58N3fEpvckXSkYu9iuls8NoEh57oR/icAEmAFuyNG7oZYSEwWOf4iQ==","_resolved":"/tmp/6deab76286a5ff3ad6215679a2a3e719/3lens-vue-bridge-1.0.1.tgz","_from":"file:3lens-vue-bridge-1.0.1.tgz","_nodeVersion":"20.19.6","_npmVersion":"10.8.2","dist":{"integrity":"sha512-mfOQcomt/xLDd1U7ZnDf8C+QjDSGWC6h58N3fEpvckXSkYu9iuls8NoEh57oR/icAEmAFuyNG7oZYSEwWOf4iQ==","shasum":"e958b316b4649ed1228dca06835f38e1148e97ad","tarball":"https://registry.npmjs.org/@3lens/vue-bridge/-/vue-bridge-1.0.1.tgz","fileCount":23,"unpackedSize":151969,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@3lens%2fvue-bridge@1.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCrRnXN30aRMYovC2r6Q9yAMZrlnfV9rGZ3A5MwYsflVwIgWT9v/9VRIySc1KkOUFhgi9TfTUyVMVxZUZgzCwL9AcI="}]},"_npmUser":{"name":"adriandarian","email":"adrian.the.hactus@gmail.com"},"directories":{},"maintainers":[{"name":"adriandarian","email":"adrian.the.hactus@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vue-bridge_1.0.1_1767872928427_0.20133371317384485"},"_hasShrinkwrap":false}},"maintainers":[{"name":"adriandarian","email":"adrian.the.hactus@gmail.com"}],"description":"Vue and TresJS integration for 3Lens - the three.js devtool","homepage":"https://github.com/adriandarian/3Lens","keywords":["three.js","threejs","vue","tresjs","devtools","debugging"],"repository":{"type":"git","url":"git+https://github.com/adriandarian/3Lens.git","directory":"packages/vue-bridge"},"author":{"name":"Adrian Darian","email":"adrian.the.hactus@gmail.com","url":"https://github.com/adriandarian"},"bugs":{"url":"https://github.com/adriandarian/3Lens/issues"},"license":"MIT","readme":"# @3lens/vue-bridge\n\nVue and TresJS integration for 3Lens - the three.js devtool.\n\n## Installation\n\n```bash\nnpm install @3lens/vue-bridge @3lens/core @3lens/overlay\n# or\npnpm add @3lens/vue-bridge @3lens/core @3lens/overlay\n```\n\n## Quick Start\n\n### Plugin Setup\n\n```typescript\nimport { createApp } from 'vue';\nimport { ThreeLensPlugin } from '@3lens/vue-bridge';\nimport App from './App.vue';\n\nconst app = createApp(App);\n\napp.use(ThreeLensPlugin, {\n  appName: 'My Vue Three.js App',\n  debug: false,\n  showOverlay: true,\n});\n\napp.mount('#app');\n```\n\n### Basic Usage\n\n```vue\n<script setup>\nimport { useThreeLens, useFPS, useDrawCalls } from '@3lens/vue-bridge';\nimport { onMounted, ref } from 'vue';\nimport * as THREE from 'three';\n\nconst { probe, isReady } = useThreeLens();\nconst fps = useFPS(true);\nconst drawCalls = useDrawCalls();\n\nconst canvasRef = ref<HTMLCanvasElement>();\n\nonMounted(() => {\n  const renderer = new THREE.WebGLRenderer({ canvas: canvasRef.value });\n  const scene = new THREE.Scene();\n  const camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000);\n\n  // Connect 3Lens\n  if (probe.value) {\n    probe.value.observeRenderer(renderer);\n    probe.value.observeScene(scene);\n  }\n\n  // Animation loop...\n});\n</script>\n\n<template>\n  <div class=\"stats\">\n    <div>FPS: {{ fps.current.toFixed(0) }}</div>\n    <div>Draw Calls: {{ drawCalls.current }}</div>\n  </div>\n  <canvas ref=\"canvasRef\" />\n</template>\n```\n\n## With TresJS\n\n```vue\n<script setup>\nimport { TresCanvas } from '@tresjs/core';\nimport { useTres } from '@tresjs/core';\nimport { ThreeLensPlugin, createTresConnector, useFPS } from '@3lens/vue-bridge';\n\n// Create connector with TresJS's useTres hook\nconst useTresConnect = createTresConnector(useTres);\n\nconst fps = useFPS(true);\n</script>\n\n<template>\n  <div>FPS: {{ fps.current.toFixed(0) }}</div>\n  \n  <TresCanvas>\n    <!-- This component connects 3Lens to TresJS -->\n    <TresConnector />\n    \n    <TresPerspectiveCamera :position=\"[0, 0, 5]\" />\n    <TresMesh>\n      <TresBoxGeometry />\n      <TresMeshStandardMaterial color=\"orange\" />\n    </TresMesh>\n  </TresCanvas>\n</template>\n\n<script>\n// TresConnector component (must be inside TresCanvas)\nconst TresConnector = defineComponent({\n  setup() {\n    useTresConnect();\n    return () => null;\n  },\n});\n</script>\n```\n\n## Composables\n\n### `useThreeLens()`\n\nAccess the full 3Lens context.\n\n```vue\n<script setup>\nimport { useThreeLens } from '@3lens/vue-bridge';\n\nconst {\n  probe,           // Ref<DevtoolProbe | null>\n  isReady,         // Ref<boolean>\n  frameStats,      // Ref<FrameStats | null>\n  snapshot,        // Ref<SceneSnapshot | null>\n  selectedNode,    // Ref<SceneNode | null>\n  fps,             // ComputedRef<number>\n  drawCalls,       // ComputedRef<number>\n  triangles,       // ComputedRef<number>\n  frameTime,       // ComputedRef<number>\n  gpuMemory,       // ComputedRef<number>\n  isOverlayVisible,// Ref<boolean>\n  selectObject,    // (uuid: string) => void\n  clearSelection,  // () => void\n  toggleOverlay,   // () => void\n  showOverlay,     // () => void\n  hideOverlay,     // () => void\n} = useThreeLens();\n</script>\n```\n\n### `useProbe()`\n\nAccess the probe instance directly.\n\n```vue\n<script setup>\nimport { useProbe } from '@3lens/vue-bridge';\n\nconst probe = useProbe();\n\nfunction takeSnapshot() {\n  const snapshot = probe.value.takeSnapshot();\n  console.log('Objects:', snapshot.root.children.length);\n}\n</script>\n```\n\n### `useSelectedObject()`\n\nAccess and manage selection.\n\n```vue\n<script setup>\nimport { useSelectedObject } from '@3lens/vue-bridge';\n\nconst {\n  selectedNode,  // Ref<SceneNode | null>\n  selectedUuid,  // ComputedRef<string | null>\n  selectedName,  // ComputedRef<string | null>\n  selectedType,  // ComputedRef<string | null>\n  hasSelection,  // ComputedRef<boolean>\n  select,        // (uuid: string) => void\n  clear,         // () => void\n  isSelected,    // (uuid: string) => boolean\n} = useSelectedObject();\n</script>\n\n<template>\n  <div v-if=\"hasSelection\">\n    <h3>{{ selectedName || 'Unnamed' }}</h3>\n    <p>Type: {{ selectedType }}</p>\n    <button @click=\"clear\">Deselect</button>\n  </div>\n</template>\n```\n\n### `useMetric(extractor, options?)`\n\nExtract custom metrics from frame stats.\n\n```vue\n<script setup>\nimport { useMetric } from '@3lens/vue-bridge';\n\nconst gpuTime = useMetric(\n  (stats) => stats.gpuTimeMs ?? 0,\n  { smoothed: true, smoothingSamples: 30 }\n);\n</script>\n\n<template>\n  <div>GPU: {{ gpuTime.current.toFixed(2) }}ms</div>\n  <div>Min: {{ gpuTime.min.toFixed(2) }}ms</div>\n  <div>Max: {{ gpuTime.max.toFixed(2) }}ms</div>\n</template>\n```\n\n### Convenience Metric Composables\n\n```vue\n<script setup>\nimport {\n  useFPS,\n  useFrameTime,\n  useDrawCalls,\n  useTriangles,\n  useGPUMemory,\n  useTextureCount,\n  useGeometryCount,\n} from '@3lens/vue-bridge';\n\nconst fps = useFPS(true);\nconst frameTime = useFrameTime();\nconst drawCalls = useDrawCalls();\nconst triangles = useTriangles();\nconst gpuMemory = useGPUMemory();\n</script>\n```\n\n### `useDevtoolEntity(object, options)`\n\nRegister objects with names and metadata.\n\n```vue\n<script setup>\nimport { ref, onMounted } from 'vue';\nimport { useDevtoolEntity } from '@3lens/vue-bridge';\nimport * as THREE from 'three';\n\nconst playerMesh = ref<THREE.Mesh | null>(null);\n\nuseDevtoolEntity(playerMesh, {\n  name: 'Player',\n  module: 'game/entities',\n  metadata: { health: 100, level: 5 },\n  tags: ['player', 'controllable'],\n});\n\nonMounted(() => {\n  playerMesh.value = new THREE.Mesh(\n    new THREE.BoxGeometry(),\n    new THREE.MeshStandardMaterial({ color: 'blue' })\n  );\n});\n</script>\n```\n\n## Provide/Inject\n\nFor more control, use `createThreeLens` with Vue's provide/inject:\n\n```vue\n<script setup>\nimport { provide } from 'vue';\nimport { createThreeLens, ThreeLensKey } from '@3lens/vue-bridge';\n\nconst threeLens = createThreeLens({ appName: 'My App' });\nprovide(ThreeLensKey, threeLens);\n</script>\n```\n\nChild components can then use any of the composables.\n\n## TypeScript\n\nAll exports are fully typed:\n\n```typescript\nimport type {\n  ThreeLensContext,\n  ThreeLensPluginConfig,\n  EntityOptions,\n  MetricValue,\n  UseMetricOptions,\n  FrameStats,\n  SceneSnapshot,\n  SceneNode,\n} from '@3lens/vue-bridge';\n```\n\n## License\n\nMIT\n\n","readmeFilename":"README.md"}