Skip to content
Strata Sync

AI agents: fetch the documentation index at llms.txt. Markdown versions are available by appending .md to any page URL, including this page's markdown.

Transactions

Create, serialize, and batch transactions for offline-first mutations in Strata Sync.

Every local change becomes a Transaction that flows through the outbox, travels to the server, and gets confirmed by the sync protocol.

Transaction interface

Every mutation conforms to this structure:

interface Transaction {
  clientTxId: string;
  clientId: string;
  modelName: string;
  modelId: string;
  action: TransactionAction;
  payload: Record<string, unknown>;
  original?: Record<string, unknown>;
  state: TransactionState;
  createdAt: number;
  retryCount: number;
  lastError?: string;
  syncIdNeededForCompletion?: number;
  batchIndex?: number;
}

TransactionAction

ActionCodeDescription
Insert"I"Creates a new model instance.
Update"U"Modifies fields on an existing model.
Delete"D"Permanently removes a model instance.
Archive"A"Soft-deletes by setting archivedAt.
Unarchive"V"Restores a soft-deleted model.

TransactionState

StateDescription
"queued"In the local outbox, not yet sent.
"sent"Sent to the server, awaiting confirmation.
"awaitingSync"Server confirmed, waiting for the sync ID via the delta stream.
"completed"Fully synced.
"failed"Failed permanently after all retries.

Creating transactions

createTransaction

General-purpose factory; all other helpers delegate to it.

import { createTransaction } from "@stratasync/core";

const tx = createTransaction({
  clientId: "client-abc",
  modelName: "Task",
  modelId: "task-123",
  action: "U",
  payload: { title: "Updated title" },
  original: { title: "Original title" },
});

CreateTransactionOptions:

FieldTypeRequiredDescription
clientIdstringYesClient instance ID.
modelNamestringYesRegistered model name.
modelIdstringYesModel instance ID.
actionTransactionActionYesMutation type.
payloadRecord<string, unknown>YesChanged data.
originalRecord<string, unknown>NoOriginal data for rollback.

createInsertTransaction

Creates an insert ("I") transaction.

import { createInsertTransaction } from "@stratasync/core";

const tx = createInsertTransaction("client-abc", "Task", "task-123", {
  title: "New Task",
  status: "todo",
  priority: 0,
  projectId: "project-456",
});

createUpdateTransaction

Creates an update ("U") transaction with changed fields and originals.

import { createUpdateTransaction } from "@stratasync/core";

const tx = createUpdateTransaction(
  "client-abc",
  "Task",
  "task-123",
  { title: "Updated title" },
  { title: "Original title" }
);

createDeleteTransaction

Creates a delete ("D") transaction. Pass original data so undo can re-create the model.

import { createDeleteTransaction } from "@stratasync/core";

const tx = createDeleteTransaction("client-abc", "Task", "task-123", {
  title: "Task to delete",
  status: "done",
});

createArchiveTransaction and createUnarchiveTransaction

Archive ("A") soft-deletes a model by setting archivedAt. Unarchive ("V") restores it.

import {
  createArchiveTransaction,
  createUnarchiveTransaction,
} from "@stratasync/core";

// Soft-delete
const archiveTx = createArchiveTransaction("client-abc", "Task", "task-123", {
  original: { archivedAt: undefined },
  archivedAt: "2025-01-15T10:30:00.000Z",
});

// Restore
const unarchiveTx = createUnarchiveTransaction(
  "client-abc",
  "Task",
  "task-123",
  {
    original: { archivedAt: "2025-01-15T10:30:00.000Z" },
  }
);

createUndoTransaction

Creates the inverse transaction. Returns null if the transaction can't be undone (for example, a delete without original data).

import { createUndoTransaction } from "@stratasync/core";

const originalTx = createUpdateTransaction(
  "client-abc",
  "Task",
  "task-123",
  { title: "New" },
  { title: "Old" }
);

const undoTx = createUndoTransaction(originalTx);
// undoTx.action === "U"
// undoTx.payload === { title: "Old" }
// undoTx.original === { title: "New" }

Undo mapping:

Original actionUndo actionNotes
Insert ("I")Delete ("D")Deletes the inserted model.
Delete ("D")Insert ("I")Re-creates with original data. Returns null if no original.
Update ("U")Update ("U")Swaps payload and original. Returns null if no original.
Archive ("A")Unarchive ("V")Restores the model.
Unarchive ("V")Archive ("A")Re-archives the model.

Batching

createTransactionBatch

Groups transactions into a batch for atomic server submission.

import {
  createTransactionBatch,
  createInsertTransaction,
  createUpdateTransaction,
} from "@stratasync/core";

const batch = createTransactionBatch([
  createInsertTransaction("client-abc", "Task", "task-1", { title: "Task 1" }),
  createUpdateTransaction(
    "client-abc",
    "Project",
    "proj-1",
    { taskCount: 5 },
    { taskCount: 4 }
  ),
]);
// batch.batchId: string
// batch.transactions: Transaction[]
// batch.createdAt: number

TransactionBatch interface:

interface TransactionBatch {
  batchId: string;
  transactions: Transaction[];
  createdAt: number;
}

Serialization

Serialize transactions to a compact format for storage or transport.

Single transactions

import {
  serializeTransaction,
  deserializeTransaction,
  transactionToJson,
  transactionFromJson,
} from "@stratasync/core";

// To compact object
const serialized = serializeTransaction(tx);
const restored = deserializeTransaction(serialized);

// To/from JSON string
const json = transactionToJson(tx);
const parsed = transactionFromJson(json);

Batches

import {
  serializeBatch,
  deserializeBatch,
  batchToJson,
  batchFromJson,
} from "@stratasync/core";

// To compact object
const serialized = serializeBatch(batch);
const restored = deserializeBatch(serialized);

// To/from JSON string
const json = batchToJson(batch);
const parsed = batchFromJson(json);

Serialized format

Short keys minimize payload size.

Transaction fieldSerialized key
clientTxIdcid
clientIdcli
modelNamem
modelIdmid
actiona
payloadp
originalo
states
createdAtt
retryCountr
lastErrore
syncIdNeededForCompletions2
batchIndexb

Server result types

Returned after submitting transactions:

TransactionResult

interface TransactionResult {
  clientTxId: string;
  success: boolean;
  syncId?: number;
  error?: string;
  errorCode?: string;
}

MutateResult

interface MutateResult {
  success: boolean;
  lastSyncId: number;
  results: TransactionResult[];
}