feat: MetonaSqlark v0.1.12 — 前端TypeScript关系型数据库
- 4种存储引擎:Memory / IndexedDB / OPFS / Hybrid - 完整SQL:SELECT/INSERT/UPDATE/DELETE/JOIN/GROUP BY/HAVING/DISTINCT - Query Builder链式API + TypeScript泛型 - 聚合/事务/插件/发布订阅/迁移/导入导出 - React/Vue集成,264测试,93.46%覆盖率,零运行时依赖
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
|
||||||
coverage/
|
coverage/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# metona-sqlark
|
# MetonaSqlark
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://img.shields.io/badge/version-0.1.12-blue?style=flat-square" alt="version">
|
<img src="https://img.shields.io/badge/version-0.1.12-blue?style=flat-square" alt="version">
|
||||||
@@ -11,35 +11,74 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✨ 核心特性
|
|
||||||
|
|
||||||
- 🧠 **双模式存储** — Memory / Disk / Hybrid,内存极速 + 磁盘持久化
|
|
||||||
- ⚡ **完整 SQL** — SELECT / INSERT / UPDATE / DELETE / JOIN / GROUP BY / HAVING / DISTINCT
|
|
||||||
- 🔗 **Query Builder** — 链式 API,TypeScript 类型友好
|
|
||||||
- 📊 **聚合函数** — COUNT / SUM / AVG / MIN / MAX
|
|
||||||
- 🔒 **事务支持** — 原子性操作,失败自动回滚
|
|
||||||
- 🧩 **插件系统** — 14 种生命周期钩子
|
|
||||||
- 📡 **发布订阅** — 表级变更监听
|
|
||||||
- 🔄 **数据迁移** — 版本化 migration 系统
|
|
||||||
- 📤 **导入导出** — JSON 格式全库/单表导入导出
|
|
||||||
- ⚛️ **React / Vue** — 原生 hooks & composables
|
|
||||||
- 📦 **零运行时依赖** — 纯 TypeScript,约 42KB min+gzip
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 安装
|
## 📦 安装
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install @metona-team/metona-sqlark
|
npm install @metona-team/metona-sqlark
|
||||||
```
|
```
|
||||||
|
|
||||||
```typescript
|
> 如果提示找不到包,先配置 scope registry(一次性):
|
||||||
// ESM / TypeScript
|
> ```bash
|
||||||
import { MetonaSqlark, MeSqlark } from '@metona-team/metona-sqlark';
|
> npm config set @metona-team:registry https://git.metona.cn/api/packages/MetonaTeam/npm/
|
||||||
|
> ```
|
||||||
|
|
||||||
// Browser UMD
|
### CDN / 直接下载
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- UMD 格式,暴露 window.MetonaSqlark 和 window.MeSqlark -->
|
||||||
|
<script src="https://git.metona.cn/MetonaTeam/MetonaSqlark/raw/branch/master/dist/metona-sqlark.min.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
或从 [`dist/`](./dist/) 目录下载:
|
||||||
|
- `metona-sqlark.js` — UMD 开发版(含 sourcemap)
|
||||||
|
- `metona-sqlark.min.js` — UMD 压缩版(~42KB)
|
||||||
|
- `metona-sqlark.esm.js` — ES Module
|
||||||
|
- `metona-sqlark.cjs.js` — CommonJS
|
||||||
|
- `metona-sqlark.d.ts` — TypeScript 类型声明
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 引入方式
|
||||||
|
|
||||||
|
### ESM / TypeScript
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { MetonaSqlark } from '@metona-team/metona-sqlark';
|
||||||
|
// 别名
|
||||||
|
import { MeSqlark } from '@metona-team/metona-sqlark';
|
||||||
|
|
||||||
|
const db = await MetonaSqlark.create({ name: 'my-app', mode: 'hybrid' });
|
||||||
|
```
|
||||||
|
|
||||||
|
### CommonJS
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const { MetonaSqlark } = require('@metona-team/metona-sqlark');
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const db = await MetonaSqlark.create({ name: 'my-app', mode: 'hybrid' });
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Browser UMD
|
||||||
|
|
||||||
|
```html
|
||||||
<script src="metona-sqlark.min.js"></script>
|
<script src="metona-sqlark.min.js"></script>
|
||||||
// → window.MetonaSqlark / window.MeSqlark
|
<script>
|
||||||
|
(async () => {
|
||||||
|
const db = await window.MetonaSqlark.create({ name: 'my-app', mode: 'hybrid' });
|
||||||
|
// 或 window.MeSqlark(完全等价)
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### ES Module in Browser
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script type="module">
|
||||||
|
import { MetonaSqlark } from './metona-sqlark.esm.js';
|
||||||
|
const db = await MetonaSqlark.create({ name: 'my-app', mode: 'hybrid' });
|
||||||
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -49,11 +88,10 @@ import { MetonaSqlark, MeSqlark } from '@metona-team/metona-sqlark';
|
|||||||
```typescript
|
```typescript
|
||||||
import { MetonaSqlark } from '@metona-team/metona-sqlark';
|
import { MetonaSqlark } from '@metona-team/metona-sqlark';
|
||||||
|
|
||||||
// 创建数据库
|
|
||||||
const db = await MetonaSqlark.create({
|
const db = await MetonaSqlark.create({
|
||||||
name: 'my-app',
|
name: 'my-app',
|
||||||
mode: 'hybrid',
|
mode: 'hybrid', // 'memory' | 'disk' | 'hybrid'
|
||||||
diskEngine: 'indexeddb',
|
diskEngine: 'indexeddb', // 'indexeddb' | 'opfs'
|
||||||
});
|
});
|
||||||
|
|
||||||
// 定义表
|
// 定义表
|
||||||
@@ -69,9 +107,12 @@ await db.query("INSERT INTO users VALUES ('1', 'Alice', 30, 'alice@demo.com')");
|
|||||||
const rows = await db.query('SELECT * FROM users WHERE age > 18 ORDER BY name');
|
const rows = await db.query('SELECT * FROM users WHERE age > 18 ORDER BY name');
|
||||||
|
|
||||||
// Query Builder
|
// Query Builder
|
||||||
const users = db.table('users');
|
const result = await db.table('users')
|
||||||
await users.insert({ id: '2', name: 'Bob', age: 25, email: 'bob@demo.com' });
|
.select(['name', 'age'])
|
||||||
const result = await users.select().where({ age: { $gt: 18 } }).orderBy('age', 'desc').execute();
|
.where({ age: { $gt: 18 } })
|
||||||
|
.orderBy('age', 'desc')
|
||||||
|
.limit(10)
|
||||||
|
.execute();
|
||||||
|
|
||||||
// JOIN
|
// JOIN
|
||||||
await db.query(`SELECT u.name, o.product FROM users u INNER JOIN orders o ON u.id = o.user_id`);
|
await db.query(`SELECT u.name, o.product FROM users u INNER JOIN orders o ON u.id = o.user_id`);
|
||||||
@@ -116,7 +157,8 @@ await db.transaction(async (trx) => {
|
|||||||
| `db.table(name)` | 获取表操作对象 |
|
| `db.table(name)` | 获取表操作对象 |
|
||||||
| `db.defineTable(name, cols)` | 定义表结构 |
|
| `db.defineTable(name, cols)` | 定义表结构 |
|
||||||
| `db.transaction(fn)` | 执行事务 |
|
| `db.transaction(fn)` | 执行事务 |
|
||||||
| `db.exportTable(name)` / `db.exportAll()` | 导出数据 |
|
| `db.exportTable(name)` / `db.exportAll()` | 导出数据 JSON |
|
||||||
|
| `db.importTable(name, data)` | 导入数据 |
|
||||||
| `db.addMigration(v, fn)` / `db.migrateTo(v)` | 数据迁移 |
|
| `db.addMigration(v, fn)` / `db.migrateTo(v)` | 数据迁移 |
|
||||||
| `db.subscribe(table, fn)` | 订阅表变更 |
|
| `db.subscribe(table, fn)` | 订阅表变更 |
|
||||||
| `db.on(hook, fn)` | 注册钩子 |
|
| `db.on(hook, fn)` | 注册钩子 |
|
||||||
@@ -135,6 +177,19 @@ const { data, loading, refresh } = useSqlarkQuery(db, 'SELECT * FROM users');
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 🛠 开发
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install # 安装依赖
|
||||||
|
npm run dev # 开发模式(localhost:3001)
|
||||||
|
npm run build # 生产构建(生成 dist/)
|
||||||
|
npm test # 运行测试
|
||||||
|
npm run lint # 代码检查
|
||||||
|
npm run typecheck # 类型检查
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 📊 项目状态
|
## 📊 项目状态
|
||||||
|
|
||||||
| 指标 | 数值 |
|
| 指标 | 数值 |
|
||||||
@@ -147,19 +202,6 @@ const { data, loading, refresh } = useSqlarkQuery(db, 'SELECT * FROM users');
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🛠 开发
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install # 安装依赖
|
|
||||||
npm run dev # 开发模式(localhost:3001)
|
|
||||||
npm run build # 生产构建
|
|
||||||
npm test # 运行测试
|
|
||||||
npm run lint # 代码检查
|
|
||||||
npm run typecheck # 类型检查
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📂 项目结构
|
## 📂 项目结构
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -181,4 +223,4 @@ src/
|
|||||||
|
|
||||||
## 📄 License
|
## 📄 License
|
||||||
|
|
||||||
MIT © [MetonaTeam](https://git.metona.cn/MetonaTeam)
|
MIT © [MetonaTeam](https://git.metona.cn/MetonaTeam/MetonaSqlark)
|
||||||
|
|||||||
Vendored
+2732
File diff suppressed because it is too large
Load Diff
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+733
@@ -0,0 +1,733 @@
|
|||||||
|
/**
|
||||||
|
* metona-sqlark Constants — 类型定义 / 默认配置 / 枚举
|
||||||
|
* @module constants
|
||||||
|
*/
|
||||||
|
/** 存储模式 */
|
||||||
|
type StorageMode = 'memory' | 'disk' | 'hybrid';
|
||||||
|
/** 磁盘引擎类型 */
|
||||||
|
type DiskEngine = 'indexeddb' | 'opfs';
|
||||||
|
/** 字段数据类型 */
|
||||||
|
type FieldType = 'string' | 'number' | 'boolean' | 'date' | 'json';
|
||||||
|
/** 列定义 */
|
||||||
|
interface ColumnDef {
|
||||||
|
/** 字段类型 */
|
||||||
|
type: FieldType;
|
||||||
|
/** 是否主键 */
|
||||||
|
primaryKey?: boolean;
|
||||||
|
/** 是否必填 */
|
||||||
|
required?: boolean;
|
||||||
|
/** 是否唯一 */
|
||||||
|
unique?: boolean;
|
||||||
|
/** 默认值 */
|
||||||
|
default?: unknown;
|
||||||
|
/** 是否创建索引 */
|
||||||
|
index?: boolean;
|
||||||
|
/** 外键引用: 'table.column' */
|
||||||
|
references?: string;
|
||||||
|
/** 字符串最大长度 */
|
||||||
|
maxLength?: number;
|
||||||
|
/** 数字最小值 */
|
||||||
|
min?: number;
|
||||||
|
/** 数字最大值 */
|
||||||
|
max?: number;
|
||||||
|
}
|
||||||
|
/** 表结构定义 */
|
||||||
|
interface TableSchema {
|
||||||
|
/** 表名 */
|
||||||
|
name: string;
|
||||||
|
/** 列定义映射 */
|
||||||
|
columns: Record<string, ColumnDef>;
|
||||||
|
}
|
||||||
|
/** 数据库配置 */
|
||||||
|
interface DatabaseConfig {
|
||||||
|
/** 数据库名称 */
|
||||||
|
name: string;
|
||||||
|
/** 存储模式 */
|
||||||
|
mode?: StorageMode;
|
||||||
|
/** 磁盘引擎(仅 mode='disk'|'hybrid' 时生效) */
|
||||||
|
diskEngine?: DiskEngine;
|
||||||
|
/** 版本号 */
|
||||||
|
version?: number;
|
||||||
|
/** 插件列表 */
|
||||||
|
plugins?: MetonaPlugin[];
|
||||||
|
/** 数据库就绪回调 */
|
||||||
|
onReady?: (db: unknown) => void;
|
||||||
|
/** 错误回调 */
|
||||||
|
onError?: (error: Error) => void;
|
||||||
|
}
|
||||||
|
/** Where 条件操作符 */
|
||||||
|
type WhereOperator = '$eq' | '$ne' | '$gt' | '$gte' | '$lt' | '$lte' | '$in' | '$nin' | '$like' | '$and' | '$or' | '$not';
|
||||||
|
/** 简单条件值:直接相等 */
|
||||||
|
type SimpleCondition = unknown;
|
||||||
|
/** 操作符条件 */
|
||||||
|
type OperatorCondition = Partial<Record<WhereOperator, unknown>>;
|
||||||
|
/** 字段条件:简单值 | 操作符对象 */
|
||||||
|
type FieldCondition = SimpleCondition | OperatorCondition;
|
||||||
|
/** Where 条件对象 */
|
||||||
|
type WhereCondition = Record<string, FieldCondition>;
|
||||||
|
/** 排序方向 */
|
||||||
|
type SortDirection = 'asc' | 'desc';
|
||||||
|
/** 排序定义 */
|
||||||
|
interface OrderBy {
|
||||||
|
/** 列名 */
|
||||||
|
column: string;
|
||||||
|
/** 排序方向 */
|
||||||
|
direction: SortDirection;
|
||||||
|
}
|
||||||
|
/** 查询计划 — 由 Executor 编译 AST 后生成 */
|
||||||
|
interface QueryPlan {
|
||||||
|
/** 表名 */
|
||||||
|
table: string;
|
||||||
|
/** 要返回的列(undefined = 全部,['*'] = 全部) */
|
||||||
|
columns?: string[];
|
||||||
|
/** 过滤条件 */
|
||||||
|
where?: WhereCondition;
|
||||||
|
/** 排序 */
|
||||||
|
orderBy?: OrderBy[];
|
||||||
|
/** 限制条数 */
|
||||||
|
limit?: number;
|
||||||
|
/** 偏移量 */
|
||||||
|
offset?: number;
|
||||||
|
}
|
||||||
|
/** 钩子名称 */
|
||||||
|
type HookName = 'beforeCreateTable' | 'afterCreateTable' | 'beforeDropTable' | 'afterDropTable' | 'beforeInsert' | 'afterInsert' | 'beforeUpdate' | 'afterUpdate' | 'beforeDelete' | 'afterDelete' | 'beforeQuery' | 'afterQuery' | 'beforeTransaction' | 'afterTransaction';
|
||||||
|
/** 插件定义 */
|
||||||
|
interface MetonaPlugin {
|
||||||
|
/** 插件名称 */
|
||||||
|
name: string;
|
||||||
|
/** 插件版本 */
|
||||||
|
version: string;
|
||||||
|
/** 描述 */
|
||||||
|
description?: string;
|
||||||
|
/** 优先级,越大越先执行 */
|
||||||
|
priority?: number;
|
||||||
|
/** 安装 */
|
||||||
|
install(db: unknown): void;
|
||||||
|
/** 销毁 */
|
||||||
|
destroy(): void;
|
||||||
|
}
|
||||||
|
declare const VERSION = "0.1.12";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark Plugin — 插件系统
|
||||||
|
* @module plugin
|
||||||
|
*
|
||||||
|
* 管理插件的注册、生命周期和钩子调度。
|
||||||
|
*/
|
||||||
|
|
||||||
|
type HookCallback = (...args: unknown[]) => void | Promise<void>;
|
||||||
|
declare class PluginManager {
|
||||||
|
private plugins;
|
||||||
|
private hooks;
|
||||||
|
/** 注册插件 */
|
||||||
|
register(plugin: MetonaPlugin): void;
|
||||||
|
/** 卸载插件 */
|
||||||
|
unregister(pluginName: string): void;
|
||||||
|
/** 获取所有已注册插件 */
|
||||||
|
getPlugins(): MetonaPlugin[];
|
||||||
|
/** 添加钩子回调 */
|
||||||
|
on(hook: HookName, callback: HookCallback): void;
|
||||||
|
/** 移除钩子回调 */
|
||||||
|
off(hook: HookName, callback: HookCallback): void;
|
||||||
|
/** 触发钩子 */
|
||||||
|
trigger(hook: HookName, ...args: unknown[]): Promise<void>;
|
||||||
|
/** 销毁所有插件 */
|
||||||
|
destroy(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark Engine Interface — 存储引擎抽象接口
|
||||||
|
* @module engine/interface
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface IStorageEngine {
|
||||||
|
/** 引擎名称 */
|
||||||
|
readonly name: string;
|
||||||
|
/** 打开数据库 */
|
||||||
|
open(dbName: string, version: number): Promise<void>;
|
||||||
|
/** 关闭数据库 */
|
||||||
|
close(): Promise<void>;
|
||||||
|
/** 检查数据库是否已打开 */
|
||||||
|
isOpen(): boolean;
|
||||||
|
/** 创建表 */
|
||||||
|
createTable(schema: TableSchema): Promise<void>;
|
||||||
|
/** 删除表 */
|
||||||
|
dropTable(tableName: string): Promise<void>;
|
||||||
|
/** 检查表是否存在 */
|
||||||
|
hasTable(tableName: string): Promise<boolean>;
|
||||||
|
/** 获取所有表名 */
|
||||||
|
getTableNames(): Promise<string[]>;
|
||||||
|
/** 获取表结构 */
|
||||||
|
getTableSchema(tableName: string): Promise<TableSchema | null>;
|
||||||
|
/** 插入行,返回主键值列表 */
|
||||||
|
insert(tableName: string, rows: Record<string, unknown>[]): Promise<string[]>;
|
||||||
|
/** 查询行 */
|
||||||
|
find(tableName: string, query: QueryPlan): Promise<Record<string, unknown>[]>;
|
||||||
|
/** 更新行,返回影响行数 */
|
||||||
|
update(tableName: string, query: QueryPlan, updates: Record<string, unknown>): Promise<number>;
|
||||||
|
/** 删除行,返回影响行数 */
|
||||||
|
delete(tableName: string, query: QueryPlan): Promise<number>;
|
||||||
|
/** 计数 */
|
||||||
|
count(tableName: string, query?: QueryPlan): Promise<number>;
|
||||||
|
/** 清空表数据(保留结构) */
|
||||||
|
clear(tableName: string): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark Query AST — 查询抽象语法树类型定义
|
||||||
|
* @module query/ast
|
||||||
|
*
|
||||||
|
* QueryBuilder 和 SQL Parser 统一输出此 AST,
|
||||||
|
* Executor 只认 AST,保证两种查询接口行为一致。
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 列引用,'*' 表示所有列;支持 'table.column' 格式 */
|
||||||
|
type ColumnRef = string;
|
||||||
|
/** JOIN 类型 */
|
||||||
|
type JoinType = 'INNER' | 'LEFT' | 'RIGHT' | 'CROSS';
|
||||||
|
/** JOIN 子句 */
|
||||||
|
interface JoinClause {
|
||||||
|
type: JoinType;
|
||||||
|
table: string;
|
||||||
|
alias?: string;
|
||||||
|
on: WhereCondition;
|
||||||
|
}
|
||||||
|
interface ASTColumnDef {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
primaryKey?: boolean;
|
||||||
|
unique?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
default?: unknown;
|
||||||
|
index?: boolean;
|
||||||
|
maxLength?: number;
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
|
}
|
||||||
|
interface CreateTableStatement {
|
||||||
|
type: 'CREATE_TABLE';
|
||||||
|
name: string;
|
||||||
|
columns: ASTColumnDef[];
|
||||||
|
}
|
||||||
|
interface DropTableStatement {
|
||||||
|
type: 'DROP_TABLE';
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
interface InsertStatement {
|
||||||
|
type: 'INSERT';
|
||||||
|
into: string;
|
||||||
|
columns?: string[];
|
||||||
|
values: unknown[][];
|
||||||
|
}
|
||||||
|
interface UpdateStatement {
|
||||||
|
type: 'UPDATE';
|
||||||
|
table: string;
|
||||||
|
sets: Record<string, unknown>;
|
||||||
|
where: WhereCondition;
|
||||||
|
}
|
||||||
|
interface DeleteStatement {
|
||||||
|
type: 'DELETE';
|
||||||
|
from: string;
|
||||||
|
where: WhereCondition;
|
||||||
|
}
|
||||||
|
interface SelectStatement {
|
||||||
|
type: 'SELECT';
|
||||||
|
columns: ColumnRef[];
|
||||||
|
distinct?: boolean;
|
||||||
|
from: string;
|
||||||
|
/** 主表别名 */
|
||||||
|
alias?: string;
|
||||||
|
/** JOIN 子句列表 */
|
||||||
|
joins?: JoinClause[];
|
||||||
|
where: WhereCondition;
|
||||||
|
/** GROUP BY */
|
||||||
|
groupBy?: string[];
|
||||||
|
/** HAVING */
|
||||||
|
having?: WhereCondition;
|
||||||
|
orderBy?: OrderBy[];
|
||||||
|
limit?: number;
|
||||||
|
offset?: number;
|
||||||
|
}
|
||||||
|
type Statement = SelectStatement | InsertStatement | UpdateStatement | DeleteStatement | CreateTableStatement | DropTableStatement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark Query Executor — AST 执行器
|
||||||
|
* @module query/executor
|
||||||
|
*
|
||||||
|
* JOIN / GROUP BY / DISTINCT 逻辑在此层处理。
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare class QueryExecutor {
|
||||||
|
private engine;
|
||||||
|
constructor(engine: IStorageEngine);
|
||||||
|
execute(stmt: Statement): Promise<unknown>;
|
||||||
|
private executeSelect;
|
||||||
|
private executeJoinSelect;
|
||||||
|
private prefixRow;
|
||||||
|
/** 嵌套循环连接(优化:避免 ON 时对象扩散) */
|
||||||
|
private joinRows;
|
||||||
|
private executeGroupBy;
|
||||||
|
private computeAggregate;
|
||||||
|
private executeDistinct;
|
||||||
|
private executeInsert;
|
||||||
|
private executeUpdate;
|
||||||
|
private executeDelete;
|
||||||
|
private executeCreateTable;
|
||||||
|
private executeDropTable;
|
||||||
|
getEngine(): IStorageEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark Query Builder — 链式查询构建器
|
||||||
|
* @module query/builder
|
||||||
|
*
|
||||||
|
* 链式调用 → 构建 AST → 执行引擎操作。
|
||||||
|
* 支持 JOIN(需要 Executor)。
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare class SelectQueryBuilder {
|
||||||
|
private engine;
|
||||||
|
private tableName;
|
||||||
|
private _columns;
|
||||||
|
private _where;
|
||||||
|
private _orderBy;
|
||||||
|
private _limit?;
|
||||||
|
private _offset?;
|
||||||
|
private _joins;
|
||||||
|
private _alias?;
|
||||||
|
private _executor?;
|
||||||
|
constructor(engine: IStorageEngine, tableName: string, _columns?: string[], executor?: QueryExecutor);
|
||||||
|
/** 主表别名 */
|
||||||
|
as(alias: string): this;
|
||||||
|
/** INNER JOIN */
|
||||||
|
innerJoin(table: string, on: WhereCondition, alias?: string): this;
|
||||||
|
/** LEFT JOIN */
|
||||||
|
leftJoin(table: string, on: WhereCondition, alias?: string): this;
|
||||||
|
/** RIGHT JOIN */
|
||||||
|
rightJoin(table: string, on: WhereCondition, alias?: string): this;
|
||||||
|
/** CROSS JOIN */
|
||||||
|
crossJoin(table: string, alias?: string): this;
|
||||||
|
/** 通用 JOIN */
|
||||||
|
join(table: string, on: WhereCondition, alias?: string): this;
|
||||||
|
private _addJoin;
|
||||||
|
/** 添加过滤条件 */
|
||||||
|
where(condition: WhereCondition): this;
|
||||||
|
/** 排序 */
|
||||||
|
orderBy(column: string, direction?: SortDirection): this;
|
||||||
|
/** 限制返回条数 */
|
||||||
|
limit(n: number): this;
|
||||||
|
/** 偏移量 */
|
||||||
|
offset(n: number): this;
|
||||||
|
/** 执行查询 */
|
||||||
|
execute(): Promise<Record<string, unknown>[]>;
|
||||||
|
/** 获取 AST */
|
||||||
|
toAST(): SelectStatement;
|
||||||
|
}
|
||||||
|
declare class UpdateQueryBuilder {
|
||||||
|
private engine;
|
||||||
|
private tableName;
|
||||||
|
private _updates;
|
||||||
|
private _where;
|
||||||
|
constructor(engine: IStorageEngine, tableName: string, _updates: Record<string, unknown>);
|
||||||
|
where(condition: WhereCondition): this;
|
||||||
|
execute(): Promise<number>;
|
||||||
|
toAST(): UpdateStatement;
|
||||||
|
}
|
||||||
|
declare class DeleteQueryBuilder {
|
||||||
|
private engine;
|
||||||
|
private tableName;
|
||||||
|
private _where;
|
||||||
|
constructor(engine: IStorageEngine, tableName: string);
|
||||||
|
where(condition: WhereCondition): this;
|
||||||
|
execute(): Promise<number>;
|
||||||
|
toAST(): DeleteStatement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark Table — 表操作 API
|
||||||
|
* @module table/table
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare class Table<T = Record<string, unknown>> {
|
||||||
|
readonly name: string;
|
||||||
|
private engine;
|
||||||
|
private schema;
|
||||||
|
private executor;
|
||||||
|
constructor(engine: IStorageEngine, tableName: string, executor?: QueryExecutor);
|
||||||
|
getSchema(): Promise<TableSchema>;
|
||||||
|
insert(row: T & Record<string, unknown>): Promise<string>;
|
||||||
|
insertMany(rows: (T & Record<string, unknown>)[]): Promise<string[]>;
|
||||||
|
select(columns?: string[]): SelectQueryBuilder;
|
||||||
|
update(updates: Partial<T> & Record<string, unknown>): UpdateQueryBuilder;
|
||||||
|
delete(): DeleteQueryBuilder;
|
||||||
|
count(where?: Record<string, unknown>): Promise<number>;
|
||||||
|
clear(): Promise<void>;
|
||||||
|
drop(): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark Transaction — 事务管理
|
||||||
|
* @module transaction
|
||||||
|
*
|
||||||
|
* 封装多操作事务,保证原子性。
|
||||||
|
* v0.0.1: 基于引擎层操作实现,IndexedDB 引擎利用原生事务。
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare class Transaction {
|
||||||
|
private engine;
|
||||||
|
private tables;
|
||||||
|
private completed;
|
||||||
|
constructor(engine: IStorageEngine);
|
||||||
|
/** 获取表操作对象 */
|
||||||
|
table(tableName: string): Table;
|
||||||
|
/** 标记事务完成(由 TransactionManager 调用) */
|
||||||
|
_markCompleted(): void;
|
||||||
|
/** 是否已完成 */
|
||||||
|
isCompleted(): boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare class MetonaSqlark {
|
||||||
|
/** 数据库名称 */
|
||||||
|
readonly name: string;
|
||||||
|
/** 存储模式 */
|
||||||
|
readonly mode: string;
|
||||||
|
/** 版本号 */
|
||||||
|
private _version;
|
||||||
|
/** 获取版本号 */
|
||||||
|
get version(): number;
|
||||||
|
private engine;
|
||||||
|
private executor;
|
||||||
|
private transactionManager;
|
||||||
|
private pluginManager;
|
||||||
|
private config;
|
||||||
|
private ready;
|
||||||
|
private tableCache;
|
||||||
|
constructor(config: DatabaseConfig);
|
||||||
|
/** 初始化数据库(创建引擎、打开连接) */
|
||||||
|
init(): Promise<void>;
|
||||||
|
/** 检查是否就绪 */
|
||||||
|
isReady(): boolean;
|
||||||
|
/** 创建表 */
|
||||||
|
defineTable(name: string, columns: Record<string, ColumnDef>): Promise<void>;
|
||||||
|
/** 获取表操作对象 */
|
||||||
|
table(name: string): Table;
|
||||||
|
/** 删除表 */
|
||||||
|
dropTable(name: string): Promise<void>;
|
||||||
|
/** 获取所有表名 */
|
||||||
|
getTableNames(): Promise<string[]>;
|
||||||
|
/** 执行 SQL 字符串查询 */
|
||||||
|
query(sql: string): Promise<unknown>;
|
||||||
|
/** 执行事务 */
|
||||||
|
transaction<T>(fn: (trx: Transaction) => Promise<T>): Promise<T>;
|
||||||
|
/** 导出表数据为 JSON */
|
||||||
|
exportTable(tableName: string): Promise<Record<string, unknown>[]>;
|
||||||
|
/** 导入 JSON 数据到表 */
|
||||||
|
importTable(tableName: string, data: Record<string, unknown>[]): Promise<string[]>;
|
||||||
|
/** 导出整个数据库为 JSON */
|
||||||
|
exportAll(): Promise<Record<string, Record<string, unknown>[]>>;
|
||||||
|
private listeners;
|
||||||
|
/** 订阅表变更 */
|
||||||
|
subscribe(tableName: string, callback: (event: {
|
||||||
|
type: string;
|
||||||
|
row?: unknown;
|
||||||
|
}) => void): () => void;
|
||||||
|
/** 触发变更事件 */
|
||||||
|
emit(tableName: string, event: {
|
||||||
|
type: string;
|
||||||
|
row?: unknown;
|
||||||
|
}): void;
|
||||||
|
private migrations;
|
||||||
|
/** 注册迁移 */
|
||||||
|
addMigration(version: number, up: (db: MetonaSqlark) => Promise<void>): void;
|
||||||
|
/** 执行迁移到指定版本 */
|
||||||
|
migrateTo(targetVersion: number): Promise<void>;
|
||||||
|
/** 获取插件管理器 */
|
||||||
|
getPluginManager(): PluginManager;
|
||||||
|
/** 注册钩子 */
|
||||||
|
on(hook: HookName, callback: HookCallback): void;
|
||||||
|
/** 关闭数据库 */
|
||||||
|
close(): Promise<void>;
|
||||||
|
/** 获取底层引擎 */
|
||||||
|
getEngine(): IStorageEngine;
|
||||||
|
private createEngine;
|
||||||
|
private ensureReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark Memory Engine — 基于 Map 的内存存储引擎
|
||||||
|
* @module engine/memory
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare class MemoryEngine implements IStorageEngine {
|
||||||
|
readonly name = "memory";
|
||||||
|
private tables;
|
||||||
|
private schemas;
|
||||||
|
private indexes;
|
||||||
|
private opened;
|
||||||
|
open(_dbName: string, _version: number): Promise<void>;
|
||||||
|
close(): Promise<void>;
|
||||||
|
isOpen(): boolean;
|
||||||
|
createTable(schema: TableSchema): Promise<void>;
|
||||||
|
dropTable(tableName: string): Promise<void>;
|
||||||
|
hasTable(tableName: string): Promise<boolean>;
|
||||||
|
getTableNames(): Promise<string[]>;
|
||||||
|
getTableSchema(tableName: string): Promise<TableSchema | null>;
|
||||||
|
insert(tableName: string, rows: Record<string, unknown>[]): Promise<string[]>;
|
||||||
|
find(tableName: string, query: QueryPlan): Promise<Record<string, unknown>[]>;
|
||||||
|
update(tableName: string, query: QueryPlan, updates: Record<string, unknown>): Promise<number>;
|
||||||
|
delete(tableName: string, query: QueryPlan): Promise<number>;
|
||||||
|
count(tableName: string, query?: QueryPlan): Promise<number>;
|
||||||
|
clear(tableName: string): Promise<void>;
|
||||||
|
private ensureTable;
|
||||||
|
private getPrimaryKey;
|
||||||
|
private validateRow;
|
||||||
|
private checkType;
|
||||||
|
/** O(1) 唯一性检查:利用哈希索引 */
|
||||||
|
private checkUniqueness;
|
||||||
|
/** 索引查找 */
|
||||||
|
private tryIndexLookup;
|
||||||
|
/** 更新索引 */
|
||||||
|
private updateIndexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark IndexedDB Engine — 基于 IndexedDB 的持久化存储引擎
|
||||||
|
* @module engine/indexeddb
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare class IndexedDBEngine implements IStorageEngine {
|
||||||
|
readonly name = "indexeddb";
|
||||||
|
private db;
|
||||||
|
private dbName;
|
||||||
|
private version;
|
||||||
|
private memoryCache;
|
||||||
|
open(dbName: string, version: number): Promise<void>;
|
||||||
|
close(): Promise<void>;
|
||||||
|
isOpen(): boolean;
|
||||||
|
createTable(schema: TableSchema): Promise<void>;
|
||||||
|
dropTable(tableName: string): Promise<void>;
|
||||||
|
hasTable(tableName: string): Promise<boolean>;
|
||||||
|
getTableNames(): Promise<string[]>;
|
||||||
|
getTableSchema(tableName: string): Promise<TableSchema | null>;
|
||||||
|
insert(tableName: string, rows: Record<string, unknown>[]): Promise<string[]>;
|
||||||
|
find(tableName: string, query: QueryPlan): Promise<Record<string, unknown>[]>;
|
||||||
|
update(tableName: string, query: QueryPlan, updates: Record<string, unknown>): Promise<number>;
|
||||||
|
delete(tableName: string, query: QueryPlan): Promise<number>;
|
||||||
|
count(tableName: string, query?: QueryPlan): Promise<number>;
|
||||||
|
clear(tableName: string): Promise<void>;
|
||||||
|
private ensureDB;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark OPFS Engine — 基于 Origin Private File System 的持久化存储引擎
|
||||||
|
* @module engine/opfs
|
||||||
|
*
|
||||||
|
* 使用 JSON-per-table 文件存储方案。
|
||||||
|
* 目录结构:{dbName}/tables/{tableName}.json
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare class OPFSEngine implements IStorageEngine {
|
||||||
|
readonly name = "opfs";
|
||||||
|
private root;
|
||||||
|
private tablesDir;
|
||||||
|
private dbName;
|
||||||
|
private memoryCache;
|
||||||
|
open(dbName: string, version: number): Promise<void>;
|
||||||
|
close(): Promise<void>;
|
||||||
|
isOpen(): boolean;
|
||||||
|
createTable(schema: TableSchema): Promise<void>;
|
||||||
|
dropTable(tableName: string): Promise<void>;
|
||||||
|
hasTable(tableName: string): Promise<boolean>;
|
||||||
|
getTableNames(): Promise<string[]>;
|
||||||
|
getTableSchema(tableName: string): Promise<TableSchema | null>;
|
||||||
|
insert(tableName: string, rows: Record<string, unknown>[]): Promise<string[]>;
|
||||||
|
find(tableName: string, query: QueryPlan): Promise<Record<string, unknown>[]>;
|
||||||
|
update(tableName: string, query: QueryPlan, updates: Record<string, unknown>): Promise<number>;
|
||||||
|
delete(tableName: string, query: QueryPlan): Promise<number>;
|
||||||
|
count(tableName: string, query?: QueryPlan): Promise<number>;
|
||||||
|
clear(tableName: string): Promise<void>;
|
||||||
|
private ensureDir;
|
||||||
|
private writeTableData;
|
||||||
|
private readTableData;
|
||||||
|
/** 从 OPFS 加载表数据到内存缓存 */
|
||||||
|
loadTableIntoMemory(tableName: string, schema: TableSchema): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark Hybrid Engine — 内存 + 磁盘混合存储引擎
|
||||||
|
* @module hybrid/index
|
||||||
|
*
|
||||||
|
* 采用 write-through 策略:
|
||||||
|
* - 所有写操作同时写入内存和磁盘
|
||||||
|
* - 所有读操作直接从内存返回
|
||||||
|
* - 数据库打开时从磁盘加载数据到内存
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare class HybridEngine implements IStorageEngine {
|
||||||
|
readonly name = "hybrid";
|
||||||
|
private memoryEngine;
|
||||||
|
private diskEngine;
|
||||||
|
private diskEngineType;
|
||||||
|
constructor(diskEngine?: DiskEngine);
|
||||||
|
open(dbName: string, version: number): Promise<void>;
|
||||||
|
close(): Promise<void>;
|
||||||
|
isOpen(): boolean;
|
||||||
|
createTable(schema: TableSchema): Promise<void>;
|
||||||
|
dropTable(tableName: string): Promise<void>;
|
||||||
|
hasTable(tableName: string): Promise<boolean>;
|
||||||
|
getTableNames(): Promise<string[]>;
|
||||||
|
getTableSchema(tableName: string): Promise<TableSchema | null>;
|
||||||
|
insert(tableName: string, rows: Record<string, unknown>[]): Promise<string[]>;
|
||||||
|
find(tableName: string, query: QueryPlan): Promise<Record<string, unknown>[]>;
|
||||||
|
update(tableName: string, query: QueryPlan, updates: Record<string, unknown>): Promise<number>;
|
||||||
|
delete(tableName: string, query: QueryPlan): Promise<number>;
|
||||||
|
count(tableName: string, query?: QueryPlan): Promise<number>;
|
||||||
|
clear(tableName: string): Promise<void>;
|
||||||
|
/** 获取磁盘引擎类型 */
|
||||||
|
getDiskEngineType(): DiskEngine;
|
||||||
|
/** 获取内存引擎(供内部使用) */
|
||||||
|
getMemoryEngine(): MemoryEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark SQL Parser — 递归下降语法分析器
|
||||||
|
* @module sql/parser
|
||||||
|
*
|
||||||
|
* Token 流 → AST Statement。
|
||||||
|
* 支持的语法是标准 SQL 的子集。
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 解析 SQL 字符串为 AST Statement */
|
||||||
|
declare function parse(sql: string): Statement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark SQL Token Types — 词法单元定义
|
||||||
|
* @module sql/tokens
|
||||||
|
*/
|
||||||
|
declare enum TokenType {
|
||||||
|
SELECT = "SELECT",
|
||||||
|
FROM = "FROM",
|
||||||
|
WHERE = "WHERE",
|
||||||
|
INSERT = "INSERT",
|
||||||
|
INTO = "INTO",
|
||||||
|
VALUES = "VALUES",
|
||||||
|
UPDATE = "UPDATE",
|
||||||
|
SET = "SET",
|
||||||
|
DELETE = "DELETE",
|
||||||
|
CREATE = "CREATE",
|
||||||
|
TABLE = "TABLE",
|
||||||
|
DROP = "DROP",
|
||||||
|
ORDER = "ORDER",
|
||||||
|
BY = "BY",
|
||||||
|
ASC = "ASC",
|
||||||
|
DESC = "DESC",
|
||||||
|
LIMIT = "LIMIT",
|
||||||
|
OFFSET = "OFFSET",
|
||||||
|
AND = "AND",
|
||||||
|
OR = "OR",
|
||||||
|
NOT = "NOT",
|
||||||
|
LIKE = "LIKE",
|
||||||
|
IN = "IN",
|
||||||
|
PRIMARY = "PRIMARY",
|
||||||
|
KEY = "KEY",
|
||||||
|
UNIQUE = "UNIQUE",
|
||||||
|
DEFAULT = "DEFAULT",
|
||||||
|
NULL = "NULL",
|
||||||
|
TRUE = "TRUE",
|
||||||
|
FALSE = "FALSE",
|
||||||
|
INNER = "INNER",
|
||||||
|
LEFT = "LEFT",
|
||||||
|
RIGHT = "RIGHT",
|
||||||
|
CROSS = "CROSS",
|
||||||
|
JOIN = "JOIN",
|
||||||
|
ON = "ON",
|
||||||
|
AS = "AS",
|
||||||
|
OUTER = "OUTER",
|
||||||
|
GROUP = "GROUP",
|
||||||
|
HAVING = "HAVING",
|
||||||
|
COUNT = "COUNT",
|
||||||
|
SUM = "SUM",
|
||||||
|
AVG = "AVG",
|
||||||
|
MIN = "MIN",
|
||||||
|
MAX = "MAX",
|
||||||
|
DISTINCT = "DISTINCT",
|
||||||
|
IDENTIFIER = "IDENTIFIER",
|
||||||
|
STRING = "STRING",
|
||||||
|
NUMBER = "NUMBER",
|
||||||
|
COMMA = "COMMA",
|
||||||
|
LPAREN = "LPAREN",
|
||||||
|
RPAREN = "RPAREN",
|
||||||
|
SEMICOLON = "SEMICOLON",
|
||||||
|
EQ = "EQ",
|
||||||
|
NEQ = "NEQ",
|
||||||
|
GT = "GT",
|
||||||
|
GTE = "GTE",
|
||||||
|
LT = "LT",
|
||||||
|
LTE = "LTE",
|
||||||
|
STAR = "STAR",
|
||||||
|
DOT = "DOT",
|
||||||
|
EOF = "EOF",
|
||||||
|
ILLEGAL = "ILLEGAL"
|
||||||
|
}
|
||||||
|
interface Token {
|
||||||
|
type: TokenType;
|
||||||
|
value: string;
|
||||||
|
position: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark SQL Lexer — 词法分析器
|
||||||
|
* @module sql/lexer
|
||||||
|
*
|
||||||
|
* 将 SQL 字符串切分为 Token 流。
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 将 SQL 字符串解析为 Token 列表 */
|
||||||
|
declare function tokenize(sql: string): Token[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* metona-sqlark — 入口文件
|
||||||
|
* @module metona-sqlark
|
||||||
|
* @version 0.1.12
|
||||||
|
*
|
||||||
|
* 前端关系型数据库,内存与磁盘双模式。
|
||||||
|
* 支持 Query Builder 链式 API 和 SQL 字符串查询。
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建数据库实例并初始化
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* const db = await MetonaSqlark.create({
|
||||||
|
* name: 'my-app',
|
||||||
|
* mode: 'hybrid',
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* await db.defineTable('users', {
|
||||||
|
* id: { type: 'string', primaryKey: true },
|
||||||
|
* name: { type: 'string', required: true },
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* await db.table('users').insert({ id: '1', name: 'Alice' });
|
||||||
|
* const results = await db.query('SELECT * FROM users');
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
declare function create(config: DatabaseConfig): Promise<MetonaSqlark>;
|
||||||
|
declare const api: {
|
||||||
|
VERSION: string;
|
||||||
|
version: string;
|
||||||
|
create: typeof create;
|
||||||
|
MetonaSqlark: typeof MetonaSqlark;
|
||||||
|
MeSqlark: typeof MetonaSqlark;
|
||||||
|
};
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
MetonaSqlark: typeof api;
|
||||||
|
MeSqlark: typeof api;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare const MeSqlark: typeof MetonaSqlark;
|
||||||
|
|
||||||
|
export { ColumnDef, DatabaseConfig, DeleteStatement, DiskEngine, FieldType, HybridEngine, IStorageEngine, IndexedDBEngine, InsertStatement, MeSqlark, MemoryEngine, MetonaSqlark, OPFSEngine, SelectStatement, Statement, StorageMode, Table, TableSchema, UpdateStatement, VERSION, api, create, api as default, parse, tokenize };
|
||||||
Vendored
+2716
File diff suppressed because it is too large
Load Diff
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+2738
File diff suppressed because it is too large
Load Diff
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
+3
-3
@@ -34,7 +34,7 @@
|
|||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://git.metona.cn/MetonaTeam/metona-sqlark.git"
|
"url": "git+https://git.metona.cn/MetonaTeam/MetonaSqlark.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"database",
|
"database",
|
||||||
@@ -49,9 +49,9 @@
|
|||||||
"author": "thzxx",
|
"author": "thzxx",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://git.metona.cn/MetonaTeam/metona-sqlark/issues"
|
"url": "https://git.metona.cn/MetonaTeam/MetonaSqlark/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://git.metona.cn/MetonaTeam/metona-sqlark#readme",
|
"homepage": "https://git.metona.cn/MetonaTeam/MetonaSqlark#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.22.0",
|
"@babel/core": "^7.22.0",
|
||||||
"@babel/plugin-transform-modules-commonjs": "^7.22.0",
|
"@babel/plugin-transform-modules-commonjs": "^7.22.0",
|
||||||
|
|||||||
+4
-4
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>在线演示 — metona-sqlark</title>
|
<title>在线演示 — MetonaSqlark</title>
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--bg:#0a0a0f; --surface:#0d1117; --surface2:#161b22; --border:#30363d;
|
--bg:#0a0a0f; --surface:#0d1117; --surface2:#161b22; --border:#30363d;
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<div class="logo"><div class="icon">◈</div><span>metona-sqlark</span></div>
|
<div class="logo"><div class="icon">◈</div><span>MetonaSqlark</span></div>
|
||||||
<nav>
|
<nav>
|
||||||
<a href="index.html">首页</a>
|
<a href="index.html">首页</a>
|
||||||
<a href="docs.html">文档</a>
|
<a href="docs.html">文档</a>
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
<div class="tab" data-tab="builder">Query Builder</div>
|
<div class="tab" data-tab="builder">Query Builder</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-area">
|
<div class="editor-area">
|
||||||
<textarea id="sql-input" placeholder="输入 SQL 语句... SELECT * FROM users WHERE age > 18 INSERT INTO users VALUES ('4', 'Diana', 'diana@test.com', 28) SELECT u.name, o.amount FROM users u INNER JOIN orders o ON u.id = o.user_id">-- 欢迎使用 metona-sqlark 在线演示 🚀
|
<textarea id="sql-input" placeholder="输入 SQL 语句... SELECT * FROM users WHERE age > 18 INSERT INTO users VALUES ('4', 'Diana', 'diana@test.com', 28) SELECT u.name, o.amount FROM users u INNER JOIN orders o ON u.id = o.user_id">-- 欢迎使用 MetonaSqlark 在线演示 🚀
|
||||||
-- 已预置 users / orders 表数据,试试以下查询:
|
-- 已预置 users / orders 表数据,试试以下查询:
|
||||||
|
|
||||||
SELECT * FROM users;
|
SELECT * FROM users;
|
||||||
@@ -335,7 +335,7 @@ document.querySelectorAll('.tab').forEach(tab => {
|
|||||||
|
|
||||||
// Boot
|
// Boot
|
||||||
initDB().then(() => {
|
initDB().then(() => {
|
||||||
console.log('✅ metona-sqlark demo ready');
|
console.log('✅ MetonaSqlark demo ready');
|
||||||
// Auto-run initial query
|
// Auto-run initial query
|
||||||
setTimeout(runQuery, 200);
|
setTimeout(runQuery, 200);
|
||||||
});
|
});
|
||||||
|
|||||||
+5
-5
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>API 文档 — metona-sqlark</title>
|
<title>API 文档 — MetonaSqlark</title>
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--bg:#0a0a0f; --surface:#14141f; --surface2:#1a1a2e; --border:#2a2a45;
|
--bg:#0a0a0f; --surface:#14141f; --surface2:#1a1a2e; --border:#2a2a45;
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
|
|
||||||
<header>
|
<header>
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<div class="logo"><div class="icon">◈</div><span>metona-sqlark</span></div>
|
<div class="logo"><div class="icon">◈</div><span>MetonaSqlark</span></div>
|
||||||
<nav>
|
<nav>
|
||||||
<a href="index.html">首页</a>
|
<a href="index.html">首页</a>
|
||||||
<a href="docs.html" class="nav-active">文档</a>
|
<a href="docs.html" class="nav-active">文档</a>
|
||||||
@@ -102,10 +102,10 @@
|
|||||||
|
|
||||||
<h2 id="install">📦 安装</h2>
|
<h2 id="install">📦 安装</h2>
|
||||||
<pre><span class="c">// npm</span>
|
<pre><span class="c">// npm</span>
|
||||||
npm install @metona-team/metona-sqlark
|
npm install @metona-team/MetonaSqlark
|
||||||
|
|
||||||
<span class="c">// ESM</span>
|
<span class="c">// ESM</span>
|
||||||
<span class="k">import</span> { MetonaSqlark, MeSqlark } <span class="k">from</span> <span class="s">'metona-sqlark'</span>;
|
<span class="k">import</span> { MetonaSqlark, MeSqlark } <span class="k">from</span> <span class="s">'MetonaSqlark'</span>;
|
||||||
|
|
||||||
<span class="c">// Browser</span>
|
<span class="c">// Browser</span>
|
||||||
<script src=<span class="s">"metona-sqlark.min.js"</span>></script>
|
<script src=<span class="s">"metona-sqlark.min.js"</span>></script>
|
||||||
@@ -273,7 +273,7 @@ db.<span class="f">on</span>(<span class="s">'afterQuery'</span>, <span class="k
|
|||||||
<span class="k">await</span> users.<span class="f">insert</span>({ <span class="s">id</span>: <span class="s">'1'</span>, <span class="s">name</span>: <span class="s">'Alice'</span>, <span class="s">age</span>: <span class="n">30</span> }); <span class="c">// ✅ 类型安全</span></pre>
|
<span class="k">await</span> users.<span class="f">insert</span>({ <span class="s">id</span>: <span class="s">'1'</span>, <span class="s">name</span>: <span class="s">'Alice'</span>, <span class="s">age</span>: <span class="n">30</span> }); <span class="c">// ✅ 类型安全</span></pre>
|
||||||
|
|
||||||
<h2 id="config">⚙️ 配置项</h2>
|
<h2 id="config">⚙️ 配置项</h2>
|
||||||
<pre><span class="k">import</span> { MetonaSqlark, MeSqlark } <span class="k">from</span> <span class="s">'metona-sqlark'</span>;
|
<pre><span class="k">import</span> { MetonaSqlark, MeSqlark } <span class="k">from</span> <span class="s">'MetonaSqlark'</span>;
|
||||||
<span class="c">// MeSqlark 是 MetonaSqlark 的别名,完全等价</span></pre>
|
<span class="c">// MeSqlark 是 MetonaSqlark 的别名,完全等价</span></pre>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
+66
-6
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>metona-sqlark — 前端 TypeScript 数据库</title>
|
<title>MetonaSqlark — 前端 TypeScript 数据库</title>
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--bg: #0a0a0f;
|
--bg: #0a0a0f;
|
||||||
@@ -136,13 +136,13 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="logo">
|
<div class="logo">
|
||||||
<div class="icon">◈</div>
|
<div class="icon">◈</div>
|
||||||
<span>metona-sqlark</span>
|
<span>MetonaSqlark</span>
|
||||||
</div>
|
</div>
|
||||||
<nav>
|
<nav>
|
||||||
<a href="index.html">首页</a>
|
<a href="index.html">首页</a>
|
||||||
<a href="docs.html">文档</a>
|
<a href="docs.html">文档</a>
|
||||||
<a href="demo.html">演示</a>
|
<a href="demo.html">演示</a>
|
||||||
<a href="https://git.metona.cn/MetonaTeam/metona-sqlark" target="_blank">GitHub</a>
|
<a href="https://git.metona.cn/MetonaTeam/MetonaSqlark" target="_blank">GitHub</a>
|
||||||
</nav>
|
</nav>
|
||||||
<a href="demo.html" class="btn btn-primary">立即体验</a>
|
<a href="demo.html" class="btn btn-primary">立即体验</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -161,11 +161,71 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- Install -->
|
||||||
|
<section style="padding:20px 0 60px;">
|
||||||
|
<div class="container">
|
||||||
|
<div class="section-title">
|
||||||
|
<h2>📦 <span>安装</span>引入</h2>
|
||||||
|
<p>多种方式,按需选择</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-grid">
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="icon">📦</div>
|
||||||
|
<h3>npm (Gitea Registry)</h3>
|
||||||
|
<div class="code-block" style="font-size:0.8rem;margin-top:12px;padding:14px;">
|
||||||
|
<span class="comment"># 配置 registry</span>
|
||||||
|
npm config set @metona-team:registry https://git.metona.cn/api/packages/MetonaTeam/npm/
|
||||||
|
|
||||||
|
<span class="comment"># 安装</span>
|
||||||
|
npm install @metona-team/metona-sqlark
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="icon">🌐</div>
|
||||||
|
<h3>CDN / Browser UMD</h3>
|
||||||
|
<div class="code-block" style="font-size:0.8rem;margin-top:12px;padding:14px;">
|
||||||
|
<span class="comment"><!-- 直接引用 dist 产物 --></span>
|
||||||
|
<<span class="keyword">script</span> src=<span class="string">"metona-sqlark.min.js"</span>></script>
|
||||||
|
<<span class="keyword">script</span>>
|
||||||
|
<span class="keyword">const</span> db = <span class="keyword">await</span> window.<span class="func">MetonaSqlark</span>.create({...});
|
||||||
|
<span class="comment">// 或 window.MeSqlark(别名)</span>
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="icon">⚡</div>
|
||||||
|
<h3>ESM / TypeScript</h3>
|
||||||
|
<div class="code-block" style="font-size:0.8rem;margin-top:12px;padding:14px;">
|
||||||
|
<span class="keyword">import</span> { MetonaSqlark, MeSqlark }
|
||||||
|
<span class="keyword">from</span> <span class="string">'@metona-team/metona-sqlark'</span>;
|
||||||
|
|
||||||
|
<span class="keyword">const</span> db = <span class="keyword">await</span> <span class="func">MetonaSqlark</span>.create({
|
||||||
|
<span class="string">name</span>: <span class="string">'my-app'</span>,
|
||||||
|
<span class="string">mode</span>: <span class="string">'hybrid'</span>,
|
||||||
|
});
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="icon">🔧</div>
|
||||||
|
<h3>CommonJS</h3>
|
||||||
|
<div class="code-block" style="font-size:0.8rem;margin-top:12px;padding:14px;">
|
||||||
|
<span class="keyword">const</span> { MetonaSqlark } =
|
||||||
|
<span class="func">require</span>(<span class="string">'@metona-team/metona-sqlark'</span>);
|
||||||
|
|
||||||
|
(<span class="keyword">async</span> () => {
|
||||||
|
<span class="keyword">const</span> db = <span class="keyword">await</span> <span class="func">MetonaSqlark</span>.create({...});
|
||||||
|
})();
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- Features -->
|
<!-- Features -->
|
||||||
<section>
|
<section>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="section-title">
|
<div class="section-title">
|
||||||
<h2>为什么选择 <span>metona-sqlark</span></h2>
|
<h2>为什么选择 <span>MetonaSqlark</span></h2>
|
||||||
<p>专为前端打造的数据库引擎</p>
|
<p>专为前端打造的数据库引擎</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-grid">
|
<div class="feature-grid">
|
||||||
@@ -238,7 +298,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="section-title">
|
<div class="section-title">
|
||||||
<h2>用<span>数字</span>说话</h2>
|
<h2>用<span>数字</span>说话</h2>
|
||||||
<p>metona-sqlark 的核心指标</p>
|
<p>MetonaSqlark 的核心指标</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="stats">
|
<div class="stats">
|
||||||
<div class="stat-card"><div class="num">235+</div><div class="label">测试用例</div></div>
|
<div class="stat-card"><div class="num">235+</div><div class="label">测试用例</div></div>
|
||||||
@@ -251,7 +311,7 @@
|
|||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>© 2026 <a href="https://git.metona.cn/MetonaTeam/metona-sqlark">MetonaTeam</a>. MIT License. Built with TypeScript.</p>
|
<p>© 2026 <a href="https://git.metona.cn/MetonaTeam/MetonaSqlark">MetonaTeam</a>. MIT License. Built with TypeScript.</p>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user