Skip to main content
Delta tracking captures all changes made to a document during a tracking session, enabling you to export those changes as a portable delta, preview them, and apply them to other documents. This is useful for collaborative editing, change review workflows, and synchronization.

Overview

The delta system supports:
  • Tracking Sessions: Start and stop change recording
  • Delta Export: Export captured changes as JSON or binary format
  • Delta Preview: Preview what changes would be applied
  • Delta Apply: Apply changes to a document with conflict detection
  • Session Management: List and manage tracking sessions

Starting and Stopping Tracking

from kodexa_document import Document

with Document() as doc:
    root = doc.create_node("document", "Original content")
    doc.content_node = root

    # Start tracking changes
    session = doc.delta.start_tracking(
        username="user@example.com",
        comment="Initial extraction review"
    )
    print(f"Tracking session started: {session}")

    # Make changes while tracking is active
    para = doc.create_node("paragraph", "New paragraph", parent=root)
    para.tag("reviewed")

    # Check tracking status
    status = doc.delta.get_status()
    print(f"Delta status: {status}")

    # Get the active session
    active = doc.delta.get_active_session()
    print(f"Active session: {active}")

    # Stop tracking (finalizes the session)
    result = doc.delta.stop_tracking()
    print(f"Session stopped: {result}")
import { Kodexa } from '@kodexa-ai/document-wasm-ts';

async function trackChanges() {
  await Kodexa.init();
  const doc = await Kodexa.createDocument();

  try {
    const root = await doc.createNode('document');
    await root.setContent('Original content');

    // Start tracking changes
    const session = await doc.delta.startTracking(
      'user@example.com',
      'Initial extraction review'
    );
    console.log(`Tracking session started: ${JSON.stringify(session)}`);

    // Make changes while tracking is active
    const para = await doc.createNode('paragraph');
    await para.setContent('New paragraph');
    await root.addChild(para);
    await para.tag('reviewed');

    // Check tracking status
    const status = await doc.delta.getStatus();
    console.log(`Delta status: ${JSON.stringify(status)}`);

    // Stop tracking
    const result = await doc.delta.stopTracking();
    console.log(`Session stopped: ${JSON.stringify(result)}`);
  } finally {
    doc.dispose();
  }
}

Cancelling a Session

If you want to discard a tracking session without finalizing it:
with Document() as doc:
    root = doc.create_node("document", "Content")
    doc.content_node = root

    doc.delta.start_tracking(username="user@example.com")

    # Make some changes...

    # Cancel - discard the tracking session
    doc.delta.cancel_tracking()
async function cancelTracking() {
  await Kodexa.init();
  const doc = await Kodexa.createDocument();

  try {
    // ... start tracking and make changes ...

    // Cancel the tracking session
    await doc.delta.cancelTracking();
  } finally {
    doc.dispose();
  }
}

Exporting Deltas

After stopping a tracking session, export the captured changes:
with Document() as doc:
    root = doc.create_node("document", "Content")
    doc.content_node = root

    doc.delta.start_tracking(username="reviewer")

    # Make changes...
    para = doc.create_node("paragraph", "Added content", parent=root)

    doc.delta.stop_tracking()

    # Export as JSON (for inspection/debugging)
    delta_json = doc.delta.export_json()
    print(f"Delta JSON: {delta_json}")

    # Export as bytes (for storage/transfer)
    delta_bytes = doc.delta.export_bytes()
    if delta_bytes:
        print(f"Delta size: {len(delta_bytes)} bytes")

        # Save to file
        with open("changes.delta", "wb") as f:
            f.write(delta_bytes)
async function exportDelta() {
  await Kodexa.init();
  const doc = await Kodexa.createDocument();

  try {
    // ... create content, track changes, stop tracking ...

    // Export as JSON
    const deltaJson = await doc.delta.exportJson();
    console.log('Delta JSON:', deltaJson);

    // Export as bytes
    const deltaBytes = await doc.delta.exportBytes();
    if (deltaBytes) {
      console.log(`Delta size: ${deltaBytes.length} bytes`);
    }
  } finally {
    doc.dispose();
  }
}

Previewing and Applying Deltas

Preview Changes

Before applying a delta, preview what would change:
with Document.from_kddb("target.kddb") as doc:
    # Load delta bytes
    with open("changes.delta", "rb") as f:
        delta_bytes = f.read()

    # Preview the changes without applying
    preview = doc.delta.preview(delta_bytes)
    print(f"Preview: {preview}")
async function previewDelta() {
  await Kodexa.init();
  const doc = await Kodexa.fromBlob(targetBlob);

  try {
    // Preview the changes without applying
    const preview = await doc.delta.preview(deltaBytes);
    console.log('Preview:', preview);
  } finally {
    doc.dispose();
  }
}

Apply Changes

with Document.from_kddb("target.kddb") as doc:
    with open("changes.delta", "rb") as f:
        delta_bytes = f.read()

    # Apply the delta
    result = doc.delta.apply(delta_bytes, options={
        "stopOnConflict": False,
        "skipMissingRefs": True,
        "createAuditTrail": True,
        "actorUri": "user://reviewer@example.com",
        "comment": "Applied review changes"
    })
    print(f"Applied: {result}")

    doc.save("updated.kddb")
async function applyDelta() {
  await Kodexa.init();
  const doc = await Kodexa.fromBlob(targetBlob);

  try {
    // Apply the delta with options
    const result = await doc.delta.apply(deltaBytes, {
      stopOnConflict: false,
      skipMissingRefs: true,
      createAuditTrail: true,
      actorUri: 'user://reviewer@example.com',
      comment: 'Applied review changes'
    });

    console.log(`Applied ${result.applied} operations`);
    console.log(`Skipped ${result.skipped} operations`);
    if (result.hasConflicts) {
      console.log('Conflicts:', result.conflicts);
    }

    const blob = await doc.toBlob();
  } finally {
    doc.dispose();
  }
}

Import a Delta

Import a previously exported delta back into a document:
with Document.from_kddb("document.kddb") as doc:
    with open("changes.delta", "rb") as f:
        delta_bytes = f.read()

    # Import the delta
    result = doc.delta.import_delta(delta_bytes)
    print(f"Import result: {result}")
async function importDelta() {
  await Kodexa.init();
  const doc = await Kodexa.fromBlob(kddbBlob);

  try {
    const result = await doc.delta.importDelta(deltaBytes);
    console.log('Import result:', result);
  } finally {
    doc.dispose();
  }
}

Managing Sessions

with Document.from_kddb("document.kddb") as doc:
    # List all tracking sessions
    sessions = doc.delta.list_sessions()
    for session in sessions:
        print(f"Session: {session}")

    # Filter by status
    active_sessions = doc.delta.list_sessions(status_filter="active")
    completed_sessions = doc.delta.list_sessions(status_filter="completed")
async function manageSessions() {
  await Kodexa.init();
  const doc = await Kodexa.fromBlob(kddbBlob);

  try {
    // List all tracking sessions
    const sessions = await doc.delta.listSessions();
    for (const session of sessions) {
      console.log(`Session: ${session.sessionUuid}, Status: ${session.status}`);
    }

    // Filter by status
    const activeSessions = await doc.delta.listSessions('active');
    const completedSessions = await doc.delta.listSessions('completed');
  } finally {
    doc.dispose();
  }
}

API Reference

DeltaAccessor Methods

Method (Python)Method (TypeScript)Description
start_tracking(username, comment)startTracking(username, comment)Start a tracking session
stop_tracking()stopTracking()Stop and finalize the session
cancel_tracking()cancelTracking()Discard the session
get_active_session()getActiveSession()Get the current session
get_status()getStatus()Get tracking status
export_json()exportJson()Export delta as JSON
export_bytes()exportBytes()Export delta as binary
import_delta(bytes)importDelta(bytes)Import a delta
apply(bytes, options)apply(bytes, options)Apply a delta
preview(bytes)preview(bytes)Preview a delta
list_sessions(filter)listSessions(filter)List tracking sessions

Apply Options

OptionTypeDescription
stopOnConflictbooleanStop applying on first conflict
skipMissingRefsbooleanSkip operations referencing missing entities
createAuditTrailbooleanRecord applied changes in the audit trail
actorUristringURI identifying who applied the changes
commentstringDescription of the applied changes