mirror of
https://github.com/waaraawa/ByteGrid.git
synced 2026-07-22 06:41:47 +00:00
chore: initial project setup
This commit is contained in:
parent
3cedbcf635
commit
71aaec03bf
14 changed files with 488 additions and 0 deletions
33
.eslintrc.json
Normal file
33
.eslintrc.json
Normal 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
40
.gitignore
vendored
Normal 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
5
.prettierignore
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
node_modules
|
||||
dist
|
||||
coverage
|
||||
*.log
|
||||
.git
|
||||
10
.prettierrc.json
Normal file
10
.prettierrc.json
Normal 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
77
README.md
Normal 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
22
jest.config.js
Normal 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
42
package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
7
packages/core/jest.config.js
Normal file
7
packages/core/jest.config.js
Normal 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'],
|
||||
};
|
||||
26
packages/core/package.json
Normal file
26
packages/core/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
58
packages/core/src/errors.ts
Normal file
58
packages/core/src/errors.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
12
packages/core/src/index.ts
Normal file
12
packages/core/src/index.ts
Normal 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
123
packages/core/src/types.ts
Normal 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;
|
||||
}
|
||||
9
packages/core/tsconfig.json
Normal file
9
packages/core/tsconfig.json
Normal 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
24
tsconfig.json
Normal 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"]
|
||||
}
|
||||
Loading…
Reference in a new issue