Skip to content

Conversation

@stevensJourney
Copy link
Collaborator

[This is just a temporary PR for internal comment]

closes TanStack#959

Summary

  • Add support for tracking collection operation metadata in PowerSync CrudEntry records
  • When trackMetadata: true is enabled on a PowerSync table, metadata passed to insert, update, and delete operations is persisted and available during upload processing

Description

This PR enables PowerSync collections to track custom metadata alongside CRUD operations. This is useful for passing additional context about mutations to the backend, such as audit information, operation sources, or custom processing hints.

Key Changes

Metadata Persistence:

  • Leverages PowerSync's built-in trackMetadata table option to persist metadata with CRUD operations
  • Insert and update operations populate the _metadata column when metadata is provided
  • Delete operations with metadata use PowerSync's soft-delete pattern (_deleted = TRUE) to preserve metadata

Validation & Warnings:

  • Added metadataIsTracked to PowerSyncCollectionMeta to track table configuration
  • Logs a warning if metadata is provided to a collection whose table doesn't have trackMetadata: true

Developer Experience:

  • Added documentation section covering enablement, usage in operations, and accessing metadata during upload

Usage

// Enable in schema
const APP_SCHEMA = new Schema({
  documents: new Table(
    { name: column.text, author: column.text },
    { trackMetadata: true }
  ),
})

// Use in operations
await collection.insert(
  { id, name: "doc", author: "Jane" },
  { metadata: { source: "web-app", userId: "user-123" } }
)

Accessing Metadata During Upload:

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()
  }
}

@Chriztiaan
Copy link

Looks good, happy with the changes.

@stevensJourney
Copy link
Collaborator Author

closing to make upstream PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants