# @irithell-js/better-sqlite3-termux

![NPM Version](https://img.shields.io/npm/v/@irithell-js/better-sqlite3-termux?style=flat-square&color=blue)
![Node Version](https://img.shields.io/node/v/@irithell-js/better-sqlite3-termux?style=flat-square)
![License](https://img.shields.io/npm/l/@irithell-js/better-sqlite3-termux?style=flat-square)
![Platform](https://img.shields.io/badge/Platform-Termux%20%7C%20Linux-lightgrey?style=flat-square)

Wrapper for the `better-sqlite3` module, specifically designed to resolve compilation and execution failures of native C++ dependencies on Termux (Android). The package acts as a **Drop-in Replacement**, providing full compatibility with existing code and supporting both CommonJS and ESM.

## Architecture and Solution

Android-based systems use emulated partitions (FUSE/FAT) on `/sdcard/` that do not have native support for creating symbolic links (symlinks) or strict execution permissions. Since the generic `better-sqlite3` module depends on `node-gyp` to compile C++ code and the base SQLite itself, the traditional installation fails on the phone's internal storage.

The `@irithell-js/better-sqlite3-termux` resolves this bottleneck through an isolation architecture:

1. **Analytical Detection:** Reads environment variables (`process.env.PREFIX`) to identify if the current runtime is Termux or a standard Linux server.
2. **System Dependency Injection:** Triggers the system package manager (`pkg`) to install required repositories and C libraries (build-essential, clang, python, sqlite, etc).
3. **Hash Isolation:** Calculates a unique MD5 identifier based on your project directory to create an aseptic build environment.
4. **Runtime & Background Compilation:** Runs the native rebuild of the SQLite engine and injects the correct paths via a `.json` state file.
5. **Original Types:** The module provides original types from better-sqlite3.

## Installation

```bash
npm install @irithell-js/better-sqlite3-termux
```

## How to Use

Usage is identical to the original package. No refactoring is required in your current code; simply replace the `import` or `require` source.

### CommonJS

```javascript
const Database = require("@irithell-js/better-sqlite3-termux");

const db = new Database("bot.db");
db.exec("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)");

const insert = db.prepare("INSERT INTO users (name) VALUES (?)");
insert.run("Irithell");

const row = db.prepare("SELECT * FROM users").get();
console.log(row.name);
```

### ESM

```typescript
import Database from "@irithell-js/better-sqlite3-termux";

const db = new Database("bot.db");
// Normal database operations...
```

## Version Control (Update & Downgrade)

By default, the proxy automatically fetches and compiles the `latest` version of the original `better-sqlite3` package. If you need to pin a specific version, downgrade, or update, you can do so seamlessly without cluttering your project with broken binaries.

There are two methods to specify the target version:

### Method 1: Via `package.json` (Recommended)

You can define the desired version using a custom `irithell` block in your project's root `package.json`:

```json
{
  "name": "your-project",
  "dependencies": {
    "@irithell-js/better-sqlite3-termux": "^1.0.13"
  },
  "irithell": {
    "sqliteVersion": "12.9.0"
  }
}
```

### Method 2: Via Environment Variable

You can force a specific version directly from the terminal, either at runtime execution or during installation:

```bash
# At runtime execution
SQLITE_VERSION=12.9.0 node app.js

# Or during installation
SQLITE_VERSION=12.9.0 npm install @irithell-js/better-sqlite3-termux
```

### Forcing the Engine Rebuild

If you wish to manually force a rebuild of the isolated engine at any time, simply run the installation script directly:

```bash
node ./node_modules/@irithell-js/better-sqlite3-termux/dist/install.cjs
```

## Engine Management API

You can programmatically manage compiled SQLite engines directly from your code:

```javascript
const {
  listEngines,
  getCurrentEngine,
  deleteEngine,
  clearAllEngines,
  engineManager,
} = require("@irithell-js/better-sqlite3-termux");

// List all compiled engines in ~/.sqlite3_engines/
console.log(listEngines());

// Get info about the current project's engine
console.log(getCurrentEngine());

// Delete a specific engine by projectId (or current project's engine if omitted)
deleteEngine();

// Delete all compiled engines
clearAllEngines();

// Alternatively, use the helper object:
engineManager.list();
engineManager.current();
engineManager.delete();
engineManager.clearAll();
```

## Internal Technical Features

### Automatic Runtime Setup & Recovery

When package managers (such as npm, yarn, or pnpm) block `postinstall` scripts via `--ignore-scripts`, `@irithell-js/better-sqlite3-termux` intercepts the missing binary state during application initialization (`require` / `import`). It dynamically compiles and configures the engine on the fly before exporting the Database API, preventing application crashes.

### Environment Migration (Cross-Environment Auto-Recovery)

When developing on Termux and later moving the entire project folder to a Linux VPS or Docker container, binary architectures conflict.
The proxy registers metadata containing the source architecture at the time of installation. During execution on the new platform, the module intercepts the discrepancy in the binary, cleans the outdated engine, and automatically initiates a native rebuild focused on the new kernel.

## Cleanup

If it is necessary to delete the compiled instances in Termux memory, the isolation directory is located at:

```bash
~/.sqlite3_engines/
```

## Changelog

### [1.0.13]
- **Standard Linux Host Fallback:** Fixed standard Linux/VPS/container fallback behavior. Isolated engine directories (`~/.sqlite3_engines/`) are now exclusively reserved for Termux (Android). On standard environments, the module resolves the standard `better-sqlite3` module directly without creating engine subdirectories.

### [1.0.12]
- **ESM Dynamic Require Fix:** Resolved `Dynamic require is not supported` errors in ESM runtime and `.mjs`/`.js` installer scripts by utilizing native `createRequire(import.meta.url)` directly.

### [1.0.11]
- **Smart Package Pre-check:** Added `dpkg-query` validation to skip running `pkg install` if required system dependencies are already installed on Termux.
- **APT Sandbox Permission Fix:** Added `-o APT::Sandbox::User=root --allow-unauthenticated` flags to prevent APT privilege drop crashes (`fstat` errors) on Android devices.
- **Manual Resolution Help:** Formatted clear error banners with Termux manual installation options.

### [1.0.10]
- **Runtime Installation Integration:** Moved engine verification and setup logic directly into runtime execution (`src/index.ts`). If `postinstall` is blocked or skipped, installation is triggered automatically upon module import.
- **Fixed `SQLITE_VERSION` Environment Variable:** Supported both `SQLITE_VERSION` and `BETTER_SQLITE3_VERSION` environment variables dynamically at runtime and setup.
- **Removed `pkg upgrade -y`:** Prevented system-wide `apt full-upgrade` crashes (`fdsan` file descriptor aborts) in Termux during auto-installation.
- **Engine Management API:** Added programmatic helper methods (`listEngines`, `getCurrentEngine`, `deleteEngine`, `clearAllEngines`, `engineManager`) to inspect and manage compiled engine instances.
- **Removed `package.json` Auto-Mutation:** Stopped automatic file mutations on consumer `package.json`.
- **English Logs Standard:** Standardized all system logs and warning banners to English.
- **Direct Install Script:** Maintained `dist/install.cjs` as an optional direct CLI entrypoint.

### [1.0.0]
- **Initial Release:** Better-SQLite3 wrapper for Termux providing a drop-in replacement architecture.
