### Complete Logging Setup Example Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/utilities.md Sets up logging for SpacetimeDB Dart, directing errors to a file in production or enabling developer logs in development. Ensure to call this early in your application's lifecycle. ```dart import 'package:spacetimedb/spacetimedb.dart'; import 'dart:io'; import 'dart:async'; void setupLogging({required String appDocDir, required bool isProduction}) { if (isProduction) { // Production: Log errors to file and service final logFile = File('$appDocDir/spacetimedb.log'); SdkLogger.onLog = (level, message) { if (level == 'E') { final timestamp = DateTime.now().toIso8601String(); logFile.writeAsStringSync( '[$timestamp] ERROR: $message\n', mode: FileMode.append, ); } }; } else { // Development: Log to DevTools for inspection SdkLogger.enableDeveloperLog(); } } void main() { // Initialize logging setupLogging( appDocDir: Directory.current.path, isProduction: const bool.fromEnvironment('dart.vm.product'), ); // Now SDK logs are available SdkLogger.i('App starting...'); // Create client with SDK logging enabled final connection = SpacetimeDbConnection( host: 'api.example.com:3000', database: 'mydb', ssl: true, ); // SDK logs connection lifecycle: // [I] Attempting to connect // [D] WebSocket connecting to wss://api.example.com:3000/v2/database/mydb/subscribe // [I] Connected (on success) // [W] Reconnecting in 1s (on failure) // [E] Max reconnect attempts reached (on fatal failure) } ``` -------------------------------- ### Complete OIDC Authentication Flow Example Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/auth.md Demonstrates the full OAuth authentication process using `OidcHelper` and `SpacetimeDbConnection`. This includes getting the auth URL, launching it in a browser, handling the callback, and reconnecting the SpacetimeDB client with the obtained token. Ensure you have `url_launcher` and `spacetimedb` packages installed. ```dart import 'package:spacetimedb/spacetimedb.dart'; import 'package:url_launcher/url_launcher.dart'; void main() async { final authStorage = InMemoryTokenStore(); final connection = SpacetimeDbConnection( host: 'localhost:3000', database: 'mydb', ssl: false, authStorage: authStorage, ); final subscriptionManager = SubscriptionManager(connection); // Set up OIDC helper final oidc = OidcHelper( host: 'api.game.com', database: 'mygame', ssl: true, ); // Step 1: Get auth URL final authUrl = oidc.getAuthUrl('google', redirectUri: 'myapp://callback', ); // Step 2: Open in browser (using url_launcher or your navigation) if (await canLaunchUrl(Uri.parse(authUrl))) { await launchUrl(Uri.parse(authUrl)); } // Step 3: Handle callback (typically in your app's deep link handler) // When the callback arrives, parse the token void handleAuthCallback(String callbackUrl) async { final token = oidc.parseTokenFromCallback(callbackUrl); if (token != null) { // Save token await authStorage.saveToken(token); // Update connection and reconnect connection.updateToken(token); await connection.reconnect(); // Now you're authenticated! print('Authentication successful'); } } } ``` -------------------------------- ### Initialize JsonFileStorage Example Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/offline.md Example demonstrating how to initialize `JsonFileStorage` using a directory path obtained from `getApplicationDocumentsDirectory` and then calling the `initialize` method. ```dart import 'package:path_provider/path_provider.dart'; final appDir = await getApplicationDocumentsDirectory(); final storage = JsonFileStorage(basePath: appDir.path); await storage.initialize(); ``` -------------------------------- ### Complete SpacetimeDB Initialization Example Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/configuration.md This example demonstrates the full initialization process for a SpacetimeDB connection, including setting up authentication storage, offline storage, creating the connection with configuration, managing subscriptions, registering decoders, and handling connection events. ```dart import 'package:spacetimedb/spacetimedb.dart'; import 'package:path_provider/path_provider.dart'; void main() async { // 1. Set up auth storage final authStorage = InMemoryTokenStore(); final savedToken = await authStorage.loadToken(); // 2. Set up offline storage (mobile/desktop) final appDir = await getApplicationDocumentsDirectory(); final storage = JsonFileStorage(basePath: appDir.path); await storage.initialize(); // 3. Create connection with configuration final connection = SpacetimeDbConnection( host: 'api.example.com:3000', database: 'production', initialToken: savedToken, ssl: true, config: ConnectionConfig.mobile, // Mobile-optimized ); // 4. Create subscription manager final subscriptionManager = SubscriptionManager( connection, offlineStorage: storage, ); // 5. Register decoders (generated code) subscriptionManager.cache.registerDecoder('user', UserDecoder()); subscriptionManager.cache.registerDecoder('post', PostDecoder()); subscriptionManager.reducerRegistry .registerDecoder('create_post', CreatePostArgsDecoder()); // 6. Configure reducer timeout subscriptionManager.reducers.defaultTimeout = Duration(seconds: 20); // 7. Connect try { await connection.connect(); } catch (e) { print('Connection failed: $e'); // Handle auth failure, network error, etc. return; } // 8. Subscribe to tables await subscriptionManager.subscribe([ 'SELECT * FROM user', 'SELECT * FROM post', ]); // 9. Listen for updates subscriptionManager.onInitialSubscription.listen((_) { print('Subscription loaded'); }); // Ready to use! final users = subscriptionManager.cache.getTableByTypedName('user'); print('Users: ${users.count()}'); } ``` -------------------------------- ### Start SpacetimeDB Server Source: https://github.com/mitsh/spacetimedb-dart/blob/main/TESTING.md Starts the SpacetimeDB server. This command is a solution for 'Connection refused' errors during integration testing. ```bash spacetime start ``` -------------------------------- ### Install Dependencies Source: https://github.com/mitsh/spacetimedb-dart/blob/main/README.md After adding the dependency, run this command to fetch all project dependencies. ```bash dart pub get ``` -------------------------------- ### Run Example Application Source: https://github.com/mitsh/spacetimedb-dart/blob/main/example/README.md Execute the example Dart application to test basic SpacetimeDB functionalities. Update connection details and subscription queries to match your specific SpacetimeDB module configuration. ```bash dart run example/example.dart ``` -------------------------------- ### Clone Repository and Install Dependencies Source: https://github.com/mitsh/spacetimedb-dart/blob/main/CONTRIBUTING.md Clone the repository, navigate to the project directory, and install Dart dependencies. ```bash git clone https://github.com/mitsh/spacetimedb-dart.git cd spacetimedb-dart dart pub get dart test ``` -------------------------------- ### SpacetimeDbConnection Example Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/configuration.md An example demonstrating how to instantiate SpacetimeDbConnection with specific host, database, token, SSL, and configuration settings. ```dart final connection = SpacetimeDbConnection( host: 'api.example.com:3000', database: 'production_db', initialToken: await authStorage.loadToken(), ssl: true, config: ConnectionConfig.mobile, ); ``` -------------------------------- ### Complete SpacetimeDB Dart SDK Usage Example Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/INDEX.md A comprehensive example showing the initialization and usage of the SpacetimeDB Dart SDK. It covers setting up logging, authentication, offline storage, connection, subscriptions, data access, reducer calls, and cleanup. ```dart import 'package:spacetimedb/spacetimedb.dart'; import 'package:path_provider/path_provider.dart'; void main() async { // 1. Initialize SDK logger SdkLogger.enableDeveloperLog(); // 2. Set up authentication storage final authStorage = InMemoryTokenStore(); // 3. Set up offline storage (optional) final appDir = await getApplicationDocumentsDirectory(); final offlineStorage = JsonFileStorage(basePath: appDir.path); await offlineStorage.initialize(); // 4. Create connection with configuration final connection = SpacetimeDbConnection( host: 'api.example.com:3000', database: 'production', ssl: true, config: ConnectionConfig.mobile, ); // 5. Create subscription manager final subscriptionManager = SubscriptionManager( connection, offlineStorage: offlineStorage, ); // 6. Register decoders (generated code) subscriptionManager.cache.registerDecoder('user', UserDecoder()); subscriptionManager.cache.registerDecoder('post', PostDecoder()); subscriptionManager.reducerRegistry .registerDecoder('create_post', CreatePostArgsDecoder()); // 7. Connect and subscribe try { await connection.connect(); await subscriptionManager.subscribe(['SELECT * FROM user', 'SELECT * FROM post']); } catch (e) { print('Connection failed: $e'); return; } // 8. Access cached data and listen to updates subscriptionManager.onInitialSubscription.listen((_) { final users = subscriptionManager.cache.getTableByTypedName('user'); print('Loaded ${users.count()} users'); }); final postTable = subscriptionManager.cache.getTableByTypedName('post'); postTable.eventStream.listen((event) { switch (event) { case TableInsertEvent(:final row, :final context): print('New post: ${row.title}'); if (context.isMyTransaction) print('Created by me!'); case TableUpdateEvent(:final newRow): print('Updated: ${newRow.title}'); case TableDeleteEvent(:final row): print('Deleted: ${row.title}'); } }); // 9. Call reducers final result = await subscriptionManager.reducers.callWith( 'create_post', (encoder) { encoder.writeString('My Post'); encoder.writeString('Content here'); }, ); if (result.isSuccess) { print('Post created!'); } else if (result.isPending) { print('Post queued for offline sync'); } // 10. Monitor offline sync subscriptionManager.onSyncStateChanged.listen((state) { print('Sync: ${state.status}, pending: ${state.pendingCount}'); }); // 11. Clean up on exit await subscriptionManager.dispose(); await connection.dispose(); await offlineStorage.dispose(); } ``` -------------------------------- ### Setup Test Database Source: https://github.com/mitsh/spacetimedb-dart/blob/main/TESTING.md Runs a script to set up the test database. This is a solution for 'Database not found' errors. ```bash ./tool/setup_test_db.sh ``` -------------------------------- ### Install SpacetimeDB CLI Source: https://github.com/mitsh/spacetimedb-dart/blob/main/TESTING.md Installs the SpacetimeDB Command Line Interface using a curl script. Ensure you have curl installed and an active internet connection. ```bash curl --proto '=https' --tlsv1.2 -sSf https://install.spacetimedb.com | sh ``` -------------------------------- ### Example Usage of Connection Presets Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/connection.md Demonstrates how to instantiate a SpacetimeDbConnection using a predefined connection configuration, such as the mobile preset. ```dart final connection = SpacetimeDbConnection( host: 'api.example.com', database: 'mydb', config: ConnectionConfig.mobile, // Use mobile preset ); ``` -------------------------------- ### Install SpacetimeDB Dart Package Source: https://github.com/mitsh/spacetimedb-dart/blob/main/README.md Add the spacetimedb package to your project's dependencies in pubspec.yaml and run dart pub get to install. ```yaml dependencies: spacetimedb: ^1.3.0 ``` -------------------------------- ### Verify SpacetimeDB CLI Installation Source: https://github.com/mitsh/spacetimedb-dart/blob/main/TESTING.md Checks if the SpacetimeDB CLI has been installed correctly by displaying its version. This command requires the CLI to be in your system's PATH. ```bash spacetime --version ``` -------------------------------- ### Connect to SpacetimeDB Source: https://github.com/mitsh/spacetimedb-dart/blob/main/README.md Establish a connection to SpacetimeDB. This example demonstrates basic connection parameters and listening to connection status changes. ```dart final client = await SpacetimeDbClient.connect( host: 'localhost:3000', database: 'your_database', ssl: false, authStorage: InMemoryTokenStore(), ); client.connection.connectionStatus.listen((status) { print('Connection status: $status'); }); ``` -------------------------------- ### Connect with InMemoryTokenStore Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/auth.md Example of connecting to SpacetimeDB using the InMemoryTokenStore. Note that this storage is not persistent. ```dart final client = await SpacetimeDbClient.connect( host: 'localhost:3000', database: 'mygame', authStorage: InMemoryTokenStore(), // Not persistent! ); ``` -------------------------------- ### Default No Logging Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/utilities.md Demonstrates the default behavior where all log methods are no-ops. No setup is required. ```dart // No setup needed — all logs are no-ops SdkLogger.d('This does nothing'); SdkLogger.i('This does nothing'); ``` -------------------------------- ### Complete Reducer Example in Dart Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/reducers.md Shows how to register a reducer decoder, call a reducer with typed arguments, handle the transaction result, and listen for reducer events. ```dart import 'package:spacetimedb/spacetimedb.dart'; // Generated args class class CreatePostArgs { final String title; final String content; CreatePostArgs({required this.title, required this.content}); } // Generated decoder class CreatePostArgsDecoder implements ReducerArgDecoder { @override dynamic decode(BsatnDecoder decoder) { final title = decoder.readString(); final content = decoder.readString(); return CreatePostArgs(title: title, content: content); } } void main() async { final subscriptionManager = SubscriptionManager(connection); // Register reducer decoders subscriptionManager.reducerRegistry .registerDecoder('create_post', CreatePostArgsDecoder()); // Call reducer with typed args final result = await subscriptionManager.reducers.callWith( 'create_post', (encoder) { encoder.writeString('My First Post'); encoder.writeString('This is the content...'); }, ); // Handle result if (result.isSuccess) { print('Post created successfully!'); print('Energy used: ${result.energyConsumed}'); print('Time: ${result.executionDuration}'); } else if (result.isPending) { print('Post queued for offline sync'); } else { print('Error: ${result.errorMessage}'); } // Listen for transaction results subscriptionManager.reducerEmitter.onReducerEvent.listen((event) { if (event.reducerName == 'create_post') { final args = event.reducerArgs as CreatePostArgs; print('Post created by ${event.callerIdentity}: ${args.title}'); } }); } ``` -------------------------------- ### Example Usage of InMemoryOfflineStorage Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/offline.md Demonstrates initializing `InMemoryOfflineStorage`, saving a table snapshot, and loading it back. Useful for testing offline data handling. ```dart final storage = InMemoryOfflineStorage(); await storage.initialize(); final rows = [ {'id': 1, 'title': 'First Note'}, {'id': 2, 'title': 'Second Note'}, ]; await storage.saveTableSnapshot('note', rows); final loaded = await storage.loadTableSnapshot('note'); print('Loaded ${loaded?.length} rows'); ``` -------------------------------- ### Complete SpacetimeDB Dart Subscription Example Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/subscription.md This snippet demonstrates the full lifecycle of connecting to SpacetimeDB, setting up subscriptions, handling data updates, calling reducers, and managing connection state. Ensure you have generated table and reducer decoders before running. ```dart import 'package:spacetimedb/spacetimedb.dart'; // Initialize connection final connection = SpacetimeDbConnection( host: 'localhost:3000', database: 'mydb', ssl: false, config: ConnectionConfig.mobile, ); // Create subscription manager final subscriptionManager = SubscriptionManager(connection); // Register table decoders (generated code) subscriptionManager.cache.registerDecoder('user', UserDecoder()); subscriptionManager.cache.registerDecoder('post', PostDecoder()); // Register reducer decoders (generated code) subscriptionManager.reducerRegistry.registerDecoder('create_post', CreatePostArgsDecoder()); // Connect to server await connection.connect(); // Subscribe to tables await subscriptionManager.subscribe([ 'SELECT * FROM user', 'SELECT * FROM post WHERE user_id = @user_id', ]); // Listen for initial subscription subscriptionManager.onInitialSubscription.listen((msg) { print('Subscription loaded with ${msg.tableUpdates.length} tables'); }); // Access cached data subscriptionManager.onInitialSubscription.first.then((_) { final users = subscriptionManager.cache.getTableByTypedName('user'); print('Users: ${users.count()}'); }); // Listen for real-time updates final postTable = subscriptionManager.cache.getTableByTypedName('post'); postTable.insertStream.listen((post) { print('New post: ${post.title}'); }); postTable.updateStream.listen((update) { print('Updated: ${update.oldRow.title} → ${update.newRow.title}'); }); // Call reducers final result = await subscriptionManager.reducers.call( 'create_post', BsatnEncoder() ..writeString('My Post') ..writeString('Content here') .toBytes(), ); if (result.isSuccess) { print('Reducer succeeded'); } else { print('Reducer failed: ${result.errorMessage}'); } // Monitor identity subscriptionManager.onIdentityToken.listen((msg) { final identity = subscriptionManager.identity; if (identity != null) { print('User identity: ${identity.toHexString}'); print('Abbreviated: ${identity.toAbbreviated}'); } }); // Offline sync monitoring (if offline storage enabled) subscriptionManager.onSyncStateChanged.listen((state) { print('Sync state: ${state.status}, pending: ${state.pendingCount}'); if (state.hasError) { print('Last error: ${state.lastError}'); } }); // Clean up await subscriptionManager.dispose(); await connection.dispose(); ``` -------------------------------- ### Connect to SpacetimeDB and Subscribe Source: https://github.com/mitsh/spacetimedb-dart/blob/main/README.md Connect to a SpacetimeDB instance using the generated client. This example shows how to establish a connection with specified host, database, SSL settings, authentication storage, and initial subscriptions. ```dart import 'package:spacetimedb/spacetimedb.dart'; import 'generated/client.dart'; final client = await SpacetimeDbClient.connect( host: 'localhost:3000', database: 'your_database', ssl: false, authStorage: InMemoryTokenStore(), initialSubscriptions: ['SELECT * FROM users'], ); ``` -------------------------------- ### Instantiate BsatnEncoder Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/codec.md Creates a new instance of the BsatnEncoder. No specific setup is required before instantiation. ```dart final encoder = BsatnEncoder(); ``` -------------------------------- ### Call a Reducer to Create User Source: https://github.com/mitsh/spacetimedb-dart/blob/main/README.md Execute a reducer function on the server to create a new user. This example checks the result of the reducer call for success. ```dart final result = await client.reducers.createUser(name: 'Alice'); if (result.isSuccess) { print('Reducer call succeeded'); } ``` -------------------------------- ### Complete Offline Example with JSON Storage Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/offline.md This snippet demonstrates initializing `JsonFileStorage`, connecting to SpacetimeDB with offline support, and managing subscriptions and mutations. It includes listening to sync state changes and mutation results, and queuing a reducer call for offline synchronization. ```dart import 'package:spacetimedb/spacetimedb.dart'; import 'package:path_provider/path_provider.dart'; void main() async { // Get app documents directory final appDir = await getApplicationDocumentsDirectory(); // Initialize storage final storage = JsonFileStorage(basePath: appDir.path); await storage.initialize(); // Create connection with offline support final connection = SpacetimeDbConnection( host: 'localhost:3000', database: 'mydb', ssl: false, ); // Create subscription manager with offline storage final subscriptionManager = SubscriptionManager( connection, offlineStorage: storage, ); // Register decoders subscriptionManager.cache.registerDecoder('note', NoteDecoder()); // Monitor sync state subscriptionManager.onSyncStateChanged.listen((state) { print('Sync state: ${state.status}'); print('Pending mutations: ${state.pendingCount}'); if (state.hasPending) { print('Will sync when online'); } if (state.hasError) { print('Last error: ${state.lastError}'); } }); // Listen for sync results subscriptionManager.onMutationSyncResult.listen((result) { if (result.success) { print('${result.reducerName} synced successfully'); } else { print('Failed to sync ${result.reducerName}: ${result.error}'); } }); // Connect and subscribe await connection.connect(); await subscriptionManager.subscribe(['SELECT * FROM note']); // Call reducer (will queue offline if disconnected) final result = await subscriptionManager.reducers.callWith( 'create_note', (encoder) { encoder.writeString('Offline Note'); encoder.writeString('This was created offline'); }, ); if (result.isPending) { print('Note queued for offline sync'); } else { print('Note created immediately'); } // Manually trigger sync when online subscriptionManager.syncPendingMutations(); // Clean up await subscriptionManager.dispose(); await connection.dispose(); await storage.dispose(); } ``` -------------------------------- ### Int64 Usage Example Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/types.md Demonstrates the creation of a 64-bit integer using the Int64 class from the 'fixnum' package. This is used for specific 64-bit integer operations. ```dart import 'package:spacetimedb/spacetimedb.dart'; final num = Int64(9223372036854775807); ``` -------------------------------- ### Implement Reducer Argument Decoding Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/reducers.md Example implementation of a ReducerArgDecoder for 'CreatePostArgs'. It defines how to read string fields from a BsatnDecoder. ```dart class CreatePostArgsDecoder implements ReducerArgDecoder { @override dynamic decode(BsatnDecoder decoder) { final title = decoder.readString(); final content = decoder.readString(); return CreatePostArgs(title: title, content: content); } } ``` -------------------------------- ### Deserialize and Use Reducer Arguments Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/reducers.md Example of deserializing arguments for 'create_post' and accessing properties like 'title'. Type checking is recommended. ```dart final args = registry.deserializeArgs('create_post', rawBytes); if (args is CreatePostArgs) { print('Title: ${args.title}'); } ``` -------------------------------- ### Complete BSATN Encoding and Decoding Example Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/codec.md Demonstrates a full cycle of encoding data using BsatnEncoder and then decoding it using BsatnDecoder. Shows how to encode and decode strings, integers, booleans, and arrays. ```dart import 'package:spacetimedb/spacetimedb.dart'; // Encoding final encoder = BsatnEncoder(); encoder.writeString('Alice'); encoder.writeU32(30); encoder.writeBool(true); encoder.writeArray([1, 2, 3], (v) => encoder.writeU32(v)); final bytes = encoder.toBytes(); // Decoding final decoder = BsatnDecoder(bytes); final name = decoder.readString(); // 'Alice' final age = decoder.readU32(); // 30 final active = decoder.readBool(); // true final scores = decoder.readArray(() => decoder.readU32()); // [1, 2, 3] ``` -------------------------------- ### Developer Logging Setup Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/utilities.md Configures the logger to send output to dart:developer, making it visible in DevTools. This is useful for debugging during development. ```dart // Enable logging to dart:developer (visible in DevTools) SdkLogger.enableDeveloperLog(); // Now logs appear in DevTools Timeline and Console SdkLogger.d('Debug info'); SdkLogger.i('Info message'); ``` -------------------------------- ### Register Reducer Argument Decoders Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/reducers.md Example of registering decoders for 'create_post' and 'update_post' reducers. Ensure you have corresponding decoder classes. ```dart registry.registerDecoder('create_post', CreatePostArgsDecoder()); registry.registerDecoder('update_post', UpdatePostArgsDecoder()); ``` -------------------------------- ### Remove Test Setup Flag Source: https://github.com/mitsh/spacetimedb-dart/blob/main/TESTING.md Removes the `.test_setup_done` file, which is used to track whether the test environment has been set up. This is part of the clean-up process. ```bash rm .test_setup_done ``` -------------------------------- ### Access and Subscribe to View Changes Source: https://github.com/mitsh/spacetimedb-dart/blob/main/README.md Interact with server-defined views, which have similar APIs to tables. This example shows iterating over a 'myGames' view and listening for updates to 'myPlayerData'. ```dart // Views work like tables — same cache and stream APIs for (final game in client.myGames.iter()) { print('Game: ${game.id}, status: ${game.status}'); } // Subscribe to view changes client.myPlayerData.updateStream.listen((update) { print('Energy changed: ${update.old.energy} → ${update.new_.energy}'); }); ``` -------------------------------- ### Enable Offline Support with JSON Storage Source: https://github.com/mitsh/spacetimedb-dart/blob/main/README.md Configure the client to support offline operations by providing a storage mechanism. This example uses JsonFileStorage to persist mutations locally. ```dart final client = await SpacetimeDbClient.connect( host: 'localhost:3000', database: 'your_database', offlineStorage: JsonFileStorage(basePath: '/tmp/spacetimedb_cache'), ); print('Pending mutations: ${client.syncState.pendingCount}'); ``` -------------------------------- ### RowDecoder getPrimaryKey method implementation Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/cache.md Example implementation of the getPrimaryKey method to extract the primary key from a row, used for efficient lookups and update detection. ```dart @override dynamic getPrimaryKey(T row) => row.id; ``` -------------------------------- ### Manually Sync Pending Mutations and Listen to Sync State Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/subscription.md Manually trigger synchronization of offline-queued mutations. This is only effective if offline storage is enabled. The example also shows how to listen to changes in the offline sync state. ```dart subscriptionManager.onSyncStateChanged.listen((state) { print('Pending mutations: ${state.pendingCount}'); }); // Manually trigger sync subscriptionManager.syncPendingMutations(); ``` -------------------------------- ### Get Count of Registered Reducers Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/reducers.md Obtain the total number of reducers that have been registered. ```dart int get count ``` -------------------------------- ### Count rows in cache Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/cache.md Get the total number of rows currently stored in the cache. ```dart int count() ``` ```dart print('Total notes: ${noteTable.count()}'); ``` -------------------------------- ### Initialize SpacetimeDbConnection Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/connection.md Instantiate SpacetimeDbConnection with host, database, and optional parameters like SSL and initial token. ```dart final connection = SpacetimeDbConnection( host: 'localhost:3000', database: 'mydb', ssl: false, ); ``` -------------------------------- ### initialize() Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/offline.md Initializes the storage backend. This method must be called before any other operations can be performed on the storage. ```APIDOC ### initialize() → Future Initialize storage backend. Must be called before other operations. **Example:** ```dart await offlineStorage.initialize(); ``` ``` -------------------------------- ### Get List of Registered Reducer Names Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/reducers.md Retrieve a list of all registered reducer names, useful for debugging purposes. ```dart List get registeredReducers ``` -------------------------------- ### Setting Up Event Listeners for Table Changes Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/events.md This snippet demonstrates how to monitor all changes to a table, handle specific event types (insert, update, delete) with context, and utilize convenience streams for personal actions and notifications for others. ```dart import 'package:spacetimedb/spacetimedb.dart'; void setupEventListeners( TableCache noteTable, TableCache userTable, ) { // 1. Monitor all changes with context noteTable.eventStream.listen((event) { switch (event) { case TableInsertEvent(:final row, :final context): _handleNoteInsert(row, context); case TableUpdateEvent(:final newRow, :final context): _handleNoteUpdate(newRow, context); case TableDeleteEvent(:final row, :final context): _handleNoteDelete(row, context); } }); // 2. Show success feedback for my actions noteTable.myInserts.listen((event) { showSnackBar('Note created: ${event.row.title}'); }); noteTable.myUpdates.listen((event) { showSnackBar('Note updated'); }); noteTable.myDeletes.listen((event) { showSnackBar('Note deleted (undo)', onUndo: () { // Call reducer to recreate }); }); // 3. Show notifications for others' actions noteTable.insertEventStream .where((e) => !e.context.isMyTransaction) .listen((event) { final note = event.row; showNotification('$note.author created: ${note.title}'); }); // 4. Track reducer calls noteTable.insertEventStream.listen((event) { if (event.context.event is ReducerEvent) { final tx = event.context.event as ReducerEvent; final args = tx.reducerArgs as CreateNoteArgs; // Log for analytics analyticsService.logReducerCall( reducerName: tx.reducerName, args: args, isMyCall: event.context.isMyTransaction, ); } }); } void _handleNoteInsert(Note note, EventContext context) { print('New note: ${note.title}'); if (context.isMyTransaction) { print('Created by me'); } else if (context.event is ReducerEvent) { final tx = context.event as ReducerEvent; print('Created by reducer ${tx.reducerName}'); } } void _handleNoteUpdate(Note note, EventContext context) { print('Updated: ${note.title}'); // Update UI optimistically or with animation } void _handleNoteDelete(Note note, EventContext context) { print('Deleted: ${note.title}'); // Animate removal from UI } ``` -------------------------------- ### File-Based Logging Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/utilities.md Sets up logging to a file named 'spacetimedb.log' in the application's directory. Log entries include timestamps and levels. Remember to close the sink when the application exits. ```dart import 'dart:io'; final logFile = File('${appDir.path}/spacetimedb.log'); final sink = logFile.openWrite(mode: FileMode.append); SdkLogger.onLog = (level, message) { final timestamp = DateTime.now().toIso8601String(); sink.writeln('[$timestamp] [$level] $message'); }; // Don't forget to close on app exit: // await sink.flush(); // await sink.close(); ``` -------------------------------- ### Get Pending Mutations Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/offline.md Retrieves all mutations currently in the offline queue that are awaiting synchronization. Returns a list of `PendingMutation` objects. ```dart Future> getPendingMutations() ``` -------------------------------- ### Simple Stream Patterns (No Context) Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/events.md Demonstrates listening to basic insert, update, and delete streams without transaction context. Use when context is not needed. ```dart // Insert stream (just the row, no context) noteTable.insertStream.listen((note) { print('New note: ${note.title}'); }); // Update stream (old and new rows, no context) noteTable.updateStream.listen((update) { print('Updated: ${update.oldRow.title} → ${update.newRow.title}'); }); // Delete stream (just the row, no context) noteTable.deleteStream.listen((note) { print('Deleted: ${note.title}'); }); ``` -------------------------------- ### Initialize ReducerRegistry Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/reducers.md Instantiate the ReducerRegistry. This is typically done during client initialization. ```dart ReducerRegistry() ``` -------------------------------- ### Encode and Get Bytes Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/codec.md Encodes written data into an immutable Uint8List. Ensure all desired data is written before calling toBytes(). ```dart final encoder = BsatnEncoder(); encoder.writeU32(42); final bytes = encoder.toBytes(); ``` -------------------------------- ### RowDecoder decode method implementation Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/cache.md Example implementation of the decode method for deserializing a row from BSATN bytes using the provided decoder. ```dart @override T decode(BsatnDecoder decoder) { final id = decoder.readU32(); final title = decoder.readString(); final active = decoder.readBool(); return Note(id: id, title: title, active: active); } ``` -------------------------------- ### Authenticate and Get Identity Source: https://github.com/mitsh/spacetimedb-dart/blob/main/README.md Connect to SpacetimeDB with SSL enabled and authenticate. This snippet shows how to retrieve the client's identity after connection. ```dart final client = await SpacetimeDbClient.connect( host: 'spacetimedb.example.com', database: 'app_db', ssl: true, authStorage: InMemoryTokenStore(), ); print(client.identity?.toHexString); ``` -------------------------------- ### OidcHelper Constructor Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/auth.md Initializes the OidcHelper with connection details for authentication. ```APIDOC ## OidcHelper Constructor ### Description Initializes the OIDC helper with the necessary server connection details. ### Parameters #### Path Parameters * None #### Query Parameters * None #### Request Body * None ### Constructor Parameters * **`host`** (`String`) - Required - Server hostname and port * **`database`** (`String`) - Required - Database name * **`ssl`** (`bool`) - Optional, defaults to `false` - Use HTTPS instead of HTTP ``` -------------------------------- ### connect() Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/connection.md Initiates the WebSocket connection to the SpacetimeDB server. This method handles the initial connection attempt and respects the auto-reconnect and connection timeout configurations. ```APIDOC ## connect() Initiates WebSocket connection to the SpacetimeDB server. Honors `config.autoReconnect` and `config.connectTimeout`. ### Method `Future connect()` ### Throws - `SpacetimeDbAuthException` — If server returns 401 (token invalid/expired) - Other exceptions — Network errors, timeout ### Example ```dart final connection = SpacetimeDbConnection( host: 'localhost:3000', database: 'mydb', ssl: false, ); try { await connection.connect(); print('Connected'); } catch (e) { print('Connection failed: $e'); } ``` ``` -------------------------------- ### Import SpacetimeDB Dart SDK Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/INDEX.md Import all public APIs from the main entry point of the SpacetimeDB Dart SDK. ```dart import 'package:spacetimedb/spacetimedb.dart'; ``` -------------------------------- ### Initialize Offline Storage Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/offline.md Call this method to initialize the storage backend before performing any other operations. ```dart await offlineStorage.initialize(); ``` -------------------------------- ### Read Map with Length Prefix Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/codec.md Decodes a map that starts with a u32 length prefix, followed by key-value pairs. Callbacks are provided for decoding both keys and values. ```dart Map readMap( K Function() readKey, V Function() readValue, ) ``` ```dart final map = decoder.readMap( () => decoder.readString(), () => decoder.readU32(), ); ``` -------------------------------- ### SpacetimeDbConnection Constructor Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/configuration.md Defines the parameters for establishing a connection to SpacetimeDB, including host, database, authentication token, SSL usage, and custom configuration. ```dart SpacetimeDbConnection({ required String host, required String database, String? initialToken, bool ssl = false, ConnectionConfig config = const ConnectionConfig(), WebSocketFactory? socketFactory, }) ``` -------------------------------- ### SpacetimeDbConnection Constructor Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/connection.md Initializes a new SpacetimeDbConnection instance to manage WebSocket communication with a SpacetimeDB server. ```APIDOC ## SpacetimeDbConnection Constructor Manages the lifecycle of a WebSocket connection including initial connection, automatic reconnection with exponential backoff, binary message sending/receiving, and connection state tracking. ### Parameters - **host** (String) - Required - Host and port (e.g., `localhost:3000`) - **database** (String) - Required - Database name - **initialToken** (String?) - Optional - Optional authentication token (bearer token) - **ssl** (bool) - Optional - Use WSS (secure) instead of WS. Defaults to `false`. - **config** (ConnectionConfig) - Optional - Connection behavior settings (reconnect delay, ping interval, etc.). Defaults to `const ConnectionConfig()`. - **socketFactory** (WebSocketFactory?) - Optional - Dependency injection for WebSocket creation (for testing). Defaults to `null`. ``` -------------------------------- ### Handle Transaction Result Status Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/reducers.md Example demonstrating how to check the status of a transaction result and access relevant information like energy consumed or error messages. ```dart final result = await reducerCaller.call('create_post', args); if (result.isSuccess) { print('Success! Energy used: ${result.energyConsumed}'); print('Duration: ${result.executionDuration}'); } else if (result.isPending) { print('Queued offline. Request: ${result.pendingRequestId}'); } else if (result.isFailed) { print('Error: ${result.errorMessage}'); } else if (result.isOutOfEnergy) { print('Out of energy: ${result.errorMessage}'); } ``` -------------------------------- ### ClientCache Constructor Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/cache.md Initializes a new ClientCache instance. This is the main container for all subscribed tables. ```dart ClientCache() ``` -------------------------------- ### Generate Typed Client Source: https://github.com/mitsh/spacetimedb-dart/blob/main/example/README.md Use this command to generate typed client code for your SpacetimeDB module. Ensure your SpacetimeDB instance is running and accessible via the specified host and database. ```bash dart run spacetimedb:generate \ -s http://localhost:3000 \ -d your_database \ -o lib/generated ``` -------------------------------- ### Get Last Sync Time Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/offline.md Retrieves the last successful synchronization timestamp for a given table. Returns a `DateTime` object or null if no sync time is recorded. ```dart Future getLastSyncTime(String tableName) ``` -------------------------------- ### SubscriptionManager with JsonFileStorage Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/configuration.md Configure SubscriptionManager with file-based storage for persisting mutations offline. Requires initializing the storage and syncing when online. ```dart import 'package:path_provider/path_provider.dart'; final appDir = await getApplicationDocumentsDirectory(); final storage = JsonFileStorage(basePath: appDir.path); await storage.initialize(); final subscriptionManager = SubscriptionManager( connection, offlineStorage: storage, ); ``` -------------------------------- ### Get Typed TableCache by ID Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/cache.md Retrieves a typed TableCache instance using its server-assigned table ID. Throws an error if the table is not registered or if there's a type mismatch. ```dart TableCache getTable(int tableId) ``` ```dart final players = cache.getTable(16); final count = players.count(); ``` -------------------------------- ### Generate Typed Client from Server Source: https://github.com/mitsh/spacetimedb-dart/blob/main/README.md Use the spacetimedb:generate command to create type-safe Dart APIs from your SpacetimeDB module running on a server. Specify the server host, database name, and output directory. ```bash dart run spacetimedb:generate -s http://localhost:3000 -d your_database -o lib/generated ``` -------------------------------- ### Connect to SpacetimeDB Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/connection.md Initiates the WebSocket connection. Handles connection timeouts and potential authentication errors. ```dart try { await connection.connect(); print('Connected'); } catch (e) { print('Connection failed: $e'); } ``` -------------------------------- ### Generate Typed Client from Local Module Source: https://github.com/mitsh/spacetimedb-dart/blob/main/README.md Generate type-safe Dart APIs from a local SpacetimeDB module directory instead of a running server. Specify the module path and the output directory. ```bash dart run spacetimedb:generate -p path/to/spacetimedb-module -o lib/generated ``` -------------------------------- ### Get Typed TableCache by Name Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/cache.md Retrieves a typed TableCache instance using its table name. This is the primary way to access table data after registration and subscription. Throws an error if the table is not activated or if there's a type mismatch. ```dart TableCache getTableByTypedName(String tableName) ``` ```dart final noteCache = cache.getTableByTypedName('note'); for (final note in noteCache.iter()) { print(note.title); } ``` -------------------------------- ### ConnectionConfig Parameters Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/connection.md Parameters available for configuring SpacetimeDB connection behavior, detailing their types, default values, and descriptions. ```dart `maxReconnectAttempts`: `int` | 10 | Maximum reconnection attempts before giving up `baseReconnectDelay`: `Duration` | 1s | Initial delay for exponential backoff `maxReconnectDelay`: `Duration` | 30s | Maximum delay between reconnection attempts `pingInterval`: `Duration` | 30s | How often to send keep-alive pings `pongTimeout`: `Duration` | 10s | How long to wait for pong before declaring connection stale `autoReconnect`: `bool` | true | Enable automatic reconnection on disconnect `connectTimeout`: `Duration` | 10s | Timeout for initial WebSocket connection ``` -------------------------------- ### ReducerCaller Constructor Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/reducers.md Initializes the ReducerCaller with a SpacetimeDbConnection and an optional OfflineStorage for offline-first capabilities. ```dart ReducerCaller( SpacetimeDbConnection _connection, {OfflineStorage? offlineStorage} ) ``` -------------------------------- ### Run Integration Tests Only Source: https://github.com/mitsh/spacetimedb-dart/blob/main/TESTING.md Executes only the integration tests, which require a running SpacetimeDB instance. This command targets the integration test directory. ```bash dart test test/integration/ ``` -------------------------------- ### Iterate and Listen to User Table Changes Source: https://github.com/mitsh/spacetimedb-dart/blob/main/README.md Access and iterate over the 'users' table. This snippet also shows how to listen for new user insertions in real-time. ```dart for (final user in client.users.iter()) { print('User: ${user.name}'); } client.users.insertStream.listen((user) { print('Inserted user: ${user.name}'); }); ``` -------------------------------- ### Run All Dart Tests Source: https://github.com/mitsh/spacetimedb-dart/blob/main/TESTING.md Executes all tests within the Dart project using the `dart test` command. This is the simplest way to run all tests, including unit and integration tests. ```bash dart test ``` -------------------------------- ### Run a Specific Test File Source: https://github.com/mitsh/spacetimedb-dart/blob/main/TESTING.md Executes tests within a single, specified test file. This is helpful for focusing on a particular test case during development. ```bash dart test test/integration/crud_test.dart ``` -------------------------------- ### Handle OfflineStorage.initialize() Failure Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/errors.md Catch exceptions during OfflineStorage initialization, which can occur due to file I/O errors, permission issues, or storage quotas. Fall back to in-memory storage if initialization fails. ```dart try { await storage.initialize(); subscriptionManager = SubscriptionManager(connection, offlineStorage: storage); } catch (e) { print('Offline storage initialization failed: $e'); // Fall back to in-memory storage subscriptionManager = SubscriptionManager( connection, offlineStorage: InMemoryOfflineStorage(), ); } ``` -------------------------------- ### JsonFileStorage Constructor Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/offline.md Initializes `JsonFileStorage` with a base path for storing data in JSON files. This implementation is available only on `dart:io` platforms and stores data unencrypted. ```APIDOC ## JsonFileStorage Constructor ### Description Initializes the `JsonFileStorage` with a specified base directory path. This storage mechanism is suitable for mobile and desktop platforms but stores data in plaintext JSON files. ### Parameters #### Path Parameters - **basePath** (`String`) - Required - The directory path where storage files will be located. ### Request Example ```dart import 'package:path_provider/path_provider.dart'; final appDir = await getApplicationDocumentsDirectory(); final storage = JsonFileStorage(basePath: appDir.path); await storage.initialize(); ``` ``` -------------------------------- ### OidcHelper Constructor Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/auth.md Initializes the OidcHelper with connection details for SpacetimeDB, used to generate authentication URLs for OAuth/OIDC flows. ```dart class OidcHelper { final String host; final String database; final bool ssl; OidcHelper({ required String host, required String database, bool ssl = false, }); } ``` -------------------------------- ### Enable SDK Logging with Custom Callback Source: https://github.com/mitsh/spacetimedb-dart/blob/main/README.md Configures a custom callback function to handle SDK log messages. This allows for flexible log routing, such as printing to the console. ```dart SdkLogger.onLog = (level, message) { // 'D' = debug, 'I' = info, 'W' = warning, 'E' = error print('[$level] $message'); }; ``` -------------------------------- ### readI64() Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/codec.md Decodes and returns a signed 64-bit integer. ```APIDOC #### readI64() → Int64 ```dart Int64 readI64() ``` Decodes a signed 64-bit integer. ``` -------------------------------- ### ClientCache.activateEmptyTable Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/cache.md Activates a table by name, specifically for cases where the server returns no rows for a subscribed table. This ensures the table is accessible via `getTableByTypedName` even if it contains no initial data. ```APIDOC ## ClientCache.activateEmptyTable ### Description Activate an empty table by name when server returns no rows. When a subscribed table has no rows, the server doesn't include it in InitialSubscription's tableUpdates. This method allows activating such tables so they're accessible via `getTableByTypedName()`. ### Method Signature ```dart TableCache activateEmptyTable(String tableName) ``` ### Parameters #### Path Parameters - **tableName** (String) - Required - Table name ### Throws - `ArgumentError` if no builder is registered for the table. ``` -------------------------------- ### SpacetimeDbConnection with InMemoryTokenStore Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/configuration.md Initialize SpacetimeDbConnection with an in-memory token store for authentication. The token can be saved and updated later. ```dart final authStorage = InMemoryTokenStore(); final connection = SpacetimeDbConnection( host: 'localhost:3000', database: 'mydb', initialToken: null, // Start unauthenticated authStorage: authStorage, ); // Later, after auth: await authStorage.saveToken(newToken); connection.updateToken(newToken); await connection.reconnect(); ``` -------------------------------- ### subscribe(List queries) → Future Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/subscription.md Subscribe to one or more SQL queries using SubscribeMulti protocol. Batches multiple queries into a single server request for efficiency. Server will send initial data via InitialSubscription, then stream updates via TransactionUpdate. ```APIDOC ## subscribe(List queries) → Future ### Description Subscribe to one or more SQL queries using SubscribeMulti protocol. Batches multiple queries into a single server request for efficiency. Server will send initial data via InitialSubscription, then stream updates via TransactionUpdate. ### Method Signature ```dart Future subscribe(List queries) ``` ### Parameters - **queries** (List) - SQL SELECT queries (e.g., `['SELECT * FROM users']`) ### Example ```dart await subscriptionManager.subscribe([ 'SELECT * FROM users WHERE active = true', 'SELECT * FROM posts WHERE user_id = 123', ]); ``` ``` -------------------------------- ### Enable SpacetimeDB Developer Logging Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/configuration.md Enable developer logging to see detailed logs in DevTools or Observatory. This is helpful during development and debugging phases. ```dart SdkLogger.enableDeveloperLog(); // Logs appear in DevTools/Observatory ``` -------------------------------- ### Monitor Connection Lifecycle with Logs and Listeners Source: https://github.com/mitsh/spacetimedb-dart/blob/main/_autodocs/api-reference/utilities.md Enables developer logs and listens to connection state and status changes to monitor the lifecycle. This is useful for debugging connection issues. ```dart SdkLogger.enableDeveloperLog(); connection.onStateChanged.listen((state) { // Also watch state changes print('State: $state'); }); connection.connectionStatus.listen((status) { print('Status: $status'); }); ```