chore: initial project setup

This commit is contained in:
waaraawa 2025-10-13 09:34:29 +09:00
parent 3cedbcf635
commit 71aaec03bf
14 changed files with 488 additions and 0 deletions

33
.eslintrc.json Normal file
View file

@ -0,0 +1,33 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module",
"project": "./tsconfig.json"
},
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking"
],
"rules": {
"@typescript-eslint/no-unused-vars": [
"error",
{ "argsIgnorePattern": "^_" }
],
"@typescript-eslint/explicit-function-return-type": [
"warn",
{ "allowExpressions": true }
],
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-non-null-assertion": "warn",
"no-console": ["warn", { "allow": ["warn", "error"] }]
},
"env": {
"node": true,
"es6": true
},
"ignorePatterns": ["dist", "node_modules", "*.js"]
}

40
.gitignore vendored Normal file
View file

@ -0,0 +1,40 @@
# Dependencies
node_modules/
package-lock.json
yarn.lock
# Build outputs
dist/
*.tsbuildinfo
# Test coverage
coverage/
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Environment
.env
.env.local
.env.*.local
# Temporary files
*.tmp
.cache/
# Backup files
*.backup

5
.prettierignore Normal file
View file

@ -0,0 +1,5 @@
node_modules
dist
coverage
*.log
.git

10
.prettierrc.json Normal file
View file

@ -0,0 +1,10 @@
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"arrowParens": "always",
"endOfLine": "lf"
}

77
README.md Normal file
View file

@ -0,0 +1,77 @@
# ByteGrid
> Binary data and C struct memory layout visualization for Obsidian
## Overview
**ByteGrid** is an Obsidian plugin that visualizes binary data and C structure memory layouts as interactive SVG diagrams.
## Features
- 🎨 Color-coded field visualization
- 📏 Byte-accurate grid layout
- 🔍 Bitfield support
- 📊 Hex dump integration
- 🎯 Interactive tooltips
- 📤 Multiple export formats (SVG, PNG, C code, Markdown)
## Project Status
🚧 **In Development** - Currently in Phase 1 (MVP)
## Quick Start
```bash
# Install dependencies
npm install
# Build all packages
npm run build
# Run tests
npm run test
# Lint
npm run lint
# Format code
npm run format
```
## Project Structure
```
bytegrid/
├── packages/
│ ├── core/ # Core rendering logic
│ └── obsidian-plugin/ # Obsidian plugin
├── docs/ # Design documentation
└── examples/ # Example files
```
## Documentation
See [CLAUDE.md](./CLAUDE.md) for detailed project guidelines and architecture.
## Development
This project follows **Test-Driven Development (TDD)**:
1. Write tests first
2. Implement minimal code to pass tests
3. Refactor
### Key Principles
- **offset is SSOT** - Field size calculated from offset ranges
- **No magic numbers** - Use constants for all layout values
- **Dynamic height** - SVG dimensions calculated from content
- **Explicit padding** - Use `reserved` or `padding` types
## License
MIT License - see [LICENSE](./LICENSE) for details
## Contributing
Currently in initial development phase. Contribution guidelines will be added soon.

22
jest.config.js Normal file
View file

@ -0,0 +1,22 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/packages'],
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
collectCoverageFrom: [
'packages/*/src/**/*.ts',
'!packages/*/src/**/*.d.ts',
'!packages/*/src/index.ts',
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
moduleNameMapper: {
'^@bytegrid/core$': '<rootDir>/packages/core/src',
},
};

42
package.json Normal file
View file

@ -0,0 +1,42 @@
{
"name": "bytegrid",
"version": "0.1.0",
"description": "Binary data and C struct memory layout visualization for Obsidian",
"private": true,
"workspaces": [
"packages/*"
],
"scripts": {
"build": "npm run build --workspaces",
"test": "npm run test --workspaces",
"lint": "eslint . --ext .ts",
"format": "prettier --write \"**/*.{ts,json,md}\"",
"format:check": "prettier --check \"**/*.{ts,json,md}\"",
"clean": "rm -rf packages/*/dist packages/*/node_modules node_modules"
},
"keywords": [
"obsidian",
"obsidian-plugin",
"binary",
"visualization",
"memory-layout",
"struct"
],
"author": "ByteGrid Contributors",
"license": "MIT",
"devDependencies": {
"@types/jest": "^29.5.11",
"@types/node": "^20.10.6",
"@typescript-eslint/eslint-plugin": "^6.17.0",
"@typescript-eslint/parser": "^6.17.0",
"eslint": "^8.56.0",
"jest": "^29.7.0",
"prettier": "^3.1.1",
"ts-jest": "^29.1.1",
"typescript": "^5.3.3"
},
"engines": {
"node": ">=18.0.0",
"npm": ">=9.0.0"
}
}

View file

@ -0,0 +1,7 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/tests'],
testMatch: ['**/?(*.)+(spec|test).ts'],
collectCoverageFrom: ['src/**/*.ts', '!src/**/*.d.ts', '!src/index.ts'],
};

View file

@ -0,0 +1,26 @@
{
"name": "@bytegrid/core",
"version": "0.1.0",
"description": "Core rendering logic for ByteGrid",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
},
"keywords": [
"bytegrid",
"binary",
"visualization"
],
"author": "ByteGrid Contributors",
"license": "MIT",
"dependencies": {
"js-yaml": "^4.1.0"
},
"devDependencies": {
"@types/js-yaml": "^4.0.9"
}
}

View file

@ -0,0 +1,58 @@
/**
* Custom error classes for ByteGrid
*/
/**
* Base error class for ByteGrid
*/
export class ByteGridError extends Error {
constructor(message: string) {
super(message);
this.name = 'ByteGridError';
Object.setPrototypeOf(this, ByteGridError.prototype);
}
}
/**
* Error thrown during YAML parsing
*/
export class ParseError extends ByteGridError {
constructor(message: string, public readonly fieldIndex?: number) {
super(message);
this.name = 'ParseError';
Object.setPrototypeOf(this, ParseError.prototype);
}
}
/**
* Error thrown during validation
*/
export class ValidationError extends ByteGridError {
constructor(message: string, public readonly fieldIndex?: number) {
super(message);
this.name = 'ValidationError';
Object.setPrototypeOf(this, ValidationError.prototype);
}
}
/**
* Error thrown during rendering
*/
export class RenderError extends ByteGridError {
constructor(message: string) {
super(message);
this.name = 'RenderError';
Object.setPrototypeOf(this, RenderError.prototype);
}
}
/**
* Error thrown during binary parsing
*/
export class BinaryParseError extends ByteGridError {
constructor(message: string, public readonly offset?: number) {
super(message);
this.name = 'BinaryParseError';
Object.setPrototypeOf(this, BinaryParseError.prototype);
}
}

View file

@ -0,0 +1,12 @@
/**
* ByteGrid Core - Public API
*/
export * from './types';
export * from './errors';
// TODO: Export parser, validator, layoutEngine, svgRenderer when implemented
// export { parse } from './parser';
// export { validate } from './validator';
// export { createLayout } from './layoutEngine';
// export { renderSVG } from './svgRenderer';

123
packages/core/src/types.ts Normal file
View file

@ -0,0 +1,123 @@
/**
* Core type definitions for ByteGrid
*/
/**
* Supported data types in ByteGrid
*/
export type DataType =
| 'char'
| 'int8_t'
| 'uint8_t'
| 'int16_t'
| 'uint16_t'
| 'short'
| 'int32_t'
| 'uint32_t'
| 'int'
| 'int64_t'
| 'uint64_t'
| 'long'
| 'float'
| 'double'
| 'reserved'
| 'padding'
| string; // For array types like 'char[4]'
/**
* Endianness for multi-byte fields
*/
export type Endianness = 'little' | 'big';
/**
* Color names for field visualization
*/
export type ColorName =
| 'blue'
| 'cyan'
| 'yellow'
| 'green'
| 'orange'
| 'purple'
| 'mint'
| 'pink'
| 'gray';
/**
* Color scheme variants
*/
export type ColorScheme = 'default' | 'dark' | 'light';
/**
* Bitfield definition within a field
*/
export interface Bitfield {
name: string;
bits: string; // e.g., "0-3" or "7"
description?: string;
}
/**
* Field definition
* Note: size is calculated from offset (SSOT principle)
*/
export interface Field {
offset: string; // e.g., "0-3" or "4" (SSOT for size calculation)
name: string;
type: DataType;
value?: string;
description?: string;
color?: ColorName;
endianness?: Endianness;
bitfields?: Bitfield[];
}
/**
* Main configuration for ByteGrid visualization
*/
export interface ByteGridConfig {
name: string;
size: number; // Total size in bytes
layout?: number; // Bytes per row (default: 16)
colorScheme?: ColorScheme;
fields: Field[];
}
/**
* Parsed offset information
*/
export interface OffsetRange {
start: number;
end: number;
size: number;
}
/**
* Layout block for rendering (after layout engine processing)
*/
export interface LayoutBlock {
row: number;
col: number;
span: number; // Number of columns this block spans
fieldName: string;
fieldType: DataType;
color: ColorName;
value?: string;
description?: string;
offsetStart: number;
offsetEnd: number;
isPadding: boolean;
bitfields?: Bitfield[];
}
/**
* Rendering options
*/
export interface RenderOptions {
showHexDump?: boolean;
showLegend?: boolean;
showGrid?: boolean;
cellWidth?: number;
cellHeight?: number;
fontSize?: number;
}

View file

@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "tests"]
}

24
tsconfig.json Normal file
View file

@ -0,0 +1,24 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./",
"composite": true,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}