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
| Action | Code | Description |
|---|---|---|
| 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
| State | Description |
|---|---|
"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:
| Field | Type | Required | Description |
|---|---|---|---|
clientId | string | Yes | Client instance ID. |
modelName | string | Yes | Registered model name. |
modelId | string | Yes | Model instance ID. |
action | TransactionAction | Yes | Mutation type. |
payload | Record<string, unknown> | Yes | Changed data. |
original | Record<string, unknown> | No | Original 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 action | Undo action | Notes |
|---|---|---|
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: numberTransactionBatch 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 field | Serialized key |
|---|---|
clientTxId | cid |
clientId | cli |
modelName | m |
modelId | mid |
action | a |
payload | p |
original | o |
state | s |
createdAt | t |
retryCount | r |
lastError | e |
syncIdNeededForCompletion | s2 |
batchIndex | b |
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[];
}