Xorma In-memory Reactive Database

0.0.1 · active · verified Wed Apr 22

Xorma is a synchronous, reactive, in-memory database at an early stage of development (version 0.0.1). It is specifically designed for building complex frontend applications such as video editors, design tools, IDEs, and games, where maintaining complex object graphs with frequent write operations is common. Developed initially in 2022 for a 3D circuit simulator, Xorma leverages MobX for its core reactivity, allowing developers to define observable models (`Model.withType(DataType)`) and manage application state in a centralized `Store`. A key differentiator is its synchronous API for data manipulation, coupled with a guarantee that only one instance of a model will ever exist for a given ID within the store, ensuring data consistency and simplifying reactivity patterns. While actively developed, its 0.0.1 version indicates a rapidly evolving API and no established release cadence.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates defining models, creating a central store, performing synchronous CRUD operations, and observing reactive updates using MobX's `autorun`.

import { DataType, Model, Store } from 'xorma';
import { observable, makeObservable, autorun } from 'mobx';

interface TaskData {
  id: string;
  name: string;
  done: boolean;
}

// 1. Define your base model
class BaseModel extends Model.withType(DataType<TaskData>()) {
  static idSelector(data: TaskData) {
    return data.id;
  }
}

// 2. Define your specific data model extending BaseModel
class TaskModel extends BaseModel.withType(DataType<TaskData>()) {
  name!: string;
  done!: boolean;

  constructor(data: TaskData) {
    super(data);
    makeObservable(this, {
      name: observable,
      done: observable
    });
    this.loadJSON(data);
  }

  // Method to update instance data from JSON
  loadJSON(data: TaskData) {
    this.name = data.name;
    this.done = data.done;
  }

  toJSON(): TaskData {
    return { id: this.id, name: this.name, done: this.done };
  }
}

// 3. Create a store and register your models
const store = new Store({
  schemaVersion: 1,
  models: {
    Task: TaskModel // Register TaskModel under the key 'Task'
  }
});

// Access the collection for TaskModel
const taskCollection = store.getCollection(TaskModel);

// 4. Add data to the store (synchronous)
console.log('Adding tasks...');
const task1 = taskCollection.create({
  id: 'task-1',
  name: 'Learn Xorma',
  done: false
});

const task2 = taskCollection.create({
  id: 'task-2',
  name: 'Build something great',
  done: false
});

// 5. Demonstrate reactivity with MobX autorun
autorun(() => {
  const allTasks = taskCollection.getAll();
  console.log('\n--- Reactive Task List ---');
  allTasks.forEach(task => console.log(`[${task.id}] ${task.name} (Done: ${task.done})`));
  console.log('--------------------------');
});

// 6. Update data and observe reactivity (synchronous)
setTimeout(() => {
  console.log('\nUpdating task-1...');
  task1.name = 'Master Xorma';
  task1.done = true;

  // Trying to create a task with an existing ID will update it
  taskCollection.create({
    id: 'task-2',
    name: 'Deploy something awesome', // Name is updated
    done: true // Done status is updated
  });

  // Add a new task
  taskCollection.create({
    id: 'task-3',
    name: 'Celebrate success',
    done: false
  });
}, 1000);

// Output after all operations (will be reactive, showing changes from setTimeout)

view raw JSON →