refactor: Replace drift by serverpod as core engine (#33)

This commit is contained in:
Marcelo Mendonça Soares 2026-05-03 09:09:23 -03:00 • committed by GitHub
commit 3545bbba1d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 6196 additions and 671 deletions

View file

@ -0,0 +1,7 @@
export 'package:serverpod_offline_sync_client/serverpod_offline_sync_client.dart';
export 'src/generated/endpoints.dart';
// The models are exported by the client package to ensure the same class as the
// one expected by the functions.
// export 'src/generated/protocol.dart';

View file

@ -0,0 +1,40 @@
// import 'package:serverpod/serverpod.dart';
// import 'package:serverpod_offline_sync_shared/serverpod_offline_sync_shared.dart';
// // import '../generated/protocol.dart';
// /// TODO: Create the classes.
// abstract class CrdtDataEntry {}
// /// Endpoint for the CRDT sync.
// class SyncOfflineChangesEndpoint extends Endpoint {
// @override
// bool get requireLogin => true;
// /// Syncs the offline changes between server and client.
// ///
// /// This endpoint is used to sync the offline changes between server and
// /// client. After a handshake on the [migrationVersion] to ensure that the
// /// merge can happen, the client will send all [offlineChanges] since the
// /// [lastSyncHlc] HLC and the server will send all online changes through
// /// the returning stream.
// ///
// /// The connection will be kept open until one end disconnects, forwarding
// /// the changes to the other end.
// Stream<CrdtDataEntry> syncOfflineChanges(
// Session session, {
// required String migrationVersion,
// required Hlc lastSyncHlc,
// /// TODO: Create the classes.
// /// CrdtDataEntry will be a sealed class with the changes.
// ///
// /// - CrdtDataRow: New rows inserted.
// /// - CrdtDataField: Fields updated.
// /// - CrdtDataDeleted: Rows deleted.
// required Stream<CrdtDataEntry> offlineChanges,
// }) async* {
// // TODO: Implement the business layer for the CRDT sync.
// // yield* CrdtSync.syncOfflineChanges(session);
// }
// }

View file

@ -0,0 +1,22 @@
### CRDT tombstone table.
###
### This table stores all tombstones for deleted data.
class: CrdtDataDeleted
extends: BaseHlc
table: crdt_data_tombstone
database: all
fields:
### Row that was deleted.
row: CrdtDataRow?, relation(name=row_deleted, field=rowId, onDelete=Cascade)
rowId: int
### The node that updated the field.
node: CrdtNode?, relation
### When the row was deleted.
isDeleted: bool
indexes:
crdt_data_tombstone_row_idx:
fields: rowId
unique: true

View file

@ -0,0 +1,22 @@
### CRDT data table.
###
### This table stores only the HLC timestamp for a field. During merge, if the
### other HLC is greater, the actual data must be fetched from the table itself.
class: CrdtDataField
extends: BaseHlc
table: crdt_data_fields
database: all
fields:
### Row that the field belongs to.
row: CrdtDataRow?, relation(name=row_fields, onDelete=Cascade)
### Column that the field belongs to.
column: CrdtSchemaColumn?, relation(onDelete=Cascade)
### The node that updated the field.
node: CrdtNode?, relation
indexes:
crdt_data_fields_row_column_idx:
fields: rowId, columnId
unique: true

View file

@ -0,0 +1,34 @@
### CRDT data rows table.
###
### This table stores the data for all tables that are registered for CRDT
### synchronization. It is used to interact with the CRDT data.
###
### The row is also the HLC timestamp for when it was inserted. This is used to
### avoid creating one entry per field until a field is updated.
class: CrdtDataRow
extends: BaseHlc
table: crdt_data_rows
database: all
fields:
### Identifier for the user or client that owns the data.
user: CrdtUser?, relation(onDelete=Cascade)
### Reference to the table this row belongs to.
tbl: CrdtSchemaTable?, relation(onDelete=Cascade)
### Row identifier.
uuidRowId: UuidValue
### The node that inserted the row with the HLC timestamp.
node: CrdtNode?, relation
### The tombstone for this row.
deleted: CrdtDataDeleted?, relation(name=row_deleted, optional)
### The fields for this row.
fields: List<CrdtDataField>?, relation(name=row_fields)
indexes:
crdt_data_rows_user_tbl_row_idx:
fields: userId, tblId, uuidRowId
unique: true

View file

@ -0,0 +1,19 @@
### CRDT nodes table.
###
### This table stores all nodes that have been seen.
class: CrdtNode
table: crdt_nodes
database: all
fields:
### The user that owns the node.
user: CrdtUser?, relation(name=user_nodes, onDelete=Cascade)
### Unique identifier for the node.
uuidNodeId: UuidValue, default=random_v7, unique
# TODO: Make this non-nullable once the migration version is implemented.
### The migration version of the CRDT data that the node has seen.
lastSeenMigrationVersion: String?
### The last HLC timestamp when the node has synchronized.
lastReceivedHlc: Hlc?

View file

@ -0,0 +1,16 @@
### CRDT users table.
###
### Normalized storage for user IDs. The normalized data table references this
### by integer id instead of storing the user id string.
class: CrdtUser
table: crdt_users
database: all
fields:
### User identifier string.
uuidUserId: UuidValue, default=random_v7, unique
### The current node id of the user.
currentNode: CrdtNode?, relation(optional)
### The nodes associated with the user.
nodes: List<CrdtNode>?, relation(name=user_nodes)

View file

@ -0,0 +1,15 @@
### CRDT schema columns table.
class: CrdtSchemaColumn
table: crdt_schema_columns
database: all
fields:
### Reference to the table this column belongs to.
tbl: CrdtSchemaTable?, relation(onDelete=Cascade)
### Name of the column.
name: String
indexes:
crdt_schema_columns_table_column_idx:
fields: tblId, name
unique: true

View file

@ -0,0 +1,7 @@
### CRDT schema tables table.
class: CrdtSchemaTable
table: crdt_schema_tables
database: all
fields:
### Name of the synchronized table.
name: String, unique