npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@onyx-p/imlib-web

v3.0.8

Published

Electron-only IM SDK with a Signal-style encrypted local message database.

Downloads

1,313

Readme

ac-imlib-web

Electron-only IM SDK with a Signal-style encrypted local message database.

安装

npm install @onyx-p/imlib-web --save

The database runtime requires Electron 30 or newer. The local database uses @signalapp/sqlcipher; review its AGPL-3.0-only license before distribution.

Electron 主进程

Initialize the database service after app.whenReady(). This creates one primary writer worker and three reader workers. The primary connection owns all writes and schema migrations.

const { app, BrowserWindow } = require('electron')
const {
  initializeDatabaseMain
} = require('@onyx-p/imlib-web/main')

let database

app.whenReady().then(() => {
  database = initializeDatabaseMain({
    // Recommended: restrict IPC to your own renderer origin.
    isTrustedEvent(event) {
      return event.senderFrame?.url.startsWith('file://') === true
    }
  })

  const window = new BrowserWindow({
    webPreferences: {
      contextIsolation: true,
      nodeIntegration: false,
      preload: require.resolve('@onyx-p/imlib-web/preload')
    }
  })
})

If the application already has a preload script, load the database preload entry from that script instead:

require('@onyx-p/imlib-web/preload')

The preload exposes only window.acimDatabase.request(). Renderer code cannot execute arbitrary SQL or invoke arbitrary Electron channels.

Renderer

The public IM API remains in the default package entry. Await user setup so the SQLCipher database, schema migrations, and legacy import finish before message synchronization starts.

import * as ACIMLib from '@onyx-p/imlib-web'

ACIMLib.init({ appkey: 'your-app-key' })
await ACIMLib.setUserLogged(profile)
await ACIMLib.connect()

数据库与迁移

  • Database files are stored below Electron's userData/sql directory.
  • Account identifiers are hashed before being used as filenames.
  • Each account receives an independent random 256-bit SQLCipher key.
  • Keys are encrypted with Electron safeStorage before they are written to database-keys.json.
  • Schema changes run automatically through ordered PRAGMA user_version migrations in the primary worker.
  • SQLCipher runs in WAL mode with foreign keys enabled and full synchronous durability.

On first open, the renderer looks for the previous IndexedDB database named im_message_cache_1_<appKey>_<userId>. Existing messages_new and dialogStates_new records are read in bounded batches, legacy content fields are decrypted, and records are idempotently inserted into SQLCipher. Completion is recorded only after every batch commits. The old IndexedDB database is kept as a recovery copy.

Migration runs automatically. It can also be retried explicitly with progress:

const result = await ACIMLib.migrateLegacyDatabase(progress => {
  console.log(
    `Migrated ${progress.processedMessages} messages and ` +
    `${progress.processedDialogStates} dialog states`
  )
})

console.log(result)
// { migrated: true|false, messages: number, dialogStates: number }

If migration is interrupted, call the same API again. Imports use upserts, so already committed batches are safe to repeat.

消息搜索

单会话搜索接口保持不变。全局搜索使用 Signal 风格的 FTS5 前缀匹配, 按消息时间倒序返回,默认最多 500 条。文本消息按正文搜索, 文件消息按文件名搜索:

const result = await ACIMLib.searchMessages('项目进度')
console.log(result.data)

// 可选:限制返回数量
const recent = await ACIMLib.searchMessages('signal', 50)