release: v0.2.2 AriaEngine OPFS 自研存储后端 — 零依赖纯文件系统
This commit is contained in:
Vendored
+88
-1
@@ -2780,6 +2780,89 @@ class MemoryBackend {
|
||||
}
|
||||
}
|
||||
|
||||
class OPFSBackend {
|
||||
constructor() {
|
||||
this.root = null;
|
||||
this.dbDir = null;
|
||||
this.dbName = '';
|
||||
}
|
||||
async open(name) {
|
||||
this.dbName = name;
|
||||
this.root = await navigator.storage.getDirectory();
|
||||
this.dbDir = await this.root.getDirectoryHandle(name, { create: true });
|
||||
}
|
||||
async close() {
|
||||
this.dbDir = null;
|
||||
this.root = null;
|
||||
}
|
||||
isOpen() {
|
||||
return this.dbDir !== null;
|
||||
}
|
||||
async read(key) {
|
||||
if (!this.dbDir)
|
||||
return null;
|
||||
try {
|
||||
const fh = await this.dbDir.getFileHandle(key);
|
||||
const file = await fh.getFile();
|
||||
return await file.arrayBuffer();
|
||||
}
|
||||
catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async write(key, data) {
|
||||
if (!this.dbDir)
|
||||
return;
|
||||
const fh = await this.dbDir.getFileHandle(key, { create: true });
|
||||
const writable = await fh.createWritable();
|
||||
await writable.write(data);
|
||||
await writable.close();
|
||||
}
|
||||
async delete(key) {
|
||||
if (!this.dbDir)
|
||||
return;
|
||||
try {
|
||||
await this.dbDir.removeEntry(key);
|
||||
}
|
||||
catch {
|
||||
// 文件不存在则忽略
|
||||
}
|
||||
}
|
||||
async listKeys() {
|
||||
if (!this.dbDir)
|
||||
return [];
|
||||
const keys = [];
|
||||
// FileSystemDirectoryHandle.entries() 返回 AsyncIterable,使用 any 绕过 dts 生成限制
|
||||
const dir = this.dbDir;
|
||||
for await (const [name] of dir.entries()) {
|
||||
keys.push(name);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
async exists(key) {
|
||||
if (!this.dbDir)
|
||||
return false;
|
||||
try {
|
||||
await this.dbDir.getFileHandle(key);
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async clear() {
|
||||
if (!this.dbDir)
|
||||
return;
|
||||
const dir = this.dbDir;
|
||||
for await (const [name] of dir.entries()) {
|
||||
try {
|
||||
await this.dbDir.removeEntry(name);
|
||||
}
|
||||
catch { /* ignore */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AriaEngine — 自研页面式存储引擎主类
|
||||
* @module engine/aria/index
|
||||
@@ -2817,7 +2900,10 @@ class AriaEngine {
|
||||
return;
|
||||
this.dbName = dbName;
|
||||
// 1. 存储后端
|
||||
if (this.config.storageBackend === 'indexeddb') {
|
||||
if (this.config.storageBackend === 'opfs') {
|
||||
this.backend = new OPFSBackend();
|
||||
}
|
||||
else if (this.config.storageBackend === 'indexeddb') {
|
||||
this.backend = new IndexedDBBackend();
|
||||
}
|
||||
else {
|
||||
@@ -5825,6 +5911,7 @@ exports.IndexedDBEngine = IndexedDBEngine;
|
||||
exports.MeSqlark = MeSqlark;
|
||||
exports.MemoryEngine = MemoryEngine;
|
||||
exports.MetonaSqlark = MetonaSqlark;
|
||||
exports.OPFSBackend = OPFSBackend;
|
||||
exports.OPFSEngine = OPFSEngine;
|
||||
exports.Table = Table;
|
||||
exports.VERSION = VERSION;
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+54
-1
@@ -851,6 +851,59 @@ interface Token {
|
||||
/** 将 SQL 字符串解析为 Token 列表 */
|
||||
declare function tokenize(sql: string): Token[];
|
||||
|
||||
/**
|
||||
* AriaEngine Storage Backend — 存储后端抽象层
|
||||
* @module engine/aria/store/backend
|
||||
*
|
||||
* 封装底层浏览器存储 API(IndexedDB / OPFS / Memory 回退),
|
||||
* 供 Buffer Pool 的 PageIO 和 WAL 的 WALStore 使用。
|
||||
*/
|
||||
interface IStorageBackend {
|
||||
/** 打开存储 */
|
||||
open(name: string): Promise<void>;
|
||||
/** 关闭存储 */
|
||||
close(): Promise<void>;
|
||||
/** 是否已打开 */
|
||||
isOpen(): boolean;
|
||||
/** 读取数据块 */
|
||||
read(key: string): Promise<ArrayBuffer | null>;
|
||||
/** 写入数据块 */
|
||||
write(key: string, data: ArrayBuffer): Promise<void>;
|
||||
/** 删除数据块 */
|
||||
delete(key: string): Promise<void>;
|
||||
/** 列出所有 key */
|
||||
listKeys(): Promise<string[]>;
|
||||
/** 检查 key 是否存在 */
|
||||
exists(key: string): Promise<boolean>;
|
||||
/** 清空所有数据 */
|
||||
clear(): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* AriaEngine OPFS Backend — 基于 Origin Private File System 的自研存储后端
|
||||
* @module engine/aria/store/opfs_backend
|
||||
*
|
||||
* 零外部依赖,纯浏览器文件系统 API。
|
||||
* 每个 key 对应 OPFS 目录下的一个二进制文件。
|
||||
*
|
||||
* 浏览器要求:Chrome 102+ / Edge 102+
|
||||
*/
|
||||
|
||||
declare class OPFSBackend implements IStorageBackend {
|
||||
private root;
|
||||
private dbDir;
|
||||
private dbName;
|
||||
open(name: string): Promise<void>;
|
||||
close(): Promise<void>;
|
||||
isOpen(): boolean;
|
||||
read(key: string): Promise<ArrayBuffer | null>;
|
||||
write(key: string, data: ArrayBuffer): Promise<void>;
|
||||
delete(key: string): Promise<void>;
|
||||
listKeys(): Promise<string[]>;
|
||||
exists(key: string): Promise<boolean>;
|
||||
clear(): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* metona-sqlark — 入口文件
|
||||
* @module metona-sqlark
|
||||
@@ -896,4 +949,4 @@ declare global {
|
||||
|
||||
declare const MeSqlark: typeof MetonaSqlark;
|
||||
|
||||
export { AriaEngine, AriaEngineConfig, 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 };
|
||||
export { AriaEngine, AriaEngineConfig, ColumnDef, DatabaseConfig, DeleteStatement, DiskEngine, FieldType, HybridEngine, IStorageEngine, IndexedDBEngine, InsertStatement, MeSqlark, MemoryEngine, MetonaSqlark, OPFSBackend, OPFSEngine, SelectStatement, Statement, StorageMode, Table, TableSchema, UpdateStatement, VERSION, api, create, api as default, parse, tokenize };
|
||||
|
||||
Vendored
+88
-2
@@ -2776,6 +2776,89 @@ class MemoryBackend {
|
||||
}
|
||||
}
|
||||
|
||||
class OPFSBackend {
|
||||
constructor() {
|
||||
this.root = null;
|
||||
this.dbDir = null;
|
||||
this.dbName = '';
|
||||
}
|
||||
async open(name) {
|
||||
this.dbName = name;
|
||||
this.root = await navigator.storage.getDirectory();
|
||||
this.dbDir = await this.root.getDirectoryHandle(name, { create: true });
|
||||
}
|
||||
async close() {
|
||||
this.dbDir = null;
|
||||
this.root = null;
|
||||
}
|
||||
isOpen() {
|
||||
return this.dbDir !== null;
|
||||
}
|
||||
async read(key) {
|
||||
if (!this.dbDir)
|
||||
return null;
|
||||
try {
|
||||
const fh = await this.dbDir.getFileHandle(key);
|
||||
const file = await fh.getFile();
|
||||
return await file.arrayBuffer();
|
||||
}
|
||||
catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async write(key, data) {
|
||||
if (!this.dbDir)
|
||||
return;
|
||||
const fh = await this.dbDir.getFileHandle(key, { create: true });
|
||||
const writable = await fh.createWritable();
|
||||
await writable.write(data);
|
||||
await writable.close();
|
||||
}
|
||||
async delete(key) {
|
||||
if (!this.dbDir)
|
||||
return;
|
||||
try {
|
||||
await this.dbDir.removeEntry(key);
|
||||
}
|
||||
catch {
|
||||
// 文件不存在则忽略
|
||||
}
|
||||
}
|
||||
async listKeys() {
|
||||
if (!this.dbDir)
|
||||
return [];
|
||||
const keys = [];
|
||||
// FileSystemDirectoryHandle.entries() 返回 AsyncIterable,使用 any 绕过 dts 生成限制
|
||||
const dir = this.dbDir;
|
||||
for await (const [name] of dir.entries()) {
|
||||
keys.push(name);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
async exists(key) {
|
||||
if (!this.dbDir)
|
||||
return false;
|
||||
try {
|
||||
await this.dbDir.getFileHandle(key);
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async clear() {
|
||||
if (!this.dbDir)
|
||||
return;
|
||||
const dir = this.dbDir;
|
||||
for await (const [name] of dir.entries()) {
|
||||
try {
|
||||
await this.dbDir.removeEntry(name);
|
||||
}
|
||||
catch { /* ignore */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AriaEngine — 自研页面式存储引擎主类
|
||||
* @module engine/aria/index
|
||||
@@ -2813,7 +2896,10 @@ class AriaEngine {
|
||||
return;
|
||||
this.dbName = dbName;
|
||||
// 1. 存储后端
|
||||
if (this.config.storageBackend === 'indexeddb') {
|
||||
if (this.config.storageBackend === 'opfs') {
|
||||
this.backend = new OPFSBackend();
|
||||
}
|
||||
else if (this.config.storageBackend === 'indexeddb') {
|
||||
this.backend = new IndexedDBBackend();
|
||||
}
|
||||
else {
|
||||
@@ -5815,5 +5901,5 @@ if (typeof window !== 'undefined') {
|
||||
// 别名
|
||||
const MeSqlark = MetonaSqlark;
|
||||
|
||||
export { AriaEngine, HybridEngine, IndexedDBEngine, MeSqlark, MemoryEngine, MetonaSqlark, OPFSEngine, Table, VERSION, api, create, api as default, parse, tokenize };
|
||||
export { AriaEngine, HybridEngine, IndexedDBEngine, MeSqlark, MemoryEngine, MetonaSqlark, OPFSBackend, OPFSEngine, Table, VERSION, api, create, api as default, parse, tokenize };
|
||||
//# sourceMappingURL=metona-sqlark.esm.js.map
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+88
-1
@@ -2782,6 +2782,89 @@
|
||||
}
|
||||
}
|
||||
|
||||
class OPFSBackend {
|
||||
constructor() {
|
||||
this.root = null;
|
||||
this.dbDir = null;
|
||||
this.dbName = '';
|
||||
}
|
||||
async open(name) {
|
||||
this.dbName = name;
|
||||
this.root = await navigator.storage.getDirectory();
|
||||
this.dbDir = await this.root.getDirectoryHandle(name, { create: true });
|
||||
}
|
||||
async close() {
|
||||
this.dbDir = null;
|
||||
this.root = null;
|
||||
}
|
||||
isOpen() {
|
||||
return this.dbDir !== null;
|
||||
}
|
||||
async read(key) {
|
||||
if (!this.dbDir)
|
||||
return null;
|
||||
try {
|
||||
const fh = await this.dbDir.getFileHandle(key);
|
||||
const file = await fh.getFile();
|
||||
return await file.arrayBuffer();
|
||||
}
|
||||
catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async write(key, data) {
|
||||
if (!this.dbDir)
|
||||
return;
|
||||
const fh = await this.dbDir.getFileHandle(key, { create: true });
|
||||
const writable = await fh.createWritable();
|
||||
await writable.write(data);
|
||||
await writable.close();
|
||||
}
|
||||
async delete(key) {
|
||||
if (!this.dbDir)
|
||||
return;
|
||||
try {
|
||||
await this.dbDir.removeEntry(key);
|
||||
}
|
||||
catch {
|
||||
// 文件不存在则忽略
|
||||
}
|
||||
}
|
||||
async listKeys() {
|
||||
if (!this.dbDir)
|
||||
return [];
|
||||
const keys = [];
|
||||
// FileSystemDirectoryHandle.entries() 返回 AsyncIterable,使用 any 绕过 dts 生成限制
|
||||
const dir = this.dbDir;
|
||||
for await (const [name] of dir.entries()) {
|
||||
keys.push(name);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
async exists(key) {
|
||||
if (!this.dbDir)
|
||||
return false;
|
||||
try {
|
||||
await this.dbDir.getFileHandle(key);
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async clear() {
|
||||
if (!this.dbDir)
|
||||
return;
|
||||
const dir = this.dbDir;
|
||||
for await (const [name] of dir.entries()) {
|
||||
try {
|
||||
await this.dbDir.removeEntry(name);
|
||||
}
|
||||
catch { /* ignore */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AriaEngine — 自研页面式存储引擎主类
|
||||
* @module engine/aria/index
|
||||
@@ -2819,7 +2902,10 @@
|
||||
return;
|
||||
this.dbName = dbName;
|
||||
// 1. 存储后端
|
||||
if (this.config.storageBackend === 'indexeddb') {
|
||||
if (this.config.storageBackend === 'opfs') {
|
||||
this.backend = new OPFSBackend();
|
||||
}
|
||||
else if (this.config.storageBackend === 'indexeddb') {
|
||||
this.backend = new IndexedDBBackend();
|
||||
}
|
||||
else {
|
||||
@@ -5827,6 +5913,7 @@
|
||||
exports.MeSqlark = MeSqlark;
|
||||
exports.MemoryEngine = MemoryEngine;
|
||||
exports.MetonaSqlark = MetonaSqlark;
|
||||
exports.OPFSBackend = OPFSBackend;
|
||||
exports.OPFSEngine = OPFSEngine;
|
||||
exports.Table = Table;
|
||||
exports.VERSION = VERSION;
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user