@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 +101 -129
- package/bin/cli.js +2 -3
- package/install.js +69 -0
- package/package.json +32 -5
- package/backend/target/release/fuzzy-img-viewer-backend +0 -0
- package/backend/target/release/fuzzy-img-viewer-backend.d +0 -1
package/README.md
CHANGED
|
@@ -1,71 +1,31 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Fuzzy Image Viewer
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
- **
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
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
|
-
- **
|
|
14
|
-
- **
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
49
|
+
## Architecture
|
|
90
50
|
|
|
91
|
-
|
|
51
|
+
This package uses platform-specific binaries for cross-platform compatibility:
|
|
92
52
|
|
|
93
|
-
- **
|
|
94
|
-
- **
|
|
95
|
-
- **
|
|
96
|
-
- **
|
|
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
|
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
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
|
-
##
|
|
65
|
+
## Development
|
|
105
66
|
|
|
106
|
-
###
|
|
67
|
+
### Prerequisites
|
|
107
68
|
|
|
108
|
-
- **
|
|
109
|
-
- **
|
|
110
|
-
- **
|
|
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
|
-
|
|
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
|
-
|
|
75
|
+
```bash
|
|
76
|
+
cd app
|
|
77
|
+
npm install
|
|
78
|
+
```
|
|
119
79
|
|
|
120
|
-
|
|
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
|
-
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
90
|
+
Visit http://localhost:5173 (frontend dev server with hot reload)
|
|
136
91
|
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
npm run dev # Hot reload enabled
|
|
140
|
-
```
|
|
92
|
+
### Building
|
|
141
93
|
|
|
142
|
-
**Backend** (Rust):
|
|
143
94
|
```bash
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
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
|
-
|
|
108
|
+
### Testing Locally
|
|
151
109
|
|
|
152
110
|
```bash
|
|
153
|
-
#
|
|
154
|
-
|
|
111
|
+
# Test the install process
|
|
112
|
+
./scripts/test-install.sh
|
|
155
113
|
|
|
156
|
-
#
|
|
157
|
-
|
|
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
|
-
|
|
161
|
-
- **Frontend**: Optimized static files in `dist/`
|
|
162
|
-
- **Backend**: Release binary in `backend/target/release/aquaeye-viz-backend`
|
|
121
|
+
## Publishing
|
|
163
122
|
|
|
164
|
-
|
|
123
|
+
See [PUBLISHING.md](./PUBLISHING.md) for detailed publishing instructions.
|
|
165
124
|
|
|
166
|
-
###
|
|
125
|
+
### Quick Publish Workflow
|
|
167
126
|
|
|
168
127
|
```bash
|
|
169
|
-
#
|
|
170
|
-
|
|
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
|
-
#
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
179
|
-
- Compiled Rust binary
|
|
180
|
-
- Built frontend (dist/)
|
|
181
|
-
- CLI wrapper (bin/cli.js)
|
|
148
|
+
## Performance
|
|
182
149
|
|
|
183
|
-
|
|
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
|
-
|
|
156
|
+
## Troubleshooting
|
|
186
157
|
|
|
187
|
-
|
|
188
|
-
# macOS (Intel)
|
|
189
|
-
cargo build --release --target x86_64-apple-darwin
|
|
158
|
+
### Binary not found error
|
|
190
159
|
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
195
|
-
cargo build --release --target x86_64-unknown-linux-gnu
|
|
165
|
+
### Cross-compilation issues
|
|
196
166
|
|
|
197
|
-
|
|
198
|
-
|
|
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 (
|
|
17
|
-
const
|
|
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.
|
|
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
|
-
"
|
|
13
|
+
"bin/cli.js",
|
|
14
|
+
"install.js"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
17
|
"dev": "vite",
|
|
18
|
-
"build": "npm run build:frontend
|
|
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",
|
|
Binary file
|
|
@@ -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
|