Skip to content

Commit b2585d1

Browse files
HassamSheikhclaude
andcommitted
docs: add dartdoc comments to all public API elements
Adds /// dartdoc comments to every undocumented public class, constructor, property, method, enum, and typedef across 11 files. Brings documentation coverage from 62.2% to 100%. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 08d8592 commit b2585d1

11 files changed

+127
-0
lines changed

lib/src/adapters/drift_local_store.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import '../local_store.dart';
88
///
99
/// **Requirement:** Tables must have a column named `id` as the primary key.
1010
class DriftLocalStore implements LocalStore {
11+
/// Creates a [DriftLocalStore] backed by the given Drift [GeneratedDatabase].
1112
const DriftLocalStore(this._db);
1213

1314
final GeneratedDatabase _db;

lib/src/adapters/drift_queue_store.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import '../sync_operation.dart';
88
///
99
/// Requires [DynosSyncQueueTable] to be registered in your Drift database.
1010
class DriftQueueStore implements QueueStore {
11+
/// Creates a [DriftQueueStore] backed by the given Drift [GeneratedDatabase].
1112
const DriftQueueStore(this._db);
1213

1314
final GeneratedDatabase _db;

lib/src/adapters/drift_timestamp_store.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import '../timestamp_store.dart';
66
/// Stores per-table sync timestamps in SQLite via the
77
/// `dynos_sync_timestamps` table.
88
class DriftTimestampStore implements TimestampStore {
9+
/// Creates a [DriftTimestampStore] backed by the given Drift [GeneratedDatabase].
910
const DriftTimestampStore(this._db);
1011

1112
final GeneratedDatabase _db;

lib/src/adapters/supabase_remote_store.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,17 @@ class SupabaseRemoteStore implements RemoteStore {
3434
this.tableTimestampKeys = const {},
3535
});
3636

37+
/// The Supabase client used for all remote operations.
3738
final SupabaseClient client;
3839

3940
/// Returns the current user ID. Called per sync cycle to handle
4041
/// session expiry and account switches.
4142
final String Function() userId;
43+
44+
/// The name of the Supabase table that tracks per-user sync timestamps.
4245
final String syncStatusTable;
46+
47+
/// Maps synced table names to their corresponding timestamp column in [syncStatusTable].
4348
final Map<String, String> tableTimestampKeys;
4449

4550
@override

lib/src/adapters/sync_queue_table.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,38 @@ const kSyncQueueAddNextRetryAtSql =
3434
/// from an external package. If you see "not understood by drift" warnings,
3535
/// use [kSyncQueueCreateSql] in your migration instead.
3636
class DynosSyncQueueTable extends Table {
37+
/// The underlying SQLite table name for the sync queue.
3738
@override
3839
String get tableName => 'dynos_sync_queue';
3940

41+
/// Unique identifier for each queued sync entry.
4042
TextColumn get id => text()();
43+
44+
/// The name of the table the queued record belongs to.
4145
TextColumn get tableName_ => text().named('table_name')();
46+
47+
/// The primary-key value of the record being synced.
4248
TextColumn get recordId => text()();
49+
50+
/// The sync operation type (e.g. upsert or delete).
4351
TextColumn get operation => text()();
52+
53+
/// JSON-encoded payload of the record data.
4454
TextColumn get payload => text()();
55+
56+
/// Timestamp when the entry was enqueued.
4557
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
58+
59+
/// Timestamp when the entry was successfully synced, or null if pending.
4660
DateTimeColumn get syncedAt => dateTime().nullable()();
61+
62+
/// Number of times this entry has been retried.
4763
IntColumn get retryCount => integer().withDefault(const Constant(0))();
64+
65+
/// Earliest time at which a failed entry may be retried, or null if immediate.
4866
IntColumn get nextRetryAt => integer().nullable()();
4967

68+
/// Uses [id] as the single-column primary key.
5069
@override
5170
Set<Column> get primaryKey => {id};
5271
}

lib/src/adapters/sync_timestamps_table.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,17 @@ const kSyncTimestampsCreateSql = '''
2424
/// from an external package. If you see "not understood by drift" warnings,
2525
/// use [kSyncTimestampsCreateSql] in your migration instead.
2626
class DynosSyncTimestampsTable extends Table {
27+
/// The underlying SQLite table name for sync timestamps.
2728
@override
2829
String get tableName => 'dynos_sync_timestamps';
2930

31+
/// The name of the synced table this timestamp belongs to.
3032
TextColumn get tableName_ => text().named('table_name')();
33+
34+
/// The last time the corresponding table was successfully synced.
3135
DateTimeColumn get lastSyncedAt => dateTime()();
3236

37+
/// Uses [tableName_] as the single-column primary key.
3338
@override
3439
Set<Column> get primaryKey => {tableName_};
3540
}

lib/src/isolate_sync_engine.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'sync_engine.dart';
77
/// Offloading [drain] and [pullAll] to an isolate ensures the main UI thread
88
/// remains at 60/120 FPS even when processing thousands of JSON records.
99
class IsolateSyncEngine {
10+
/// Creates an [IsolateSyncEngine] that wraps the given [SyncEngine].
1011
IsolateSyncEngine(this._engine);
1112

1213
final SyncEngine _engine;

lib/src/sync_entry.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'sync_operation.dart';
22

33
/// A single queued sync operation waiting to be pushed to the remote.
44
class SyncEntry {
5+
/// Creates a [SyncEntry] with the given properties.
56
const SyncEntry({
67
required this.id,
78
required this.table,
@@ -14,18 +15,37 @@ class SyncEntry {
1415
this.nextRetryAt,
1516
});
1617

18+
/// Unique identifier for this sync entry.
1719
final String id;
20+
21+
/// Name of the database table this entry targets.
1822
final String table;
23+
24+
/// Identifier of the record being synced.
1925
final String recordId;
26+
27+
/// The type of sync operation (create, update, delete).
2028
final SyncOperation operation;
29+
30+
/// The data payload to be synced.
2131
final Map<String, dynamic> payload;
32+
33+
/// Timestamp when this entry was created.
2234
final DateTime createdAt;
35+
36+
/// Timestamp when this entry was successfully synced, or `null` if pending.
2337
final DateTime? syncedAt;
38+
39+
/// Number of times this entry has been retried.
2440
final int retryCount;
41+
42+
/// Scheduled time for the next retry attempt, or `null` if not scheduled.
2543
final DateTime? nextRetryAt;
2644

45+
/// Whether this entry has not yet been synced.
2746
bool get isPending => syncedAt == null;
2847

48+
/// Returns a copy of this entry with the given fields replaced.
2949
SyncEntry copyWith({
3050
String? id,
3151
String? table,

lib/src/sync_event.dart

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,47 @@ import 'sync_entry.dart';
33

44
/// Base class for all sync lifecycle events.
55
sealed class SyncEvent {
6+
/// Creates a [SyncEvent] with the given [timestamp].
67
const SyncEvent({required this.timestamp});
8+
9+
/// The time at which this event occurred.
710
final DateTime timestamp;
811
}
912

13+
/// Emitted when the local outbound queue has been fully drained.
1014
class SyncDrainComplete extends SyncEvent {
15+
/// Creates a [SyncDrainComplete] event.
1116
const SyncDrainComplete({required super.timestamp});
1217
}
1318

19+
/// Emitted when a pull operation for a table completes successfully.
1420
class SyncPullComplete extends SyncEvent {
21+
/// Creates a [SyncPullComplete] event.
1522
const SyncPullComplete({
1623
required super.timestamp,
1724
required this.table,
1825
required this.rowCount,
1926
});
27+
28+
/// The name of the table that was pulled.
2029
final String table;
30+
31+
/// The number of rows received during the pull.
2132
final int rowCount;
2233
}
2334

35+
/// Emitted when the remote server rejects the request due to authentication.
2436
class SyncAuthRequired extends SyncEvent {
37+
/// Creates a [SyncAuthRequired] event.
2538
const SyncAuthRequired({required super.timestamp, required this.error});
39+
40+
/// The underlying authentication error.
2641
final Object error;
2742
}
2843

44+
/// Emitted when a conflict between local and remote data is detected and resolved.
2945
class SyncConflict extends SyncEvent {
46+
/// Creates a [SyncConflict] event.
3047
const SyncConflict({
3148
required super.timestamp,
3249
required this.table,
@@ -36,35 +53,63 @@ class SyncConflict extends SyncEvent {
3653
required this.resolvedVersion,
3754
required this.strategyUsed,
3855
});
56+
57+
/// The table in which the conflict occurred.
3958
final String table;
59+
60+
/// The identifier of the conflicting record.
4061
final String recordId;
62+
63+
/// The local version of the record before resolution.
4164
final Map<String, dynamic> localVersion;
65+
66+
/// The remote version of the record before resolution.
4267
final Map<String, dynamic> remoteVersion;
68+
69+
/// The final merged version of the record after resolution.
4370
final Map<String, dynamic> resolvedVersion;
71+
72+
/// The conflict resolution strategy that was applied.
4473
final ConflictStrategy strategyUsed;
4574
}
4675

76+
/// Emitted when a sync entry exceeds its maximum retry count and is discarded.
4777
class SyncPoisonPill extends SyncEvent {
78+
/// Creates a [SyncPoisonPill] event.
4879
const SyncPoisonPill({required super.timestamp, required this.entry});
80+
81+
/// The sync entry that was permanently discarded.
4982
final SyncEntry entry;
5083
}
5184

85+
/// Emitted when a failed sync entry is scheduled for a later retry.
5286
class SyncRetryScheduled extends SyncEvent {
87+
/// Creates a [SyncRetryScheduled] event.
5388
const SyncRetryScheduled({
5489
required super.timestamp,
5590
required this.entry,
5691
required this.nextRetryAt,
5792
});
93+
94+
/// The sync entry that will be retried.
5895
final SyncEntry entry;
96+
97+
/// The scheduled time for the next retry attempt.
5998
final DateTime nextRetryAt;
6099
}
61100

101+
/// Emitted when an unexpected error occurs during a sync operation.
62102
class SyncError extends SyncEvent {
103+
/// Creates a [SyncError] event.
63104
const SyncError({
64105
required super.timestamp,
65106
required this.error,
66107
required this.context,
67108
});
109+
110+
/// The underlying error object.
68111
final Object error;
112+
113+
/// A human-readable description of where the error occurred.
69114
final String context;
70115
}

lib/src/sync_exceptions.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,69 @@
11
/// Thrown by [RemoteStore] when the auth token is expired or invalid (HTTP 401/403).
22
class AuthExpiredException implements Exception {
3+
/// Creates an [AuthExpiredException] wrapping the original error.
34
const AuthExpiredException(this.inner);
5+
6+
/// The underlying error or response that triggered this exception.
47
final Object inner;
8+
59
@override
610
String toString() => 'AuthExpiredException: $inner';
711
}
812

913
/// Thrown when a payload exceeds [SyncConfig.maxPayloadBytes].
1014
class PayloadTooLargeException implements Exception {
15+
/// Creates a [PayloadTooLargeException] with the actual [bytes] and the configured [limit].
1116
const PayloadTooLargeException({required this.bytes, required this.limit});
17+
18+
/// The actual size of the payload in bytes.
1219
final int bytes;
20+
21+
/// The maximum allowed payload size in bytes.
1322
final int limit;
23+
1424
@override
1525
String toString() =>
1626
'PayloadTooLargeException: payload is $bytes bytes, limit is $limit bytes';
1727
}
1828

1929
/// Thrown when a remote response cannot be deserialized.
2030
class SyncDeserializationException implements Exception {
31+
/// Creates a [SyncDeserializationException] wrapping the parse error.
2132
const SyncDeserializationException(this.inner);
33+
34+
/// The underlying parse error or malformed response.
2235
final Object inner;
36+
2337
@override
2438
String toString() => 'SyncDeserializationException: $inner';
2539
}
2640

2741
/// Thrown when the remote returns HTTP 200 but with an empty body or error payload.
2842
class SyncRemoteException implements Exception {
43+
/// Creates a [SyncRemoteException] with a human-readable [message] and optional [statusCode].
2944
const SyncRemoteException({required this.message, this.statusCode});
45+
46+
/// A human-readable description of the remote error.
3047
final String message;
48+
49+
/// The HTTP status code returned by the remote, if available.
3150
final int? statusCode;
51+
3252
@override
3353
String toString() => 'SyncRemoteException($statusCode): $message';
3454
}
3555

3656
/// Thrown when a pulled row's user_id doesn't match the engine's userId.
3757
class RlsViolationException implements Exception {
58+
/// Creates an [RlsViolationException] for the given [recordId] and optional [rowOwner].
3859
const RlsViolationException({required this.recordId, this.rowOwner});
60+
61+
/// The primary-key identifier of the offending record.
3962
final String recordId;
63+
64+
/// The user_id that owns the row, if known.
4065
final String? rowOwner;
66+
4167
@override
4268
String toString() =>
4369
'RlsViolationException: record $recordId owned by $rowOwner';

0 commit comments

Comments
 (0)