@vmasrani/fuzzy-img-viewer 0.1.1 → 0.1.2

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.
package/README.md CHANGED
@@ -1,71 +1,31 @@
1
- # AquaEye Viz - Web App
1
+ # Fuzzy Image Viewer
2
2
 
3
- A high-performance image browser with fzf-like fuzzy search, virtualized grid rendering, and keyboard-first navigation. Now accessible through your browser!
3
+ High-performance image browser with fuzzy search and virtualized grid rendering. Accessible through your browser with a single command.
4
4
 
5
5
  ## Features
6
6
 
7
- - **fzf-like Search**: Instant, incremental fuzzy search with match highlighting
8
- - **Virtualized Grid**: Smoothly browse thousands of images with TanStack Virtual
9
- - **Keyboard Navigation**: Full keyboard control for fast workflow
10
- - **Smart Thumbnail Caching**: Fast thumbnail generation with SHA2-based caching
11
- - **Filename Parsing**: Automatic extraction of metadata from filenames (dates, subjects, series, frame numbers)
7
+ - **Fuzzy Search**: Lightning-fast fuzzy search across all images using fuzzysort with match highlighting
8
+ - **Recursive Scanning**: Automatically scans subdirectories for images (configurable depth)
9
+ - **Virtual Scrolling**: Smooth performance with thousands of images using TanStack Virtual
10
+ - **Thumbnail Generation**: Automatic thumbnail caching with SHA2-based hashing for fast loading
11
+ - **Multi-format Support**: PNG, JPG, JPEG, WebP, GIF
12
12
  - **Multi-view Modes**: Grid, Detail (with zoom/pan), and Compare modes
13
- - **Multi-selection**: Select multiple images for comparison
14
- - **Browser-based**: Access through Chrome/Firefox - no desktop environment needed!
13
+ - **Keyboard-first Navigation**: Full keyboard control for fast workflow
14
+ - **Cross-platform**: Works on macOS (Intel/ARM), Linux (x64/ARM64), and Windows
15
15
 
16
- ## Architecture
17
-
18
- - **Frontend**: React + Vite → builds to static files
19
- - **Backend**: Rust + Axum web server → serves both API and static frontend
20
- - **Communication**: REST API
21
- - **Distribution**: Single Rust binary + static files, packaged via npm
22
-
23
- ## Quick Start
24
-
25
- ### Production Use (via npm package)
16
+ ## Installation
26
17
 
27
18
  ```bash
28
- # Install the package (when published)
29
- npm install -g aquaeye-viz
30
-
31
- # Run it
32
- aquaeye-viz /path/to/images
19
+ npm install -g @vmasrani/fuzzy-img-viewer
33
20
  ```
34
21
 
35
- Then open **http://localhost:3000** in your browser.
36
-
37
- ### Development
38
-
39
- **Prerequisites:**
40
- - **Rust** (1.70+): `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`
41
- - **Node.js** (20+): `nvm install 20` or download from [nodejs.org](https://nodejs.org)
42
-
43
- **Setup:**
44
- ```bash
45
- # Install dependencies
46
- npm install
47
- ```
22
+ ## Usage
48
23
 
49
- **Run development servers:**
50
24
  ```bash
51
- # Option 1: Using the start script (runs both backend and frontend)
52
- ./start.sh /path/to/images
53
-
54
- # Option 2: Manual start
55
- # Terminal 1 - Backend:
56
- cd backend && cargo run -- /path/to/images
57
-
58
- # Terminal 2 - Frontend:
59
- npm run dev
25
+ fuzzy-img-viewer /path/to/your/images
60
26
  ```
61
27
 
62
- Development mode runs frontend on **http://localhost:5173** with hot reload.
63
-
64
- ## Usage
65
-
66
- 1. Click "Select Folder" button
67
- 2. Enter the **full path** to a folder containing images (e.g., `/home/user/Pictures`)
68
- 3. Use keyboard shortcuts to navigate
28
+ The viewer will start a local web server and automatically open in your browser at http://localhost:3000
69
29
 
70
30
  ### Keyboard Shortcuts
71
31
 
@@ -86,116 +46,128 @@ Development mode runs frontend on **http://localhost:5173** with hot reload.
86
46
  2. **Detail View**: View full-resolution image with zoom/pan (mouse wheel to zoom, drag to pan)
87
47
  3. **Compare View**: View multiple selected images side-by-side
88
48
 
89
- ### Filename Parsing
49
+ ## Architecture
90
50
 
91
- The app automatically parses filenames to extract metadata:
51
+ This package uses platform-specific binaries for cross-platform compatibility:
92
52
 
93
- - **Date**: ISO format at start (e.g., `2025-07-23-...`)
94
- - **Subject**: Identified keywords (e.g., `sasamat`, `lake`)
95
- - **Series**: Patterns like `delta3`, `series-01`
96
- - **Numbers**: Extracted as `a`, `b`, `frame` values for filtering
53
+ - **Frontend**: React + Vite static files served by the backend
54
+ - **Backend**: Rust + Axum web server → REST API + static file serving
55
+ - **Distribution**: Main npm package + platform-specific binary packages
56
+ - **Installation**: Automatically selects and copies the correct binary for your platform
97
57
 
98
- Example: `2025-07-23-sasamat-delta3-0028.png`
99
- - Date: 2025-07-23
100
- - Subject: sasamat
101
- - Series: delta3
102
- - Frame: 0028
58
+ Platform packages:
59
+ - `@vmasrani/fuzzy-img-viewer-darwin-arm64` (macOS Apple Silicon)
60
+ - `@vmasrani/fuzzy-img-viewer-darwin-x64` (macOS Intel)
61
+ - `@vmasrani/fuzzy-img-viewer-linux-x64` (Linux x64)
62
+ - `@vmasrani/fuzzy-img-viewer-linux-arm64` (Linux ARM64)
63
+ - `@vmasrani/fuzzy-img-viewer-win32-x64` (Windows x64)
103
64
 
104
- ## Architecture Details
65
+ ## Development
105
66
 
106
- ### Backend (Rust/Axum)
67
+ ### Prerequisites
107
68
 
108
- - **backend/src/parser.rs**: Filename parsing and metadata extraction
109
- - **backend/src/thumbnail.rs**: Thumbnail generation and caching with SHA2 hashing
110
- - **backend/src/main.rs**: Axum web server with REST API endpoints
69
+ - **Node.js** 18+
70
+ - **Rust** 1.70+: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`
71
+ - (Optional) **cross**: `cargo install cross` for cross-compilation
111
72
 
112
- **API Endpoints:**
113
- - `POST /api/scan` - Scan folder for images
114
- - `POST /api/thumbnails` - Generate thumbnails
115
- - `GET /api/image/*path` - Serve image by path
116
- - `GET /api/folders?path=...` - List folders
73
+ ### Setup
117
74
 
118
- ### Frontend (React)
75
+ ```bash
76
+ cd app
77
+ npm install
78
+ ```
119
79
 
120
- - **src/store.ts**: Zustand state management
121
- - **src/search.ts**: Fuzzy search implementation
122
- - **src/commands.ts**: HTTP API client
123
- - **src/components/Grid.tsx**: Virtualized grid with TanStack Virtual
124
- - **src/components/Viewer.tsx**: Detail view with zoom/pan
125
- - **src/components/Compare.tsx**: Multi-image comparison
80
+ ### Development Mode
126
81
 
127
- ## Performance
82
+ ```bash
83
+ # Terminal 1: Start backend with a folder path
84
+ cargo run --manifest-path=backend/Cargo.toml -- /path/to/images
128
85
 
129
- - Thumbnails are generated lazily (only for visible items)
130
- - Thumbnails are cached using SHA256(path + mtime + size) as key
131
- - Grid virtualization ensures smooth scrolling with 10k+ images
132
- - Search is debounced and optimized for large datasets
133
- - Parallel thumbnail generation with rayon
86
+ # Terminal 2: Start frontend dev server
87
+ npm run dev
88
+ ```
134
89
 
135
- ## Development
90
+ Visit http://localhost:5173 (frontend dev server with hot reload)
136
91
 
137
- **Frontend** (React + TypeScript):
138
- ```bash
139
- npm run dev # Hot reload enabled
140
- ```
92
+ ### Building
141
93
 
142
- **Backend** (Rust):
143
94
  ```bash
144
- cd backend
145
- cargo run # Auto-recompile with cargo watch
146
- ```
95
+ # Build frontend only
96
+ npm run build
97
+
98
+ # Build for your current platform
99
+ cd backend && cargo build --release
147
100
 
148
- ## Building for Distribution
101
+ # Build for all platforms (requires cross-compilation setup)
102
+ ./scripts/build-binaries.sh
103
+
104
+ # Build just for Linux (most common for deployment)
105
+ ./scripts/build-linux.sh
106
+ ```
149
107
 
150
- Build both frontend and backend for production:
108
+ ### Testing Locally
151
109
 
152
110
  ```bash
153
- # Build everything
154
- npm run build
111
+ # Test the install process
112
+ ./scripts/test-install.sh
155
113
 
156
- # Or use the build script
157
- ./scripts/build-all.sh
114
+ # Test with a local package
115
+ npm run build
116
+ npm pack
117
+ npm install -g vmasrani-fuzzy-img-viewer-0.1.1.tgz
118
+ fuzzy-img-viewer /path/to/images
158
119
  ```
159
120
 
160
- This creates:
161
- - **Frontend**: Optimized static files in `dist/`
162
- - **Backend**: Release binary in `backend/target/release/aquaeye-viz-backend`
121
+ ## Publishing
163
122
 
164
- The backend automatically serves the static frontend files when running in production.
123
+ See [PUBLISHING.md](./PUBLISHING.md) for detailed publishing instructions.
165
124
 
166
- ### Package for npm
125
+ ### Quick Publish Workflow
167
126
 
168
127
  ```bash
169
- # Create npm package
170
- npm pack
128
+ # 1. Bump version across all packages
129
+ ./scripts/bump-version.sh 0.1.2
130
+
131
+ # 2. Commit version bump
132
+ git add -A && git commit -m "Bump version to 0.1.2"
133
+
134
+ # 3. Build Linux binary (most important for servers)
135
+ ./scripts/build-linux.sh
136
+
137
+ # 4. Copy your macOS binary
138
+ cp backend/target/release/fuzzy-img-viewer-backend npm/darwin-arm64/
171
139
 
172
- # This creates: aquaeye-viz-0.1.0.tgz
173
- # Install locally to test:
174
- npm install -g ./aquaeye-viz-0.1.0.tgz
175
- aquaeye-viz /path/to/images
140
+ # 5. Build frontend
141
+ npm run build
142
+
143
+ # 6. Publish all packages
144
+ npm login
145
+ ./scripts/publish-all.sh
176
146
  ```
177
147
 
178
- The package includes:
179
- - Compiled Rust binary
180
- - Built frontend (dist/)
181
- - CLI wrapper (bin/cli.js)
148
+ ## Performance
182
149
 
183
- ### Cross-platform Builds
150
+ - Thumbnails are generated lazily (only for visible items)
151
+ - Thumbnails are cached using SHA256(path + mtime + size) as key
152
+ - Grid virtualization ensures smooth scrolling with 10k+ images
153
+ - Parallel thumbnail generation with rayon
154
+ - Fuzzy search optimized with fuzzysort prepared keys
184
155
 
185
- For distributing to different platforms, build the Rust binary on each target platform:
156
+ ## Troubleshooting
186
157
 
187
- ```bash
188
- # macOS (Intel)
189
- cargo build --release --target x86_64-apple-darwin
158
+ ### Binary not found error
190
159
 
191
- # macOS (Apple Silicon)
192
- cargo build --release --target aarch64-apple-darwin
160
+ If you see "Backend binary not found" after installation, this usually means:
161
+ 1. Your platform isn't supported (check `node -p "process.platform + '-' + process.arch"`)
162
+ 2. The platform package failed to install (check npm logs)
163
+ 3. The postinstall script failed (try running `node install.js` manually)
193
164
 
194
- # Linux
195
- cargo build --release --target x86_64-unknown-linux-gnu
165
+ ### Cross-compilation issues
196
166
 
197
- # Windows
198
- cargo build --release --target x86_64-pc-windows-msvc
167
+ For Linux builds on macOS, use `cross`:
168
+ ```bash
169
+ cargo install cross
170
+ ./scripts/build-linux.sh
199
171
  ```
200
172
 
201
173
  ## License
package/bin/cli.js CHANGED
@@ -13,9 +13,8 @@ const __dirname = dirname(__filename);
13
13
  const isWindows = platform() === 'win32';
14
14
  const binaryName = isWindows ? 'fuzzy-img-viewer-backend.exe' : 'fuzzy-img-viewer-backend';
15
15
 
16
- // Find the binary path (relative to package root)
17
- const packageRoot = join(__dirname, '..');
18
- const binaryPath = join(packageRoot, 'backend', 'target', 'release', binaryName);
16
+ // Find the binary path (installed by postinstall script from platform package)
17
+ const binaryPath = join(__dirname, binaryName);
19
18
 
20
19
  // Check if binary exists
21
20
  if (!existsSync(binaryPath)) {
package/install.js ADDED
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { platform, arch } from 'os';
4
+ import { existsSync, mkdirSync, copyFileSync } from 'fs';
5
+ import { dirname, join } from 'path';
6
+ import { fileURLToPath } from 'url';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+
11
+ // Determine the platform-specific package name
12
+ const PLATFORM = platform();
13
+ const ARCH = arch();
14
+
15
+ // Map Node's arch to our package names
16
+ const ARCH_MAP = {
17
+ 'x64': 'x64',
18
+ 'arm64': 'arm64',
19
+ 'aarch64': 'arm64'
20
+ };
21
+
22
+ const mappedArch = ARCH_MAP[ARCH] || ARCH;
23
+ const packageName = `@vmasrani/fuzzy-img-viewer-${PLATFORM}-${mappedArch}`;
24
+
25
+ console.log(`📦 Installing fuzzy-img-viewer for ${PLATFORM}-${mappedArch}`);
26
+
27
+ // Try to find the platform-specific package
28
+ let binarySource;
29
+ try {
30
+ // The platform package will be in node_modules as an optional dependency
31
+ const platformPkg = `./node_modules/${packageName}`;
32
+ const binaryName = PLATFORM === 'win32' ? 'fuzzy-img-viewer-backend.exe' : 'fuzzy-img-viewer-backend';
33
+ binarySource = join(__dirname, platformPkg, binaryName);
34
+
35
+ if (!existsSync(binarySource)) {
36
+ console.error(`❌ Platform binary not found at: ${binarySource}`);
37
+ console.error(` This usually means the platform package ${packageName} is not installed.`);
38
+ console.error(` Supported platforms: darwin-arm64, darwin-x64, linux-x64, linux-arm64, win32-x64`);
39
+ process.exit(1);
40
+ }
41
+ } catch (err) {
42
+ console.error(`❌ Failed to locate platform binary: ${err.message}`);
43
+ process.exit(1);
44
+ }
45
+
46
+ // Create bin directory if it doesn't exist
47
+ const binDir = join(__dirname, 'bin');
48
+ if (!existsSync(binDir)) {
49
+ mkdirSync(binDir, { recursive: true });
50
+ }
51
+
52
+ // Copy the binary to the bin directory
53
+ const binaryName = PLATFORM === 'win32' ? 'fuzzy-img-viewer-backend.exe' : 'fuzzy-img-viewer-backend';
54
+ const binaryDest = join(binDir, binaryName);
55
+
56
+ try {
57
+ copyFileSync(binarySource, binaryDest);
58
+
59
+ // Make executable on Unix
60
+ if (PLATFORM !== 'win32') {
61
+ const { chmodSync } = await import('fs');
62
+ chmodSync(binaryDest, 0o755);
63
+ }
64
+
65
+ console.log(`✅ Binary installed successfully to ${binaryDest}`);
66
+ } catch (err) {
67
+ console.error(`❌ Failed to install binary: ${err.message}`);
68
+ process.exit(1);
69
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vmasrani/fuzzy-img-viewer",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "High-performance image browser with fuzzy search and virtualized grid rendering",
5
5
  "author": "vmasrani",
6
6
  "license": "MIT",
@@ -10,15 +10,15 @@
10
10
  },
11
11
  "files": [
12
12
  "dist",
13
- "bin",
14
- "backend/target/release/fuzzy-img-viewer-backend*"
13
+ "bin/cli.js",
14
+ "install.js"
15
15
  ],
16
16
  "scripts": {
17
17
  "dev": "vite",
18
- "build": "npm run build:frontend && npm run build:backend",
18
+ "build": "npm run build:frontend",
19
19
  "build:frontend": "tsc && vite build",
20
- "build:backend": "cd backend && cargo build --release",
21
20
  "preview": "vite preview",
21
+ "postinstall": "node install.js",
22
22
  "package": "npm run build && npm pack",
23
23
  "prepublishOnly": "npm run build"
24
24
  },
@@ -29,6 +29,33 @@
29
29
  "react-dom": "^18.3.1",
30
30
  "zustand": "^4.5.5"
31
31
  },
32
+ "optionalDependencies": {
33
+ "@vmasrani/fuzzy-img-viewer-darwin-arm64": "0.1.2",
34
+ "@vmasrani/fuzzy-img-viewer-darwin-x64": "0.1.2",
35
+ "@vmasrani/fuzzy-img-viewer-linux-x64": "0.1.2",
36
+ "@vmasrani/fuzzy-img-viewer-linux-arm64": "0.1.2",
37
+ "@vmasrani/fuzzy-img-viewer-win32-x64": "0.1.2",
38
+ "@vmasrani/fuzzy-img-viewer-darwin-arm64": "0.1.2",
39
+ "@vmasrani/fuzzy-img-viewer-darwin-x64": "0.1.2",
40
+ "@vmasrani/fuzzy-img-viewer-linux-x64": "0.1.2",
41
+ "@vmasrani/fuzzy-img-viewer-linux-arm64": "0.1.2",
42
+ "@vmasrani/fuzzy-img-viewer-win32-x64": "0.1.2",
43
+ "@vmasrani/fuzzy-img-viewer-darwin-arm64": "0.1.2",
44
+ "@vmasrani/fuzzy-img-viewer-darwin-x64": "0.1.2",
45
+ "@vmasrani/fuzzy-img-viewer-linux-x64": "0.1.2",
46
+ "@vmasrani/fuzzy-img-viewer-linux-arm64": "0.1.2",
47
+ "@vmasrani/fuzzy-img-viewer-win32-x64": "0.1.2",
48
+ "@vmasrani/fuzzy-img-viewer-darwin-arm64": "0.1.2",
49
+ "@vmasrani/fuzzy-img-viewer-darwin-x64": "0.1.2",
50
+ "@vmasrani/fuzzy-img-viewer-linux-x64": "0.1.2",
51
+ "@vmasrani/fuzzy-img-viewer-linux-arm64": "0.1.2",
52
+ "@vmasrani/fuzzy-img-viewer-win32-x64": "0.1.2",
53
+ "@vmasrani/fuzzy-img-viewer-darwin-arm64": "0.1.2",
54
+ "@vmasrani/fuzzy-img-viewer-darwin-x64": "0.1.2",
55
+ "@vmasrani/fuzzy-img-viewer-linux-x64": "0.1.2",
56
+ "@vmasrani/fuzzy-img-viewer-linux-arm64": "0.1.2",
57
+ "@vmasrani/fuzzy-img-viewer-win32-x64": "0.1.2"
58
+ },
32
59
  "devDependencies": {
33
60
  "@types/react": "^18.3.12",
34
61
  "@types/react-dom": "^18.3.1",
@@ -1 +0,0 @@
1
- /Users/vmasrani/dev/projects/rust-img-viewer/app/backend/target/release/fuzzy-img-viewer-backend: /Users/vmasrani/dev/projects/rust-img-viewer/app/backend/src/main.rs /Users/vmasrani/dev/projects/rust-img-viewer/app/backend/src/parser.rs /Users/vmasrani/dev/projects/rust-img-viewer/app/backend/src/thumbnail.rs