This guide provides information for developers working on Vectorizer Sync, including setup instructions, development workflow, and coding standards.
- Node.js: Version 20.x or later
- npm or pnpm: Package manager
- Git: Version control
- TypeScript: Version 5.x or later
- Visual Studio Build Tools (for native modules)
- Windows SDK
- Xcode Command Line Tools
- macOS 10.15 or later
- Build essentials (gcc, make, etc.)
- libnss3-dev (for Electron)
git clone <repository-url>
cd vectorizer-syncnpm install
# or
pnpm installCreate .env file (optional, for development):
NODE_ENV=development
LOG_LEVEL=debug
DB_PATH=./dev-database.dbvectorizer-sync/
├── src/
│ ├── main/ # Electron main process
│ │ ├── index.ts # Main entry point
│ │ ├── database/ # Database management
│ │ ├── sync/ # Sync engine
│ │ ├── watcher/ # File system watcher
│ │ └── api/ # HiveHub API client
│ ├── renderer/ # Electron renderer process (React)
│ │ ├── components/ # React components
│ │ ├── pages/ # Page components
│ │ ├── hooks/ # React hooks
│ │ ├── store/ # State management
│ │ └── utils/ # Utility functions
│ └── shared/ # Shared code between main and renderer
│ ├── types/ # TypeScript types
│ └── constants/ # Constants
├── tests/ # Test files
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ └── e2e/ # End-to-end tests
├── docs/ # Documentation
├── scripts/ # Build and utility scripts
├── public/ # Static assets
└── package.json
npm run devThis will:
- Start Electron in development mode
- Enable hot reload for renderer process
- Open DevTools automatically
- Watch for file changes
# Build for current platform
npm run build
# Build for specific platform
npm run build:win
npm run build:mac
npm run build:linux
# Build for all platforms
npm run build:all# Run all tests
npm test
# Run unit tests only
npm run test:unit
# Run integration tests
npm run test:integration
# Run E2E tests
npm run test:e2e
# Run tests with coverage
npm run test:coverage# Run linter
npm run lint
# Fix linting issues
npm run lint:fixnpm run type-check- Use strict mode
- Prefer interfaces over types for object shapes
- Use
constassertions where appropriate - Avoid
anytype (useunknownif needed) - Use async/await instead of promises
- Handle errors explicitly
- Use 2 spaces for indentation
- Use single quotes for strings
- Use trailing commas
- Maximum line length: 100 characters
- Use meaningful variable and function names
- Components: PascalCase (e.g.,
ProjectList.tsx) - Utilities: camelCase (e.g.,
fileUtils.ts) - Types: PascalCase (e.g.,
Project.ts) - Constants: UPPER_SNAKE_CASE (e.g.,
MAX_FILE_SIZE.ts)
// Component structure
import React from 'react';
import { Project } from '../types';
interface ProjectListProps {
projects: Project[];
onSelect: (project: Project) => void;
}
export const ProjectList: React.FC<ProjectListProps> = ({ projects, onSelect }) => {
// Component logic
return (
<div>
{/* JSX */}
</div>
);
};// Always handle errors explicitly
try {
await someAsyncOperation();
} catch (error) {
if (error instanceof Error) {
console.error('Operation failed:', error.message);
// Handle error appropriately
}
}The database is automatically created on first run. For development:
import Database from 'better-sqlite3';
const db = new Database('./dev-database.db');
// Initialize schemanpm run db:migratenpm run db:resetWarning: This will delete all data!
// main/index.ts
import { BrowserWindow } from 'electron';
const window = BrowserWindow.getFocusedWindow();
window?.webContents.send('event-name', data);// renderer/components/MyComponent.tsx
import { ipcRenderer } from 'electron';
const result = await ipcRenderer.invoke('action-name', data);// main/ipc/handlers.ts
import { ipcMain } from 'electron';
ipcMain.handle('action-name', async (event, data) => {
// Handle action
return result;
});import { readFile } from 'fs/promises';
import { join } from 'path';
const content = await readFile(join(projectPath, 'file.txt'), 'utf-8');import chokidar from 'chokidar';
const watcher = chokidar.watch(projectPath, {
ignored: /node_modules/,
persistent: true
});
watcher.on('change', (path) => {
// Handle file change
});// tests/unit/fileUtils.test.ts
import { describe, it, expect } from 'vitest';
import { isFileExcluded } from '../../src/shared/utils/fileUtils';
describe('fileUtils', () => {
it('should exclude node_modules', () => {
expect(isFileExcluded('node_modules/file.js')).toBe(true);
});
});// tests/integration/database.test.ts
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import Database from 'better-sqlite3';
describe('Database', () => {
let db: Database.Database;
beforeAll(() => {
db = new Database(':memory:');
// Initialize schema
});
afterAll(() => {
db.close();
});
it('should create project', () => {
// Test database operations
});
});// tests/e2e/sync.test.ts
import { test, expect } from '@playwright/test';
test('should sync files', async ({ page }) => {
await page.goto('http://localhost:3000');
// Test user interactions
});Add breakpoints in VS Code or use:
debugger; // BreakpointUse Chrome DevTools (automatically opened in dev mode).
// Enable verbose logging
const db = new Database('./database.db', {
verbose: console.log
});- Use prepared statements
- Use transactions for batch operations
- Create appropriate indexes
- Limit result sets
- Batch file operations
- Use streaming for large files
- Cache file metadata
- Debounce file watcher events
- Use React.memo for expensive components
- Use useMemo and useCallback appropriately
- Avoid unnecessary re-renders
- Code split large components
Configuration in package.json:
{
"build": {
"appId": "com.hivellm.vectorizer-sync",
"productName": "Vectorizer Sync",
"directories": {
"output": "dist"
},
"files": [
"dist/**/*",
"package.json"
],
"win": {
"target": "nsis"
},
"mac": {
"target": "dmg"
},
"linux": {
"target": "AppImage"
}
}
}For production builds, configure code signing:
- Windows: Configure in
winsection - macOS: Configure in
macsection - Linux: Not required
- Update version in
package.json - Update
CHANGELOG.md - Run tests:
npm test - Build:
npm run build:all - Create git tag:
git tag v1.0.0 - Push tag:
git push --tags
Solution: Ensure only one instance accesses the database at a time.
Solution: Install platform-specific build tools.
Solution: Check main/index.ts for DevTools configuration.
Solution: Check file permissions and watcher configuration.