@devrev/meerkat-dbm

中文文档
0.1.49发布于 2026/10/15TypeScriptCommonJS构建来源已验证近 30 天下载 1.5万

@devrev/meerkat-dbm 是浏览器首个数据库管理层,建立在 鸭子 - 瓦斯姆它协调查询执行,管理 DuckDB 实例,缓存文件,在浏览器存储中坚持数据,并优化备忘

中文使用文档
文档目录10 节
  1. 建筑
  2. 为什么是Meerkat DBM?
  3. 关键特性
  4. 数据库管理
  5. QQ 文件管理
  6. 安装
  7. 使用量
  8. 1. 实施实例管理
  9. 2. 实例:带有持久性存储的序列查询
  10. 3. 实例:与IFrame运行器平行查询

@devrev/meerkat-dbm (英语)

@devrev/meerkat-dbm 是浏览器首个数据库管理层,建立在 鸭子 - 瓦斯姆. 它协调查询执行,管理 DuckDB 实例,缓存文件,在浏览器存储中坚持数据,并优化内存使用,以便在网络应用程序中实现稳健的高性能数据处理.

它旨在将分析SQL的力量带入浏览器而不损害应用程序稳定性或用户体验. 无论是构建数据密集型的仪表板,交互式报告工具,还是离线第一应用程序,Meerkat DBM都提供了您需要的基础.

建筑

Meerkat DBM由几个关键组件组成,它们共同管理数据并在浏览器中执行查询:

  • DBM (数据库管理器):中央管弦乐团. 它接收询问,管理执行周期,并与其他组成部分进行协调.
  • 文件管理器:处理数据存储和检索的所有方面。 它可以管理内存数据,或者坚持到索引数据库.
  • 实例管理器: 由用户执行的组件,负责创建、管理和终止 duckdb-wasm 实例.
  • DuckDB 实例: 基础 duckdb-wasm 执行查询的引擎,在主线程中运行,或在 iFrames 为并行性运行.

这种模块化设计为在浏览器中管理复杂数据工作流程提供了明确分离的关切.

为什么是Meerkat DBM?

虽然 duckdb-wasm 在复杂的网络应用程序中直接使用, Meerkat DBM提供了一个结构化的,生产准备的层,解决了常见的问题:

  • * 记忆安全:通过管理查询队列和内存互换来防止出记忆出错,确保您的应用即使有大数据集也能保持稳定.
  • * 持久性: 提供无缝索引 DB 存储,允许数据在浏览器会话中持续.
  • 高级文件管理: 简化各种文件格式(Parquet,JSON,远程URL)的处理,以智能缓存和分出.
  • ++ 并行处理:解锁高性能分析器,可选iframe基于架构进行并行查询执行,防止UI被冻结.

关键特性

数据库管理

  • 实例管理: DuckDB 实例的自动生命周期管理.
  • 循环和关闭:通过在最终停产前回收发动机(teardown + warm recretting)来恢复工人在无活性后的高水记忆,并设有由消费者供应的门.
  • 连接集合: 有效管理数据库连接.
  • 查询排队:按顺序或平行执行的查询的智能调度.
  • 表格锁定:确保同时访问期间的线性安全表操作.

QQ 文件管理

  • 多个格式: Parquet的原生支持,JSON文件.
  • 散装操作:用于批量登记和处理文件的高性能API.
  • 分区: 支持表格分割,以高效地管理和查询大数据集.
  • 元数据处理: 对表格和文件的丰富元数据支持.
  • 多个存储模式: 有弹性存储选项,包括内存和索引数据库.

安装

npm install @devrev/meerkat-dbm @duckdb/duckdb-wasm

使用量

1. 实施实例管理

Meerkat DBM要求您提供 InstanceManager将图书馆与特定的 duckdb-wasm 版本,赋予您对其即时和配置的全部控制.

// src/instance-manager.ts
import * as duckdb from '@duckdb/duckdb-wasm';
import { InstanceManagerType } from '@devrev/meerkat-dbm';

// Select the desired DuckDB bundle
const JSDELIVR_BUNDLES = duckdb.getJsDelivrBundles();

export class InstanceManager implements InstanceManagerType {
  private db: duckdb.AsyncDuckDB | null = null;

  private async initDB(): Promise<duckdb.AsyncDuckDB> {
    const bundle = await duckdb.selectBundle(JSDELIVR_BUNDLES);

    const worker_url = URL.createObjectURL(new Blob([`importScripts("${bundle.mainWorker!}");`], { type: 'text/javascript' }));

    const worker = new Worker(worker_url);
    const logger = { log: (msg: any) => console.log(msg) };
    const db = new duckdb.AsyncDuckDB(logger, worker);

    await db.instantiate(bundle.mainModule, bundle.pthreadWorker);

    URL.revokeObjectURL(worker_url);
    return db;
  }

  async getDB(): Promise<duckdb.AsyncDuckDB> {
    if (!this.db) {
      this.db = await this.initDB();
    }
    return this.db;
  }

  async terminateDB(): Promise<void> {
    if (this.db) {
      await this.db.terminate();
      this.db = null;
    }
  }
}

2. 实例:带有持久性存储的序列查询

此示例使用 DBM 带有 IndexedDBFileManager 用于安全、相继的查询执行和浏览器会话的数据持续.

import { DBM, IndexedDBFileManager } from '@devrev/meerkat-dbm';
import { InstanceManager } from './instance-manager';

// 1. Create the managers
const instanceManager = new InstanceManager();
const fileManager = new IndexedDBFileManager({
  instanceManager,
  // This function is called by Meerkat to fetch file data when needed
  fetchTableFileBuffers: async (tableName) => {
    // In a real app, you would fetch data from a indexdb
    return [];
  },
});

// 2. Create the DBM instance
const dbm = new DBM({
  instanceManager,
  fileManager,
  onEvent: (event) => console.info('DBM Event:', event),
  options: {
    // Optional intermediate "recycle" after 2s of inactivity: tear down the
    // DuckDB instance and immediately re-instantiate it. Reclaims the worker's
    // high-water memory (WASM linear memory only grows) while keeping the
    // engine warm for the next query. Must be less than shutdownInactiveTime.
    recycleInactiveTime: 2000,
    // Optional gate consulted before each recycle. Return false to skip it
    // (e.g. nothing worth reclaiming). Defaults to always-recycle when omitted.
    shouldRecycle: () => true,
    // Automatically shut down the DuckDB instance after 5s of inactivity
    shutdownInactiveTime: 5000,
  },
});

// 3. Register data
await fileManager.registerJSON({
  tableName: 'sales',
  fileName: 'sales.json',
  json: [
    { id: 1, product: 'Laptop', amount: 1200 },
    { id: 2, product: 'Mouse', amount: 25 },
    { id: 3, product: 'Keyboard', amount: 75 },
  ],
});

// 4. Run a query
const results = await dbm.query('SELECT * FROM sales WHERE amount > 50');
console.log(results);

3. 实例:与IFrame运行器平行查询

此设置用途 DBMParallel 财务报告和审定财务报表 ParallelIndexedDBFileManager 在多个基于 Iframe DuckDB 实例中并行执行查询.

import { DBMParallel, IFrameRunnerManager, ParallelIndexedDBFileManager } from '@devrev/meerkat-dbm';
import log from 'loglevel';
import { InstanceManager } from './instance-manager';

// 1. Create instance and file managers
const instanceManager = new InstanceManager();
const fileManager = new ParallelIndexedDBFileManager({
  instanceManager,
  fetchTableFileBuffers: async (table) => [],
  logger: log,
});

// 2. Set up the iframe runner manager for parallel execution
const iframeManager = new IFrameRunnerManager({
  // URL to the runner HTML file that hosts the DuckDB instance
  runnerURL: 'http://localhost:4204/runner/indexeddb-runner.html',
  origin: 'http://localhost:4204',
  totalRunners: 4, // Number of parallel iframes
  fetchTableFileBuffers: async (table) => [],
  logger: log,
});

// 3. Create the parallel DBM instance
const parallelDBM = new DBMParallel({
  instanceManager,
  fileManager,
  iFrameRunnerManager: iframeManager,
  logger: log,
  options: {
    shutdownInactiveTime: 10000,
  },
});

// 4. Register data
await fileManager.bulkRegisterJSON([
  {
    tableName: 'transactions',
    fileName: 'transactions.json',
    json: [
      { id: 1, product_id: 101, amount: 1200 },
      { id: 2, product_id: 102, amount: 25 },
    ],
  },
  {
    tableName: 'products',
    fileName: 'products.json',
    json: [
      { id: 101, name: 'Laptop', category: 'Electronics' },
      { id: 102, name: 'Mouse', category: 'Accessories' },
    ],
  },
]);

// 5. Execute queries in parallel
const results = await Promise.all([
  parallelDBM.query('SELECT * FROM transactions WHERE amount > 100'),
  parallelDBM.query(`
    SELECT p.category, COUNT(*) as product_count 
    FROM transactions t 
    JOIN products p ON t.product_id = p.id 
    GROUP BY p.category
  `),
]);

console.log('Query Results', results);

版本与发布记录

@devrev/meerkat-dbm 共发布 28 个版本,首次发布于 2024/09/05;过去 12 个月发布了 13 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.1.49latest2026/10/1527 天前
0.1.482026/10/081 个月前
0.1.472026/07/024 个月前
0.1.462026/07/024 个月前
0.1.452026/07/014 个月前
0.1.442026/06/254 个月前

关于 @devrev/meerkat-dbm 的常见问题

@devrev/meerkat-dbm 是什么?

@devrev/meerkat-dbm 是浏览器首个数据库管理层,建立在 鸭子 - 瓦斯姆它协调查询执行,管理 DuckDB 实例,缓存文件,在浏览器存储中坚持数据,并优化备忘

如何安装 @devrev/meerkat-dbm?

在项目目录运行 npm install @devrev/meerkat-dbm,或使用 pnpm add / yarn add / bun add。

@devrev/meerkat-dbm 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@devrev/meerkat-dbm 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@devrev/meerkat-dbm 可以商用吗?

@devrev/meerkat-dbm 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@devrev/meerkat-dbm 的下载量有多少?

根据 npm 官方下载统计,@devrev/meerkat-dbm 在 2026/10/12 – 2026/11/10 这 30 天内被下载 14,778 次,日均约 493 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@devrev/meerkat-dbm 还在维护吗?

最新版本 0.1.49 发布于 2026/10/15(27 天前);至今共发布 28 个版本,其中过去 12 个月发布了 13 个;首次发布于 2024/09/05。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。