Files
MetonaSqlark/CONTRIBUTING.md
T
thzxx d544501e1c
CI / test (18.x) (push) Failing after 5m11s
CI / test (20.x) (push) Failing after 5m8s
CI / test (22.x) (push) Successful in 9m58s
CI / test (24.x) (push) Successful in 9m56s
release: v0.3.2 — 质量加固 + SQL扩展 + 表达式 + 并发同步
v0.2.6 质量加固:
- 修复 AriaEngine 二级索引 SSTable 互相覆盖(命名空间隔离)
- 修复 LSM 多版本读取顺序错误 + MergeIterator 取最新来源
- 重写 LZ4 压缩器(往返一致性 + 缓冲区溢出)
- sstableCache LRU 上限 + 预加载兜底(BufferPool 配置生效)
- 修复 React/Vue 集成 import type 运行时 bug + exports 子路径
- 新增 38 个测试(LZ4往返/Crypto/集成), 删除伪测试

v0.3.0 SQL 功能扩展:
- 多语句 parseAll + 事务语句 BEGIN/COMMIT/ROLLBACK
- INSERT INTO ... SELECT + UNION/UNION ALL + EXISTS 关联子查询
- CREATE/DROP INDEX 五引擎实现 + 别名 WHERE 修复
- benchmark 页面 + 36 个新测试

v0.3.1 表达式与性能:
- CASE WHEN 表达式(SELECT 列/WHERE/聚合)
- JOIN + 关联子查询逐行绑定
- WAL 批量组提交(写放大 O(N)→O(1))
- 修复 pending frozen 可见性 + flush 缓存竞争

v0.3.2 并发:
- CASE WHEN 用于 WHERE/聚合 + JOIN 哈希连接
- 多标签页同步(multiTabSync + BroadcastChannel)
- IndexedDB schema 持久化(reopen 后表结构恢复)
- 修复 where-matcher 顶层 $not
- 修复 CJS 产物 .js 被 ESM 解析(exports 空) — .cjs 后缀 + exports 修正
- 836 测试 / 44 套件 / 81.0% 覆盖率
2026-08-08 10:41:30 +08:00

7.9 KiB

Contributing to MetonaSqlark

Thanks for your interest in contributing! This document outlines the development workflow and conventions.

Prerequisites

  • Node.js >= 16.0.0
  • npm >= 8.0.0

Setup

git clone https://git.metona.cn/MetonaTeam/MetonaSqlark.git
cd MetonaSqlark
npm install

Development

# Start dev server with hot reload (port 3001)
npm run dev

# Run tests in watch mode
npm run test:watch

# Type check
npm run typecheck

# Lint
npm run lint
npm run lint:fix

# Format
npm run format

Project Structure

src/
├── index.ts              # Entry point, global API (MetonaSqlark + MeSqlark)
├── core.ts               # MetonaSqlark main class
├── constants.ts          # Types, defaults, enums, errors
├── utils.ts              # Utility functions
├── connection-manager.ts # Connection pool (connect/disconnect)
├── engine/               # Storage engines
│   ├── interface.ts      # IStorageEngine interface
│   ├── memory.ts         # MemoryEngine (Map-based)
│   ├── indexeddb.ts      # IndexedDBEngine (browser persistence)
│   ├── opfs.ts           # OPFSEngine (Origin Private File System)
│   └── aria/             # AriaEngine (LSM-Tree page storage engine)
│       ├── index/        # LSM / MemTable / SSTable / Bloom / MergeIterator
│       ├── page/         # 4KB slotted page format
│       ├── buffer/       # Buffer Pool (LRU eviction)
│       ├── wal/          # Write-Ahead Log + Checkpoint
│       ├── transaction/  # MVCC manager
│       ├── store/        # Backends (IndexedDB / OPFS / Memory)
│       └── compression/  # LZ4
├── hybrid/               # HybridEngine (write-through)
├── table/                # Table management & Schema validation
├── query/                # Query system
│   ├── ast.ts            # SQL AST type definitions
│   ├── builder.ts        # Chainable QueryBuilder API
│   ├── compiler.ts       # AST → QueryPlan compiler
│   ├── executor.ts       # QueryExecutor with JOIN/GROUP BY support
│   └── where-matcher.ts  # Unified WHERE matching logic
├── sql/                  # SQL parser
│   ├── tokens.ts         # Token types & keywords
│   ├── lexer.ts          # Tokenizer
│   └── parser.ts         # Recursive descent parser
├── transaction/          # Transaction manager
├── plugin/               # Plugin system (14 lifecycle hooks)
└── integrations/         # React & Vue hooks

tests/                    # Test suite (761+ test cases, 41 test suites)
site/                     # Documentation site (index / docs / demo)

Code Conventions

TypeScript

  • Strict mode is enabled — all code must pass tsc --noEmit.
  • Export types explicitly. Avoid any where possible.
  • Use interface for object shapes, type for unions/primitives.

Style

  • Run npm run format before committing (uses Prettier).
  • Follow existing comment patterns: JSDoc /** */ for public APIs, // for inline notes.
  • Keep functions focused and under ~60 lines where practical.

Testing

  • Every new feature must include tests.
  • Test files mirror source structure: src/foo.tstests/foo.test.ts.
  • Use descriptive test names: ('does X when Y').
  • Run the full suite before submitting: npm test.

Commits

  • Use conventional commit messages:
    • feat: add SQL GROUP BY support
    • fix: JOIN with multiple ON conditions
    • docs: update API reference
    • test: add edge case coverage
    • chore: optimize rollup dev build

Architecture

MetonaSqlark follows a layered architecture:

┌──────────────────────────────────────────────────┐
│         MetonaSqlark / MeSqlark (Public API)      │
├──────────────────────────────────────────────────┤
│  SQL Parser  │ QueryBuilder │ Transaction │ Plugin │
│  (Lexer→AST) │ (.select…)   │  Manager    │ System │
├──────────────────────────────────────────────────┤
│         QueryExecutor (AST → Results)             │
│    JOIN · GROUP BY · HAVING · DISTINCT · Agg     │
├──────────────────────────────────────────────────┤
│         IStorageEngine (Interface)                │
├─────────┬──────────┬──────────┬──────────────────┤
│ Memory  │ IndexedDB │ OPFS     │ Hybrid           │
│ Engine  │ Engine    │ Engine   │ Engine           │
└─────────┴──────────┴──────────┴──────────────────┘

Key Design Decisions

  1. AST as Universal Intermediate Representation: Both SQL strings and Query Builder produce the same AST, ensuring consistent behavior regardless of API used.

  2. Write-Through Hybrid Strategy: When using mode: 'hybrid', all writes go to both memory and disk simultaneously. Reads always hit memory for maximum speed.

  3. Plugin Hook Pipeline: 14 lifecycle hooks allow intercepting database operations without modifying core code.

  4. Hand-Written SQL Parser: No dependencies on parser generators — a recursive-descent parser keeps the bundle size minimal.

Building

# Production build (all formats)
npm run build

# Output in dist/
# ├── metona-sqlark.js        UMD
# ├── metona-sqlark.min.js    UMD minified (~105KB / ~27KB gzip)
# ├── metona-sqlark.esm.js    ES Module
# ├── metona-sqlark.cjs    CommonJS
# └── metona-sqlark.d.ts      TypeScript declarations

Plugin Development

Plugins follow a simple convention:

import type { MetonaPlugin } from '@metona-team/metona-sqlark';

const myPlugin: MetonaPlugin = {
  name: 'myPlugin',
  version: '1.0.0',
  description: 'Description of my plugin',
  priority: 50,  // higher = executed first

  install(db) {
    // Use db.on() to subscribe to hooks
    db.on('beforeInsert', async (rows) => {
      // Validate or transform data
    });
    db.on('afterQuery', async (sql, result) => {
      // Log or cache query results
    });
  },

  destroy() {
    // Clean up event listeners, timers, etc.
  },
};

// Register in config
const db = await MetonaSqlark.create({
  name: 'my-app',
  plugins: [myPlugin],
});

Available Lifecycle Hooks

Hook Trigger Parameters
beforeCreateTable Before table creation schema
afterCreateTable After table creation schema
beforeDropTable Before table drop tableName
afterDropTable After table drop tableName
beforeInsert Before row insert rows[]
afterInsert After row insert rows[]
beforeUpdate Before row update query, updates
afterUpdate After row update query, updates, count
beforeDelete Before row delete query
afterDelete After row delete query, count
beforeQuery Before SQL query sql
afterQuery After SQL query sql, result
beforeTransaction Before transaction -
afterTransaction After transaction -

Releasing

  1. Update version in package.json and src/constants.ts (VERSION constant).
  2. Update CHANGELOG.md.
  3. Run full test suite: npm test.
  4. Build: npm run build.
  5. Publish: npm publish.

Questions?

Open an issue at git.metona.cn/MetonaTeam/MetonaSqlark/issues.