Skip to content
39 changes: 39 additions & 0 deletions .changeset/some-wombats-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
'@tanstack/powersync-db-collection': patch
---

Added support for tracking collection operation metadata in PowerSync CrudEntry operations.

```typescript
// Schema config
const APP_SCHEMA = new Schema({
documents: new Table(
{
name: column.text,
author: column.text,
created_at: column.text,
},
{
// Metadata tracking must be enabled on the PowerSync table
trackMetadata: true,
},
),
})

// ... Other config

// Collection operations which specify metadata
await collection.insert(
{
id,
name: `document`,
author: `Foo`,
},
// The string version of this will be present in PowerSync `CrudEntry`s during uploads
{
metadata: {
extraInfo: 'Info',
},
},
)
```
103 changes: 103 additions & 0 deletions docs/collections/powersync-collection.md
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,109 @@ task.due_date.getTime() // OK - TypeScript knows this is a Date

Updates to the collection are applied optimistically to the local state first, then synchronized with PowerSync and the backend. If an error occurs during sync, the changes are automatically rolled back.

### Metadata Tracking

Metadata tracking allows attaching custom metadata to collection operations (insert, update, delete). This metadata is persisted alongside the operation and available in PowerSync `CrudEntry` records during upload processing. This is useful for passing additional context about mutations to the backend, such as audit information, operation sources, or custom processing hints.

#### Enabling Metadata Tracking

Metadata tracking must be enabled on the PowerSync table:

```typescript
const APP_SCHEMA = new Schema({
documents: new Table(
{
name: column.text,
author: column.text,
},
{
// Enable metadata tracking on this table
trackMetadata: true,
}
),
})
```

#### Using Metadata in Operations

Once enabled, metadata can be passed to any collection operation:

```typescript
const documents = createCollection(
powerSyncCollectionOptions({
database: db,
table: APP_SCHEMA.props.documents,
})
)

// Insert with metadata
await documents.insert(
{
id: crypto.randomUUID(),
name: "Report Q4",
author: "Jane Smith",
},
{
metadata: {
source: "web-app",
userId: "user-123",
timestamp: Date.now(),
},
}
).isPersisted.promise

// Update with metadata
await documents.update(
docId,
{ metadata: { reason: "typo-fix", editor: "user-456" } },
(doc) => {
doc.name = "Report Q4 (Updated)"
}
).isPersisted.promise

// Delete with metadata
await documents.delete(docId, {
metadata: { deletedBy: "user-789", reason: "duplicate" },
}).isPersisted.promise
```

#### Accessing Metadata During Upload

The metadata is available in PowerSync `CrudEntry` records when processing uploads in the connector:

```typescript
import { CrudEntry } from "@powersync/web"

class Connector implements PowerSyncBackendConnector {
// ...

async uploadData(database: AbstractPowerSyncDatabase) {
const batch = await database.getCrudBatch()
if (!batch) return

for (const entry of batch.crud) {
console.log("Operation:", entry.op) // PUT, PATCH, DELETE
console.log("Table:", entry.table)
console.log("Data:", entry.opData)
console.log("Metadata:", entry.metadata) // Custom metadata (stringified)

// Parse metadata if needed
if (entry.metadata) {
const meta = JSON.parse(entry.metadata)
console.log("Source:", meta.source)
console.log("User ID:", meta.userId)
}

// Process the operation with the backend...
}

await batch.complete()
}
}
```

**Note**: If metadata is provided to an operation but the table doesn't have `trackMetadata: true`, a warning will be logged and the metadata will be ignored.

## Configuration Options

The `powerSyncCollectionOptions` function accepts the following options:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: PowerSyncTransactor

# Class: PowerSyncTransactor

Defined in: [PowerSyncTransactor.ts:51](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L51)
Defined in: [PowerSyncTransactor.ts:54](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L54)

Applies mutations to the PowerSync database. This method is called automatically by the collection's
insert, update, and delete operations. You typically don't need to call this directly unless you
Expand Down Expand Up @@ -51,7 +51,7 @@ The transaction containing mutations to apply
new PowerSyncTransactor(options): PowerSyncTransactor;
```

Defined in: [PowerSyncTransactor.ts:55](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L55)
Defined in: [PowerSyncTransactor.ts:58](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L58)

#### Parameters

Expand All @@ -71,7 +71,7 @@ Defined in: [PowerSyncTransactor.ts:55](https://github.com/TanStack/db/blob/main
database: AbstractPowerSyncDatabase;
```

Defined in: [PowerSyncTransactor.ts:52](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L52)
Defined in: [PowerSyncTransactor.ts:55](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L55)

***

Expand All @@ -81,7 +81,7 @@ Defined in: [PowerSyncTransactor.ts:52](https://github.com/TanStack/db/blob/main
pendingOperationStore: PendingOperationStore;
```

Defined in: [PowerSyncTransactor.ts:53](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L53)
Defined in: [PowerSyncTransactor.ts:56](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L56)

## Methods

Expand All @@ -91,7 +91,7 @@ Defined in: [PowerSyncTransactor.ts:53](https://github.com/TanStack/db/blob/main
applyTransaction(transaction): Promise<void>;
```

Defined in: [PowerSyncTransactor.ts:63](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L63)
Defined in: [PowerSyncTransactor.ts:66](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L66)

Persists a Transaction to the PowerSync SQLite database.

Expand All @@ -107,6 +107,26 @@ Persists a Transaction to the PowerSync SQLite database.

***

### getMutationCollectionMeta()

```ts
protected getMutationCollectionMeta(mutation): PowerSyncCollectionMeta<any>;
```

Defined in: [PowerSyncTransactor.ts:294](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L294)

#### Parameters

##### mutation

`PendingMutation`\<`any`\>

#### Returns

[`PowerSyncCollectionMeta`](../type-aliases/PowerSyncCollectionMeta.md)\<`any`\>

***

### handleDelete()

```ts
Expand All @@ -116,7 +136,7 @@ protected handleDelete(
waitForCompletion): Promise<PendingOperation | null>;
```

Defined in: [PowerSyncTransactor.ts:204](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L204)
Defined in: [PowerSyncTransactor.ts:221](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L221)

#### Parameters

Expand Down Expand Up @@ -147,7 +167,7 @@ protected handleInsert(
waitForCompletion): Promise<PendingOperation | null>;
```

Defined in: [PowerSyncTransactor.ts:149](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L149)
Defined in: [PowerSyncTransactor.ts:152](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L152)

#### Parameters

Expand Down Expand Up @@ -179,7 +199,7 @@ protected handleOperationWithCompletion(
handler): Promise<PendingOperation | null>;
```

Defined in: [PowerSyncTransactor.ts:232](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L232)
Defined in: [PowerSyncTransactor.ts:263](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L263)

Helper function which wraps a persistence operation by:
- Fetching the mutation's collection's SQLite table details
Expand Down Expand Up @@ -219,7 +239,7 @@ protected handleUpdate(
waitForCompletion): Promise<PendingOperation | null>;
```

Defined in: [PowerSyncTransactor.ts:177](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L177)
Defined in: [PowerSyncTransactor.ts:187](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L187)

#### Parameters

Expand All @@ -238,3 +258,28 @@ Defined in: [PowerSyncTransactor.ts:177](https://github.com/TanStack/db/blob/mai
#### Returns

`Promise`\<`PendingOperation` \| `null`\>

***

### processMutationMetadata()

```ts
protected processMutationMetadata(mutation): string | null;
```

Defined in: [PowerSyncTransactor.ts:313](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L313)

Processes collection mutation metadata for persistence to the database.
We only support storing string metadata.

#### Parameters

##### mutation

`PendingMutation`\<`any`\>

#### Returns

`string` \| `null`

null if no metadata should be stored.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ title: EnhancedPowerSyncCollectionConfig
type EnhancedPowerSyncCollectionConfig<TTable, OutputType, TSchema> = CollectionConfig<OutputType, string, TSchema> & object;
```

Defined in: [definitions.ts:254](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/definitions.ts#L254)
Defined in: [definitions.ts:259](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/definitions.ts#L259)

A CollectionConfig which includes utilities for PowerSync.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ Metadata for the PowerSync Collection.

## Properties

### metadataIsTracked

```ts
metadataIsTracked: boolean;
```

Defined in: [definitions.ts:253](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/definitions.ts#L253)

Whether the PowerSync table tracks metadata.

***

### serializeValue()

```ts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ title: PowerSyncCollectionUtils
type PowerSyncCollectionUtils<TTable> = object;
```

Defined in: [definitions.ts:267](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/definitions.ts#L267)
Defined in: [definitions.ts:272](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/definitions.ts#L272)

Collection-level utilities for PowerSync.

Expand All @@ -27,7 +27,7 @@ Collection-level utilities for PowerSync.
getMeta: () => PowerSyncCollectionMeta<TTable>;
```

Defined in: [definitions.ts:268](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/definitions.ts#L268)
Defined in: [definitions.ts:273](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/definitions.ts#L273)

#### Returns

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ title: TransactorOptions
type TransactorOptions = object;
```

Defined in: [PowerSyncTransactor.ts:12](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L12)
Defined in: [PowerSyncTransactor.ts:15](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L15)

## Properties

Expand All @@ -19,4 +19,4 @@ Defined in: [PowerSyncTransactor.ts:12](https://github.com/TanStack/db/blob/main
database: AbstractPowerSyncDatabase;
```

Defined in: [PowerSyncTransactor.ts:13](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L13)
Defined in: [PowerSyncTransactor.ts:16](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/PowerSyncTransactor.ts#L16)
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ title: DEFAULT_BATCH_SIZE
const DEFAULT_BATCH_SIZE: 1000 = 1000;
```

Defined in: [definitions.ts:274](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/definitions.ts#L274)
Defined in: [definitions.ts:279](https://github.com/TanStack/db/blob/main/packages/powersync-db-collection/src/definitions.ts#L279)

Default value for [PowerSyncCollectionConfig#syncBatchSize](../type-aliases/BasePowerSyncCollectionConfig.md).
Loading
Loading