Skip to content

NeverChange is a database solution for web applications using SQLite WASM and OPFS.

Notifications You must be signed in to change notification settings

shinshin86/neverchange

Repository files navigation

NeverChange

CI

Project logo

NeverChange is a database solution for web applications using SQLite WASM and OPFS.

⚠ Alpha Version Warning

This package is currently in alpha stage. The interface and method names may change with each update. Please use with caution.

Table of Contents

For Users

Installation

npm install neverchange

Supported Browsers

This project currently supports and is tested on Google Chrome only.
We use Playwright for our end-to-end (E2E) tests, which are configured to run exclusively on Chrome.

All tests are tested only through Playwright.

  • Google Chrome
  • Microsoft Edge
  • Firefox
  • Safari

Requirements

  • Node.js (version 20 or higher recommended)
  • npm (usually comes with Node.js)

Usage

Basic

Here's a basic example of how to use NeverChangeDB to create a database, insert data, and query it:

import { NeverChangeDB } from 'neverchange';

async function main() {
  // Initialize the database
  const db = new NeverChangeDB('myDatabase');
  await db.init();

  // Create a table
  await db.execute(`
    CREATE TABLE IF NOT EXISTS users (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT NOT NULL,
      email TEXT UNIQUE NOT NULL
    )
  `);

  // Insert data
  await db.execute(
    'INSERT INTO users (name, email) VALUES (?, ?)',
    ['John Doe', 'john@example.com']
  );

  // Query data
  const users = await db.query('SELECT * FROM users');
  console.log('Users:', users);

  // Close the database connection
  await db.close();
}

main().catch(console.error);

Migration

NeverChangeDB supports database migrations, allowing you to evolve your database schema over time. Here's an example of how to define and use migrations:

import { NeverChangeDB } from 'neverchange';

// Define migrations
const migrations = [
  {
    version: 1,
    up: async (db) => {
      await db.execute(`
        CREATE TABLE users (
          id INTEGER PRIMARY KEY AUTOINCREMENT,
          name TEXT NOT NULL
        )
      `);
    }
  },
  {
    version: 2,
    up: async (db) => {
      await db.execute(`
        ALTER TABLE users ADD COLUMN email TEXT
      `);
    }
  }
];

async function main() {
  // Initialize the database with migrations
  const db = new NeverChangeDB('myDatabase', { isMigrationActive: true });
  db.addMigrations(migrations);
  await db.init();

  // The database will now have the latest schema
  const tableInfo = await db.query('PRAGMA table_info(users)');
  console.log('Users table schema:', tableInfo);

  await db.close();
}

main().catch(console.error);

Dump and Import Features

NeverChangeDB offers two modes for database dump and import: Optimized Mode and SQLite Compatibility Mode.

Optimized Mode (Default)

In the optimized mode, the dump output does not include transaction control statements or PRAGMA settings. This mode is designed for:

  • Flexibility: Allows for custom transaction control during import.
  • Consistency: Ensures the entire import process is wrapped in a single transaction.
  • Error Handling: Facilitates easy rollback in case of import errors.
  • Performance: Enables fine-tuned control over transaction size and checkpoints for large datasets.
  • Platform Independence: Improves compatibility between different SQLite implementations.
SQLite Compatibility Mode

This mode generates dump output that closely resembles the standard SQLite .dump command, including transaction control statements and PRAGMA settings. Use this mode when:

  • Compatibility with standard SQLite tools is required.
  • You need to use the dump with other systems expecting standard SQLite dump format.

Examples

// Dumping a Database
const db = new NeverChangeDB('myDatabase');
await db.init();

// Optimized Mode (default)
const optimizedDump = await db.dumpDatabase();

// SQLite Compatibility Mode
const compatibleDump = await db.dumpDatabase({ compatibilityMode: true });

// Importing a Database
// Optimized Mode (default)
await db.importDump(dumpContent);

// SQLite Compatibility Mode
await db.importDump(dumpContent, { compatibilityMode: true });

Handling of BLOB Data

When using the dump and import features, special attention should be paid to BLOB (Binary Large Object) data:

  • Dumping BLOB Data: BLOB data is serialized into a special string format during the dump process. This ensures that binary data is correctly represented in the dump output.

  • Importing BLOB Data: When importing, the special string format for BLOB data is automatically detected and converted back into the appropriate binary format.

  • Working with BLOB Data: After importing, BLOB data may be represented as an object with numeric keys (e.g., {"0":1,"1":2,"2":3}). To work with this data as a Uint8Array, you may need to convert it:

const convertToUint8Array = (obj) => {
   if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
      return new Uint8Array(Object.values(obj));
   }

   return obj;
};

// Usage
const blobData = convertToUint8Array(row.blobColumn);

Limitations and Considerations

  • Large Databases: When working with large databases, consider the memory limitations of the browser environment. For very large datasets, you may need to implement chunking strategies for dump and import operations.
  • Complex Data Types: While NeverChangeDB handles most SQLite data types seamlessly, complex types like JSON or custom data structures may require additional processing when dumping or importing.
  • Cross-Browser Compatibility: Although the core functionality is designed to work across modern browsers, some advanced features or performance optimizations may vary between different browser environments. Always test thoroughly in your target browsers.

For Developers

Setup

  1. Clone the repository:

    git clone https://github.com/shinshin86/neverchange.git
    cd neverchange
    
  2. Install dependencies:

    npm install
    
  3. Install browsers for Playwright for e2e test:

    npx playwright install
    

Available Scripts

  • npm run build: Build the project.
  • npm run dev:e2e: Start the development server for E2E tests.
  • npm run e2e: Run E2E tests using Playwright.

Main Dependencies

Development

Run E2E tests:

npm run e2e

Code Format:

npm run fmt

License

This project is released under the MIT License.

About

NeverChange is a database solution for web applications using SQLite WASM and OPFS.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published