From 982cfd78ae05053a27feb927105ee43ff018cd56 Mon Sep 17 00:00:00 2001 From: vim-sroberge Date: Tue, 11 Aug 2026 10:07:05 -0400 Subject: [PATCH 1/5] Ship three as a peer dependency and drop the IIFE build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit three was a hard dependency inlined into the bundle (~1.8 MB), so any host app that already used three ended up with two three instances in one page — breaking instanceof across the boundary, duplicating module-level state, and double-shipping the payload. Because vim-web re-exports THREE (VIM.THREE), this also meant VIM.THREE !== the host's THREE. - vite.config.js: externalize three (and three/* subpaths); emit ESM only. The IIFE build is dropped — it can't cleanly externalize three (the three/examples/jsm/* passes have no UMD global), nothing documents or uses the script-tag path, and the package's exports map already routes modern consumers to ESM. - package.json: move three + @types/three from dependencies to devDependencies, add three to peerDependencies at the tested range (^0.183.2), point main at the ESM bundle, bump to 1.0.0-beta.3. - README.md: document the peer dependencies and that only the pinned three version is tested (others may work). ESM bundle drops from 3.43 MB to 1.57 MB (-54%). Build verified: three is no longer inlined (no __THREE__ detector, no node_modules/three/build region); it is imported as an external instead. Co-Authored-By: Claude Opus 4.8 --- README.md | 18 +++++++++++++++--- package.json | 11 ++++++----- vite.config.js | 17 +++++------------ 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 70ae99c9..66218350 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ npm run documentation # TypeDoc generation `npm run build` runs three steps in sequence: -1. **Vite build** — bundles `vim-web.js` (ESM) and `vim-web.iife.js` (IIFE) into `dist/` +1. **Vite build** — bundles `vim-web.js` (ESM) into `dist/` 2. **TypeScript declarations** (`tsc -p tsconfig.types.json`) — emits individual `.d.ts` files to `dist/types/` 3. **Rollup d.ts bundling** — produces two self-contained type bundles: - `dist/vim-web.d.ts` — full library API (3,300+ lines), referenced by `"types"` in package.json @@ -85,9 +85,21 @@ The React viewer exposes customization points for: ## Documentation - **[CLAUDE.md](./CLAUDE.md)** — Detailed API reference, code examples, architecture details, and patterns. This is the primary reference for both developers and AI tools. -- **[.claude/docs/INPUT.md](./.claude/docs/INPUT.md)** — Input system architecture, coordinate systems, override patterns +- **[.claude/docs/input.md](./.claude/docs/input.md)** — Input system architecture, coordinate systems, override patterns - **[.claude/docs/optimization.md](./.claude/docs/optimization.md)** — Loading pipeline performance and profiling -- **[.claude/docs/RENDERING_OPTIMIZATIONS.md](./.claude/docs/RENDERING_OPTIMIZATIONS.md)** — Shader material architecture and rendering patterns +- **[.claude/docs/rendering-optimizations.md](./.claude/docs/rendering-optimizations.md)** — Shader material architecture and rendering patterns + +## Peer Dependencies + +`vim-web` does not bundle `react`, `react-dom`, or `three` — the host application provides them, so a single instance of each is shared across the app. Install them alongside the package: + +```bash +npm install vim-web three react react-dom +``` + +`three` is pinned to the version the library is built and tested against (currently `^0.183`). **Only the pinned version is officially tested and supported**, but other three.js versions may work just as well — the public API surface `vim-web` relies on is stable across recent releases. If your app pins a different `three`, override the peer range at your own risk; keeping a single shared copy of three is still preferable to the duplicate-instance problems that come from bundling it. + +TypeScript users should also install `@types/three` matching their `three` version, since three.js does not ship its own type definitions. ## Tech Stack diff --git a/package.json b/package.json index 4d9c16a3..a88b25cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vim-web", - "version": "1.0.0-beta.1", + "version": "1.0.0-beta.3", "description": "WebGL and cloud-streaming 3D viewers for VIM files with BIM support", "type": "module", "files": [ @@ -8,7 +8,7 @@ "!dist/types" ], "readme": "README.md", - "main": "./dist/vim-web.iife.js", + "main": "./dist/vim-web.js", "types": "./dist/vim-web.d.ts", "module": "./dist/vim-web.js", "exports": { @@ -48,10 +48,12 @@ "@types/dom-webcodecs": "^0.1.13", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", + "@types/three": "^0.183.1", "@vitejs/plugin-react": "^6.0.1", "gh-pages": "^6.3.0", "rollup": "^4.60.0", "rollup-plugin-dts": "^6.4.1", + "three": "^0.183.2", "typedoc": "^0.28.18", "typescript": "^6.0.2", "vite": "^8.0.2" @@ -60,18 +62,17 @@ "@headless-tree/core": "^1.6.3", "@headless-tree/react": "^1.6.3", "@tanstack/react-virtual": "^3.13.23", - "@types/three": "^0.183.1", "deepmerge": "^4.3.1", "is-plain-object": "^5.0.0", "stats-js": "^1.0.1", "ste-signals": "^3.0.11", "ste-simple-events": "^3.0.11", - "three": "^0.183.2", "vim-format": "^1.0.16-dev.6" }, "peerDependencies": { "react": "^18.3.1 || ^19.0.0", - "react-dom": "^18.3.1 || ^19.0.0" + "react-dom": "^18.3.1 || ^19.0.0", + "three": "^0.183.2" }, "keywords": [ "3d", diff --git a/vite.config.js b/vite.config.js index 94fe12bb..96635b06 100644 --- a/vite.config.js +++ b/vite.config.js @@ -6,21 +6,14 @@ export default defineConfig({ build: { sourcemap: true, lib: { - formats: ['iife', 'es'], - entry: resolve(__dirname, 'src/vim-web/index.ts'), - name: 'VIMReact' + formats: ['es'], + entry: resolve(__dirname, 'src/vim-web/index.ts') }, rollupOptions: { - external: ['react', 'react-dom', /^react\//, /^react-dom\//], + // react, react-dom and three are peer dependencies provided by the host app, + // never bundled — this keeps a single instance of each in the consuming app. + external: ['react', 'react-dom', /^react\//, /^react-dom\//, 'three', /^three\//], output: { - // Save react and react-dom as globals so they can be provided as external dependencies - globals: { - 'react': 'React', - 'react/jsx-runtime': 'React', - 'react-dom': 'ReactDOM', - 'react-dom/client': 'ReactDOM' - }, - // Keep style.css name assetFileNames: (assetInfo) => { if (assetInfo.names[0] === 'vim-web.css') { From 9cbe6b53ef473d395371eb0997aa198eb2363df3 Mon Sep 17 00:00:00 2001 From: vim-sroberge Date: Tue, 11 Aug 2026 10:35:13 -0400 Subject: [PATCH 2/5] Normalize AI docs/skills filename casing Establish one rule: uppercase for tooling-required entry points (CLAUDE.md, README.md, SKILL.md), lowercase kebab-case for everything in .claude/docs. Fixes two skills that used lowercase skill.md (the skill loader looks for SKILL.md and would miss them on case-sensitive systems) and normalizes the screaming-caps doc names. - .claude/skills/{auto-refactor,css}/skill.md -> SKILL.md - .claude/docs/INPUT.md -> input.md, RENDERING_OPTIMIZATIONS.md -> rendering-optimizations.md - CLAUDE.md: repoint doc links (also fixes two that were missing the docs/ segment) - rendering-optimizations.md: fix inter-doc link - input handlers: update "See INPUT.md" comments to the resolvable path Co-Authored-By: Claude Opus 4.8 --- .claude/docs/{INPUT.md => input.md} | 0 ...DERING_OPTIMIZATIONS.md => rendering-optimizations.md} | 2 +- .claude/skills/auto-refactor/{skill.md => SKILL.md} | 0 .claude/skills/css/{skill.md => SKILL.md} | 0 CLAUDE.md | 8 ++++---- src/vim-web/core-viewers/shared/input/inputHandler.ts | 4 ++-- src/vim-web/core-viewers/shared/input/mouseHandler.ts | 2 +- src/vim-web/core-viewers/shared/input/touchHandler.ts | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) rename .claude/docs/{INPUT.md => input.md} (100%) rename .claude/docs/{RENDERING_OPTIMIZATIONS.md => rendering-optimizations.md} (99%) rename .claude/skills/auto-refactor/{skill.md => SKILL.md} (100%) rename .claude/skills/css/{skill.md => SKILL.md} (100%) diff --git a/.claude/docs/INPUT.md b/.claude/docs/input.md similarity index 100% rename from .claude/docs/INPUT.md rename to .claude/docs/input.md diff --git a/.claude/docs/RENDERING_OPTIMIZATIONS.md b/.claude/docs/rendering-optimizations.md similarity index 99% rename from .claude/docs/RENDERING_OPTIMIZATIONS.md rename to .claude/docs/rendering-optimizations.md index f1a82156..9699814b 100644 --- a/.claude/docs/RENDERING_OPTIMIZATIONS.md +++ b/.claude/docs/rendering-optimizations.md @@ -199,5 +199,5 @@ All custom shader materials use `glslVersion: THREE.GLSL3`. The StandardMaterial ### Related Documentation - [CLAUDE.md](../../CLAUDE.md) - Main project documentation -- [INPUT.md](./INPUT.md) - Input system architecture +- [input.md](./input.md) - Input system architecture - [optimization.md](./optimization.md) - Loading pipeline performance diff --git a/.claude/skills/auto-refactor/skill.md b/.claude/skills/auto-refactor/SKILL.md similarity index 100% rename from .claude/skills/auto-refactor/skill.md rename to .claude/skills/auto-refactor/SKILL.md diff --git a/.claude/skills/css/skill.md b/.claude/skills/css/SKILL.md similarity index 100% rename from .claude/skills/css/skill.md rename to .claude/skills/css/SKILL.md diff --git a/CLAUDE.md b/CLAUDE.md index a9cf758d..cdafb8f5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -274,7 +274,7 @@ state.useMemo((v) => compute(v)) ## Input System -> **📖 Full Documentation**: See [INPUT.md](./.claude/docs/INPUT.md) for architecture, patterns, and advanced customization +> **📖 Full Documentation**: See [.claude/docs/input.md](./.claude/docs/input.md) for architecture, patterns, and advanced customization ### Default Bindings @@ -335,7 +335,7 @@ viewer.core.inputs.mouse.onClick = (pos) => { /* custom logic */ } // Restore: viewer.core.inputs.pointerMode = originalMode ``` -See [INPUT.md](./.claude/docs/INPUT.md) for more patterns, coordinate systems, performance optimization, and debugging techniques +See [.claude/docs/input.md](./.claude/docs/input.md) for more patterns, coordinate systems, performance optimization, and debugging techniques --- @@ -566,7 +566,7 @@ npm run documentation # TypeDoc ### Loading Pipeline (WebGL) -> **📖 Loading Optimization**: See [.claude/optimization.md](./.claude/docs/optimization.md) for geometry building performance, lazy Element3D creation, and profiling techniques +> **📖 Loading Optimization**: See [.claude/docs/optimization.md](./.claude/docs/optimization.md) for geometry building performance, lazy Element3D creation, and profiling techniques Full call chain from `viewer.load()` to rendered scene: @@ -607,7 +607,7 @@ await vim.load(sub) ### Rendering Pipeline (WebGL) -> **📖 Optimization Guide**: See [.claude/RENDERING_OPTIMIZATIONS.md](./.claude/docs/RENDERING_OPTIMIZATIONS.md) for shader optimizations, GLSL3 migration, and performance improvements +> **📖 Optimization Guide**: See [.claude/docs/rendering-optimizations.md](./.claude/docs/rendering-optimizations.md) for shader optimizations, GLSL3 migration, and performance improvements Multi-pass compositor: ``` diff --git a/src/vim-web/core-viewers/shared/input/inputHandler.ts b/src/vim-web/core-viewers/shared/input/inputHandler.ts index d7761265..b30d392d 100644 --- a/src/vim-web/core-viewers/shared/input/inputHandler.ts +++ b/src/vim-web/core-viewers/shared/input/inputHandler.ts @@ -1,7 +1,7 @@ /** * Input coordinator that routes device events to viewer-specific adapters. * - * See INPUT.md for architecture, pointer modes, and customization patterns. + * See .claude/docs/input.md for architecture, pointer modes, and customization patterns. */ import type { ISignal } from '../events' @@ -93,7 +93,7 @@ export interface IInputHandler { * Input handler coordinator. * * Manages two-tier pointer modes (active/override). - * See INPUT.md for mode system and customization. + * See .claude/docs/input.md for mode system and customization. * @internal */ export class InputHandler implements IInputHandler { diff --git a/src/vim-web/core-viewers/shared/input/mouseHandler.ts b/src/vim-web/core-viewers/shared/input/mouseHandler.ts index 72448593..e6e941cb 100644 --- a/src/vim-web/core-viewers/shared/input/mouseHandler.ts +++ b/src/vim-web/core-viewers/shared/input/mouseHandler.ts @@ -1,7 +1,7 @@ /** * Mouse and pointer input handler. * - * See INPUT.md for architecture, coordinate systems, and performance patterns. + * See .claude/docs/input.md for architecture, coordinate systems, and performance patterns. */ import { BaseInputHandler } from "./baseInputHandler"; diff --git a/src/vim-web/core-viewers/shared/input/touchHandler.ts b/src/vim-web/core-viewers/shared/input/touchHandler.ts index d85f8aac..0d2506d3 100644 --- a/src/vim-web/core-viewers/shared/input/touchHandler.ts +++ b/src/vim-web/core-viewers/shared/input/touchHandler.ts @@ -1,7 +1,7 @@ /** * Touch input handler with support for tap, pinch, and pan gestures. * - * See INPUT.md for gesture recognition, state management, and performance patterns. + * See .claude/docs/input.md for gesture recognition, state management, and performance patterns. */ import * as THREE from 'three' From e8d80d9a69effe7d797d02381f4f427cc669fb98 Mon Sep 17 00:00:00 2001 From: vim-sroberge Date: Tue, 11 Aug 2026 10:41:28 -0400 Subject: [PATCH 3/5] Document three peer-dependency and IIFE removal in release notes Add RELEASE_NOTES.md section for 1.0.0-beta.3 and a MIGRATION.md section covering the three peer-dependency move and the IIFE build removal, so consumers know to install their own three and switch script-tag usage to ESM. Co-Authored-By: Claude Opus 4.8 --- MIGRATION.md | 27 ++++++++++++++++++++++----- RELEASE_NOTES.md | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index c046998f..8944b9cd 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1,4 +1,4 @@ -# Migration Guide: vim-web 0.5 → 1.0.0-beta.1 +# Migration Guide: vim-web 0.5 → 1.0.0-beta.3 ## Install @@ -185,9 +185,26 @@ All Tailwind utility classes (`vc-flex`, `vc-text-sm`, etc.) have been replaced ## Peer Dependencies -| | 0.5 | 1.0-beta.1 | -|---|---|---| -| react | ^18.3.1 | ^18.3.1 \|\| ^19.0.0 | -| react-dom | ^18.3.1 | ^18.3.1 \|\| ^19.0.0 | +| | 0.5 | 1.0-beta.1 | 1.0-beta.3 | +|---|---|---|---| +| react | ^18.3.1 | ^18.3.1 \|\| ^19.0.0 | ^18.3.1 \|\| ^19.0.0 | +| react-dom | ^18.3.1 | ^18.3.1 \|\| ^19.0.0 | ^18.3.1 \|\| ^19.0.0 | +| three | (bundled) | (bundled) | ^0.183 | React 18.3+ continues to work. React 19 is now also supported. + +### three is now a peer dependency (1.0.0-beta.3) + +Through beta.2, `three` was bundled inside vim-web. As of beta.3 it is a peer dependency the host app must install: + +```bash +npm install three @types/three +``` + +This keeps a single instance of three in your app. Previously an app that already used three ended up with two copies — breaking `instanceof` checks across the boundary (including against `VIM.THREE`), duplicating three's module-level state, and shipping ~1.8 MB twice. + +Only the pinned version (`^0.183`) is tested; other three.js versions may work. If your app pins a different three, override the peer range at your own risk — a single shared copy is still preferable to a bundled duplicate. + +### IIFE build removed (1.0.0-beta.3) + +The `